Commit | Line | Data |
---|---|---|
1da177e4 | 1 | /* |
1da177e4 LT |
2 | * |
3 | * device driver for Conexant 2388x based TV cards | |
4 | * MPEG Transport Stream (DVB) routines | |
5 | * | |
fc40b261 | 6 | * (c) 2004, 2005 Chris Pascoe <c.pascoe@itee.uq.edu.au> |
1da177e4 LT |
7 | * (c) 2004 Gerd Knorr <kraxel@bytesex.org> [SuSE Labs] |
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 | #include <linux/module.h> | |
25 | #include <linux/init.h> | |
26 | #include <linux/device.h> | |
27 | #include <linux/fs.h> | |
28 | #include <linux/kthread.h> | |
29 | #include <linux/file.h> | |
30 | #include <linux/suspend.h> | |
31 | ||
1da177e4 LT |
32 | #include "cx88.h" |
33 | #include "dvb-pll.h" | |
5e453dc7 | 34 | #include <media/v4l2-common.h> |
41ef7c1e | 35 | |
1f10c7af AQ |
36 | #include "mt352.h" |
37 | #include "mt352_priv.h" | |
ecf854df | 38 | #include "cx88-vp3054-i2c.h" |
1f10c7af AQ |
39 | #include "zl10353.h" |
40 | #include "cx22702.h" | |
41 | #include "or51132.h" | |
42 | #include "lgdt330x.h" | |
60464da8 ST |
43 | #include "s5h1409.h" |
44 | #include "xc5000.h" | |
1f10c7af AQ |
45 | #include "nxt200x.h" |
46 | #include "cx24123.h" | |
cd20ca9f | 47 | #include "isl6421.h" |
5c00fac0 ST |
48 | #include "tuner-xc2028.h" |
49 | #include "tuner-xc2028-types.h" | |
1da177e4 LT |
50 | |
51 | MODULE_DESCRIPTION("driver for cx2388x based DVB cards"); | |
52 | MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>"); | |
53 | MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); | |
54 | MODULE_LICENSE("GPL"); | |
55 | ||
ff699e6b | 56 | static unsigned int debug; |
1da177e4 LT |
57 | module_param(debug, int, 0644); |
58 | MODULE_PARM_DESC(debug,"enable debug messages [dvb]"); | |
59 | ||
60 | #define dprintk(level,fmt, arg...) if (debug >= level) \ | |
6c5be74c | 61 | printk(KERN_DEBUG "%s/2-dvb: " fmt, core->name, ## arg) |
1da177e4 LT |
62 | |
63 | /* ------------------------------------------------------------------ */ | |
64 | ||
65 | static int dvb_buf_setup(struct videobuf_queue *q, | |
66 | unsigned int *count, unsigned int *size) | |
67 | { | |
68 | struct cx8802_dev *dev = q->priv_data; | |
69 | ||
70 | dev->ts_packet_size = 188 * 4; | |
71 | dev->ts_packet_count = 32; | |
72 | ||
73 | *size = dev->ts_packet_size * dev->ts_packet_count; | |
74 | *count = 32; | |
75 | return 0; | |
76 | } | |
77 | ||
4a390558 MK |
78 | static int dvb_buf_prepare(struct videobuf_queue *q, |
79 | struct videobuf_buffer *vb, enum v4l2_field field) | |
1da177e4 LT |
80 | { |
81 | struct cx8802_dev *dev = q->priv_data; | |
c7b0ac05 | 82 | return cx8802_buf_prepare(q, dev, (struct cx88_buffer*)vb,field); |
1da177e4 LT |
83 | } |
84 | ||
85 | static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb) | |
86 | { | |
87 | struct cx8802_dev *dev = q->priv_data; | |
88 | cx8802_buf_queue(dev, (struct cx88_buffer*)vb); | |
89 | } | |
90 | ||
4a390558 MK |
91 | static void dvb_buf_release(struct videobuf_queue *q, |
92 | struct videobuf_buffer *vb) | |
1da177e4 | 93 | { |
c7b0ac05 | 94 | cx88_free_buffer(q, (struct cx88_buffer*)vb); |
1da177e4 LT |
95 | } |
96 | ||
408b664a | 97 | static struct videobuf_queue_ops dvb_qops = { |
1da177e4 LT |
98 | .buf_setup = dvb_buf_setup, |
99 | .buf_prepare = dvb_buf_prepare, | |
100 | .buf_queue = dvb_buf_queue, | |
101 | .buf_release = dvb_buf_release, | |
102 | }; | |
103 | ||
104 | /* ------------------------------------------------------------------ */ | |
22f3f17d MK |
105 | |
106 | static int cx88_dvb_bus_ctrl(struct dvb_frontend* fe, int acquire) | |
107 | { | |
108 | struct cx8802_dev *dev= fe->dvb->priv; | |
109 | struct cx8802_driver *drv = NULL; | |
110 | int ret = 0; | |
111 | ||
112 | drv = cx8802_get_driver(dev, CX88_MPEG_DVB); | |
113 | if (drv) { | |
4a390558 | 114 | if (acquire) |
22f3f17d MK |
115 | ret = drv->request_acquire(drv); |
116 | else | |
117 | ret = drv->request_release(drv); | |
118 | } | |
119 | ||
120 | return ret; | |
121 | } | |
122 | ||
123 | /* ------------------------------------------------------------------ */ | |
124 | ||
3d7d027a | 125 | static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe) |
1da177e4 LT |
126 | { |
127 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 }; | |
128 | static u8 reset [] = { RESET, 0x80 }; | |
129 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | |
130 | static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 }; | |
131 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | |
132 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | |
133 | ||
134 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
135 | udelay(200); | |
136 | mt352_write(fe, reset, sizeof(reset)); | |
137 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
138 | ||
139 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
140 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | |
141 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
142 | return 0; | |
143 | } | |
144 | ||
43eabb4e CP |
145 | static int dvico_dual_demod_init(struct dvb_frontend *fe) |
146 | { | |
147 | static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x38 }; | |
148 | static u8 reset [] = { RESET, 0x80 }; | |
149 | static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 }; | |
150 | static u8 agc_cfg [] = { AGC_TARGET, 0x28, 0x20 }; | |
151 | static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 }; | |
152 | static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 }; | |
153 | ||
154 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
155 | udelay(200); | |
156 | mt352_write(fe, reset, sizeof(reset)); | |
157 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
158 | ||
159 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
160 | mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg)); | |
161 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
162 | ||
163 | return 0; | |
164 | } | |
165 | ||
1da177e4 LT |
166 | static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe) |
167 | { | |
168 | static u8 clock_config [] = { 0x89, 0x38, 0x39 }; | |
169 | static u8 reset [] = { 0x50, 0x80 }; | |
170 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | |
171 | static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF, | |
f2421ca3 | 172 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; |
1da177e4 LT |
173 | static u8 dntv_extra[] = { 0xB5, 0x7A }; |
174 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | |
175 | ||
176 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
177 | udelay(2000); | |
178 | mt352_write(fe, reset, sizeof(reset)); | |
179 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
180 | ||
181 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
182 | udelay(2000); | |
183 | mt352_write(fe, dntv_extra, sizeof(dntv_extra)); | |
184 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
185 | ||
186 | return 0; | |
187 | } | |
188 | ||
1da177e4 | 189 | static struct mt352_config dvico_fusionhdtv = { |
f7b54b10 | 190 | .demod_address = 0x0f, |
3d7d027a | 191 | .demod_init = dvico_fusionhdtv_demod_init, |
1da177e4 LT |
192 | }; |
193 | ||
194 | static struct mt352_config dntv_live_dvbt_config = { | |
195 | .demod_address = 0x0f, | |
196 | .demod_init = dntv_live_dvbt_demod_init, | |
1da177e4 | 197 | }; |
fc40b261 | 198 | |
43eabb4e | 199 | static struct mt352_config dvico_fusionhdtv_dual = { |
f7b54b10 | 200 | .demod_address = 0x0f, |
43eabb4e | 201 | .demod_init = dvico_dual_demod_init, |
43eabb4e CP |
202 | }; |
203 | ||
ecf854df | 204 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
3d7d027a CP |
205 | static int dntv_live_dvbt_pro_demod_init(struct dvb_frontend* fe) |
206 | { | |
207 | static u8 clock_config [] = { 0x89, 0x38, 0x38 }; | |
208 | static u8 reset [] = { 0x50, 0x80 }; | |
209 | static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 }; | |
210 | static u8 agc_cfg [] = { 0x67, 0x10, 0x20, 0x00, 0xFF, 0xFF, | |
211 | 0x00, 0xFF, 0x00, 0x40, 0x40 }; | |
212 | static u8 dntv_extra[] = { 0xB5, 0x7A }; | |
213 | static u8 capt_range_cfg[] = { 0x75, 0x32 }; | |
214 | ||
215 | mt352_write(fe, clock_config, sizeof(clock_config)); | |
216 | udelay(2000); | |
217 | mt352_write(fe, reset, sizeof(reset)); | |
218 | mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg)); | |
219 | ||
220 | mt352_write(fe, agc_cfg, sizeof(agc_cfg)); | |
221 | udelay(2000); | |
222 | mt352_write(fe, dntv_extra, sizeof(dntv_extra)); | |
223 | mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg)); | |
224 | ||
225 | return 0; | |
226 | } | |
227 | ||
fc40b261 CP |
228 | static struct mt352_config dntv_live_dvbt_pro_config = { |
229 | .demod_address = 0x0f, | |
230 | .no_tuner = 1, | |
3d7d027a | 231 | .demod_init = dntv_live_dvbt_pro_demod_init, |
fc40b261 CP |
232 | }; |
233 | #endif | |
1da177e4 | 234 | |
780dfef3 | 235 | static struct zl10353_config dvico_fusionhdtv_hybrid = { |
f7b54b10 | 236 | .demod_address = 0x0f, |
f54376e2 | 237 | .no_tuner = 1, |
780dfef3 CP |
238 | }; |
239 | ||
240 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { | |
f7b54b10 | 241 | .demod_address = 0x0f, |
780dfef3 | 242 | }; |
780dfef3 | 243 | |
1da177e4 LT |
244 | static struct cx22702_config connexant_refboard_config = { |
245 | .demod_address = 0x43, | |
38d84c3b | 246 | .output_mode = CX22702_SERIAL_OUTPUT, |
1da177e4 LT |
247 | }; |
248 | ||
ed355260 | 249 | static struct cx22702_config hauppauge_hvr_config = { |
aa481a65 ST |
250 | .demod_address = 0x63, |
251 | .output_mode = CX22702_SERIAL_OUTPUT, | |
252 | }; | |
1da177e4 | 253 | |
4a390558 | 254 | static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
1da177e4 LT |
255 | { |
256 | struct cx8802_dev *dev= fe->dvb->priv; | |
257 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | |
258 | return 0; | |
259 | } | |
260 | ||
408b664a | 261 | static struct or51132_config pchdtv_hd3000 = { |
f7b54b10 MK |
262 | .demod_address = 0x15, |
263 | .set_ts_params = or51132_set_ts_param, | |
1da177e4 | 264 | }; |
1da177e4 | 265 | |
6ddcc919 | 266 | static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) |
0ccef6db MK |
267 | { |
268 | struct cx8802_dev *dev= fe->dvb->priv; | |
269 | struct cx88_core *core = dev->core; | |
270 | ||
271 | dprintk(1, "%s: index = %d\n", __FUNCTION__, index); | |
272 | if (index == 0) | |
273 | cx_clear(MO_GP0_IO, 8); | |
274 | else | |
275 | cx_set(MO_GP0_IO, 8); | |
276 | return 0; | |
277 | } | |
278 | ||
6ddcc919 | 279 | static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
f1798495 MK |
280 | { |
281 | struct cx8802_dev *dev= fe->dvb->priv; | |
282 | if (is_punctured) | |
283 | dev->ts_gen_cntrl |= 0x04; | |
284 | else | |
285 | dev->ts_gen_cntrl &= ~0x04; | |
286 | return 0; | |
287 | } | |
288 | ||
6ddcc919 | 289 | static struct lgdt330x_config fusionhdtv_3_gold = { |
f7b54b10 MK |
290 | .demod_address = 0x0e, |
291 | .demod_chip = LGDT3302, | |
292 | .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ | |
293 | .set_ts_params = lgdt330x_set_ts_param, | |
0d723c09 | 294 | }; |
e52e98a7 MCC |
295 | |
296 | static struct lgdt330x_config fusionhdtv_5_gold = { | |
f7b54b10 MK |
297 | .demod_address = 0x0e, |
298 | .demod_chip = LGDT3303, | |
299 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | |
300 | .set_ts_params = lgdt330x_set_ts_param, | |
e52e98a7 | 301 | }; |
da215d22 RS |
302 | |
303 | static struct lgdt330x_config pchdtv_hd5500 = { | |
f7b54b10 MK |
304 | .demod_address = 0x59, |
305 | .demod_chip = LGDT3303, | |
306 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | |
307 | .set_ts_params = lgdt330x_set_ts_param, | |
da215d22 | 308 | }; |
f1798495 | 309 | |
4a390558 | 310 | static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
fde6d31e KL |
311 | { |
312 | struct cx8802_dev *dev= fe->dvb->priv; | |
313 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | |
314 | return 0; | |
315 | } | |
316 | ||
317 | static struct nxt200x_config ati_hdtvwonder = { | |
f7b54b10 | 318 | .demod_address = 0x0a, |
f7b54b10 | 319 | .set_ts_params = nxt200x_set_ts_param, |
fde6d31e | 320 | }; |
fde6d31e | 321 | |
0fa14aa6 ST |
322 | static int cx24123_set_ts_param(struct dvb_frontend* fe, |
323 | int is_punctured) | |
324 | { | |
325 | struct cx8802_dev *dev= fe->dvb->priv; | |
f7b54b10 | 326 | dev->ts_gen_cntrl = 0x02; |
0fa14aa6 ST |
327 | return 0; |
328 | } | |
329 | ||
f7b54b10 MK |
330 | static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, |
331 | fe_sec_voltage_t voltage) | |
0e0351e3 VC |
332 | { |
333 | struct cx8802_dev *dev= fe->dvb->priv; | |
334 | struct cx88_core *core = dev->core; | |
335 | ||
4a390558 | 336 | if (voltage == SEC_VOLTAGE_OFF) |
f7b54b10 | 337 | cx_write(MO_GP0_IO, 0x000006fb); |
4a390558 | 338 | else |
cd20ca9f | 339 | cx_write(MO_GP0_IO, 0x000006f9); |
cd20ca9f AQ |
340 | |
341 | if (core->prev_set_voltage) | |
342 | return core->prev_set_voltage(fe, voltage); | |
343 | return 0; | |
0e0351e3 VC |
344 | } |
345 | ||
f7b54b10 MK |
346 | static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, |
347 | fe_sec_voltage_t voltage) | |
c02a34f4 SA |
348 | { |
349 | struct cx8802_dev *dev= fe->dvb->priv; | |
350 | struct cx88_core *core = dev->core; | |
351 | ||
352 | if (voltage == SEC_VOLTAGE_OFF) { | |
353 | dprintk(1,"LNB Voltage OFF\n"); | |
354 | cx_write(MO_GP0_IO, 0x0000efff); | |
355 | } | |
356 | ||
357 | if (core->prev_set_voltage) | |
358 | return core->prev_set_voltage(fe, voltage); | |
359 | return 0; | |
360 | } | |
361 | ||
5c00fac0 ST |
362 | static int cx88_xc3028_callback(void *ptr, int command, int arg) |
363 | { | |
364 | struct cx88_core *core = ptr; | |
365 | ||
366 | switch (command) { | |
367 | case XC2028_TUNER_RESET: | |
368 | /* Send the tuner in then out of reset */ | |
369 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); | |
370 | ||
371 | switch (core->boardnr) { | |
372 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | |
373 | /* GPIO-4 xc3028 tuner */ | |
374 | ||
375 | cx_set(MO_GP0_IO, 0x00001000); | |
376 | cx_clear(MO_GP0_IO, 0x00000010); | |
377 | msleep(100); | |
378 | cx_set(MO_GP0_IO, 0x00000010); | |
379 | msleep(100); | |
380 | break; | |
381 | } | |
382 | ||
383 | break; | |
384 | case XC2028_RESET_CLK: | |
385 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); | |
386 | break; | |
387 | default: | |
388 | dprintk(1, "%s: unknown command %d, arg %d\n", __FUNCTION__, | |
389 | command, arg); | |
390 | return -EINVAL; | |
391 | } | |
392 | ||
393 | return 0; | |
394 | } | |
395 | ||
c02a34f4 | 396 | static struct cx24123_config geniatech_dvbs_config = { |
f7b54b10 MK |
397 | .demod_address = 0x55, |
398 | .set_ts_params = cx24123_set_ts_param, | |
c02a34f4 SA |
399 | }; |
400 | ||
0fa14aa6 | 401 | static struct cx24123_config hauppauge_novas_config = { |
f7b54b10 MK |
402 | .demod_address = 0x55, |
403 | .set_ts_params = cx24123_set_ts_param, | |
0e0351e3 VC |
404 | }; |
405 | ||
406 | static struct cx24123_config kworld_dvbs_100_config = { | |
f7b54b10 MK |
407 | .demod_address = 0x15, |
408 | .set_ts_params = cx24123_set_ts_param, | |
ef76856d | 409 | .lnb_polarity = 1, |
0fa14aa6 | 410 | }; |
0fa14aa6 | 411 | |
60464da8 ST |
412 | static struct s5h1409_config pinnacle_pctv_hd_800i_config = { |
413 | .demod_address = 0x32 >> 1, | |
414 | .output_mode = S5H1409_PARALLEL_OUTPUT, | |
415 | .gpio = S5H1409_GPIO_ON, | |
416 | .qam_if = 44000, | |
417 | .inversion = S5H1409_INVERSION_OFF, | |
418 | .status_mode = S5H1409_DEMODLOCKING, | |
4917019d | 419 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, |
60464da8 ST |
420 | }; |
421 | ||
5c00fac0 ST |
422 | static struct s5h1409_config dvico_hdtv5_pci_nano_config = { |
423 | .demod_address = 0x32 >> 1, | |
424 | .output_mode = S5H1409_SERIAL_OUTPUT, | |
425 | .gpio = S5H1409_GPIO_OFF, | |
426 | .inversion = S5H1409_INVERSION_OFF, | |
427 | .status_mode = S5H1409_DEMODLOCKING, | |
428 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | |
429 | }; | |
430 | ||
60464da8 ST |
431 | static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { |
432 | .i2c_address = 0x64, | |
433 | .if_khz = 5380, | |
60464da8 ST |
434 | .tuner_callback = cx88_tuner_callback, |
435 | }; | |
436 | ||
9507901e MCC |
437 | static struct zl10353_config cx88_geniatech_x8000_mt = { |
438 | .demod_address = (0x1e >> 1), | |
439 | .no_tuner = 1, | |
440 | }; | |
441 | ||
442 | ||
1da177e4 LT |
443 | static int dvb_register(struct cx8802_dev *dev) |
444 | { | |
9507901e MCC |
445 | int attach_xc3028 = 0; |
446 | ||
1da177e4 LT |
447 | /* init struct videobuf_dvb */ |
448 | dev->dvb.name = dev->core->name; | |
449 | dev->ts_gen_cntrl = 0x0c; | |
450 | ||
451 | /* init frontend */ | |
6a59d64c | 452 | switch (dev->core->boardnr) { |
1da177e4 | 453 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
f7b54b10 | 454 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
ed355260 | 455 | &connexant_refboard_config, |
f7b54b10 | 456 | &dev->core->i2c_adap); |
f54376e2 | 457 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 458 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
f7b54b10 | 459 | &dev->core->i2c_adap, |
47a9991e | 460 | DVB_PLL_THOMSON_DTT759X); |
f54376e2 | 461 | } |
1da177e4 | 462 | break; |
e057ee11 | 463 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
1da177e4 | 464 | case CX88_BOARD_CONEXANT_DVB_T1: |
f39624fd | 465 | case CX88_BOARD_KWORLD_DVB_T_CX22702: |
2b5200a7 | 466 | case CX88_BOARD_WINFAST_DTV1000: |
f7b54b10 MK |
467 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
468 | &connexant_refboard_config, | |
469 | &dev->core->i2c_adap); | |
f54376e2 | 470 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 471 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
f7b54b10 | 472 | &dev->core->i2c_adap, |
47a9991e | 473 | DVB_PLL_THOMSON_DTT7579); |
f54376e2 | 474 | } |
1da177e4 | 475 | break; |
4bd6e9d9 | 476 | case CX88_BOARD_WINFAST_DTV2000H: |
611900c1 ST |
477 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
478 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | |
a5a2ecfc TP |
479 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
480 | case CX88_BOARD_HAUPPAUGE_HVR3000: | |
f7b54b10 | 481 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
ed355260 | 482 | &hauppauge_hvr_config, |
f7b54b10 | 483 | &dev->core->i2c_adap); |
f54376e2 | 484 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 485 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 486 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); |
f54376e2 | 487 | } |
611900c1 | 488 | break; |
780dfef3 | 489 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
f7b54b10 MK |
490 | dev->dvb.frontend = dvb_attach(mt352_attach, |
491 | &dvico_fusionhdtv, | |
492 | &dev->core->i2c_adap); | |
f54376e2 | 493 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 494 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
47a9991e | 495 | NULL, DVB_PLL_THOMSON_DTT7579); |
780dfef3 | 496 | break; |
f54376e2 | 497 | } |
780dfef3 | 498 | /* ZL10353 replaces MT352 on later cards */ |
f7b54b10 MK |
499 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
500 | &dvico_fusionhdtv_plus_v1_1, | |
501 | &dev->core->i2c_adap); | |
f54376e2 | 502 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 503 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
47a9991e | 504 | NULL, DVB_PLL_THOMSON_DTT7579); |
f54376e2 | 505 | } |
c2af3cd6 MK |
506 | break; |
507 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | |
c2af3cd6 MK |
508 | /* The tin box says DEE1601, but it seems to be DTT7579 |
509 | * compatible, with a slightly different MT352 AGC gain. */ | |
f7b54b10 MK |
510 | dev->dvb.frontend = dvb_attach(mt352_attach, |
511 | &dvico_fusionhdtv_dual, | |
512 | &dev->core->i2c_adap); | |
c2af3cd6 | 513 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 514 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 515 | NULL, DVB_PLL_THOMSON_DTT7579); |
c2af3cd6 MK |
516 | break; |
517 | } | |
c2af3cd6 | 518 | /* ZL10353 replaces MT352 on later cards */ |
f7b54b10 MK |
519 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
520 | &dvico_fusionhdtv_plus_v1_1, | |
521 | &dev->core->i2c_adap); | |
c2af3cd6 | 522 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 523 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 524 | NULL, DVB_PLL_THOMSON_DTT7579); |
c2af3cd6 | 525 | } |
1da177e4 | 526 | break; |
780dfef3 | 527 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
f7b54b10 MK |
528 | dev->dvb.frontend = dvb_attach(mt352_attach, |
529 | &dvico_fusionhdtv, | |
530 | &dev->core->i2c_adap); | |
f54376e2 | 531 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 532 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 533 | NULL, DVB_PLL_LG_Z201); |
f54376e2 | 534 | } |
1da177e4 LT |
535 | break; |
536 | case CX88_BOARD_KWORLD_DVB_T: | |
537 | case CX88_BOARD_DNTV_LIVE_DVB_T: | |
a82decf6 | 538 | case CX88_BOARD_ADSTECH_DVB_T_PCI: |
f7b54b10 MK |
539 | dev->dvb.frontend = dvb_attach(mt352_attach, |
540 | &dntv_live_dvbt_config, | |
541 | &dev->core->i2c_adap); | |
f54376e2 | 542 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 543 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 544 | NULL, DVB_PLL_UNKNOWN_1); |
f54376e2 | 545 | } |
1da177e4 | 546 | break; |
fc40b261 | 547 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: |
ecf854df | 548 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
f0ad9097 | 549 | /* MT352 is on a secondary I2C bus made from some GPIO lines */ |
2bfe031d | 550 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, |
f0ad9097 | 551 | &dev->vp3054->adap); |
f54376e2 | 552 | if (dev->dvb.frontend != NULL) { |
b7754d74 | 553 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 554 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); |
f54376e2 | 555 | } |
fc40b261 | 556 | #else |
5772f813 | 557 | printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name); |
fc40b261 CP |
558 | #endif |
559 | break; | |
780dfef3 | 560 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: |
f7b54b10 MK |
561 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
562 | &dvico_fusionhdtv_hybrid, | |
563 | &dev->core->i2c_adap); | |
f54376e2 | 564 | if (dev->dvb.frontend != NULL) { |
5786a34b MK |
565 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
566 | &dev->core->i2c_adap, | |
47a9991e | 567 | DVB_PLL_THOMSON_FE6600); |
f54376e2 | 568 | } |
780dfef3 | 569 | break; |
1da177e4 | 570 | case CX88_BOARD_PCHDTV_HD3000: |
4a390558 | 571 | dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, |
f7b54b10 | 572 | &dev->core->i2c_adap); |
f54376e2 | 573 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 574 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
f7b54b10 | 575 | &dev->core->i2c_adap, |
47a9991e | 576 | DVB_PLL_THOMSON_DTT761X); |
f54376e2 | 577 | } |
1da177e4 | 578 | break; |
f1798495 MK |
579 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: |
580 | dev->ts_gen_cntrl = 0x08; | |
581 | { | |
582 | /* Do a hardware reset of chip before using it. */ | |
583 | struct cx88_core *core = dev->core; | |
584 | ||
585 | cx_clear(MO_GP0_IO, 1); | |
586 | mdelay(100); | |
0ccef6db | 587 | cx_set(MO_GP0_IO, 1); |
f1798495 | 588 | mdelay(200); |
0ccef6db MK |
589 | |
590 | /* Select RF connector callback */ | |
6ddcc919 | 591 | fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; |
f7b54b10 MK |
592 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
593 | &fusionhdtv_3_gold, | |
594 | &dev->core->i2c_adap); | |
f54376e2 | 595 | if (dev->dvb.frontend != NULL) { |
1d4bb7d3 MK |
596 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
597 | &dev->core->i2c_adap, | |
47a9991e | 598 | DVB_PLL_MICROTUNE_4042); |
f54376e2 | 599 | } |
f1798495 MK |
600 | } |
601 | break; | |
0d723c09 MK |
602 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: |
603 | dev->ts_gen_cntrl = 0x08; | |
604 | { | |
605 | /* Do a hardware reset of chip before using it. */ | |
606 | struct cx88_core *core = dev->core; | |
607 | ||
608 | cx_clear(MO_GP0_IO, 1); | |
609 | mdelay(100); | |
d975872c | 610 | cx_set(MO_GP0_IO, 9); |
0d723c09 | 611 | mdelay(200); |
f7b54b10 MK |
612 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
613 | &fusionhdtv_3_gold, | |
614 | &dev->core->i2c_adap); | |
f54376e2 | 615 | if (dev->dvb.frontend != NULL) { |
1d4bb7d3 MK |
616 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
617 | &dev->core->i2c_adap, | |
47a9991e | 618 | DVB_PLL_THOMSON_DTT761X); |
f54376e2 | 619 | } |
0d723c09 MK |
620 | } |
621 | break; | |
e52e98a7 MCC |
622 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
623 | dev->ts_gen_cntrl = 0x08; | |
624 | { | |
625 | /* Do a hardware reset of chip before using it. */ | |
626 | struct cx88_core *core = dev->core; | |
627 | ||
628 | cx_clear(MO_GP0_IO, 1); | |
629 | mdelay(100); | |
630 | cx_set(MO_GP0_IO, 1); | |
631 | mdelay(200); | |
f7b54b10 MK |
632 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
633 | &fusionhdtv_5_gold, | |
634 | &dev->core->i2c_adap); | |
f54376e2 | 635 | if (dev->dvb.frontend != NULL) { |
6bdcc6e6 TP |
636 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
637 | &dev->core->i2c_adap, | |
47a9991e | 638 | DVB_PLL_LG_TDVS_H06XF); |
f54376e2 | 639 | } |
e52e98a7 MCC |
640 | } |
641 | break; | |
da215d22 RS |
642 | case CX88_BOARD_PCHDTV_HD5500: |
643 | dev->ts_gen_cntrl = 0x08; | |
644 | { | |
645 | /* Do a hardware reset of chip before using it. */ | |
646 | struct cx88_core *core = dev->core; | |
647 | ||
648 | cx_clear(MO_GP0_IO, 1); | |
649 | mdelay(100); | |
650 | cx_set(MO_GP0_IO, 1); | |
651 | mdelay(200); | |
f7b54b10 MK |
652 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
653 | &pchdtv_hd5500, | |
654 | &dev->core->i2c_adap); | |
f54376e2 | 655 | if (dev->dvb.frontend != NULL) { |
6bdcc6e6 TP |
656 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
657 | &dev->core->i2c_adap, | |
47a9991e | 658 | DVB_PLL_LG_TDVS_H06XF); |
f54376e2 | 659 | } |
da215d22 RS |
660 | } |
661 | break; | |
fde6d31e | 662 | case CX88_BOARD_ATI_HDTVWONDER: |
f7b54b10 MK |
663 | dev->dvb.frontend = dvb_attach(nxt200x_attach, |
664 | &ati_hdtvwonder, | |
665 | &dev->core->i2c_adap); | |
f54376e2 | 666 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 667 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 668 | NULL, DVB_PLL_TUV1236D); |
f54376e2 | 669 | } |
0fa14aa6 | 670 | break; |
0fa14aa6 ST |
671 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
672 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | |
f7b54b10 MK |
673 | dev->dvb.frontend = dvb_attach(cx24123_attach, |
674 | &hauppauge_novas_config, | |
675 | &dev->core->i2c_adap); | |
cd20ca9f | 676 | if (dev->dvb.frontend) { |
f7b54b10 MK |
677 | dvb_attach(isl6421_attach, dev->dvb.frontend, |
678 | &dev->core->i2c_adap, 0x08, 0x00, 0x00); | |
cd20ca9f | 679 | } |
0e0351e3 VC |
680 | break; |
681 | case CX88_BOARD_KWORLD_DVBS_100: | |
f7b54b10 MK |
682 | dev->dvb.frontend = dvb_attach(cx24123_attach, |
683 | &kworld_dvbs_100_config, | |
684 | &dev->core->i2c_adap); | |
cd20ca9f | 685 | if (dev->dvb.frontend) { |
dea74869 PB |
686 | dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; |
687 | dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; | |
cd20ca9f | 688 | } |
fde6d31e | 689 | break; |
c02a34f4 | 690 | case CX88_BOARD_GENIATECH_DVBS: |
f7b54b10 MK |
691 | dev->dvb.frontend = dvb_attach(cx24123_attach, |
692 | &geniatech_dvbs_config, | |
693 | &dev->core->i2c_adap); | |
c02a34f4 SA |
694 | if (dev->dvb.frontend) { |
695 | dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | |
696 | dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; | |
697 | } | |
698 | break; | |
60464da8 | 699 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
60464da8 ST |
700 | dev->dvb.frontend = dvb_attach(s5h1409_attach, |
701 | &pinnacle_pctv_hd_800i_config, | |
702 | &dev->core->i2c_adap); | |
703 | if (dev->dvb.frontend != NULL) { | |
704 | /* tuner_config.video_dev must point to | |
705 | * i2c_adap.algo_data | |
706 | */ | |
73c993a8 | 707 | pinnacle_pctv_hd_800i_tuner_config.priv = |
60464da8 ST |
708 | dev->core->i2c_adap.algo_data; |
709 | dvb_attach(xc5000_attach, dev->dvb.frontend, | |
710 | &dev->core->i2c_adap, | |
711 | &pinnacle_pctv_hd_800i_tuner_config); | |
712 | } | |
713 | break; | |
5c00fac0 ST |
714 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
715 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | |
716 | &dvico_hdtv5_pci_nano_config, | |
717 | &dev->core->i2c_adap); | |
718 | if (dev->dvb.frontend != NULL) { | |
719 | struct dvb_frontend *fe; | |
720 | struct xc2028_config cfg = { | |
721 | .i2c_adap = &dev->core->i2c_adap, | |
722 | .i2c_addr = 0x61, | |
723 | .video_dev = dev->core, | |
724 | .callback = cx88_xc3028_callback, | |
725 | }; | |
726 | static struct xc2028_ctrl ctl = { | |
727 | .fname = "xc3028-v27.fw", | |
728 | .max_len = 64, | |
729 | .scode_table = OREN538, | |
730 | }; | |
731 | ||
732 | fe = dvb_attach(xc2028_attach, | |
733 | dev->dvb.frontend, &cfg); | |
734 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | |
735 | fe->ops.tuner_ops.set_config(fe, &ctl); | |
736 | } | |
737 | break; | |
9507901e MCC |
738 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: |
739 | dev->dvb.frontend = dvb_attach(zl10353_attach, | |
740 | &cx88_geniatech_x8000_mt, | |
741 | &dev->core->i2c_adap); | |
742 | attach_xc3028 = 1; | |
743 | break; | |
744 | case CX88_BOARD_GENIATECH_X8000_MT: | |
745 | dev->ts_gen_cntrl = 0x00; | |
746 | ||
747 | dev->dvb.frontend = dvb_attach(zl10353_attach, | |
748 | &cx88_geniatech_x8000_mt, | |
749 | &dev->core->i2c_adap); | |
750 | attach_xc3028 = 1; | |
751 | break; | |
1da177e4 | 752 | default: |
5772f813 | 753 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", |
1622c3fc | 754 | dev->core->name); |
1da177e4 LT |
755 | break; |
756 | } | |
757 | if (NULL == dev->dvb.frontend) { | |
9507901e MCC |
758 | printk(KERN_ERR |
759 | "%s/2: frontend initialization failed\n", | |
760 | dev->core->name); | |
1da177e4 LT |
761 | return -1; |
762 | } | |
763 | ||
9507901e MCC |
764 | if (attach_xc3028) { |
765 | struct dvb_frontend *fe; | |
766 | struct xc2028_config cfg = { | |
767 | .i2c_adap = &dev->core->i2c_adap, | |
768 | .i2c_addr = 0x61, | |
769 | .video_dev = dev->core, | |
770 | }; | |
771 | fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); | |
772 | if (!fe) { | |
773 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | |
774 | dev->core->name); | |
775 | dvb_frontend_detach(dev->dvb.frontend); | |
776 | dvb_unregister_frontend(dev->dvb.frontend); | |
777 | dev->dvb.frontend = NULL; | |
778 | return -1; | |
779 | } | |
780 | } | |
781 | ||
6c5be74c ST |
782 | /* Ensure all frontends negotiate bus access */ |
783 | dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | |
1da177e4 | 784 | |
93352f5c MCC |
785 | /* Put the analog decoder in standby to keep it quiet */ |
786 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | |
787 | ||
1da177e4 | 788 | /* register everything */ |
d09dbf92 | 789 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); |
1da177e4 LT |
790 | } |
791 | ||
792 | /* ----------------------------------------------------------- */ | |
793 | ||
6c5be74c ST |
794 | /* CX8802 MPEG -> mini driver - We have been given the hardware */ |
795 | static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) | |
1da177e4 | 796 | { |
6c5be74c ST |
797 | struct cx88_core *core = drv->core; |
798 | int err = 0; | |
799 | dprintk( 1, "%s\n", __FUNCTION__); | |
800 | ||
6a59d64c | 801 | switch (core->boardnr) { |
6c5be74c ST |
802 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
803 | /* We arrive here with either the cx23416 or the cx22702 | |
804 | * on the bus. Take the bus from the cx23416 and enable the | |
805 | * cx22702 demod | |
806 | */ | |
807 | cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ | |
808 | cx_clear(MO_GP0_IO, 0x00000004); | |
809 | udelay(1000); | |
810 | break; | |
811 | default: | |
812 | err = -ENODEV; | |
813 | } | |
814 | return err; | |
815 | } | |
816 | ||
817 | /* CX8802 MPEG -> mini driver - We no longer have the hardware */ | |
818 | static int cx8802_dvb_advise_release(struct cx8802_driver *drv) | |
819 | { | |
820 | struct cx88_core *core = drv->core; | |
821 | int err = 0; | |
822 | dprintk( 1, "%s\n", __FUNCTION__); | |
823 | ||
6a59d64c | 824 | switch (core->boardnr) { |
6c5be74c ST |
825 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
826 | /* Do Nothing, leave the cx22702 on the bus. */ | |
827 | break; | |
828 | default: | |
829 | err = -ENODEV; | |
830 | } | |
831 | return err; | |
832 | } | |
833 | ||
834 | static int cx8802_dvb_probe(struct cx8802_driver *drv) | |
835 | { | |
836 | struct cx88_core *core = drv->core; | |
837 | struct cx8802_dev *dev = drv->core->dvbdev; | |
1da177e4 LT |
838 | int err; |
839 | ||
6c5be74c ST |
840 | dprintk( 1, "%s\n", __FUNCTION__); |
841 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | |
6a59d64c | 842 | core->boardnr, |
6c5be74c ST |
843 | core->name, |
844 | core->pci_bus, | |
845 | core->pci_slot); | |
1da177e4 LT |
846 | |
847 | err = -ENODEV; | |
6a59d64c | 848 | if (!(core->board.mpeg & CX88_MPEG_DVB)) |
1da177e4 LT |
849 | goto fail_core; |
850 | ||
ecf854df | 851 | /* If vp3054 isn't enabled, a stub will just return 0 */ |
fc40b261 CP |
852 | err = vp3054_i2c_probe(dev); |
853 | if (0 != err) | |
6c5be74c | 854 | goto fail_core; |
fc40b261 | 855 | |
1da177e4 | 856 | /* dvb stuff */ |
5772f813 | 857 | printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); |
0705135e GL |
858 | videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, |
859 | &dev->pci->dev, &dev->slock, | |
1da177e4 LT |
860 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
861 | V4L2_FIELD_TOP, | |
862 | sizeof(struct cx88_buffer), | |
863 | dev); | |
864 | err = dvb_register(dev); | |
6c5be74c | 865 | if (err != 0) |
5772f813 TP |
866 | printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", |
867 | core->name, err); | |
1da177e4 | 868 | |
1da177e4 | 869 | fail_core: |
1da177e4 LT |
870 | return err; |
871 | } | |
872 | ||
6c5be74c | 873 | static int cx8802_dvb_remove(struct cx8802_driver *drv) |
1da177e4 | 874 | { |
6c5be74c | 875 | struct cx8802_dev *dev = drv->core->dvbdev; |
611900c1 | 876 | |
1da177e4 LT |
877 | /* dvb */ |
878 | videobuf_dvb_unregister(&dev->dvb); | |
879 | ||
fc40b261 | 880 | vp3054_i2c_remove(dev); |
fc40b261 | 881 | |
6c5be74c | 882 | return 0; |
1da177e4 LT |
883 | } |
884 | ||
6c5be74c ST |
885 | static struct cx8802_driver cx8802_dvb_driver = { |
886 | .type_id = CX88_MPEG_DVB, | |
887 | .hw_access = CX8802_DRVCTL_SHARED, | |
888 | .probe = cx8802_dvb_probe, | |
889 | .remove = cx8802_dvb_remove, | |
890 | .advise_acquire = cx8802_dvb_advise_acquire, | |
891 | .advise_release = cx8802_dvb_advise_release, | |
1da177e4 LT |
892 | }; |
893 | ||
894 | static int dvb_init(void) | |
895 | { | |
5772f813 | 896 | printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n", |
1da177e4 LT |
897 | (CX88_VERSION_CODE >> 16) & 0xff, |
898 | (CX88_VERSION_CODE >> 8) & 0xff, | |
899 | CX88_VERSION_CODE & 0xff); | |
900 | #ifdef SNAPSHOT | |
901 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", | |
902 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | |
903 | #endif | |
6c5be74c | 904 | return cx8802_register_driver(&cx8802_dvb_driver); |
1da177e4 LT |
905 | } |
906 | ||
907 | static void dvb_fini(void) | |
908 | { | |
6c5be74c | 909 | cx8802_unregister_driver(&cx8802_dvb_driver); |
1da177e4 LT |
910 | } |
911 | ||
912 | module_init(dvb_init); | |
913 | module_exit(dvb_fini); | |
914 | ||
915 | /* | |
916 | * Local variables: | |
917 | * c-basic-offset: 8 | |
918 | * compile-command: "make DVB=1" | |
919 | * End: | |
920 | */ |