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 | ||
b3fb91d2 CP |
240 | static struct zl10353_config dvico_fusionhdtv_xc3028 = { |
241 | .demod_address = 0x0f, | |
242 | .if2 = 45600, | |
243 | .no_tuner = 1, | |
244 | }; | |
245 | ||
246 | static struct mt352_config dvico_fusionhdtv_mt352_xc3028 = { | |
247 | .demod_address = 0x0f, | |
248 | .if2 = 4560, | |
249 | .no_tuner = 1, | |
250 | .demod_init = dvico_fusionhdtv_demod_init, | |
251 | }; | |
252 | ||
780dfef3 | 253 | static struct zl10353_config dvico_fusionhdtv_plus_v1_1 = { |
f7b54b10 | 254 | .demod_address = 0x0f, |
780dfef3 | 255 | }; |
780dfef3 | 256 | |
1da177e4 LT |
257 | static struct cx22702_config connexant_refboard_config = { |
258 | .demod_address = 0x43, | |
38d84c3b | 259 | .output_mode = CX22702_SERIAL_OUTPUT, |
1da177e4 LT |
260 | }; |
261 | ||
ed355260 | 262 | static struct cx22702_config hauppauge_hvr_config = { |
aa481a65 ST |
263 | .demod_address = 0x63, |
264 | .output_mode = CX22702_SERIAL_OUTPUT, | |
265 | }; | |
1da177e4 | 266 | |
4a390558 | 267 | static int or51132_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
1da177e4 LT |
268 | { |
269 | struct cx8802_dev *dev= fe->dvb->priv; | |
270 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | |
271 | return 0; | |
272 | } | |
273 | ||
408b664a | 274 | static struct or51132_config pchdtv_hd3000 = { |
f7b54b10 MK |
275 | .demod_address = 0x15, |
276 | .set_ts_params = or51132_set_ts_param, | |
1da177e4 | 277 | }; |
1da177e4 | 278 | |
6ddcc919 | 279 | static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index) |
0ccef6db MK |
280 | { |
281 | struct cx8802_dev *dev= fe->dvb->priv; | |
282 | struct cx88_core *core = dev->core; | |
283 | ||
284 | dprintk(1, "%s: index = %d\n", __FUNCTION__, index); | |
285 | if (index == 0) | |
286 | cx_clear(MO_GP0_IO, 8); | |
287 | else | |
288 | cx_set(MO_GP0_IO, 8); | |
289 | return 0; | |
290 | } | |
291 | ||
6ddcc919 | 292 | static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
f1798495 MK |
293 | { |
294 | struct cx8802_dev *dev= fe->dvb->priv; | |
295 | if (is_punctured) | |
296 | dev->ts_gen_cntrl |= 0x04; | |
297 | else | |
298 | dev->ts_gen_cntrl &= ~0x04; | |
299 | return 0; | |
300 | } | |
301 | ||
6ddcc919 | 302 | static struct lgdt330x_config fusionhdtv_3_gold = { |
f7b54b10 MK |
303 | .demod_address = 0x0e, |
304 | .demod_chip = LGDT3302, | |
305 | .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */ | |
306 | .set_ts_params = lgdt330x_set_ts_param, | |
0d723c09 | 307 | }; |
e52e98a7 MCC |
308 | |
309 | static struct lgdt330x_config fusionhdtv_5_gold = { | |
f7b54b10 MK |
310 | .demod_address = 0x0e, |
311 | .demod_chip = LGDT3303, | |
312 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | |
313 | .set_ts_params = lgdt330x_set_ts_param, | |
e52e98a7 | 314 | }; |
da215d22 RS |
315 | |
316 | static struct lgdt330x_config pchdtv_hd5500 = { | |
f7b54b10 MK |
317 | .demod_address = 0x59, |
318 | .demod_chip = LGDT3303, | |
319 | .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */ | |
320 | .set_ts_params = lgdt330x_set_ts_param, | |
da215d22 | 321 | }; |
f1798495 | 322 | |
4a390558 | 323 | static int nxt200x_set_ts_param(struct dvb_frontend* fe, int is_punctured) |
fde6d31e KL |
324 | { |
325 | struct cx8802_dev *dev= fe->dvb->priv; | |
326 | dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00; | |
327 | return 0; | |
328 | } | |
329 | ||
330 | static struct nxt200x_config ati_hdtvwonder = { | |
f7b54b10 | 331 | .demod_address = 0x0a, |
f7b54b10 | 332 | .set_ts_params = nxt200x_set_ts_param, |
fde6d31e | 333 | }; |
fde6d31e | 334 | |
0fa14aa6 ST |
335 | static int cx24123_set_ts_param(struct dvb_frontend* fe, |
336 | int is_punctured) | |
337 | { | |
338 | struct cx8802_dev *dev= fe->dvb->priv; | |
f7b54b10 | 339 | dev->ts_gen_cntrl = 0x02; |
0fa14aa6 ST |
340 | return 0; |
341 | } | |
342 | ||
f7b54b10 MK |
343 | static int kworld_dvbs_100_set_voltage(struct dvb_frontend* fe, |
344 | fe_sec_voltage_t voltage) | |
0e0351e3 VC |
345 | { |
346 | struct cx8802_dev *dev= fe->dvb->priv; | |
347 | struct cx88_core *core = dev->core; | |
348 | ||
4a390558 | 349 | if (voltage == SEC_VOLTAGE_OFF) |
f7b54b10 | 350 | cx_write(MO_GP0_IO, 0x000006fb); |
4a390558 | 351 | else |
cd20ca9f | 352 | cx_write(MO_GP0_IO, 0x000006f9); |
cd20ca9f AQ |
353 | |
354 | if (core->prev_set_voltage) | |
355 | return core->prev_set_voltage(fe, voltage); | |
356 | return 0; | |
0e0351e3 VC |
357 | } |
358 | ||
f7b54b10 MK |
359 | static int geniatech_dvbs_set_voltage(struct dvb_frontend *fe, |
360 | fe_sec_voltage_t voltage) | |
c02a34f4 SA |
361 | { |
362 | struct cx8802_dev *dev= fe->dvb->priv; | |
363 | struct cx88_core *core = dev->core; | |
364 | ||
365 | if (voltage == SEC_VOLTAGE_OFF) { | |
366 | dprintk(1,"LNB Voltage OFF\n"); | |
367 | cx_write(MO_GP0_IO, 0x0000efff); | |
368 | } | |
369 | ||
370 | if (core->prev_set_voltage) | |
371 | return core->prev_set_voltage(fe, voltage); | |
372 | return 0; | |
373 | } | |
374 | ||
5c00fac0 ST |
375 | static int cx88_xc3028_callback(void *ptr, int command, int arg) |
376 | { | |
377 | struct cx88_core *core = ptr; | |
378 | ||
379 | switch (command) { | |
380 | case XC2028_TUNER_RESET: | |
381 | /* Send the tuner in then out of reset */ | |
382 | dprintk(1, "%s: XC2028_TUNER_RESET %d\n", __FUNCTION__, arg); | |
383 | ||
384 | switch (core->boardnr) { | |
385 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: | |
386 | /* GPIO-4 xc3028 tuner */ | |
387 | ||
388 | cx_set(MO_GP0_IO, 0x00001000); | |
389 | cx_clear(MO_GP0_IO, 0x00000010); | |
390 | msleep(100); | |
391 | cx_set(MO_GP0_IO, 0x00000010); | |
392 | msleep(100); | |
393 | break; | |
394 | } | |
395 | ||
396 | break; | |
397 | case XC2028_RESET_CLK: | |
398 | dprintk(1, "%s: XC2028_RESET_CLK %d\n", __FUNCTION__, arg); | |
399 | break; | |
400 | default: | |
401 | dprintk(1, "%s: unknown command %d, arg %d\n", __FUNCTION__, | |
402 | command, arg); | |
403 | return -EINVAL; | |
404 | } | |
405 | ||
406 | return 0; | |
407 | } | |
408 | ||
c02a34f4 | 409 | static struct cx24123_config geniatech_dvbs_config = { |
f7b54b10 MK |
410 | .demod_address = 0x55, |
411 | .set_ts_params = cx24123_set_ts_param, | |
c02a34f4 SA |
412 | }; |
413 | ||
0fa14aa6 | 414 | static struct cx24123_config hauppauge_novas_config = { |
f7b54b10 MK |
415 | .demod_address = 0x55, |
416 | .set_ts_params = cx24123_set_ts_param, | |
0e0351e3 VC |
417 | }; |
418 | ||
419 | static struct cx24123_config kworld_dvbs_100_config = { | |
f7b54b10 MK |
420 | .demod_address = 0x15, |
421 | .set_ts_params = cx24123_set_ts_param, | |
ef76856d | 422 | .lnb_polarity = 1, |
0fa14aa6 | 423 | }; |
0fa14aa6 | 424 | |
60464da8 ST |
425 | static struct s5h1409_config pinnacle_pctv_hd_800i_config = { |
426 | .demod_address = 0x32 >> 1, | |
427 | .output_mode = S5H1409_PARALLEL_OUTPUT, | |
428 | .gpio = S5H1409_GPIO_ON, | |
429 | .qam_if = 44000, | |
430 | .inversion = S5H1409_INVERSION_OFF, | |
431 | .status_mode = S5H1409_DEMODLOCKING, | |
4917019d | 432 | .mpeg_timing = S5H1409_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK, |
60464da8 ST |
433 | }; |
434 | ||
5c00fac0 ST |
435 | static struct s5h1409_config dvico_hdtv5_pci_nano_config = { |
436 | .demod_address = 0x32 >> 1, | |
437 | .output_mode = S5H1409_SERIAL_OUTPUT, | |
438 | .gpio = S5H1409_GPIO_OFF, | |
439 | .inversion = S5H1409_INVERSION_OFF, | |
440 | .status_mode = S5H1409_DEMODLOCKING, | |
441 | .mpeg_timing = S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK, | |
442 | }; | |
443 | ||
60464da8 ST |
444 | static struct xc5000_config pinnacle_pctv_hd_800i_tuner_config = { |
445 | .i2c_address = 0x64, | |
446 | .if_khz = 5380, | |
60464da8 ST |
447 | .tuner_callback = cx88_tuner_callback, |
448 | }; | |
449 | ||
9507901e MCC |
450 | static struct zl10353_config cx88_geniatech_x8000_mt = { |
451 | .demod_address = (0x1e >> 1), | |
452 | .no_tuner = 1, | |
453 | }; | |
454 | ||
23fb348d MCC |
455 | static int attach_xc3028(u8 addr, struct cx8802_dev *dev) |
456 | { | |
457 | struct dvb_frontend *fe; | |
458 | struct xc2028_config cfg = { | |
459 | .i2c_adap = &dev->core->i2c_adap, | |
460 | .i2c_addr = addr, | |
461 | .video_dev = dev->core, | |
462 | }; | |
463 | ||
464 | fe = dvb_attach(xc2028_attach, dev->dvb.frontend, &cfg); | |
465 | if (!fe) { | |
466 | printk(KERN_ERR "%s/2: xc3028 attach failed\n", | |
467 | dev->core->name); | |
468 | dvb_frontend_detach(dev->dvb.frontend); | |
469 | dvb_unregister_frontend(dev->dvb.frontend); | |
470 | dev->dvb.frontend = NULL; | |
471 | return -EINVAL; | |
472 | } | |
473 | ||
474 | printk(KERN_INFO "%s/2: xc3028 attached\n", | |
475 | dev->core->name); | |
476 | ||
477 | return 0; | |
478 | } | |
9507901e | 479 | |
1da177e4 LT |
480 | static int dvb_register(struct cx8802_dev *dev) |
481 | { | |
482 | /* init struct videobuf_dvb */ | |
483 | dev->dvb.name = dev->core->name; | |
484 | dev->ts_gen_cntrl = 0x0c; | |
485 | ||
486 | /* init frontend */ | |
6a59d64c | 487 | switch (dev->core->boardnr) { |
1da177e4 | 488 | case CX88_BOARD_HAUPPAUGE_DVB_T1: |
f7b54b10 | 489 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
ed355260 | 490 | &connexant_refboard_config, |
f7b54b10 | 491 | &dev->core->i2c_adap); |
f54376e2 | 492 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 493 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
f7b54b10 | 494 | &dev->core->i2c_adap, |
47a9991e | 495 | DVB_PLL_THOMSON_DTT759X); |
f54376e2 | 496 | } |
1da177e4 | 497 | break; |
e057ee11 | 498 | case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1: |
1da177e4 | 499 | case CX88_BOARD_CONEXANT_DVB_T1: |
f39624fd | 500 | case CX88_BOARD_KWORLD_DVB_T_CX22702: |
2b5200a7 | 501 | case CX88_BOARD_WINFAST_DTV1000: |
f7b54b10 MK |
502 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
503 | &connexant_refboard_config, | |
504 | &dev->core->i2c_adap); | |
f54376e2 | 505 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 506 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
f7b54b10 | 507 | &dev->core->i2c_adap, |
47a9991e | 508 | DVB_PLL_THOMSON_DTT7579); |
f54376e2 | 509 | } |
1da177e4 | 510 | break; |
4bd6e9d9 | 511 | case CX88_BOARD_WINFAST_DTV2000H: |
611900c1 ST |
512 | case CX88_BOARD_HAUPPAUGE_HVR1100: |
513 | case CX88_BOARD_HAUPPAUGE_HVR1100LP: | |
a5a2ecfc TP |
514 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
515 | case CX88_BOARD_HAUPPAUGE_HVR3000: | |
f7b54b10 | 516 | dev->dvb.frontend = dvb_attach(cx22702_attach, |
ed355260 | 517 | &hauppauge_hvr_config, |
f7b54b10 | 518 | &dev->core->i2c_adap); |
f54376e2 | 519 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 520 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 521 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); |
f54376e2 | 522 | } |
611900c1 | 523 | break; |
780dfef3 | 524 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS: |
f7b54b10 MK |
525 | dev->dvb.frontend = dvb_attach(mt352_attach, |
526 | &dvico_fusionhdtv, | |
527 | &dev->core->i2c_adap); | |
f54376e2 | 528 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 529 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
47a9991e | 530 | NULL, DVB_PLL_THOMSON_DTT7579); |
780dfef3 | 531 | break; |
f54376e2 | 532 | } |
780dfef3 | 533 | /* ZL10353 replaces MT352 on later cards */ |
f7b54b10 MK |
534 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
535 | &dvico_fusionhdtv_plus_v1_1, | |
536 | &dev->core->i2c_adap); | |
f54376e2 | 537 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 538 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x60, |
47a9991e | 539 | NULL, DVB_PLL_THOMSON_DTT7579); |
f54376e2 | 540 | } |
c2af3cd6 MK |
541 | break; |
542 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL: | |
c2af3cd6 MK |
543 | /* The tin box says DEE1601, but it seems to be DTT7579 |
544 | * compatible, with a slightly different MT352 AGC gain. */ | |
f7b54b10 MK |
545 | dev->dvb.frontend = dvb_attach(mt352_attach, |
546 | &dvico_fusionhdtv_dual, | |
547 | &dev->core->i2c_adap); | |
c2af3cd6 | 548 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 549 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 550 | NULL, DVB_PLL_THOMSON_DTT7579); |
c2af3cd6 MK |
551 | break; |
552 | } | |
c2af3cd6 | 553 | /* ZL10353 replaces MT352 on later cards */ |
f7b54b10 MK |
554 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
555 | &dvico_fusionhdtv_plus_v1_1, | |
556 | &dev->core->i2c_adap); | |
c2af3cd6 | 557 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 558 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 559 | NULL, DVB_PLL_THOMSON_DTT7579); |
c2af3cd6 | 560 | } |
1da177e4 | 561 | break; |
780dfef3 | 562 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1: |
f7b54b10 MK |
563 | dev->dvb.frontend = dvb_attach(mt352_attach, |
564 | &dvico_fusionhdtv, | |
565 | &dev->core->i2c_adap); | |
f54376e2 | 566 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 567 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 568 | NULL, DVB_PLL_LG_Z201); |
f54376e2 | 569 | } |
1da177e4 LT |
570 | break; |
571 | case CX88_BOARD_KWORLD_DVB_T: | |
572 | case CX88_BOARD_DNTV_LIVE_DVB_T: | |
a82decf6 | 573 | case CX88_BOARD_ADSTECH_DVB_T_PCI: |
f7b54b10 MK |
574 | dev->dvb.frontend = dvb_attach(mt352_attach, |
575 | &dntv_live_dvbt_config, | |
576 | &dev->core->i2c_adap); | |
f54376e2 | 577 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 578 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 579 | NULL, DVB_PLL_UNKNOWN_1); |
f54376e2 | 580 | } |
1da177e4 | 581 | break; |
fc40b261 | 582 | case CX88_BOARD_DNTV_LIVE_DVB_T_PRO: |
ecf854df | 583 | #if defined(CONFIG_VIDEO_CX88_VP3054) || (defined(CONFIG_VIDEO_CX88_VP3054_MODULE) && defined(MODULE)) |
f0ad9097 | 584 | /* MT352 is on a secondary I2C bus made from some GPIO lines */ |
2bfe031d | 585 | dev->dvb.frontend = dvb_attach(mt352_attach, &dntv_live_dvbt_pro_config, |
f0ad9097 | 586 | &dev->vp3054->adap); |
f54376e2 | 587 | if (dev->dvb.frontend != NULL) { |
b7754d74 | 588 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 589 | &dev->core->i2c_adap, DVB_PLL_FMD1216ME); |
f54376e2 | 590 | } |
fc40b261 | 591 | #else |
5772f813 | 592 | printk(KERN_ERR "%s/2: built without vp3054 support\n", dev->core->name); |
fc40b261 CP |
593 | #endif |
594 | break; | |
780dfef3 | 595 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_HYBRID: |
f7b54b10 MK |
596 | dev->dvb.frontend = dvb_attach(zl10353_attach, |
597 | &dvico_fusionhdtv_hybrid, | |
598 | &dev->core->i2c_adap); | |
f54376e2 | 599 | if (dev->dvb.frontend != NULL) { |
5786a34b MK |
600 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
601 | &dev->core->i2c_adap, | |
47a9991e | 602 | DVB_PLL_THOMSON_FE6600); |
f54376e2 | 603 | } |
780dfef3 | 604 | break; |
b3fb91d2 CP |
605 | case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PRO: |
606 | dev->dvb.frontend = dvb_attach(zl10353_attach, | |
607 | &dvico_fusionhdtv_xc3028, | |
608 | &dev->core->i2c_adap); | |
609 | if (dev->dvb.frontend == NULL) | |
610 | dev->dvb.frontend = dvb_attach(mt352_attach, | |
611 | &dvico_fusionhdtv_mt352_xc3028, | |
612 | &dev->core->i2c_adap); | |
8765561f CP |
613 | /* |
614 | * On this board, the demod provides the I2C bus pullup. | |
615 | * We must not permit gate_ctrl to be performed, or | |
616 | * the xc3028 cannot communicate on the bus. | |
617 | */ | |
618 | if (dev->dvb.frontend) | |
619 | dev->dvb.frontend->ops.i2c_gate_ctrl = NULL; | |
23fb348d MCC |
620 | if (attach_xc3028(0x61, dev) < 0) |
621 | return -EINVAL; | |
b3fb91d2 | 622 | break; |
1da177e4 | 623 | case CX88_BOARD_PCHDTV_HD3000: |
4a390558 | 624 | dev->dvb.frontend = dvb_attach(or51132_attach, &pchdtv_hd3000, |
f7b54b10 | 625 | &dev->core->i2c_adap); |
f54376e2 | 626 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 627 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
f7b54b10 | 628 | &dev->core->i2c_adap, |
47a9991e | 629 | DVB_PLL_THOMSON_DTT761X); |
f54376e2 | 630 | } |
1da177e4 | 631 | break; |
f1798495 MK |
632 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q: |
633 | dev->ts_gen_cntrl = 0x08; | |
634 | { | |
635 | /* Do a hardware reset of chip before using it. */ | |
636 | struct cx88_core *core = dev->core; | |
637 | ||
638 | cx_clear(MO_GP0_IO, 1); | |
639 | mdelay(100); | |
0ccef6db | 640 | cx_set(MO_GP0_IO, 1); |
f1798495 | 641 | mdelay(200); |
0ccef6db MK |
642 | |
643 | /* Select RF connector callback */ | |
6ddcc919 | 644 | fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set; |
f7b54b10 MK |
645 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
646 | &fusionhdtv_3_gold, | |
647 | &dev->core->i2c_adap); | |
f54376e2 | 648 | if (dev->dvb.frontend != NULL) { |
1d4bb7d3 MK |
649 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
650 | &dev->core->i2c_adap, | |
47a9991e | 651 | DVB_PLL_MICROTUNE_4042); |
f54376e2 | 652 | } |
f1798495 MK |
653 | } |
654 | break; | |
0d723c09 MK |
655 | case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T: |
656 | dev->ts_gen_cntrl = 0x08; | |
657 | { | |
658 | /* Do a hardware reset of chip before using it. */ | |
659 | struct cx88_core *core = dev->core; | |
660 | ||
661 | cx_clear(MO_GP0_IO, 1); | |
662 | mdelay(100); | |
d975872c | 663 | cx_set(MO_GP0_IO, 9); |
0d723c09 | 664 | mdelay(200); |
f7b54b10 MK |
665 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
666 | &fusionhdtv_3_gold, | |
667 | &dev->core->i2c_adap); | |
f54376e2 | 668 | if (dev->dvb.frontend != NULL) { |
1d4bb7d3 MK |
669 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
670 | &dev->core->i2c_adap, | |
47a9991e | 671 | DVB_PLL_THOMSON_DTT761X); |
f54376e2 | 672 | } |
0d723c09 MK |
673 | } |
674 | break; | |
e52e98a7 MCC |
675 | case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD: |
676 | dev->ts_gen_cntrl = 0x08; | |
677 | { | |
678 | /* Do a hardware reset of chip before using it. */ | |
679 | struct cx88_core *core = dev->core; | |
680 | ||
681 | cx_clear(MO_GP0_IO, 1); | |
682 | mdelay(100); | |
683 | cx_set(MO_GP0_IO, 1); | |
684 | mdelay(200); | |
f7b54b10 MK |
685 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
686 | &fusionhdtv_5_gold, | |
687 | &dev->core->i2c_adap); | |
f54376e2 | 688 | if (dev->dvb.frontend != NULL) { |
6bdcc6e6 TP |
689 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
690 | &dev->core->i2c_adap, | |
47a9991e | 691 | DVB_PLL_LG_TDVS_H06XF); |
f54376e2 | 692 | } |
e52e98a7 MCC |
693 | } |
694 | break; | |
da215d22 RS |
695 | case CX88_BOARD_PCHDTV_HD5500: |
696 | dev->ts_gen_cntrl = 0x08; | |
697 | { | |
698 | /* Do a hardware reset of chip before using it. */ | |
699 | struct cx88_core *core = dev->core; | |
700 | ||
701 | cx_clear(MO_GP0_IO, 1); | |
702 | mdelay(100); | |
703 | cx_set(MO_GP0_IO, 1); | |
704 | mdelay(200); | |
f7b54b10 MK |
705 | dev->dvb.frontend = dvb_attach(lgdt330x_attach, |
706 | &pchdtv_hd5500, | |
707 | &dev->core->i2c_adap); | |
f54376e2 | 708 | if (dev->dvb.frontend != NULL) { |
6bdcc6e6 TP |
709 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
710 | &dev->core->i2c_adap, | |
47a9991e | 711 | DVB_PLL_LG_TDVS_H06XF); |
f54376e2 | 712 | } |
da215d22 RS |
713 | } |
714 | break; | |
fde6d31e | 715 | case CX88_BOARD_ATI_HDTVWONDER: |
f7b54b10 MK |
716 | dev->dvb.frontend = dvb_attach(nxt200x_attach, |
717 | &ati_hdtvwonder, | |
718 | &dev->core->i2c_adap); | |
f54376e2 | 719 | if (dev->dvb.frontend != NULL) { |
2bfe031d | 720 | dvb_attach(dvb_pll_attach, dev->dvb.frontend, 0x61, |
47a9991e | 721 | NULL, DVB_PLL_TUV1236D); |
f54376e2 | 722 | } |
0fa14aa6 | 723 | break; |
0fa14aa6 ST |
724 | case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1: |
725 | case CX88_BOARD_HAUPPAUGE_NOVASE2_S1: | |
f7b54b10 MK |
726 | dev->dvb.frontend = dvb_attach(cx24123_attach, |
727 | &hauppauge_novas_config, | |
728 | &dev->core->i2c_adap); | |
cd20ca9f | 729 | if (dev->dvb.frontend) { |
f7b54b10 MK |
730 | dvb_attach(isl6421_attach, dev->dvb.frontend, |
731 | &dev->core->i2c_adap, 0x08, 0x00, 0x00); | |
cd20ca9f | 732 | } |
0e0351e3 VC |
733 | break; |
734 | case CX88_BOARD_KWORLD_DVBS_100: | |
f7b54b10 MK |
735 | dev->dvb.frontend = dvb_attach(cx24123_attach, |
736 | &kworld_dvbs_100_config, | |
737 | &dev->core->i2c_adap); | |
cd20ca9f | 738 | if (dev->dvb.frontend) { |
dea74869 PB |
739 | dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; |
740 | dev->dvb.frontend->ops.set_voltage = kworld_dvbs_100_set_voltage; | |
cd20ca9f | 741 | } |
fde6d31e | 742 | break; |
c02a34f4 | 743 | case CX88_BOARD_GENIATECH_DVBS: |
f7b54b10 MK |
744 | dev->dvb.frontend = dvb_attach(cx24123_attach, |
745 | &geniatech_dvbs_config, | |
746 | &dev->core->i2c_adap); | |
c02a34f4 SA |
747 | if (dev->dvb.frontend) { |
748 | dev->core->prev_set_voltage = dev->dvb.frontend->ops.set_voltage; | |
749 | dev->dvb.frontend->ops.set_voltage = geniatech_dvbs_set_voltage; | |
750 | } | |
751 | break; | |
60464da8 | 752 | case CX88_BOARD_PINNACLE_PCTV_HD_800i: |
60464da8 ST |
753 | dev->dvb.frontend = dvb_attach(s5h1409_attach, |
754 | &pinnacle_pctv_hd_800i_config, | |
755 | &dev->core->i2c_adap); | |
756 | if (dev->dvb.frontend != NULL) { | |
757 | /* tuner_config.video_dev must point to | |
758 | * i2c_adap.algo_data | |
759 | */ | |
73c993a8 | 760 | pinnacle_pctv_hd_800i_tuner_config.priv = |
60464da8 ST |
761 | dev->core->i2c_adap.algo_data; |
762 | dvb_attach(xc5000_attach, dev->dvb.frontend, | |
763 | &dev->core->i2c_adap, | |
764 | &pinnacle_pctv_hd_800i_tuner_config); | |
765 | } | |
766 | break; | |
5c00fac0 ST |
767 | case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO: |
768 | dev->dvb.frontend = dvb_attach(s5h1409_attach, | |
769 | &dvico_hdtv5_pci_nano_config, | |
770 | &dev->core->i2c_adap); | |
771 | if (dev->dvb.frontend != NULL) { | |
772 | struct dvb_frontend *fe; | |
773 | struct xc2028_config cfg = { | |
774 | .i2c_adap = &dev->core->i2c_adap, | |
775 | .i2c_addr = 0x61, | |
776 | .video_dev = dev->core, | |
777 | .callback = cx88_xc3028_callback, | |
778 | }; | |
779 | static struct xc2028_ctrl ctl = { | |
780 | .fname = "xc3028-v27.fw", | |
781 | .max_len = 64, | |
782 | .scode_table = OREN538, | |
783 | }; | |
784 | ||
785 | fe = dvb_attach(xc2028_attach, | |
786 | dev->dvb.frontend, &cfg); | |
787 | if (fe != NULL && fe->ops.tuner_ops.set_config != NULL) | |
788 | fe->ops.tuner_ops.set_config(fe, &ctl); | |
789 | } | |
790 | break; | |
9507901e MCC |
791 | case CX88_BOARD_PINNACLE_HYBRID_PCTV: |
792 | dev->dvb.frontend = dvb_attach(zl10353_attach, | |
793 | &cx88_geniatech_x8000_mt, | |
794 | &dev->core->i2c_adap); | |
23fb348d MCC |
795 | if (attach_xc3028(0x61, dev) < 0) |
796 | return -EINVAL; | |
9507901e MCC |
797 | break; |
798 | case CX88_BOARD_GENIATECH_X8000_MT: | |
799 | dev->ts_gen_cntrl = 0x00; | |
800 | ||
801 | dev->dvb.frontend = dvb_attach(zl10353_attach, | |
802 | &cx88_geniatech_x8000_mt, | |
803 | &dev->core->i2c_adap); | |
23fb348d MCC |
804 | if (attach_xc3028(0x61, dev) < 0) |
805 | return -EINVAL; | |
9507901e | 806 | break; |
1da177e4 | 807 | default: |
5772f813 | 808 | printk(KERN_ERR "%s/2: The frontend of your DVB/ATSC card isn't supported yet\n", |
1622c3fc | 809 | dev->core->name); |
1da177e4 LT |
810 | break; |
811 | } | |
812 | if (NULL == dev->dvb.frontend) { | |
9507901e MCC |
813 | printk(KERN_ERR |
814 | "%s/2: frontend initialization failed\n", | |
815 | dev->core->name); | |
23fb348d | 816 | return -EINVAL; |
9507901e MCC |
817 | } |
818 | ||
6c5be74c ST |
819 | /* Ensure all frontends negotiate bus access */ |
820 | dev->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl; | |
1da177e4 | 821 | |
93352f5c MCC |
822 | /* Put the analog decoder in standby to keep it quiet */ |
823 | cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL); | |
824 | ||
1da177e4 | 825 | /* register everything */ |
d09dbf92 | 826 | return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev, &dev->pci->dev); |
1da177e4 LT |
827 | } |
828 | ||
829 | /* ----------------------------------------------------------- */ | |
830 | ||
6c5be74c ST |
831 | /* CX8802 MPEG -> mini driver - We have been given the hardware */ |
832 | static int cx8802_dvb_advise_acquire(struct cx8802_driver *drv) | |
1da177e4 | 833 | { |
6c5be74c ST |
834 | struct cx88_core *core = drv->core; |
835 | int err = 0; | |
836 | dprintk( 1, "%s\n", __FUNCTION__); | |
837 | ||
6a59d64c | 838 | switch (core->boardnr) { |
6c5be74c ST |
839 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
840 | /* We arrive here with either the cx23416 or the cx22702 | |
841 | * on the bus. Take the bus from the cx23416 and enable the | |
842 | * cx22702 demod | |
843 | */ | |
844 | cx_set(MO_GP0_IO, 0x00000080); /* cx22702 out of reset and enable */ | |
845 | cx_clear(MO_GP0_IO, 0x00000004); | |
846 | udelay(1000); | |
847 | break; | |
848 | default: | |
849 | err = -ENODEV; | |
850 | } | |
851 | return err; | |
852 | } | |
853 | ||
854 | /* CX8802 MPEG -> mini driver - We no longer have the hardware */ | |
855 | static int cx8802_dvb_advise_release(struct cx8802_driver *drv) | |
856 | { | |
857 | struct cx88_core *core = drv->core; | |
858 | int err = 0; | |
859 | dprintk( 1, "%s\n", __FUNCTION__); | |
860 | ||
6a59d64c | 861 | switch (core->boardnr) { |
6c5be74c ST |
862 | case CX88_BOARD_HAUPPAUGE_HVR1300: |
863 | /* Do Nothing, leave the cx22702 on the bus. */ | |
864 | break; | |
865 | default: | |
866 | err = -ENODEV; | |
867 | } | |
868 | return err; | |
869 | } | |
870 | ||
871 | static int cx8802_dvb_probe(struct cx8802_driver *drv) | |
872 | { | |
873 | struct cx88_core *core = drv->core; | |
874 | struct cx8802_dev *dev = drv->core->dvbdev; | |
1da177e4 LT |
875 | int err; |
876 | ||
6c5be74c ST |
877 | dprintk( 1, "%s\n", __FUNCTION__); |
878 | dprintk( 1, " ->being probed by Card=%d Name=%s, PCI %02x:%02x\n", | |
6a59d64c | 879 | core->boardnr, |
6c5be74c ST |
880 | core->name, |
881 | core->pci_bus, | |
882 | core->pci_slot); | |
1da177e4 LT |
883 | |
884 | err = -ENODEV; | |
6a59d64c | 885 | if (!(core->board.mpeg & CX88_MPEG_DVB)) |
1da177e4 LT |
886 | goto fail_core; |
887 | ||
ecf854df | 888 | /* If vp3054 isn't enabled, a stub will just return 0 */ |
fc40b261 CP |
889 | err = vp3054_i2c_probe(dev); |
890 | if (0 != err) | |
6c5be74c | 891 | goto fail_core; |
fc40b261 | 892 | |
1da177e4 | 893 | /* dvb stuff */ |
5772f813 | 894 | printk(KERN_INFO "%s/2: cx2388x based DVB/ATSC card\n", core->name); |
0705135e GL |
895 | videobuf_queue_sg_init(&dev->dvb.dvbq, &dvb_qops, |
896 | &dev->pci->dev, &dev->slock, | |
1da177e4 LT |
897 | V4L2_BUF_TYPE_VIDEO_CAPTURE, |
898 | V4L2_FIELD_TOP, | |
899 | sizeof(struct cx88_buffer), | |
900 | dev); | |
901 | err = dvb_register(dev); | |
6c5be74c | 902 | if (err != 0) |
5772f813 TP |
903 | printk(KERN_ERR "%s/2: dvb_register failed (err = %d)\n", |
904 | core->name, err); | |
1da177e4 | 905 | |
1da177e4 | 906 | fail_core: |
1da177e4 LT |
907 | return err; |
908 | } | |
909 | ||
6c5be74c | 910 | static int cx8802_dvb_remove(struct cx8802_driver *drv) |
1da177e4 | 911 | { |
6c5be74c | 912 | struct cx8802_dev *dev = drv->core->dvbdev; |
611900c1 | 913 | |
1da177e4 LT |
914 | /* dvb */ |
915 | videobuf_dvb_unregister(&dev->dvb); | |
916 | ||
fc40b261 | 917 | vp3054_i2c_remove(dev); |
fc40b261 | 918 | |
6c5be74c | 919 | return 0; |
1da177e4 LT |
920 | } |
921 | ||
6c5be74c ST |
922 | static struct cx8802_driver cx8802_dvb_driver = { |
923 | .type_id = CX88_MPEG_DVB, | |
924 | .hw_access = CX8802_DRVCTL_SHARED, | |
925 | .probe = cx8802_dvb_probe, | |
926 | .remove = cx8802_dvb_remove, | |
927 | .advise_acquire = cx8802_dvb_advise_acquire, | |
928 | .advise_release = cx8802_dvb_advise_release, | |
1da177e4 LT |
929 | }; |
930 | ||
931 | static int dvb_init(void) | |
932 | { | |
5772f813 | 933 | printk(KERN_INFO "cx88/2: cx2388x dvb driver version %d.%d.%d loaded\n", |
1da177e4 LT |
934 | (CX88_VERSION_CODE >> 16) & 0xff, |
935 | (CX88_VERSION_CODE >> 8) & 0xff, | |
936 | CX88_VERSION_CODE & 0xff); | |
937 | #ifdef SNAPSHOT | |
938 | printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n", | |
939 | SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100); | |
940 | #endif | |
6c5be74c | 941 | return cx8802_register_driver(&cx8802_dvb_driver); |
1da177e4 LT |
942 | } |
943 | ||
944 | static void dvb_fini(void) | |
945 | { | |
6c5be74c | 946 | cx8802_unregister_driver(&cx8802_dvb_driver); |
1da177e4 LT |
947 | } |
948 | ||
949 | module_init(dvb_init); | |
950 | module_exit(dvb_fini); | |
951 | ||
952 | /* | |
953 | * Local variables: | |
954 | * c-basic-offset: 8 | |
955 | * compile-command: "make DVB=1" | |
956 | * End: | |
957 | */ |