GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / media / video / hexium_gemini.c
blobe2ce2a4f60ab31ad12c99756c92cea3e3f247d8b
1 /*
2 hexium_gemini.c - v4l2 driver for Hexium Gemini frame grabber cards
4 Visit http://www.mihu.de/linux/saa7146/ and follow the link
5 to "hexium" for further details about this card.
7 Copyright (C) 2003 Michael Hunold <michael@mihu.de>
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.
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.
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.
24 #define DEBUG_VARIABLE debug
26 #include <media/saa7146_vv.h>
28 static int debug;
29 module_param(debug, int, 0);
30 MODULE_PARM_DESC(debug, "debug verbosity");
32 /* global variables */
33 static int hexium_num;
35 #define HEXIUM_GEMINI 4
36 #define HEXIUM_GEMINI_DUAL 5
38 #define HEXIUM_INPUTS 9
39 static struct v4l2_input hexium_inputs[HEXIUM_INPUTS] = {
40 { 0, "CVBS 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
41 { 1, "CVBS 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
42 { 2, "CVBS 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
43 { 3, "CVBS 4", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
44 { 4, "CVBS 5", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
45 { 5, "CVBS 6", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
46 { 6, "Y/C 1", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
47 { 7, "Y/C 2", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
48 { 8, "Y/C 3", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 },
51 #define HEXIUM_AUDIOS 0
53 struct hexium_data
55 s8 adr;
56 u8 byte;
59 #define HEXIUM_CONTROLS 1
60 static struct v4l2_queryctrl hexium_controls[] = {
61 { V4L2_CID_PRIVATE_BASE, V4L2_CTRL_TYPE_BOOLEAN, "B/W", 0, 1, 1, 0, 0 },
64 #define HEXIUM_GEMINI_V_1_0 1
65 #define HEXIUM_GEMINI_DUAL_V_1_0 2
67 struct hexium
69 int type;
71 struct video_device *video_dev;
72 struct i2c_adapter i2c_adapter;
74 int cur_input; /* current input */
75 v4l2_std_id cur_std; /* current standard */
76 int cur_bw; /* current black/white status */
79 /* Samsung KS0127B decoder default registers */
80 static u8 hexium_ks0127b[0x100]={
81 /*00*/ 0x00,0x52,0x30,0x40,0x01,0x0C,0x2A,0x10,
82 /*08*/ 0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x06,
83 /*10*/ 0x00,0x00,0xE4,0xC0,0x00,0x00,0x00,0x00,
84 /*18*/ 0x14,0x9B,0xFE,0xFF,0xFC,0xFF,0x03,0x22,
85 /*20*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
86 /*28*/ 0x00,0x00,0x00,0x00,0x00,0x2C,0x9B,0x00,
87 /*30*/ 0x00,0x00,0x10,0x80,0x80,0x10,0x80,0x80,
88 /*38*/ 0x01,0x04,0x00,0x00,0x00,0x29,0xC0,0x00,
89 /*40*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
90 /*48*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
91 /*50*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
92 /*58*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
93 /*60*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
94 /*68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
95 /*70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
96 /*78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
97 /*80*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
98 /*88*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
99 /*90*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
100 /*98*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
101 /*A0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
102 /*A8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
103 /*B0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
104 /*B8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
105 /*C0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
106 /*C8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
107 /*D0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
108 /*D8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
109 /*E0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
110 /*E8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
111 /*F0*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
112 /*F8*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
115 static struct hexium_data hexium_pal[] = {
116 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
119 static struct hexium_data hexium_pal_bw[] = {
120 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
123 static struct hexium_data hexium_ntsc[] = {
124 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
127 static struct hexium_data hexium_ntsc_bw[] = {
128 { 0x01, 0x53 }, { 0x12, 0x04 }, { 0x2D, 0x23 }, { 0x2E, 0x81 }, { -1 , 0xFF }
131 static struct hexium_data hexium_secam[] = {
132 { 0x01, 0x52 }, { 0x12, 0x64 }, { 0x2D, 0x2C }, { 0x2E, 0x9B }, { -1 , 0xFF }
135 static struct hexium_data hexium_input_select[] = {
136 { 0x02, 0x60 },
137 { 0x02, 0x64 },
138 { 0x02, 0x61 },
139 { 0x02, 0x65 },
140 { 0x02, 0x62 },
141 { 0x02, 0x66 },
142 { 0x02, 0x68 },
143 { 0x02, 0x69 },
144 { 0x02, 0x6A },
147 static struct saa7146_standard hexium_standards[] = {
149 .name = "PAL", .id = V4L2_STD_PAL,
150 .v_offset = 28, .v_field = 288,
151 .h_offset = 1, .h_pixels = 680,
152 .v_max_out = 576, .h_max_out = 768,
153 }, {
154 .name = "NTSC", .id = V4L2_STD_NTSC,
155 .v_offset = 28, .v_field = 240,
156 .h_offset = 1, .h_pixels = 640,
157 .v_max_out = 480, .h_max_out = 640,
158 }, {
159 .name = "SECAM", .id = V4L2_STD_SECAM,
160 .v_offset = 28, .v_field = 288,
161 .h_offset = 1, .h_pixels = 720,
162 .v_max_out = 576, .h_max_out = 768,
166 /* bring hardware to a sane state. this has to be done, just in case someone
167 wants to capture from this device before it has been properly initialized.
168 the capture engine would badly fail, because no valid signal arrives on the
169 saa7146, thus leading to timeouts and stuff. */
170 static int hexium_init_done(struct saa7146_dev *dev)
172 struct hexium *hexium = (struct hexium *) dev->ext_priv;
173 union i2c_smbus_data data;
174 int i = 0;
176 DEB_D(("hexium_init_done called.\n"));
178 /* initialize the helper ics to useful values */
179 for (i = 0; i < sizeof(hexium_ks0127b); i++) {
180 data.byte = hexium_ks0127b[i];
181 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, i, I2C_SMBUS_BYTE_DATA, &data)) {
182 printk("hexium_gemini: hexium_init_done() failed for address 0x%02x\n", i);
186 return 0;
189 static int hexium_set_input(struct hexium *hexium, int input)
191 union i2c_smbus_data data;
193 DEB_D((".\n"));
195 data.byte = hexium_input_select[input].byte;
196 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, hexium_input_select[input].adr, I2C_SMBUS_BYTE_DATA, &data)) {
197 return -1;
200 return 0;
203 static int hexium_set_standard(struct hexium *hexium, struct hexium_data *vdec)
205 union i2c_smbus_data data;
206 int i = 0;
208 DEB_D((".\n"));
210 while (vdec[i].adr != -1) {
211 data.byte = vdec[i].byte;
212 if (0 != i2c_smbus_xfer(&hexium->i2c_adapter, 0x6c, 0, I2C_SMBUS_WRITE, vdec[i].adr, I2C_SMBUS_BYTE_DATA, &data)) {
213 printk("hexium_init_done: hexium_set_standard() failed for address 0x%02x\n", i);
214 return -1;
216 i++;
218 return 0;
221 static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
223 DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
225 if (i->index >= HEXIUM_INPUTS)
226 return -EINVAL;
228 memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
230 DEB_D(("v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n", i->index));
231 return 0;
234 static int vidioc_g_input(struct file *file, void *fh, unsigned int *input)
236 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
237 struct hexium *hexium = (struct hexium *) dev->ext_priv;
239 *input = hexium->cur_input;
241 DEB_D(("VIDIOC_G_INPUT: %d\n", *input));
242 return 0;
245 static int vidioc_s_input(struct file *file, void *fh, unsigned int input)
247 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
248 struct hexium *hexium = (struct hexium *) dev->ext_priv;
250 DEB_EE(("VIDIOC_S_INPUT %d.\n", input));
252 if (input >= HEXIUM_INPUTS)
253 return -EINVAL;
255 hexium->cur_input = input;
256 hexium_set_input(hexium, input);
257 return 0;
260 /* the saa7146 provides some controls (brightness, contrast, saturation)
261 which gets registered *after* this function. because of this we have
262 to return with a value != 0 even if the function succeded.. */
263 static int vidioc_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qc)
265 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
266 int i;
268 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
269 if (hexium_controls[i].id == qc->id) {
270 *qc = hexium_controls[i];
271 DEB_D(("VIDIOC_QUERYCTRL %d.\n", qc->id));
272 return 0;
275 return dev->ext_vv_data->core_ops->vidioc_queryctrl(file, fh, qc);
278 static int vidioc_g_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
280 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
281 struct hexium *hexium = (struct hexium *) dev->ext_priv;
282 int i;
284 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
285 if (hexium_controls[i].id == vc->id)
286 break;
289 if (i < 0)
290 return dev->ext_vv_data->core_ops->vidioc_g_ctrl(file, fh, vc);
292 if (vc->id == V4L2_CID_PRIVATE_BASE) {
293 vc->value = hexium->cur_bw;
294 DEB_D(("VIDIOC_G_CTRL BW:%d.\n", vc->value));
295 return 0;
297 return -EINVAL;
300 static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
302 struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
303 struct hexium *hexium = (struct hexium *) dev->ext_priv;
304 int i = 0;
306 for (i = HEXIUM_CONTROLS - 1; i >= 0; i--) {
307 if (hexium_controls[i].id == vc->id)
308 break;
311 if (i < 0)
312 return dev->ext_vv_data->core_ops->vidioc_s_ctrl(file, fh, vc);
314 if (vc->id == V4L2_CID_PRIVATE_BASE)
315 hexium->cur_bw = vc->value;
317 DEB_D(("VIDIOC_S_CTRL BW:%d.\n", hexium->cur_bw));
319 if (0 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
320 hexium_set_standard(hexium, hexium_pal);
321 return 0;
323 if (0 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
324 hexium_set_standard(hexium, hexium_ntsc);
325 return 0;
327 if (0 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std) {
328 hexium_set_standard(hexium, hexium_secam);
329 return 0;
331 if (1 == hexium->cur_bw && V4L2_STD_PAL == hexium->cur_std) {
332 hexium_set_standard(hexium, hexium_pal_bw);
333 return 0;
335 if (1 == hexium->cur_bw && V4L2_STD_NTSC == hexium->cur_std) {
336 hexium_set_standard(hexium, hexium_ntsc_bw);
337 return 0;
339 if (1 == hexium->cur_bw && V4L2_STD_SECAM == hexium->cur_std)
340 return -EINVAL;
342 return -EINVAL;
346 static struct saa7146_ext_vv vv_data;
348 /* this function only gets called when the probing was successful */
349 static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info)
351 struct hexium *hexium = (struct hexium *) dev->ext_priv;
352 int ret;
354 DEB_EE((".\n"));
356 hexium = kzalloc(sizeof(struct hexium), GFP_KERNEL);
357 if (NULL == hexium) {
358 printk("hexium_gemini: not enough kernel memory in hexium_attach().\n");
359 return -ENOMEM;
361 dev->ext_priv = hexium;
363 /* enable i2c-port pins */
364 saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
366 hexium->i2c_adapter = (struct i2c_adapter) {
367 .class = I2C_CLASS_TV_ANALOG,
368 .name = "hexium gemini",
370 saa7146_i2c_adapter_prepare(dev, &hexium->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480);
371 if (i2c_add_adapter(&hexium->i2c_adapter) < 0) {
372 DEB_S(("cannot register i2c-device. skipping.\n"));
373 kfree(hexium);
374 return -EFAULT;
377 /* set HWControl GPIO number 2 */
378 saa7146_setgpio(dev, 2, SAA7146_GPIO_OUTHI);
380 saa7146_write(dev, DD1_INIT, 0x07000700);
381 saa7146_write(dev, DD1_STREAM_B, 0x00000000);
382 saa7146_write(dev, MC2, (MASK_09 | MASK_25 | MASK_10 | MASK_26));
384 /* the rest */
385 hexium->cur_input = 0;
386 hexium_init_done(dev);
388 hexium_set_standard(hexium, hexium_pal);
389 hexium->cur_std = V4L2_STD_PAL;
391 hexium_set_input(hexium, 0);
392 hexium->cur_input = 0;
394 saa7146_vv_init(dev, &vv_data);
395 vv_data.ops.vidioc_queryctrl = vidioc_queryctrl;
396 vv_data.ops.vidioc_g_ctrl = vidioc_g_ctrl;
397 vv_data.ops.vidioc_s_ctrl = vidioc_s_ctrl;
398 vv_data.ops.vidioc_enum_input = vidioc_enum_input;
399 vv_data.ops.vidioc_g_input = vidioc_g_input;
400 vv_data.ops.vidioc_s_input = vidioc_s_input;
401 ret = saa7146_register_device(&hexium->video_dev, dev, "hexium gemini", VFL_TYPE_GRABBER);
402 if (ret < 0) {
403 printk("hexium_gemini: cannot register capture v4l2 device. skipping.\n");
404 return ret;
407 printk("hexium_gemini: found 'hexium gemini' frame grabber-%d.\n", hexium_num);
408 hexium_num++;
410 return 0;
413 static int hexium_detach(struct saa7146_dev *dev)
415 struct hexium *hexium = (struct hexium *) dev->ext_priv;
417 DEB_EE(("dev:%p\n", dev));
419 saa7146_unregister_device(&hexium->video_dev, dev);
420 saa7146_vv_release(dev);
422 hexium_num--;
424 i2c_del_adapter(&hexium->i2c_adapter);
425 kfree(hexium);
426 return 0;
429 static int std_callback(struct saa7146_dev *dev, struct saa7146_standard *std)
431 struct hexium *hexium = (struct hexium *) dev->ext_priv;
433 if (V4L2_STD_PAL == std->id) {
434 hexium_set_standard(hexium, hexium_pal);
435 hexium->cur_std = V4L2_STD_PAL;
436 return 0;
437 } else if (V4L2_STD_NTSC == std->id) {
438 hexium_set_standard(hexium, hexium_ntsc);
439 hexium->cur_std = V4L2_STD_NTSC;
440 return 0;
441 } else if (V4L2_STD_SECAM == std->id) {
442 hexium_set_standard(hexium, hexium_secam);
443 hexium->cur_std = V4L2_STD_SECAM;
444 return 0;
447 return -1;
450 static struct saa7146_extension hexium_extension;
452 static struct saa7146_pci_extension_data hexium_gemini_4bnc = {
453 .ext_priv = "Hexium Gemini (4 BNC)",
454 .ext = &hexium_extension,
457 static struct saa7146_pci_extension_data hexium_gemini_dual_4bnc = {
458 .ext_priv = "Hexium Gemini Dual (4 BNC)",
459 .ext = &hexium_extension,
462 static struct pci_device_id pci_tbl[] = {
464 .vendor = PCI_VENDOR_ID_PHILIPS,
465 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
466 .subvendor = 0x17c8,
467 .subdevice = 0x2401,
468 .driver_data = (unsigned long) &hexium_gemini_4bnc,
471 .vendor = PCI_VENDOR_ID_PHILIPS,
472 .device = PCI_DEVICE_ID_PHILIPS_SAA7146,
473 .subvendor = 0x17c8,
474 .subdevice = 0x2402,
475 .driver_data = (unsigned long) &hexium_gemini_dual_4bnc,
478 .vendor = 0,
482 MODULE_DEVICE_TABLE(pci, pci_tbl);
484 static struct saa7146_ext_vv vv_data = {
485 .inputs = HEXIUM_INPUTS,
486 .capabilities = 0,
487 .stds = &hexium_standards[0],
488 .num_stds = sizeof(hexium_standards) / sizeof(struct saa7146_standard),
489 .std_callback = &std_callback,
492 static struct saa7146_extension hexium_extension = {
493 .name = "hexium gemini",
494 .flags = SAA7146_USE_I2C_IRQ,
496 .pci_tbl = &pci_tbl[0],
497 .module = THIS_MODULE,
499 .attach = hexium_attach,
500 .detach = hexium_detach,
502 .irq_mask = 0,
503 .irq_func = NULL,
506 static int __init hexium_init_module(void)
508 if (0 != saa7146_register_extension(&hexium_extension)) {
509 DEB_S(("failed to register extension.\n"));
510 return -ENODEV;
513 return 0;
516 static void __exit hexium_cleanup_module(void)
518 saa7146_unregister_extension(&hexium_extension);
521 module_init(hexium_init_module);
522 module_exit(hexium_cleanup_module);
524 MODULE_DESCRIPTION("video4linux-2 driver for Hexium Gemini frame grabber cards");
525 MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");
526 MODULE_LICENSE("GPL");