diff options
Diffstat (limited to 'drivers/media/usb/em28xx/em28xx-dvb.c')
-rw-r--r-- | drivers/media/usb/em28xx/em28xx-dvb.c | 1197 |
1 files changed, 1197 insertions, 0 deletions
diff --git a/drivers/media/usb/em28xx/em28xx-dvb.c b/drivers/media/usb/em28xx/em28xx-dvb.c new file mode 100644 index 000000000000..a16531fa937a --- /dev/null +++ b/drivers/media/usb/em28xx/em28xx-dvb.c | |||
@@ -0,0 +1,1197 @@ | |||
1 | /* | ||
2 | DVB device driver for em28xx | ||
3 | |||
4 | (c) 2008-2011 Mauro Carvalho Chehab <mchehab@infradead.org> | ||
5 | |||
6 | (c) 2008 Devin Heitmueller <devin.heitmueller@gmail.com> | ||
7 | - Fixes for the driver to properly work with HVR-950 | ||
8 | - Fixes for the driver to properly work with Pinnacle PCTV HD Pro Stick | ||
9 | - Fixes for the driver to properly work with AMD ATI TV Wonder HD 600 | ||
10 | |||
11 | (c) 2008 Aidan Thornton <makosoft@googlemail.com> | ||
12 | |||
13 | Based on cx88-dvb, saa7134-dvb and videobuf-dvb originally written by: | ||
14 | (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> | ||
15 | (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] | ||
16 | |||
17 | This program is free software; you can redistribute it and/or modify | ||
18 | it under the terms of the GNU General Public License as published by | ||
19 | the Free Software Foundation; either version 2 of the License. | ||
20 | */ | ||
21 | |||
22 | #include <linux/kernel.h> | ||
23 | #include <linux/slab.h> | ||
24 | #include <linux/usb.h> | ||
25 | |||
26 | #include "em28xx.h" | ||
27 | #include <media/v4l2-common.h> | ||
28 | #include <media/videobuf-vmalloc.h> | ||
29 | #include <media/tuner.h> | ||
30 | #include "tuner-simple.h" | ||
31 | |||
32 | #include "lgdt330x.h" | ||
33 | #include "lgdt3305.h" | ||
34 | #include "zl10353.h" | ||
35 | #include "s5h1409.h" | ||
36 | #include "mt352.h" | ||
37 | #include "mt352_priv.h" /* FIXME */ | ||
38 | #include "tda1002x.h" | ||
39 | #include "tda18271.h" | ||
40 | #include "s921.h" | ||
41 | #include "drxd.h" | ||
42 | #include "cxd2820r.h" | ||
43 | #include "tda18271c2dd.h" | ||
44 | #include "drxk.h" | ||
45 | #include "tda10071.h" | ||
46 | #include "a8293.h" | ||
47 | #include "qt1010.h" | ||
48 | |||
49 | MODULE_DESCRIPTION("driver for em28xx based DVB cards"); | ||
50 | MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>"); | ||
51 | MODULE_LICENSE("GPL"); | ||
52 | |||
53 | static unsigned int debug; | ||
54 | module_param(debug, int, 0644); | ||
55 | MODULE_PARM_DESC(debug, "enable debug messages [dvb]"); | ||
56 | |||
57 | DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr); | ||
58 | |||
59 | #define dprintk(level, fmt, arg...) do { \ | ||
60 | if (debug >= level) \ | ||
61 | printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->name, ## arg); \ | ||
62 | } while (0) | ||
63 | |||
64 | struct em28xx_dvb { | ||
65 | struct dvb_frontend *fe[2]; | ||
66 | |||
67 | /* feed count management */ | ||
68 | struct mutex lock; | ||
69 | int nfeeds; | ||
70 | |||
71 | /* general boilerplate stuff */ | ||
72 | struct dvb_adapter adapter; | ||
73 | struct dvb_demux demux; | ||
74 | struct dmxdev dmxdev; | ||
75 | struct dmx_frontend fe_hw; | ||
76 | struct dmx_frontend fe_mem; | ||
77 | struct dvb_net net; | ||
78 | |||
79 | /* Due to DRX-K - probably need changes */ | ||
80 | int (*gate_ctrl)(struct dvb_frontend *, int); | ||
81 | struct semaphore pll_mutex; | ||
82 | bool dont_attach_fe1; | ||
83 | }; | ||
84 | |||
85 | |||
86 | static inline void print_err_status(struct em28xx *dev, | ||
87 | int packet, int status) | ||
88 | { | ||
89 | char *errmsg = "Unknown"; | ||
90 | |||
91 | switch (status) { | ||
92 | case -ENOENT: | ||
93 | errmsg = "unlinked synchronuously"; | ||
94 | break; | ||
95 | case -ECONNRESET: | ||
96 | errmsg = "unlinked asynchronuously"; | ||
97 | break; | ||
98 | case -ENOSR: | ||
99 | errmsg = "Buffer error (overrun)"; | ||
100 | break; | ||
101 | case -EPIPE: | ||
102 | errmsg = "Stalled (device not responding)"; | ||
103 | break; | ||
104 | case -EOVERFLOW: | ||
105 | errmsg = "Babble (bad cable?)"; | ||
106 | break; | ||
107 | case -EPROTO: | ||
108 | errmsg = "Bit-stuff error (bad cable?)"; | ||
109 | break; | ||
110 | case -EILSEQ: | ||
111 | errmsg = "CRC/Timeout (could be anything)"; | ||
112 | break; | ||
113 | case -ETIME: | ||
114 | errmsg = "Device does not respond"; | ||
115 | break; | ||
116 | } | ||
117 | if (packet < 0) { | ||
118 | dprintk(1, "URB status %d [%s].\n", status, errmsg); | ||
119 | } else { | ||
120 | dprintk(1, "URB packet %d, status %d [%s].\n", | ||
121 | packet, status, errmsg); | ||
122 | } | ||
123 | } | ||
124 | |||
125 | static inline int em28xx_dvb_isoc_copy(struct em28xx *dev, struct urb *urb) | ||
126 | { | ||
127 | int i; | ||
128 | |||
129 | if (!dev) | ||
130 | return 0; | ||
131 | |||
132 | if ((dev->state & DEV_DISCONNECTED) || (dev->state & DEV_MISCONFIGURED)) | ||
133 | return 0; | ||
134 | |||
135 | if (urb->status < 0) { | ||
136 | print_err_status(dev, -1, urb->status); | ||
137 | if (urb->status == -ENOENT) | ||
138 | return 0; | ||
139 | } | ||
140 | |||
141 | for (i = 0; i < urb->number_of_packets; i++) { | ||
142 | int status = urb->iso_frame_desc[i].status; | ||
143 | |||
144 | if (status < 0) { | ||
145 | print_err_status(dev, i, status); | ||
146 | if (urb->iso_frame_desc[i].status != -EPROTO) | ||
147 | continue; | ||
148 | } | ||
149 | |||
150 | dvb_dmx_swfilter(&dev->dvb->demux, urb->transfer_buffer + | ||
151 | urb->iso_frame_desc[i].offset, | ||
152 | urb->iso_frame_desc[i].actual_length); | ||
153 | } | ||
154 | |||
155 | return 0; | ||
156 | } | ||
157 | |||
158 | static int em28xx_start_streaming(struct em28xx_dvb *dvb) | ||
159 | { | ||
160 | int rc; | ||
161 | struct em28xx *dev = dvb->adapter.priv; | ||
162 | int max_dvb_packet_size; | ||
163 | |||
164 | usb_set_interface(dev->udev, 0, dev->dvb_alt); | ||
165 | rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
166 | if (rc < 0) | ||
167 | return rc; | ||
168 | |||
169 | max_dvb_packet_size = dev->dvb_max_pkt_size; | ||
170 | if (max_dvb_packet_size < 0) | ||
171 | return max_dvb_packet_size; | ||
172 | dprintk(1, "Using %d buffers each with %d x %d bytes\n", | ||
173 | EM28XX_DVB_NUM_BUFS, | ||
174 | EM28XX_DVB_MAX_PACKETS, | ||
175 | max_dvb_packet_size); | ||
176 | |||
177 | return em28xx_init_isoc(dev, EM28XX_DIGITAL_MODE, | ||
178 | EM28XX_DVB_MAX_PACKETS, EM28XX_DVB_NUM_BUFS, | ||
179 | max_dvb_packet_size, em28xx_dvb_isoc_copy); | ||
180 | } | ||
181 | |||
182 | static int em28xx_stop_streaming(struct em28xx_dvb *dvb) | ||
183 | { | ||
184 | struct em28xx *dev = dvb->adapter.priv; | ||
185 | |||
186 | em28xx_stop_urbs(dev); | ||
187 | |||
188 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int em28xx_start_feed(struct dvb_demux_feed *feed) | ||
194 | { | ||
195 | struct dvb_demux *demux = feed->demux; | ||
196 | struct em28xx_dvb *dvb = demux->priv; | ||
197 | int rc, ret; | ||
198 | |||
199 | if (!demux->dmx.frontend) | ||
200 | return -EINVAL; | ||
201 | |||
202 | mutex_lock(&dvb->lock); | ||
203 | dvb->nfeeds++; | ||
204 | rc = dvb->nfeeds; | ||
205 | |||
206 | if (dvb->nfeeds == 1) { | ||
207 | ret = em28xx_start_streaming(dvb); | ||
208 | if (ret < 0) | ||
209 | rc = ret; | ||
210 | } | ||
211 | |||
212 | mutex_unlock(&dvb->lock); | ||
213 | return rc; | ||
214 | } | ||
215 | |||
216 | static int em28xx_stop_feed(struct dvb_demux_feed *feed) | ||
217 | { | ||
218 | struct dvb_demux *demux = feed->demux; | ||
219 | struct em28xx_dvb *dvb = demux->priv; | ||
220 | int err = 0; | ||
221 | |||
222 | mutex_lock(&dvb->lock); | ||
223 | dvb->nfeeds--; | ||
224 | |||
225 | if (0 == dvb->nfeeds) | ||
226 | err = em28xx_stop_streaming(dvb); | ||
227 | |||
228 | mutex_unlock(&dvb->lock); | ||
229 | return err; | ||
230 | } | ||
231 | |||
232 | |||
233 | |||
234 | /* ------------------------------------------------------------------ */ | ||
235 | static int em28xx_dvb_bus_ctrl(struct dvb_frontend *fe, int acquire) | ||
236 | { | ||
237 | struct em28xx *dev = fe->dvb->priv; | ||
238 | |||
239 | if (acquire) | ||
240 | return em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
241 | else | ||
242 | return em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
243 | } | ||
244 | |||
245 | /* ------------------------------------------------------------------ */ | ||
246 | |||
247 | static struct lgdt330x_config em2880_lgdt3303_dev = { | ||
248 | .demod_address = 0x0e, | ||
249 | .demod_chip = LGDT3303, | ||
250 | }; | ||
251 | |||
252 | static struct lgdt3305_config em2870_lgdt3304_dev = { | ||
253 | .i2c_addr = 0x0e, | ||
254 | .demod_chip = LGDT3304, | ||
255 | .spectral_inversion = 1, | ||
256 | .deny_i2c_rptr = 1, | ||
257 | .mpeg_mode = LGDT3305_MPEG_PARALLEL, | ||
258 | .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE, | ||
259 | .tpvalid_polarity = LGDT3305_TP_VALID_HIGH, | ||
260 | .vsb_if_khz = 3250, | ||
261 | .qam_if_khz = 4000, | ||
262 | }; | ||
263 | |||
264 | static struct s921_config sharp_isdbt = { | ||
265 | .demod_address = 0x30 >> 1 | ||
266 | }; | ||
267 | |||
268 | static struct zl10353_config em28xx_zl10353_with_xc3028 = { | ||
269 | .demod_address = (0x1e >> 1), | ||
270 | .no_tuner = 1, | ||
271 | .parallel_ts = 1, | ||
272 | .if2 = 45600, | ||
273 | }; | ||
274 | |||
275 | static struct s5h1409_config em28xx_s5h1409_with_xc3028 = { | ||
276 | .demod_address = 0x32 >> 1, | ||
277 | .output_mode = S5H1409_PARALLEL_OUTPUT, | ||
278 | .gpio = S5H1409_GPIO_OFF, | ||
279 | .inversion = S5H1409_INVERSION_OFF, | ||
280 | .status_mode = S5H1409_DEMODLOCKING, | ||
281 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK | ||
282 | }; | ||
283 | |||
284 | static struct tda18271_std_map kworld_a340_std_map = { | ||
285 | .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 0, | ||
286 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
287 | .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 1, | ||
288 | .if_lvl = 1, .rfagc_top = 0x37, }, | ||
289 | }; | ||
290 | |||
291 | static struct tda18271_config kworld_a340_config = { | ||
292 | .std_map = &kworld_a340_std_map, | ||
293 | }; | ||
294 | |||
295 | static struct zl10353_config em28xx_zl10353_xc3028_no_i2c_gate = { | ||
296 | .demod_address = (0x1e >> 1), | ||
297 | .no_tuner = 1, | ||
298 | .disable_i2c_gate_ctrl = 1, | ||
299 | .parallel_ts = 1, | ||
300 | .if2 = 45600, | ||
301 | }; | ||
302 | |||
303 | static struct drxd_config em28xx_drxd = { | ||
304 | .demod_address = 0x70, | ||
305 | .demod_revision = 0xa2, | ||
306 | .pll_type = DRXD_PLL_NONE, | ||
307 | .clock = 12000, | ||
308 | .insert_rs_byte = 1, | ||
309 | .IF = 42800000, | ||
310 | .disable_i2c_gate_ctrl = 1, | ||
311 | }; | ||
312 | |||
313 | static struct drxk_config terratec_h5_drxk = { | ||
314 | .adr = 0x29, | ||
315 | .single_master = 1, | ||
316 | .no_i2c_bridge = 1, | ||
317 | .microcode_name = "dvb-usb-terratec-h5-drxk.fw", | ||
318 | .qam_demod_parameter_count = 2, | ||
319 | }; | ||
320 | |||
321 | static struct drxk_config hauppauge_930c_drxk = { | ||
322 | .adr = 0x29, | ||
323 | .single_master = 1, | ||
324 | .no_i2c_bridge = 1, | ||
325 | .microcode_name = "dvb-usb-hauppauge-hvr930c-drxk.fw", | ||
326 | .chunk_size = 56, | ||
327 | .qam_demod_parameter_count = 2, | ||
328 | }; | ||
329 | |||
330 | struct drxk_config terratec_htc_stick_drxk = { | ||
331 | .adr = 0x29, | ||
332 | .single_master = 1, | ||
333 | .no_i2c_bridge = 1, | ||
334 | .microcode_name = "dvb-usb-terratec-htc-stick-drxk.fw", | ||
335 | .chunk_size = 54, | ||
336 | .qam_demod_parameter_count = 2, | ||
337 | /* Required for the antenna_gpio to disable LNA. */ | ||
338 | .antenna_dvbt = true, | ||
339 | /* The windows driver uses the same. This will disable LNA. */ | ||
340 | .antenna_gpio = 0x6, | ||
341 | }; | ||
342 | |||
343 | static struct drxk_config maxmedia_ub425_tc_drxk = { | ||
344 | .adr = 0x29, | ||
345 | .single_master = 1, | ||
346 | .no_i2c_bridge = 1, | ||
347 | }; | ||
348 | |||
349 | static struct drxk_config pctv_520e_drxk = { | ||
350 | .adr = 0x29, | ||
351 | .single_master = 1, | ||
352 | .microcode_name = "dvb-demod-drxk-pctv.fw", | ||
353 | .qam_demod_parameter_count = 2, | ||
354 | .chunk_size = 58, | ||
355 | .antenna_dvbt = true, /* disable LNA */ | ||
356 | .antenna_gpio = (1 << 2), /* disable LNA */ | ||
357 | }; | ||
358 | |||
359 | static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
360 | { | ||
361 | struct em28xx_dvb *dvb = fe->sec_priv; | ||
362 | int status; | ||
363 | |||
364 | if (!dvb) | ||
365 | return -EINVAL; | ||
366 | |||
367 | if (enable) { | ||
368 | down(&dvb->pll_mutex); | ||
369 | status = dvb->gate_ctrl(fe, 1); | ||
370 | } else { | ||
371 | status = dvb->gate_ctrl(fe, 0); | ||
372 | up(&dvb->pll_mutex); | ||
373 | } | ||
374 | return status; | ||
375 | } | ||
376 | |||
377 | static void hauppauge_hvr930c_init(struct em28xx *dev) | ||
378 | { | ||
379 | int i; | ||
380 | |||
381 | struct em28xx_reg_seq hauppauge_hvr930c_init[] = { | ||
382 | {EM2874_R80_GPIO, 0xff, 0xff, 0x65}, | ||
383 | {EM2874_R80_GPIO, 0xfb, 0xff, 0x32}, | ||
384 | {EM2874_R80_GPIO, 0xff, 0xff, 0xb8}, | ||
385 | { -1, -1, -1, -1}, | ||
386 | }; | ||
387 | struct em28xx_reg_seq hauppauge_hvr930c_end[] = { | ||
388 | {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, | ||
389 | {EM2874_R80_GPIO, 0xaf, 0xff, 0x65}, | ||
390 | {EM2874_R80_GPIO, 0xef, 0xff, 0x76}, | ||
391 | {EM2874_R80_GPIO, 0xef, 0xff, 0x01}, | ||
392 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, | ||
393 | {EM2874_R80_GPIO, 0xef, 0xff, 0x40}, | ||
394 | |||
395 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x65}, | ||
396 | {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, | ||
397 | {EM2874_R80_GPIO, 0xcf, 0xff, 0x0b}, | ||
398 | {EM2874_R80_GPIO, 0xef, 0xff, 0x65}, | ||
399 | |||
400 | { -1, -1, -1, -1}, | ||
401 | }; | ||
402 | |||
403 | struct { | ||
404 | unsigned char r[4]; | ||
405 | int len; | ||
406 | } regs[] = { | ||
407 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
408 | {{ 0x01, 0x02 }, 2}, | ||
409 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
410 | {{ 0x01, 0x00 }, 2}, | ||
411 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
412 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
413 | {{ 0x01, 0x00 }, 2}, | ||
414 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
415 | {{ 0x04, 0x00 }, 2}, | ||
416 | {{ 0x00, 0x04 }, 2}, | ||
417 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
418 | {{ 0x04, 0x14 }, 2}, | ||
419 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
420 | }; | ||
421 | |||
422 | em28xx_gpio_set(dev, hauppauge_hvr930c_init); | ||
423 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
424 | msleep(10); | ||
425 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
426 | msleep(10); | ||
427 | |||
428 | dev->i2c_client.addr = 0x82 >> 1; | ||
429 | |||
430 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
431 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
432 | em28xx_gpio_set(dev, hauppauge_hvr930c_end); | ||
433 | |||
434 | msleep(100); | ||
435 | |||
436 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
437 | msleep(30); | ||
438 | |||
439 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
440 | msleep(10); | ||
441 | |||
442 | } | ||
443 | |||
444 | static void terratec_h5_init(struct em28xx *dev) | ||
445 | { | ||
446 | int i; | ||
447 | struct em28xx_reg_seq terratec_h5_init[] = { | ||
448 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
449 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
450 | {EM2874_R80_GPIO, 0xf2, 0xff, 50}, | ||
451 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
452 | { -1, -1, -1, -1}, | ||
453 | }; | ||
454 | struct em28xx_reg_seq terratec_h5_end[] = { | ||
455 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
456 | {EM2874_R80_GPIO, 0xa6, 0xff, 50}, | ||
457 | {EM2874_R80_GPIO, 0xe6, 0xff, 100}, | ||
458 | { -1, -1, -1, -1}, | ||
459 | }; | ||
460 | struct { | ||
461 | unsigned char r[4]; | ||
462 | int len; | ||
463 | } regs[] = { | ||
464 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
465 | {{ 0x01, 0x02 }, 2}, | ||
466 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
467 | {{ 0x01, 0x00 }, 2}, | ||
468 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
469 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
470 | {{ 0x01, 0x00 }, 2}, | ||
471 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
472 | {{ 0x04, 0x00 }, 2}, | ||
473 | {{ 0x00, 0x04 }, 2}, | ||
474 | {{ 0x00, 0x04, 0x00, 0x0a }, 4}, | ||
475 | {{ 0x04, 0x14 }, 2}, | ||
476 | {{ 0x04, 0x14, 0x00, 0x00 }, 4}, | ||
477 | }; | ||
478 | |||
479 | em28xx_gpio_set(dev, terratec_h5_init); | ||
480 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
481 | msleep(10); | ||
482 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x45); | ||
483 | msleep(10); | ||
484 | |||
485 | dev->i2c_client.addr = 0x82 >> 1; | ||
486 | |||
487 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
488 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
489 | em28xx_gpio_set(dev, terratec_h5_end); | ||
490 | }; | ||
491 | |||
492 | static void terratec_htc_stick_init(struct em28xx *dev) | ||
493 | { | ||
494 | int i; | ||
495 | |||
496 | /* | ||
497 | * GPIO configuration: | ||
498 | * 0xff: unknown (does not affect DVB-T). | ||
499 | * 0xf6: DRX-K (demodulator). | ||
500 | * 0xe6: unknown (does not affect DVB-T). | ||
501 | * 0xb6: unknown (does not affect DVB-T). | ||
502 | */ | ||
503 | struct em28xx_reg_seq terratec_htc_stick_init[] = { | ||
504 | {EM28XX_R08_GPIO, 0xff, 0xff, 10}, | ||
505 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
506 | {EM2874_R80_GPIO, 0xe6, 0xff, 50}, | ||
507 | {EM2874_R80_GPIO, 0xf6, 0xff, 100}, | ||
508 | { -1, -1, -1, -1}, | ||
509 | }; | ||
510 | struct em28xx_reg_seq terratec_htc_stick_end[] = { | ||
511 | {EM2874_R80_GPIO, 0xb6, 0xff, 100}, | ||
512 | {EM2874_R80_GPIO, 0xf6, 0xff, 50}, | ||
513 | { -1, -1, -1, -1}, | ||
514 | }; | ||
515 | |||
516 | /* Init the analog decoder? */ | ||
517 | struct { | ||
518 | unsigned char r[4]; | ||
519 | int len; | ||
520 | } regs[] = { | ||
521 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
522 | {{ 0x01, 0x02 }, 2}, | ||
523 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
524 | {{ 0x01, 0x00 }, 2}, | ||
525 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
526 | }; | ||
527 | |||
528 | em28xx_gpio_set(dev, terratec_htc_stick_init); | ||
529 | |||
530 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x40); | ||
531 | msleep(10); | ||
532 | em28xx_write_reg(dev, EM28XX_R06_I2C_CLK, 0x44); | ||
533 | msleep(10); | ||
534 | |||
535 | dev->i2c_client.addr = 0x82 >> 1; | ||
536 | |||
537 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
538 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
539 | |||
540 | em28xx_gpio_set(dev, terratec_htc_stick_end); | ||
541 | }; | ||
542 | |||
543 | static void pctv_520e_init(struct em28xx *dev) | ||
544 | { | ||
545 | /* | ||
546 | * Init AVF4910B analog decoder. Looks like I2C traffic to | ||
547 | * digital demodulator and tuner are routed via AVF4910B. | ||
548 | */ | ||
549 | int i; | ||
550 | struct { | ||
551 | unsigned char r[4]; | ||
552 | int len; | ||
553 | } regs[] = { | ||
554 | {{ 0x06, 0x02, 0x00, 0x31 }, 4}, | ||
555 | {{ 0x01, 0x02 }, 2}, | ||
556 | {{ 0x01, 0x02, 0x00, 0xc6 }, 4}, | ||
557 | {{ 0x01, 0x00 }, 2}, | ||
558 | {{ 0x01, 0x00, 0xff, 0xaf }, 4}, | ||
559 | {{ 0x01, 0x00, 0x03, 0xa0 }, 4}, | ||
560 | {{ 0x01, 0x00 }, 2}, | ||
561 | {{ 0x01, 0x00, 0x73, 0xaf }, 4}, | ||
562 | }; | ||
563 | |||
564 | dev->i2c_client.addr = 0x82 >> 1; /* 0x41 */ | ||
565 | |||
566 | for (i = 0; i < ARRAY_SIZE(regs); i++) | ||
567 | i2c_master_send(&dev->i2c_client, regs[i].r, regs[i].len); | ||
568 | }; | ||
569 | |||
570 | static int em28xx_mt352_terratec_xs_init(struct dvb_frontend *fe) | ||
571 | { | ||
572 | /* Values extracted from a USB trace of the Terratec Windows driver */ | ||
573 | static u8 clock_config[] = { CLOCK_CTL, 0x38, 0x2c }; | ||
574 | static u8 reset[] = { RESET, 0x80 }; | ||
575 | static u8 adc_ctl_1_cfg[] = { ADC_CTL_1, 0x40 }; | ||
576 | static u8 agc_cfg[] = { AGC_TARGET, 0x28, 0xa0 }; | ||
577 | static u8 input_freq_cfg[] = { INPUT_FREQ_1, 0x31, 0xb8 }; | ||
578 | static u8 rs_err_cfg[] = { RS_ERR_PER_1, 0x00, 0x4d }; | ||
579 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | ||
580 | static u8 trl_nom_cfg[] = { TRL_NOMINAL_RATE_1, 0x64, 0x00 }; | ||
581 | static u8 tps_given_cfg[] = { TPS_GIVEN_1, 0x40, 0x80, 0x50 }; | ||
582 | static u8 tuner_go[] = { TUNER_GO, 0x01}; | ||
583 | |||
584 | mt352_write(fe, clock_config, sizeof(clock_config)); | ||
585 | udelay(200); | ||
586 | mt352_write(fe, reset, sizeof(reset)); | ||
587 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | ||
588 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | ||
589 | mt352_write(fe, input_freq_cfg, sizeof(input_freq_cfg)); | ||
590 | mt352_write(fe, rs_err_cfg, sizeof(rs_err_cfg)); | ||
591 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | ||
592 | mt352_write(fe, trl_nom_cfg, sizeof(trl_nom_cfg)); | ||
593 | mt352_write(fe, tps_given_cfg, sizeof(tps_given_cfg)); | ||
594 | mt352_write(fe, tuner_go, sizeof(tuner_go)); | ||
595 | return 0; | ||
596 | } | ||
597 | |||
598 | static struct mt352_config terratec_xs_mt352_cfg = { | ||
599 | .demod_address = (0x1e >> 1), | ||
600 | .no_tuner = 1, | ||
601 | .if2 = 45600, | ||
602 | .demod_init = em28xx_mt352_terratec_xs_init, | ||
603 | }; | ||
604 | |||
605 | static struct tda10023_config em28xx_tda10023_config = { | ||
606 | .demod_address = 0x0c, | ||
607 | .invert = 1, | ||
608 | }; | ||
609 | |||
610 | static struct cxd2820r_config em28xx_cxd2820r_config = { | ||
611 | .i2c_address = (0xd8 >> 1), | ||
612 | .ts_mode = CXD2820R_TS_SERIAL, | ||
613 | |||
614 | /* enable LNA for DVB-T, DVB-T2 and DVB-C */ | ||
615 | .gpio_dvbt[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
616 | .gpio_dvbt2[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
617 | .gpio_dvbc[0] = CXD2820R_GPIO_E | CXD2820R_GPIO_O | CXD2820R_GPIO_L, | ||
618 | }; | ||
619 | |||
620 | static struct tda18271_config em28xx_cxd2820r_tda18271_config = { | ||
621 | .output_opt = TDA18271_OUTPUT_LT_OFF, | ||
622 | .gate = TDA18271_GATE_DIGITAL, | ||
623 | }; | ||
624 | |||
625 | static const struct tda10071_config em28xx_tda10071_config = { | ||
626 | .i2c_address = 0x55, /* (0xaa >> 1) */ | ||
627 | .i2c_wr_max = 64, | ||
628 | .ts_mode = TDA10071_TS_SERIAL, | ||
629 | .spec_inv = 0, | ||
630 | .xtal = 40444000, /* 40.444 MHz */ | ||
631 | .pll_multiplier = 20, | ||
632 | }; | ||
633 | |||
634 | static const struct a8293_config em28xx_a8293_config = { | ||
635 | .i2c_addr = 0x08, /* (0x10 >> 1) */ | ||
636 | }; | ||
637 | |||
638 | static struct zl10353_config em28xx_zl10353_no_i2c_gate_dev = { | ||
639 | .demod_address = (0x1e >> 1), | ||
640 | .disable_i2c_gate_ctrl = 1, | ||
641 | .no_tuner = 1, | ||
642 | .parallel_ts = 1, | ||
643 | }; | ||
644 | static struct qt1010_config em28xx_qt1010_config = { | ||
645 | .i2c_address = 0x62 | ||
646 | |||
647 | }; | ||
648 | |||
649 | /* ------------------------------------------------------------------ */ | ||
650 | |||
651 | static int em28xx_attach_xc3028(u8 addr, struct em28xx *dev) | ||
652 | { | ||
653 | struct dvb_frontend *fe; | ||
654 | struct xc2028_config cfg; | ||
655 | |||
656 | memset(&cfg, 0, sizeof(cfg)); | ||
657 | cfg.i2c_adap = &dev->i2c_adap; | ||
658 | cfg.i2c_addr = addr; | ||
659 | |||
660 | if (!dev->dvb->fe[0]) { | ||
661 | em28xx_errdev("/2: dvb frontend not attached. " | ||
662 | "Can't attach xc3028\n"); | ||
663 | return -EINVAL; | ||
664 | } | ||
665 | |||
666 | fe = dvb_attach(xc2028_attach, dev->dvb->fe[0], &cfg); | ||
667 | if (!fe) { | ||
668 | em28xx_errdev("/2: xc3028 attach failed\n"); | ||
669 | dvb_frontend_detach(dev->dvb->fe[0]); | ||
670 | dev->dvb->fe[0] = NULL; | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | |||
674 | em28xx_info("%s/2: xc3028 attached\n", dev->name); | ||
675 | |||
676 | return 0; | ||
677 | } | ||
678 | |||
679 | /* ------------------------------------------------------------------ */ | ||
680 | |||
681 | static int em28xx_register_dvb(struct em28xx_dvb *dvb, struct module *module, | ||
682 | struct em28xx *dev, struct device *device) | ||
683 | { | ||
684 | int result; | ||
685 | |||
686 | mutex_init(&dvb->lock); | ||
687 | |||
688 | /* register adapter */ | ||
689 | result = dvb_register_adapter(&dvb->adapter, dev->name, module, device, | ||
690 | adapter_nr); | ||
691 | if (result < 0) { | ||
692 | printk(KERN_WARNING "%s: dvb_register_adapter failed (errno = %d)\n", | ||
693 | dev->name, result); | ||
694 | goto fail_adapter; | ||
695 | } | ||
696 | |||
697 | /* Ensure all frontends negotiate bus access */ | ||
698 | dvb->fe[0]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; | ||
699 | if (dvb->fe[1]) | ||
700 | dvb->fe[1]->ops.ts_bus_ctrl = em28xx_dvb_bus_ctrl; | ||
701 | |||
702 | dvb->adapter.priv = dev; | ||
703 | |||
704 | /* register frontend */ | ||
705 | result = dvb_register_frontend(&dvb->adapter, dvb->fe[0]); | ||
706 | if (result < 0) { | ||
707 | printk(KERN_WARNING "%s: dvb_register_frontend failed (errno = %d)\n", | ||
708 | dev->name, result); | ||
709 | goto fail_frontend0; | ||
710 | } | ||
711 | |||
712 | /* register 2nd frontend */ | ||
713 | if (dvb->fe[1]) { | ||
714 | result = dvb_register_frontend(&dvb->adapter, dvb->fe[1]); | ||
715 | if (result < 0) { | ||
716 | printk(KERN_WARNING "%s: 2nd dvb_register_frontend failed (errno = %d)\n", | ||
717 | dev->name, result); | ||
718 | goto fail_frontend1; | ||
719 | } | ||
720 | } | ||
721 | |||
722 | /* register demux stuff */ | ||
723 | dvb->demux.dmx.capabilities = | ||
724 | DMX_TS_FILTERING | DMX_SECTION_FILTERING | | ||
725 | DMX_MEMORY_BASED_FILTERING; | ||
726 | dvb->demux.priv = dvb; | ||
727 | dvb->demux.filternum = 256; | ||
728 | dvb->demux.feednum = 256; | ||
729 | dvb->demux.start_feed = em28xx_start_feed; | ||
730 | dvb->demux.stop_feed = em28xx_stop_feed; | ||
731 | |||
732 | result = dvb_dmx_init(&dvb->demux); | ||
733 | if (result < 0) { | ||
734 | printk(KERN_WARNING "%s: dvb_dmx_init failed (errno = %d)\n", | ||
735 | dev->name, result); | ||
736 | goto fail_dmx; | ||
737 | } | ||
738 | |||
739 | dvb->dmxdev.filternum = 256; | ||
740 | dvb->dmxdev.demux = &dvb->demux.dmx; | ||
741 | dvb->dmxdev.capabilities = 0; | ||
742 | result = dvb_dmxdev_init(&dvb->dmxdev, &dvb->adapter); | ||
743 | if (result < 0) { | ||
744 | printk(KERN_WARNING "%s: dvb_dmxdev_init failed (errno = %d)\n", | ||
745 | dev->name, result); | ||
746 | goto fail_dmxdev; | ||
747 | } | ||
748 | |||
749 | dvb->fe_hw.source = DMX_FRONTEND_0; | ||
750 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
751 | if (result < 0) { | ||
752 | printk(KERN_WARNING "%s: add_frontend failed (DMX_FRONTEND_0, errno = %d)\n", | ||
753 | dev->name, result); | ||
754 | goto fail_fe_hw; | ||
755 | } | ||
756 | |||
757 | dvb->fe_mem.source = DMX_MEMORY_FE; | ||
758 | result = dvb->demux.dmx.add_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
759 | if (result < 0) { | ||
760 | printk(KERN_WARNING "%s: add_frontend failed (DMX_MEMORY_FE, errno = %d)\n", | ||
761 | dev->name, result); | ||
762 | goto fail_fe_mem; | ||
763 | } | ||
764 | |||
765 | result = dvb->demux.dmx.connect_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
766 | if (result < 0) { | ||
767 | printk(KERN_WARNING "%s: connect_frontend failed (errno = %d)\n", | ||
768 | dev->name, result); | ||
769 | goto fail_fe_conn; | ||
770 | } | ||
771 | |||
772 | /* register network adapter */ | ||
773 | dvb_net_init(&dvb->adapter, &dvb->net, &dvb->demux.dmx); | ||
774 | return 0; | ||
775 | |||
776 | fail_fe_conn: | ||
777 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
778 | fail_fe_mem: | ||
779 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
780 | fail_fe_hw: | ||
781 | dvb_dmxdev_release(&dvb->dmxdev); | ||
782 | fail_dmxdev: | ||
783 | dvb_dmx_release(&dvb->demux); | ||
784 | fail_dmx: | ||
785 | if (dvb->fe[1]) | ||
786 | dvb_unregister_frontend(dvb->fe[1]); | ||
787 | dvb_unregister_frontend(dvb->fe[0]); | ||
788 | fail_frontend1: | ||
789 | if (dvb->fe[1]) | ||
790 | dvb_frontend_detach(dvb->fe[1]); | ||
791 | fail_frontend0: | ||
792 | dvb_frontend_detach(dvb->fe[0]); | ||
793 | dvb_unregister_adapter(&dvb->adapter); | ||
794 | fail_adapter: | ||
795 | return result; | ||
796 | } | ||
797 | |||
798 | static void em28xx_unregister_dvb(struct em28xx_dvb *dvb) | ||
799 | { | ||
800 | dvb_net_release(&dvb->net); | ||
801 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_mem); | ||
802 | dvb->demux.dmx.remove_frontend(&dvb->demux.dmx, &dvb->fe_hw); | ||
803 | dvb_dmxdev_release(&dvb->dmxdev); | ||
804 | dvb_dmx_release(&dvb->demux); | ||
805 | if (dvb->fe[1]) | ||
806 | dvb_unregister_frontend(dvb->fe[1]); | ||
807 | dvb_unregister_frontend(dvb->fe[0]); | ||
808 | if (dvb->fe[1] && !dvb->dont_attach_fe1) | ||
809 | dvb_frontend_detach(dvb->fe[1]); | ||
810 | dvb_frontend_detach(dvb->fe[0]); | ||
811 | dvb_unregister_adapter(&dvb->adapter); | ||
812 | } | ||
813 | |||
814 | static int em28xx_dvb_init(struct em28xx *dev) | ||
815 | { | ||
816 | int result = 0, mfe_shared = 0; | ||
817 | struct em28xx_dvb *dvb; | ||
818 | |||
819 | if (!dev->board.has_dvb) { | ||
820 | /* This device does not support the extension */ | ||
821 | printk(KERN_INFO "em28xx_dvb: This device does not support the extension\n"); | ||
822 | return 0; | ||
823 | } | ||
824 | |||
825 | dvb = kzalloc(sizeof(struct em28xx_dvb), GFP_KERNEL); | ||
826 | |||
827 | if (dvb == NULL) { | ||
828 | em28xx_info("em28xx_dvb: memory allocation failed\n"); | ||
829 | return -ENOMEM; | ||
830 | } | ||
831 | dev->dvb = dvb; | ||
832 | dvb->fe[0] = dvb->fe[1] = NULL; | ||
833 | |||
834 | mutex_lock(&dev->lock); | ||
835 | em28xx_set_mode(dev, EM28XX_DIGITAL_MODE); | ||
836 | /* init frontend */ | ||
837 | switch (dev->model) { | ||
838 | case EM2874_BOARD_LEADERSHIP_ISDBT: | ||
839 | dvb->fe[0] = dvb_attach(s921_attach, | ||
840 | &sharp_isdbt, &dev->i2c_adap); | ||
841 | |||
842 | if (!dvb->fe[0]) { | ||
843 | result = -EINVAL; | ||
844 | goto out_free; | ||
845 | } | ||
846 | |||
847 | break; | ||
848 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_850: | ||
849 | case EM2883_BOARD_HAUPPAUGE_WINTV_HVR_950: | ||
850 | case EM2880_BOARD_PINNACLE_PCTV_HD_PRO: | ||
851 | case EM2880_BOARD_AMD_ATI_TV_WONDER_HD_600: | ||
852 | dvb->fe[0] = dvb_attach(lgdt330x_attach, | ||
853 | &em2880_lgdt3303_dev, | ||
854 | &dev->i2c_adap); | ||
855 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
856 | result = -EINVAL; | ||
857 | goto out_free; | ||
858 | } | ||
859 | break; | ||
860 | case EM2880_BOARD_KWORLD_DVB_310U: | ||
861 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
862 | &em28xx_zl10353_with_xc3028, | ||
863 | &dev->i2c_adap); | ||
864 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
865 | result = -EINVAL; | ||
866 | goto out_free; | ||
867 | } | ||
868 | break; | ||
869 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900: | ||
870 | case EM2882_BOARD_TERRATEC_HYBRID_XS: | ||
871 | case EM2880_BOARD_EMPIRE_DUAL_TV: | ||
872 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
873 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
874 | &dev->i2c_adap); | ||
875 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
876 | result = -EINVAL; | ||
877 | goto out_free; | ||
878 | } | ||
879 | break; | ||
880 | case EM2880_BOARD_TERRATEC_HYBRID_XS: | ||
881 | case EM2880_BOARD_TERRATEC_HYBRID_XS_FR: | ||
882 | case EM2881_BOARD_PINNACLE_HYBRID_PRO: | ||
883 | case EM2882_BOARD_DIKOM_DK300: | ||
884 | case EM2882_BOARD_KWORLD_VS_DVBT: | ||
885 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
886 | &em28xx_zl10353_xc3028_no_i2c_gate, | ||
887 | &dev->i2c_adap); | ||
888 | if (dvb->fe[0] == NULL) { | ||
889 | /* This board could have either a zl10353 or a mt352. | ||
890 | If the chip id isn't for zl10353, try mt352 */ | ||
891 | dvb->fe[0] = dvb_attach(mt352_attach, | ||
892 | &terratec_xs_mt352_cfg, | ||
893 | &dev->i2c_adap); | ||
894 | } | ||
895 | |||
896 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
897 | result = -EINVAL; | ||
898 | goto out_free; | ||
899 | } | ||
900 | break; | ||
901 | case EM2870_BOARD_KWORLD_355U: | ||
902 | dvb->fe[0] = dvb_attach(zl10353_attach, | ||
903 | &em28xx_zl10353_no_i2c_gate_dev, | ||
904 | &dev->i2c_adap); | ||
905 | if (dvb->fe[0] != NULL) | ||
906 | dvb_attach(qt1010_attach, dvb->fe[0], | ||
907 | &dev->i2c_adap, &em28xx_qt1010_config); | ||
908 | break; | ||
909 | case EM2883_BOARD_KWORLD_HYBRID_330U: | ||
910 | case EM2882_BOARD_EVGA_INDTUBE: | ||
911 | dvb->fe[0] = dvb_attach(s5h1409_attach, | ||
912 | &em28xx_s5h1409_with_xc3028, | ||
913 | &dev->i2c_adap); | ||
914 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
915 | result = -EINVAL; | ||
916 | goto out_free; | ||
917 | } | ||
918 | break; | ||
919 | case EM2882_BOARD_KWORLD_ATSC_315U: | ||
920 | dvb->fe[0] = dvb_attach(lgdt330x_attach, | ||
921 | &em2880_lgdt3303_dev, | ||
922 | &dev->i2c_adap); | ||
923 | if (dvb->fe[0] != NULL) { | ||
924 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], | ||
925 | &dev->i2c_adap, 0x61, TUNER_THOMSON_DTT761X)) { | ||
926 | result = -EINVAL; | ||
927 | goto out_free; | ||
928 | } | ||
929 | } | ||
930 | break; | ||
931 | case EM2880_BOARD_HAUPPAUGE_WINTV_HVR_900_R2: | ||
932 | case EM2882_BOARD_PINNACLE_HYBRID_PRO_330E: | ||
933 | dvb->fe[0] = dvb_attach(drxd_attach, &em28xx_drxd, NULL, | ||
934 | &dev->i2c_adap, &dev->udev->dev); | ||
935 | if (em28xx_attach_xc3028(0x61, dev) < 0) { | ||
936 | result = -EINVAL; | ||
937 | goto out_free; | ||
938 | } | ||
939 | break; | ||
940 | case EM2870_BOARD_REDDO_DVB_C_USB_BOX: | ||
941 | /* Philips CU1216L NIM (Philips TDA10023 + Infineon TUA6034) */ | ||
942 | dvb->fe[0] = dvb_attach(tda10023_attach, | ||
943 | &em28xx_tda10023_config, | ||
944 | &dev->i2c_adap, 0x48); | ||
945 | if (dvb->fe[0]) { | ||
946 | if (!dvb_attach(simple_tuner_attach, dvb->fe[0], | ||
947 | &dev->i2c_adap, 0x60, TUNER_PHILIPS_CU1216L)) { | ||
948 | result = -EINVAL; | ||
949 | goto out_free; | ||
950 | } | ||
951 | } | ||
952 | break; | ||
953 | case EM2870_BOARD_KWORLD_A340: | ||
954 | dvb->fe[0] = dvb_attach(lgdt3305_attach, | ||
955 | &em2870_lgdt3304_dev, | ||
956 | &dev->i2c_adap); | ||
957 | if (dvb->fe[0] != NULL) | ||
958 | dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
959 | &dev->i2c_adap, &kworld_a340_config); | ||
960 | break; | ||
961 | case EM28174_BOARD_PCTV_290E: | ||
962 | dvb->fe[0] = dvb_attach(cxd2820r_attach, | ||
963 | &em28xx_cxd2820r_config, | ||
964 | &dev->i2c_adap); | ||
965 | if (dvb->fe[0]) { | ||
966 | /* FE 0 attach tuner */ | ||
967 | if (!dvb_attach(tda18271_attach, | ||
968 | dvb->fe[0], | ||
969 | 0x60, | ||
970 | &dev->i2c_adap, | ||
971 | &em28xx_cxd2820r_tda18271_config)) { | ||
972 | |||
973 | dvb_frontend_detach(dvb->fe[0]); | ||
974 | result = -EINVAL; | ||
975 | goto out_free; | ||
976 | } | ||
977 | } | ||
978 | break; | ||
979 | case EM2884_BOARD_HAUPPAUGE_WINTV_HVR_930C: | ||
980 | { | ||
981 | struct xc5000_config cfg; | ||
982 | hauppauge_hvr930c_init(dev); | ||
983 | |||
984 | dvb->fe[0] = dvb_attach(drxk_attach, | ||
985 | &hauppauge_930c_drxk, &dev->i2c_adap); | ||
986 | if (!dvb->fe[0]) { | ||
987 | result = -EINVAL; | ||
988 | goto out_free; | ||
989 | } | ||
990 | /* FIXME: do we need a pll semaphore? */ | ||
991 | dvb->fe[0]->sec_priv = dvb; | ||
992 | sema_init(&dvb->pll_mutex, 1); | ||
993 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
994 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
995 | |||
996 | /* Attach xc5000 */ | ||
997 | memset(&cfg, 0, sizeof(cfg)); | ||
998 | cfg.i2c_address = 0x61; | ||
999 | cfg.if_khz = 4000; | ||
1000 | |||
1001 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1002 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
1003 | if (!dvb_attach(xc5000_attach, dvb->fe[0], &dev->i2c_adap, | ||
1004 | &cfg)) { | ||
1005 | result = -EINVAL; | ||
1006 | goto out_free; | ||
1007 | } | ||
1008 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1009 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
1010 | |||
1011 | break; | ||
1012 | } | ||
1013 | case EM2884_BOARD_TERRATEC_H5: | ||
1014 | terratec_h5_init(dev); | ||
1015 | |||
1016 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_h5_drxk, &dev->i2c_adap); | ||
1017 | if (!dvb->fe[0]) { | ||
1018 | result = -EINVAL; | ||
1019 | goto out_free; | ||
1020 | } | ||
1021 | /* FIXME: do we need a pll semaphore? */ | ||
1022 | dvb->fe[0]->sec_priv = dvb; | ||
1023 | sema_init(&dvb->pll_mutex, 1); | ||
1024 | dvb->gate_ctrl = dvb->fe[0]->ops.i2c_gate_ctrl; | ||
1025 | dvb->fe[0]->ops.i2c_gate_ctrl = drxk_gate_ctrl; | ||
1026 | |||
1027 | /* Attach tda18271 to DVB-C frontend */ | ||
1028 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1029 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 1); | ||
1030 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], &dev->i2c_adap, 0x60)) { | ||
1031 | result = -EINVAL; | ||
1032 | goto out_free; | ||
1033 | } | ||
1034 | if (dvb->fe[0]->ops.i2c_gate_ctrl) | ||
1035 | dvb->fe[0]->ops.i2c_gate_ctrl(dvb->fe[0], 0); | ||
1036 | |||
1037 | break; | ||
1038 | case EM28174_BOARD_PCTV_460E: | ||
1039 | /* attach demod */ | ||
1040 | dvb->fe[0] = dvb_attach(tda10071_attach, | ||
1041 | &em28xx_tda10071_config, &dev->i2c_adap); | ||
1042 | |||
1043 | /* attach SEC */ | ||
1044 | if (dvb->fe[0]) | ||
1045 | dvb_attach(a8293_attach, dvb->fe[0], &dev->i2c_adap, | ||
1046 | &em28xx_a8293_config); | ||
1047 | break; | ||
1048 | case EM2874_BOARD_MAXMEDIA_UB425_TC: | ||
1049 | /* attach demodulator */ | ||
1050 | dvb->fe[0] = dvb_attach(drxk_attach, &maxmedia_ub425_tc_drxk, | ||
1051 | &dev->i2c_adap); | ||
1052 | |||
1053 | if (dvb->fe[0]) { | ||
1054 | /* disable I2C-gate */ | ||
1055 | dvb->fe[0]->ops.i2c_gate_ctrl = NULL; | ||
1056 | |||
1057 | /* attach tuner */ | ||
1058 | if (!dvb_attach(tda18271c2dd_attach, dvb->fe[0], | ||
1059 | &dev->i2c_adap, 0x60)) { | ||
1060 | dvb_frontend_detach(dvb->fe[0]); | ||
1061 | result = -EINVAL; | ||
1062 | goto out_free; | ||
1063 | } | ||
1064 | } | ||
1065 | |||
1066 | /* TODO: we need drx-3913k firmware in order to support DVB-T */ | ||
1067 | em28xx_info("MaxMedia UB425-TC: only DVB-C supported by that " \ | ||
1068 | "driver version\n"); | ||
1069 | |||
1070 | break; | ||
1071 | case EM2884_BOARD_PCTV_510E: | ||
1072 | case EM2884_BOARD_PCTV_520E: | ||
1073 | pctv_520e_init(dev); | ||
1074 | |||
1075 | /* attach demodulator */ | ||
1076 | dvb->fe[0] = dvb_attach(drxk_attach, &pctv_520e_drxk, | ||
1077 | &dev->i2c_adap); | ||
1078 | |||
1079 | if (dvb->fe[0]) { | ||
1080 | /* attach tuner */ | ||
1081 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
1082 | &dev->i2c_adap, | ||
1083 | &em28xx_cxd2820r_tda18271_config)) { | ||
1084 | dvb_frontend_detach(dvb->fe[0]); | ||
1085 | result = -EINVAL; | ||
1086 | goto out_free; | ||
1087 | } | ||
1088 | } | ||
1089 | break; | ||
1090 | case EM2884_BOARD_CINERGY_HTC_STICK: | ||
1091 | terratec_htc_stick_init(dev); | ||
1092 | |||
1093 | /* attach demodulator */ | ||
1094 | dvb->fe[0] = dvb_attach(drxk_attach, &terratec_htc_stick_drxk, | ||
1095 | &dev->i2c_adap); | ||
1096 | if (!dvb->fe[0]) { | ||
1097 | result = -EINVAL; | ||
1098 | goto out_free; | ||
1099 | } | ||
1100 | |||
1101 | /* Attach the demodulator. */ | ||
1102 | if (!dvb_attach(tda18271_attach, dvb->fe[0], 0x60, | ||
1103 | &dev->i2c_adap, | ||
1104 | &em28xx_cxd2820r_tda18271_config)) { | ||
1105 | result = -EINVAL; | ||
1106 | goto out_free; | ||
1107 | } | ||
1108 | break; | ||
1109 | default: | ||
1110 | em28xx_errdev("/2: The frontend of your DVB/ATSC card" | ||
1111 | " isn't supported yet\n"); | ||
1112 | break; | ||
1113 | } | ||
1114 | if (NULL == dvb->fe[0]) { | ||
1115 | em28xx_errdev("/2: frontend initialization failed\n"); | ||
1116 | result = -EINVAL; | ||
1117 | goto out_free; | ||
1118 | } | ||
1119 | /* define general-purpose callback pointer */ | ||
1120 | dvb->fe[0]->callback = em28xx_tuner_callback; | ||
1121 | if (dvb->fe[1]) | ||
1122 | dvb->fe[1]->callback = em28xx_tuner_callback; | ||
1123 | |||
1124 | /* register everything */ | ||
1125 | result = em28xx_register_dvb(dvb, THIS_MODULE, dev, &dev->udev->dev); | ||
1126 | |||
1127 | if (result < 0) | ||
1128 | goto out_free; | ||
1129 | |||
1130 | /* MFE lock */ | ||
1131 | dvb->adapter.mfe_shared = mfe_shared; | ||
1132 | |||
1133 | em28xx_info("Successfully loaded em28xx-dvb\n"); | ||
1134 | ret: | ||
1135 | em28xx_set_mode(dev, EM28XX_SUSPEND); | ||
1136 | mutex_unlock(&dev->lock); | ||
1137 | return result; | ||
1138 | |||
1139 | out_free: | ||
1140 | kfree(dvb); | ||
1141 | dev->dvb = NULL; | ||
1142 | goto ret; | ||
1143 | } | ||
1144 | |||
1145 | static inline void prevent_sleep(struct dvb_frontend_ops *ops) | ||
1146 | { | ||
1147 | ops->set_voltage = NULL; | ||
1148 | ops->sleep = NULL; | ||
1149 | ops->tuner_ops.sleep = NULL; | ||
1150 | } | ||
1151 | |||
1152 | static int em28xx_dvb_fini(struct em28xx *dev) | ||
1153 | { | ||
1154 | if (!dev->board.has_dvb) { | ||
1155 | /* This device does not support the extension */ | ||
1156 | return 0; | ||
1157 | } | ||
1158 | |||
1159 | if (dev->dvb) { | ||
1160 | struct em28xx_dvb *dvb = dev->dvb; | ||
1161 | |||
1162 | if (dev->state & DEV_DISCONNECTED) { | ||
1163 | /* We cannot tell the device to sleep | ||
1164 | * once it has been unplugged. */ | ||
1165 | if (dvb->fe[0]) | ||
1166 | prevent_sleep(&dvb->fe[0]->ops); | ||
1167 | if (dvb->fe[1]) | ||
1168 | prevent_sleep(&dvb->fe[1]->ops); | ||
1169 | } | ||
1170 | |||
1171 | em28xx_unregister_dvb(dvb); | ||
1172 | kfree(dvb); | ||
1173 | dev->dvb = NULL; | ||
1174 | } | ||
1175 | |||
1176 | return 0; | ||
1177 | } | ||
1178 | |||
1179 | static struct em28xx_ops dvb_ops = { | ||
1180 | .id = EM28XX_DVB, | ||
1181 | .name = "Em28xx dvb Extension", | ||
1182 | .init = em28xx_dvb_init, | ||
1183 | .fini = em28xx_dvb_fini, | ||
1184 | }; | ||
1185 | |||
1186 | static int __init em28xx_dvb_register(void) | ||
1187 | { | ||
1188 | return em28xx_register_extension(&dvb_ops); | ||
1189 | } | ||
1190 | |||
1191 | static void __exit em28xx_dvb_unregister(void) | ||
1192 | { | ||
1193 | em28xx_unregister_extension(&dvb_ops); | ||
1194 | } | ||
1195 | |||
1196 | module_init(em28xx_dvb_register); | ||
1197 | module_exit(em28xx_dvb_unregister); | ||