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