media: replace all <spaces><tab> occurrences
[sfrench/cifs-2.6.git] / drivers / media / pci / saa7146 / hexium_orion.c
1 /*
2     hexium_orion.c - v4l2 driver for the Hexium Orion frame grabber cards
3
4     Visit http://www.mihu.de/linux/saa7146/ and follow the link
5     to "hexium" for further details about this card.
6
7     Copyright (C) 2003 Michael Hunold <michael@mihu.de>
8
9     This program is free software; you can redistribute it and/or modify
10     it under the terms of the GNU General Public License as published by
11     the Free Software Foundation; either version 2 of the License, or
12     (at your option) any later version.
13
14     This program is distributed in the hope that it will be useful,
15     but WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17     GNU General Public License for more details.
18
19     You should have received a copy of the GNU General Public License
20     along with this program; if not, write to the Free Software
21     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26 #define DEBUG_VARIABLE debug
27
28 #include <media/drv-intf/saa7146_vv.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31
32 static int debug;
33 module_param(debug, int, 0);
34 MODULE_PARM_DESC(debug, "debug verbosity");
35
36 /* global variables */
37 static int hexium_num;
38
39 #define HEXIUM_HV_PCI6_ORION            1
40 #define HEXIUM_ORION_1SVHS_3BNC         2
41 #define HEXIUM_ORION_4BNC               3
42
43 #define HEXIUM_INPUTS   9
44 static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
45         { 0, "CVBS 1",  V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
46         { 1, "CVBS 2",  V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
47         { 2, "CVBS 3",  V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
48         { 3, "CVBS 4",  V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
49         { 4, "CVBS 5",  V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
50         { 5, "CVBS 6",  V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
51         { 6, "Y/C 1",   V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
52         { 7, "Y/C 2",   V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
53         { 8, "Y/C 3",   V4L2_INPUT_TYPE_CAMERA, 0, 0, V4L2_STD_ALL, 0, V4L2_IN_CAP_STD },
54 };
55
56 #define HEXIUM_AUDIOS   0
57
58 struct hexium_data
59 {
60         s8 adr;
61         u8 byte;
62 };
63
64 struct hexium
65 {
66         int type;
67         struct video_device     video_dev;
68         struct i2c_adapter      i2c_adapter;
69
70         int cur_input;  /* current input */
71 };
72
73 /* Philips SAA7110 decoder default registers */
74 static u8 hexium_saa7110[53]={
75 /*00*/ 0x4C,0x3C,0x0D,0xEF,0xBD,0xF0,0x00,0x00,
76 /*08*/ 0xF8,0xF8,0x60,0x60,0x40,0x86,0x18,0x90,
77 /*10*/ 0x00,0x2C,0x40,0x46,0x42,0x1A,0xFF,0xDA,
78 /*18*/ 0xF0,0x8B,0x00,0x00,0x00,0x00,0x00,0x00,
79 /*20*/ 0xD9,0x17,0x40,0x41,0x80,0x41,0x80,0x4F,
80 /*28*/ 0xFE,0x01,0x0F,0x0F,0x03,0x01,0x81,0x03,
81 /*30*/ 0x44,0x75,0x01,0x8C,0x03
82 };
83
84 static struct {
85         struct hexium_data data[8];
86 } hexium_input_select[] = {
87 {
88         { /* cvbs 1 */
89                 { 0x06, 0x00 },
90                 { 0x20, 0xD9 },
91                 { 0x21, 0x17 }, // 0x16,
92                 { 0x22, 0x40 },
93                 { 0x2C, 0x03 },
94                 { 0x30, 0x44 },
95                 { 0x31, 0x75 }, // ??
96                 { 0x21, 0x16 }, // 0x03,
97         }
98 }, {
99         { /* cvbs 2 */
100                 { 0x06, 0x00 },
101                 { 0x20, 0x78 },
102                 { 0x21, 0x07 }, // 0x03,
103                 { 0x22, 0xD2 },
104                 { 0x2C, 0x83 },
105                 { 0x30, 0x60 },
106                 { 0x31, 0xB5 }, // ?
107                 { 0x21, 0x03 },
108         }
109 }, {
110         { /* cvbs 3 */
111                 { 0x06, 0x00 },
112                 { 0x20, 0xBA },
113                 { 0x21, 0x07 }, // 0x05,
114                 { 0x22, 0x91 },
115                 { 0x2C, 0x03 },
116                 { 0x30, 0x60 },
117                 { 0x31, 0xB5 }, // ??
118                 { 0x21, 0x05 }, // 0x03,
119         }
120 }, {
121         { /* cvbs 4 */
122                 { 0x06, 0x00 },
123                 { 0x20, 0xD8 },
124                 { 0x21, 0x17 }, // 0x16,
125                 { 0x22, 0x40 },
126                 { 0x2C, 0x03 },
127                 { 0x30, 0x44 },
128                 { 0x31, 0x75 }, // ??
129                 { 0x21, 0x16 }, // 0x03,
130         }
131 }, {
132         { /* cvbs 5 */
133                 { 0x06, 0x00 },
134                 { 0x20, 0xB8 },
135                 { 0x21, 0x07 }, // 0x05,
136                 { 0x22, 0x91 },
137                 { 0x2C, 0x03 },
138                 { 0x30, 0x60 },
139                 { 0x31, 0xB5 }, // ??
140                 { 0x21, 0x05 }, // 0x03,
141         }
142 }, {
143         { /* cvbs 6 */
144                 { 0x06, 0x00 },
145                 { 0x20, 0x7C },
146                 { 0x21, 0x07 }, // 0x03
147                 { 0x22, 0xD2 },
148                 { 0x2C, 0x83 },
149                 { 0x30, 0x60 },
150                 { 0x31, 0xB5 }, // ??
151                 { 0x21, 0x03 },
152         }
153 }, {
154         { /* y/c 1 */
155                 { 0x06, 0x80 },
156                 { 0x20, 0x59 },
157                 { 0x21, 0x17 },
158                 { 0x22, 0x42 },
159                 { 0x2C, 0xA3 },
160                 { 0x30, 0x44 },
161                 { 0x31, 0x75 },
162                 { 0x21, 0x12 },
163         }
164 }, {
165         { /* y/c 2 */
166                 { 0x06, 0x80 },
167                 { 0x20, 0x9A },
168                 { 0x21, 0x17 },
169                 { 0x22, 0xB1 },
170                 { 0x2C, 0x13 },
171                 { 0x30, 0x60 },
172                 { 0x31, 0xB5 },
173                 { 0x21, 0x14 },
174         }
175 }, {
176         { /* y/c 3 */
177                 { 0x06, 0x80 },
178                 { 0x20, 0x3C },
179                 { 0x21, 0x27 },
180                 { 0x22, 0xC1 },
181                 { 0x2C, 0x23 },
182                 { 0x30, 0x44 },
183                 { 0x31, 0x75 },
184                 { 0x21, 0x21 },
185         }
186 }
187 };
188
189 static struct saa7146_standard hexium_standards[] = {
190         {
191                 .name   = "PAL",        .id     = V4L2_STD_PAL,
192                 .v_offset       = 16,   .v_field        = 288,
193                 .h_offset       = 1,    .h_pixels       = 680,
194                 .v_max_out      = 576,  .h_max_out      = 768,
195         }, {
196                 .name   = "NTSC",       .id     = V4L2_STD_NTSC,
197                 .v_offset       = 16,   .v_field        = 240,
198                 .h_offset       = 1,    .h_pixels       = 640,
199                 .v_max_out      = 480,  .h_max_out      = 640,
200         }, {
201                 .name   = "SECAM",      .id     = V4L2_STD_SECAM,
202                 .v_offset       = 16,   .v_field        = 288,
203                 .h_offset       = 1,    .h_pixels       = 720,
204                 .v_max_out      = 576,  .h_max_out      = 768,
205         }
206 };
207
208 /* this is only called for old HV-PCI6/Orion cards
209    without eeprom */
210 static int hexium_probe(struct saa7146_dev *dev)
211 {
212         struct hexium *hexium = NULL;
213         union i2c_smbus_data data;
214         int err = 0;
215
216         DEB_EE("\n");
217
218         /* there are no hexium orion cards with revision 0 saa7146s */
219         if (0 == dev->revision) {
220                 return -EFAULT;
221         }
222
223         hexium = kzalloc(sizeof(*hexium), GFP_KERNEL);
224         if (!hexium)
225                 return -ENOMEM;
226
227         /* enable i2c-port pins */
228         saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
229
230         saa7146_write(dev, DD1_INIT, 0x01000100);
231         saa7146_write(dev, DD1_STREAM_B, 0x00000000);
232         saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
233
234         hexium->i2c_adapter = (struct i2c_adapter) {
235                 .name = "hexium orion",
236         };
237         saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
238         if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
239                 DEB_S("cannot register i2c-device. skipping.\n");
240                 kfree(hexium);
241                 return -EFAULT;
242         }
243
244         /* set SAA7110 control GPIO 0 */
245         saa7146_setgpio(dev, 0, SAA7146_GPIO_OUTHI);
246         /*  set HWControl GPIO number 2 */
247         saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
248
249         mdelay(10);
250
251         /* detect newer Hexium Orion cards by subsystem ids */
252         if (0x17c8 == dev->pci->subsystem_vendor && 0x0101 == dev->pci->subsystem_device) {
253                 pr_info("device is a Hexium Orion w/ 1 SVHS + 3 BNC inputs\n");
254                 /* we store the pointer in our private data field */
255                 dev->ext_priv = hexium;
256                 hexium->type = HEXIUM_ORION_1SVHS_3BNC;
257                 return 0;
258         }
259
260         if (0x17c8 == dev->pci->subsystem_vendor && 0x2101 == dev->pci->subsystem_device) {
261                 pr_info("device is a Hexium Orion w/ 4 BNC inputs\n");
262                 /* we store the pointer in our private data field */
263                 dev->ext_priv = hexium;
264                 hexium->type = HEXIUM_ORION_4BNC;
265                 return 0;
266         }
267
268         /* check if this is an old hexium Orion card by looking at
269            a saa7110 at address 0x4e */
270         err = i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_READ,
271                              0x00, I2C_SMBUS_BYTE_DATA, &data);
272         if (err == 0) {
273                 pr_info("device is a Hexium HV-PCI6/Orion (old)\n");
274                 /* we store the pointer in our private data field */
275                 dev->ext_priv = hexium;
276                 hexium->type = HEXIUM_HV_PCI6_ORION;
277                 return 0;
278         }
279
280         i2c_del_adapter(&hexium->i2c_adapter);
281         kfree(hexium);
282         return -EFAULT;
283 }
284
285 /* bring hardware to a sane state. this has to be done, just in case someone
286    wants to capture from this device before it has been properly initialized.
287    the capture engine would badly fail, because no valid signal arrives on the
288    saa7146, thus leading to timeouts and stuff. */
289 static int hexium_init_done(struct saa7146_dev *dev)
290 {
291         struct hexium *hexium = (struct hexium *) dev->ext_priv;
292         union i2c_smbus_data data;
293         int i = 0;
294
295         DEB_D("hexium_init_done called\n");
296
297         /* initialize the helper ics to useful values */
298         for (i = 0; i < sizeof(hexium_saa7110); i++) {
299                 data.byte = hexium_saa7110[i];
300                 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
301                         pr_err("failed for address 0x%02x\n", i);
302                 }
303         }
304
305         return 0;
306 }
307
308 static int hexium_set_input(struct hexium *hexium, int input)
309 {
310         union i2c_smbus_data data;
311         int i = 0;
312
313         DEB_D("\n");
314
315         for (i = 0; i < 8; i++) {
316                 int adr = hexium_input_select[input].data[i].adr;
317                 data.byte = hexium_input_select[input].data[i].byte;
318                 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x4e, 0, I2C_SMBUS_WRITE, adr, I2C_SMBUS_BYTE_DATA, &data)) {
319                         return -1;
320                 }
321                 pr_debug("%d: 0x%02x => 0x%02x\n", input, adr, data.byte);
322         }
323
324         return 0;
325 }
326
327 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
328 {
329         DEB_EE("VIDIOC_ENUMINPUT %d\n", i->index);
330
331         if (i->index >= HEXIUM_INPUTS)
332                 return -EINVAL;
333
334         memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
335
336         DEB_D("v4l2_ioctl: VIDIOC_ENUMINPUT %d\n", i->index);
337         return 0;
338 }
339
340 static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
341 {
342         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
343         struct hexium *hexium = (struct hexium *) dev->ext_priv;
344
345         *input = hexium->cur_input;
346
347         DEB_D("VIDIOC_G_INPUT: %d\n", *input);
348         return 0;
349 }
350
351 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
352 {
353         struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
354         struct hexium *hexium = (struct hexium *) dev->ext_priv;
355
356         if (input >= HEXIUM_INPUTS)
357                 return -EINVAL;
358
359         hexium->cur_input = input;
360         hexium_set_input(hexium, input);
361
362         return 0;
363 }
364
365 static struct saa7146_ext_vv vv_data;
366
367 /* this function only gets called when the probing was successful */
368 static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
369 {
370         struct hexium *hexium = (struct hexium *) dev->ext_priv;
371
372         DEB_EE("\n");
373
374         saa7146_vv_init(dev, &vv_data);
375         vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input;
376         vv_data.vid_ops.vidioc_g_input = vidioc_g_input;
377         vv_data.vid_ops.vidioc_s_input = vidioc_s_input;
378         if (0 != saa7146_register_device(&hexium->video_dev, dev, "hexium orion", VFL_TYPE_GRABBER)) {
379                 pr_err("cannot register capture v4l2 device. skipping.\n");
380                 return -1;
381         }
382
383         pr_err("found 'hexium orion' frame grabber-%d\n", hexium_num);
384         hexium_num++;
385
386         /* the rest */
387         hexium->cur_input = 0;
388         hexium_init_done(dev);
389
390         return 0;
391 }
392
393 static int hexium_detach(struct saa7146_dev *dev)
394 {
395         struct hexium *hexium = (struct hexium *) dev->ext_priv;
396
397         DEB_EE("dev:%p\n", dev);
398
399         saa7146_unregister_device(&hexium->video_dev, dev);
400         saa7146_vv_release(dev);
401
402         hexium_num--;
403
404         i2c_del_adapter(&hexium->i2c_adapter);
405         kfree(hexium);
406         return 0;
407 }
408
409 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
410 {
411         return 0;
412 }
413
414 static struct saa7146_extension extension;
415
416 static struct saa7146_pci_extension_data hexium_hv_pci6 = {
417         .ext_priv = "Hexium HV-PCI6 / Orion",
418         .ext = &extension,
419 };
420
421 static struct saa7146_pci_extension_data hexium_orion_1svhs_3bnc = {
422         .ext_priv = "Hexium HV-PCI6 / Orion (1 SVHS/3 BNC)",
423         .ext = &extension,
424 };
425
426 static struct saa7146_pci_extension_data hexium_orion_4bnc = {
427         .ext_priv = "Hexium HV-PCI6 / Orion (4 BNC)",
428         .ext = &extension,
429 };
430
431 static const struct pci_device_id pci_tbl[] = {
432         {
433          .vendor = PCI_VENDOR_ID_PHILIPS,
434          .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
435          .subvendor = 0x0000,
436          .subdevice = 0x0000,
437          .driver_data = (unsigned long) &hexium_hv_pci6,
438          },
439         {
440          .vendor = PCI_VENDOR_ID_PHILIPS,
441          .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
442          .subvendor = 0x17c8,
443          .subdevice = 0x0101,
444          .driver_data = (unsigned long) &hexium_orion_1svhs_3bnc,
445          },
446         {
447          .vendor = PCI_VENDOR_ID_PHILIPS,
448          .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
449          .subvendor = 0x17c8,
450          .subdevice = 0x2101,
451          .driver_data = (unsigned long) &hexium_orion_4bnc,
452          },
453         {
454          .vendor = 0,
455          }
456 };
457
458 MODULE_DEVICE_TABLE(pci, pci_tbl);
459
460 static struct saa7146_ext_vv vv_data = {
461         .inputs = HEXIUM_INPUTS,
462         .capabilities = 0,
463         .stds = &hexium_standards[0],
464         .num_stds = ARRAY_SIZE(hexium_standards),
465         .std_callback = &std_callback,
466 };
467
468 static struct saa7146_extension extension = {
469         .name = "hexium HV-PCI6 Orion",
470         .flags = 0,             // SAA7146_USE_I2C_IRQ,
471
472         .pci_tbl = &pci_tbl[0],
473         .module = THIS_MODULE,
474
475         .probe = hexium_probe,
476         .attach = hexium_attach,
477         .detach = hexium_detach,
478
479         .irq_mask = 0,
480         .irq_func = NULL,
481 };
482
483 static int __init hexium_init_module(void)
484 {
485         if (0 != saa7146_register_extension(&extension)) {
486                 DEB_S("failed to register extension\n");
487                 return -ENODEV;
488         }
489
490         return 0;
491 }
492
493 static void __exit hexium_cleanup_module(void)
494 {
495         saa7146_unregister_extension(&extension);
496 }
497
498 module_init(hexium_init_module);
499 module_exit(hexium_cleanup_module);
500
501 MODULE_DESCRIPTION("video4linux-2 driver for Hexium Orion frame grabber cards");
502 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
503 MODULE_LICENSE("GPL");