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