1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "cx18-driver.h"
26#include "cx18-cards.h"
27#include "cx18-av-core.h"
28#include "cx18-i2c.h"
29#include <media/cs5345.h>
30
31#define V4L2_STD_PAL_SECAM (V4L2_STD_PAL|V4L2_STD_SECAM)
32
33
34
35
36static struct cx18_card_tuner_i2c cx18_i2c_std = {
37 .radio = { I2C_CLIENT_END },
38 .demod = { 0x43, I2C_CLIENT_END },
39 .tv = { 0x61, 0x60, I2C_CLIENT_END },
40};
41
42
43
44
45
46
47
48
49
50
51static const struct cx18_card cx18_card_hvr1600_esmt = {
52 .type = CX18_CARD_HVR_1600_ESMT,
53 .name = "Hauppauge HVR-1600",
54 .comment = "Simultaneous Digital and Analog TV capture supported\n",
55 .v4l2_capabilities = CX18_CAP_ENCODER,
56 .hw_audio_ctrl = CX18_HW_418_AV,
57 .hw_muxer = CX18_HW_CS5345,
58 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
59 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
60 CX18_HW_Z8F0811_IR_HAUP,
61 .video_inputs = {
62 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
63 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
64 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
65 { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
66 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
67 },
68 .audio_inputs = {
69 { CX18_CARD_INPUT_AUD_TUNER,
70 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
71 { CX18_CARD_INPUT_LINE_IN1,
72 CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
73 { CX18_CARD_INPUT_LINE_IN2,
74 CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
75 },
76 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
77 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
78 .ddr = {
79
80 .chip_config = 0x003,
81 .refresh = 0x30c,
82 .timing1 = 0x44220e82,
83 .timing2 = 0x08,
84 .tune_lane = 0,
85 .initial_emrs = 0,
86 },
87 .gpio_init.initial_value = 0x3001,
88 .gpio_init.direction = 0x3001,
89 .gpio_i2c_slave_reset = {
90 .active_lo_mask = 0x3001,
91 .msecs_asserted = 10,
92 .msecs_recovery = 40,
93 .ir_reset_mask = 0x0001,
94 },
95 .i2c = &cx18_i2c_std,
96};
97
98static const struct cx18_card cx18_card_hvr1600_samsung = {
99 .type = CX18_CARD_HVR_1600_SAMSUNG,
100 .name = "Hauppauge HVR-1600 (Preproduction)",
101 .comment = "Simultaneous Digital and Analog TV capture supported\n",
102 .v4l2_capabilities = CX18_CAP_ENCODER,
103 .hw_audio_ctrl = CX18_HW_418_AV,
104 .hw_muxer = CX18_HW_CS5345,
105 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
106 CX18_HW_CS5345 | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL |
107 CX18_HW_Z8F0811_IR_HAUP,
108 .video_inputs = {
109 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE7 },
110 { CX18_CARD_INPUT_SVIDEO1, 1, CX18_AV_SVIDEO1 },
111 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE3 },
112 { CX18_CARD_INPUT_SVIDEO2, 2, CX18_AV_SVIDEO2 },
113 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE4 },
114 },
115 .audio_inputs = {
116 { CX18_CARD_INPUT_AUD_TUNER,
117 CX18_AV_AUDIO8, CS5345_IN_1 | CS5345_MCLK_1_5 },
118 { CX18_CARD_INPUT_LINE_IN1,
119 CX18_AV_AUDIO_SERIAL1, CS5345_IN_2 },
120 { CX18_CARD_INPUT_LINE_IN2,
121 CX18_AV_AUDIO_SERIAL1, CS5345_IN_3 },
122 },
123 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
124 CX18_AV_AUDIO_SERIAL1, CS5345_IN_4 },
125 .ddr = {
126
127 .chip_config = 0x003,
128 .refresh = 0x30c,
129 .timing1 = 0x23230b73,
130 .timing2 = 0x08,
131 .tune_lane = 0,
132 .initial_emrs = 2,
133 },
134 .gpio_init.initial_value = 0x3001,
135 .gpio_init.direction = 0x3001,
136 .gpio_i2c_slave_reset = {
137 .active_lo_mask = 0x3001,
138 .msecs_asserted = 10,
139 .msecs_recovery = 40,
140 .ir_reset_mask = 0x0001,
141 },
142 .i2c = &cx18_i2c_std,
143};
144
145
146
147
148
149static const struct cx18_card_pci_info cx18_pci_h900[] = {
150 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_COMPRO, 0xe100 },
151 { 0, 0, 0 }
152};
153
154static const struct cx18_card cx18_card_h900 = {
155 .type = CX18_CARD_COMPRO_H900,
156 .name = "Compro VideoMate H900",
157 .comment = "Analog TV capture supported\n",
158 .v4l2_capabilities = CX18_CAP_ENCODER,
159 .hw_audio_ctrl = CX18_HW_418_AV,
160 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
161 .video_inputs = {
162 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
163 { CX18_CARD_INPUT_SVIDEO1, 1,
164 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
165 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
166 },
167 .audio_inputs = {
168 { CX18_CARD_INPUT_AUD_TUNER,
169 CX18_AV_AUDIO5, 0 },
170 { CX18_CARD_INPUT_LINE_IN1,
171 CX18_AV_AUDIO_SERIAL1, 0 },
172 },
173 .radio_input = { CX18_CARD_INPUT_AUD_TUNER,
174 CX18_AV_AUDIO_SERIAL1, 0 },
175 .tuners = {
176 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
177 },
178 .ddr = {
179
180 .chip_config = 0x50003,
181 .refresh = 0x753,
182 .timing1 = 0x24330e84,
183 .timing2 = 0x1f,
184 .tune_lane = 0,
185 .initial_emrs = 0,
186 },
187 .xceive_pin = 15,
188 .pci_list = cx18_pci_h900,
189 .i2c = &cx18_i2c_std,
190};
191
192
193
194
195
196static const struct cx18_card_pci_info cx18_pci_mpc718[] = {
197 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_YUAN, 0x0718 },
198 { 0, 0, 0 }
199};
200
201static const struct cx18_card cx18_card_mpc718 = {
202 .type = CX18_CARD_YUAN_MPC718,
203 .name = "Yuan MPC718 MiniPCI DVB-T/Analog",
204 .comment = "Experimenters needed for device to work well.\n"
205 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
206 .v4l2_capabilities = CX18_CAP_ENCODER,
207 .hw_audio_ctrl = CX18_HW_418_AV,
208 .hw_muxer = CX18_HW_GPIO_MUX,
209 .hw_all = CX18_HW_TVEEPROM | CX18_HW_418_AV | CX18_HW_TUNER |
210 CX18_HW_GPIO_MUX | CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
211 .video_inputs = {
212 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
213 { CX18_CARD_INPUT_SVIDEO1, 1,
214 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
215 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
216 { CX18_CARD_INPUT_SVIDEO2, 2,
217 CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
218 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
219 },
220 .audio_inputs = {
221 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
222 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
223 { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
224 },
225 .tuners = {
226
227 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
228 },
229
230 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
231 .ddr = {
232
233 .chip_config = 0x303,
234 .refresh = 0x3bd,
235 .timing1 = 0x36320966,
236 .timing2 = 0x1f,
237 .tune_lane = 0,
238 .initial_emrs = 2,
239 },
240 .gpio_init.initial_value = 0x1,
241 .gpio_init.direction = 0x3,
242
243 .gpio_audio_input = { .mask = 0x3,
244 .tuner = 0x1,
245 .linein = 0x3,
246 .radio = 0x1 },
247 .xceive_pin = 0,
248 .pci_list = cx18_pci_mpc718,
249 .i2c = &cx18_i2c_std,
250};
251
252
253
254
255
256static const struct cx18_card_pci_info cx18_pci_cnxt_raptor_pal[] = {
257 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_CONEXANT, 0x0009 },
258 { 0, 0, 0 }
259};
260
261static const struct cx18_card cx18_card_cnxt_raptor_pal = {
262 .type = CX18_CARD_CNXT_RAPTOR_PAL,
263 .name = "Conexant Raptor PAL/SECAM",
264 .comment = "Analog TV capture supported\n",
265 .v4l2_capabilities = CX18_CAP_ENCODER,
266 .hw_audio_ctrl = CX18_HW_418_AV,
267 .hw_muxer = CX18_HW_GPIO_MUX,
268 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX,
269 .video_inputs = {
270 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
271 { CX18_CARD_INPUT_SVIDEO1, 1,
272 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
273 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
274 { CX18_CARD_INPUT_SVIDEO2, 2,
275 CX18_AV_SVIDEO_LUMA7 | CX18_AV_SVIDEO_CHROMA8 },
276 { CX18_CARD_INPUT_COMPOSITE2, 2, CX18_AV_COMPOSITE6 },
277 },
278 .audio_inputs = {
279 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
280 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
281 { CX18_CARD_INPUT_LINE_IN2, CX18_AV_AUDIO_SERIAL2, 1 },
282 },
283 .tuners = {
284 { .std = V4L2_STD_PAL_SECAM, .tuner = TUNER_PHILIPS_FM1216ME_MK3 },
285 },
286 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO_SERIAL1, 2 },
287 .ddr = {
288
289 .chip_config = 0x50306,
290 .refresh = 0x753,
291 .timing1 = 0x33220953,
292 .timing2 = 0x09,
293 .tune_lane = 0,
294 .initial_emrs = 0,
295 },
296 .gpio_init.initial_value = 0x1002,
297 .gpio_init.direction = 0xf002,
298 .gpio_audio_input = { .mask = 0xf002,
299 .tuner = 0x1002,
300 .linein = 0x2000,
301 .radio = 0x4002 },
302 .pci_list = cx18_pci_cnxt_raptor_pal,
303 .i2c = &cx18_i2c_std,
304};
305
306
307
308
309
310static const struct cx18_card_pci_info cx18_pci_toshiba_qosmio_dvbt[] = {
311 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_TOSHIBA, 0x0110 },
312 { 0, 0, 0 }
313};
314
315static const struct cx18_card cx18_card_toshiba_qosmio_dvbt = {
316 .type = CX18_CARD_TOSHIBA_QOSMIO_DVBT,
317 .name = "Toshiba Qosmio DVB-T/Analog",
318 .comment = "Experimenters and photos needed for device to work well.\n"
319 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
320 .v4l2_capabilities = CX18_CAP_ENCODER,
321 .hw_audio_ctrl = CX18_HW_418_AV,
322 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_RESET_CTRL,
323 .video_inputs = {
324 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE6 },
325 { CX18_CARD_INPUT_SVIDEO1, 1,
326 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
327 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE1 },
328 },
329 .audio_inputs = {
330 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
331 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
332 },
333 .tuners = {
334 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
335 },
336 .ddr = {
337 .chip_config = 0x202,
338 .refresh = 0x3bb,
339 .timing1 = 0x33320a63,
340 .timing2 = 0x0a,
341 .tune_lane = 0,
342 .initial_emrs = 0x42,
343 },
344 .xceive_pin = 15,
345 .pci_list = cx18_pci_toshiba_qosmio_dvbt,
346 .i2c = &cx18_i2c_std,
347};
348
349
350
351
352
353static const struct cx18_card_pci_info cx18_pci_leadtek_pvr2100[] = {
354 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6f27 },
355 { 0, 0, 0 }
356};
357
358static const struct cx18_card cx18_card_leadtek_pvr2100 = {
359 .type = CX18_CARD_LEADTEK_PVR2100,
360 .name = "Leadtek WinFast PVR2100",
361 .comment = "Experimenters and photos needed for device to work well.\n"
362 "\tTo help, mail the ivtv-devel list (www.ivtvdriver.org).\n",
363 .v4l2_capabilities = CX18_CAP_ENCODER,
364 .hw_audio_ctrl = CX18_HW_418_AV,
365 .hw_muxer = CX18_HW_GPIO_MUX,
366 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
367 CX18_HW_GPIO_RESET_CTRL,
368 .video_inputs = {
369 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
370 { CX18_CARD_INPUT_SVIDEO1, 1,
371 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
372 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
373 },
374 .audio_inputs = {
375 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
376 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
377 },
378 .tuners = {
379
380 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
381 },
382 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
383 .ddr = {
384
385 .chip_config = 0x303,
386 .refresh = 0x3bb,
387 .timing1 = 0x24220e83,
388 .timing2 = 0x1f,
389 .tune_lane = 0,
390 .initial_emrs = 0x2,
391 },
392 .gpio_init.initial_value = 0x6,
393 .gpio_init.direction = 0x7,
394 .gpio_audio_input = { .mask = 0x7,
395 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
396 .xceive_pin = 15,
397 .pci_list = cx18_pci_leadtek_pvr2100,
398 .i2c = &cx18_i2c_std,
399};
400
401
402
403
404
405static const struct cx18_card_pci_info cx18_pci_leadtek_dvr3100h[] = {
406 { PCI_DEVICE_ID_CX23418, CX18_PCI_ID_LEADTEK, 0x6690 },
407 { 0, 0, 0 }
408};
409
410static const struct cx18_card cx18_card_leadtek_dvr3100h = {
411 .type = CX18_CARD_LEADTEK_DVR3100H,
412 .name = "Leadtek WinFast DVR3100 H",
413 .comment = "Simultaneous DVB-T and Analog capture supported,\n"
414 "\texcept when capturing Analog from the antenna input.\n",
415 .v4l2_capabilities = CX18_CAP_ENCODER,
416 .hw_audio_ctrl = CX18_HW_418_AV,
417 .hw_muxer = CX18_HW_GPIO_MUX,
418 .hw_all = CX18_HW_418_AV | CX18_HW_TUNER | CX18_HW_GPIO_MUX |
419 CX18_HW_DVB | CX18_HW_GPIO_RESET_CTRL,
420 .video_inputs = {
421 { CX18_CARD_INPUT_VID_TUNER, 0, CX18_AV_COMPOSITE2 },
422 { CX18_CARD_INPUT_SVIDEO1, 1,
423 CX18_AV_SVIDEO_LUMA3 | CX18_AV_SVIDEO_CHROMA4 },
424 { CX18_CARD_INPUT_COMPOSITE1, 1, CX18_AV_COMPOSITE7 },
425 },
426 .audio_inputs = {
427 { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 0 },
428 { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 1 },
429 },
430 .tuners = {
431
432 { .std = V4L2_STD_ALL, .tuner = TUNER_XC2028 },
433 },
434 .radio_input = { CX18_CARD_INPUT_AUD_TUNER, CX18_AV_AUDIO5, 2 },
435 .ddr = {
436
437 .chip_config = 0x303,
438 .refresh = 0x3bb,
439 .timing1 = 0x24220e83,
440 .timing2 = 0x1f,
441 .tune_lane = 0,
442 .initial_emrs = 0x2,
443 },
444 .gpio_init.initial_value = 0x6,
445 .gpio_init.direction = 0x7,
446 .gpio_audio_input = { .mask = 0x7,
447 .tuner = 0x6, .linein = 0x2, .radio = 0x2 },
448 .xceive_pin = 1,
449 .pci_list = cx18_pci_leadtek_dvr3100h,
450 .i2c = &cx18_i2c_std,
451};
452
453
454
455static const struct cx18_card *cx18_card_list[] = {
456 &cx18_card_hvr1600_esmt,
457 &cx18_card_hvr1600_samsung,
458 &cx18_card_h900,
459 &cx18_card_mpc718,
460 &cx18_card_cnxt_raptor_pal,
461 &cx18_card_toshiba_qosmio_dvbt,
462 &cx18_card_leadtek_pvr2100,
463 &cx18_card_leadtek_dvr3100h,
464};
465
466const struct cx18_card *cx18_get_card(u16 index)
467{
468 if (index >= ARRAY_SIZE(cx18_card_list))
469 return NULL;
470 return cx18_card_list[index];
471}
472
473int cx18_get_input(struct cx18 *cx, u16 index, struct v4l2_input *input)
474{
475 const struct cx18_card_video_input *card_input =
476 cx->card->video_inputs + index;
477 static const char * const input_strs[] = {
478 "Tuner 1",
479 "S-Video 1",
480 "S-Video 2",
481 "Composite 1",
482 "Composite 2",
483 "Composite 3"
484 };
485
486 memset(input, 0, sizeof(*input));
487 if (index >= cx->nof_inputs)
488 return -EINVAL;
489 input->index = index;
490 strlcpy(input->name, input_strs[card_input->video_type - 1],
491 sizeof(input->name));
492 input->type = (card_input->video_type == CX18_CARD_INPUT_VID_TUNER ?
493 V4L2_INPUT_TYPE_TUNER : V4L2_INPUT_TYPE_CAMERA);
494 input->audioset = (1 << cx->nof_audio_inputs) - 1;
495 input->std = (input->type == V4L2_INPUT_TYPE_TUNER) ?
496 cx->tuner_std : V4L2_STD_ALL;
497 return 0;
498}
499
500int cx18_get_audio_input(struct cx18 *cx, u16 index, struct v4l2_audio *audio)
501{
502 const struct cx18_card_audio_input *aud_input =
503 cx->card->audio_inputs + index;
504 static const char * const input_strs[] = {
505 "Tuner 1",
506 "Line In 1",
507 "Line In 2"
508 };
509
510 memset(audio, 0, sizeof(*audio));
511 if (index >= cx->nof_audio_inputs)
512 return -EINVAL;
513 strlcpy(audio->name, input_strs[aud_input->audio_type - 1],
514 sizeof(audio->name));
515 audio->index = index;
516 audio->capability = V4L2_AUDCAP_STEREO;
517 return 0;
518}
519