blob: 21972572a94324848349095b5f11b671e12206a6 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 *
3 * device driver for Conexant 2388x based TV cards
4 * MPEG Transport Stream (DVB) routines
5 *
6 * (c) 2004 Chris Pascoe <c.pascoe@itee.uq.edu.au>
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
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include "cx88.h"
33#include "dvb-pll.h"
Mauro Carvalho Chehab41ef7c12005-07-12 13:58:44 -070034
Michael Krufky29780bb2005-07-27 11:45:59 -070035#ifdef HAVE_MT352
Mauro Carvalho Chehab41ef7c12005-07-12 13:58:44 -070036# include "mt352.h"
37# include "mt352_priv.h"
38#endif
Michael Krufky29780bb2005-07-27 11:45:59 -070039#ifdef HAVE_CX22702
Linus Torvalds1da177e2005-04-16 15:20:36 -070040# include "cx22702.h"
41#endif
Michael Krufky29780bb2005-07-27 11:45:59 -070042#ifdef HAVE_OR51132
Linus Torvalds1da177e2005-04-16 15:20:36 -070043# include "or51132.h"
44#endif
Michael Krufky6ddcc912005-07-27 11:46:00 -070045#ifdef HAVE_LGDT330X
46# include "lgdt330x.h"
Michael Krufkyf1798492005-07-07 17:58:39 -070047#endif
Kirk Laprayfde6d312005-11-08 21:38:18 -080048#ifdef HAVE_NXT200X
49# include "nxt200x.h"
50#endif
Steven Toth0fa14aa2006-01-09 15:25:02 -020051#ifdef HAVE_CX24123
52# include "cx24123.h"
53#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
56MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
57MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
58MODULE_LICENSE("GPL");
59
60static unsigned int debug = 0;
61module_param(debug, int, 0644);
62MODULE_PARM_DESC(debug,"enable debug messages [dvb]");
63
64#define dprintk(level,fmt, arg...) if (debug >= level) \
65 printk(KERN_DEBUG "%s/2-dvb: " fmt, dev->core->name , ## arg)
66
67/* ------------------------------------------------------------------ */
68
69static int dvb_buf_setup(struct videobuf_queue *q,
70 unsigned int *count, unsigned int *size)
71{
72 struct cx8802_dev *dev = q->priv_data;
73
74 dev->ts_packet_size = 188 * 4;
75 dev->ts_packet_count = 32;
76
77 *size = dev->ts_packet_size * dev->ts_packet_count;
78 *count = 32;
79 return 0;
80}
81
82static int dvb_buf_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,
83 enum v4l2_field field)
84{
85 struct cx8802_dev *dev = q->priv_data;
Michael Krufkyccd7b652005-11-08 21:36:19 -080086 return cx8802_buf_prepare(dev, (struct cx88_buffer*)vb,field);
Linus Torvalds1da177e2005-04-16 15:20:36 -070087}
88
89static void dvb_buf_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
90{
91 struct cx8802_dev *dev = q->priv_data;
92 cx8802_buf_queue(dev, (struct cx88_buffer*)vb);
93}
94
95static void dvb_buf_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
96{
97 struct cx8802_dev *dev = q->priv_data;
98 cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
99}
100
Adrian Bunk408b6642005-05-01 08:59:29 -0700101static struct videobuf_queue_ops dvb_qops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700102 .buf_setup = dvb_buf_setup,
103 .buf_prepare = dvb_buf_prepare,
104 .buf_queue = dvb_buf_queue,
105 .buf_release = dvb_buf_release,
106};
107
108/* ------------------------------------------------------------------ */
109
Michael Krufky29780bb2005-07-27 11:45:59 -0700110#ifdef HAVE_MT352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111static int dvico_fusionhdtv_demod_init(struct dvb_frontend* fe)
112{
113 static u8 clock_config [] = { CLOCK_CTL, 0x38, 0x39 };
114 static u8 reset [] = { RESET, 0x80 };
115 static u8 adc_ctl_1_cfg [] = { ADC_CTL_1, 0x40 };
116 static u8 agc_cfg [] = { AGC_TARGET, 0x24, 0x20 };
117 static u8 gpp_ctl_cfg [] = { GPP_CTL, 0x33 };
118 static u8 capt_range_cfg[] = { CAPT_RANGE, 0x32 };
119
120 mt352_write(fe, clock_config, sizeof(clock_config));
121 udelay(200);
122 mt352_write(fe, reset, sizeof(reset));
123 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
124
125 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
126 mt352_write(fe, gpp_ctl_cfg, sizeof(gpp_ctl_cfg));
127 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
128 return 0;
129}
130
131static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
132{
133 static u8 clock_config [] = { 0x89, 0x38, 0x39 };
134 static u8 reset [] = { 0x50, 0x80 };
135 static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
136 static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
Mauro Carvalho Chehabf2421ca2005-11-08 21:37:45 -0800137 0x00, 0xFF, 0x00, 0x40, 0x40 };
Linus Torvalds1da177e2005-04-16 15:20:36 -0700138 static u8 dntv_extra[] = { 0xB5, 0x7A };
139 static u8 capt_range_cfg[] = { 0x75, 0x32 };
140
141 mt352_write(fe, clock_config, sizeof(clock_config));
142 udelay(2000);
143 mt352_write(fe, reset, sizeof(reset));
144 mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
145
146 mt352_write(fe, agc_cfg, sizeof(agc_cfg));
147 udelay(2000);
148 mt352_write(fe, dntv_extra, sizeof(dntv_extra));
149 mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
150
151 return 0;
152}
153
154static int mt352_pll_set(struct dvb_frontend* fe,
155 struct dvb_frontend_parameters* params,
156 u8* pllbuf)
157{
158 struct cx8802_dev *dev= fe->dvb->priv;
159
160 pllbuf[0] = dev->core->pll_addr << 1;
161 dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
162 params->frequency,
163 params->u.ofdm.bandwidth);
164 return 0;
165}
166
167static struct mt352_config dvico_fusionhdtv = {
168 .demod_address = 0x0F,
169 .demod_init = dvico_fusionhdtv_demod_init,
170 .pll_set = mt352_pll_set,
171};
172
173static struct mt352_config dntv_live_dvbt_config = {
174 .demod_address = 0x0f,
175 .demod_init = dntv_live_dvbt_demod_init,
176 .pll_set = mt352_pll_set,
177};
Mauro Carvalho Chehab41ef7c12005-07-12 13:58:44 -0700178#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179
Michael Krufky29780bb2005-07-27 11:45:59 -0700180#ifdef HAVE_CX22702
Linus Torvalds1da177e2005-04-16 15:20:36 -0700181static struct cx22702_config connexant_refboard_config = {
182 .demod_address = 0x43,
Patrick Boettcher38d84c32005-07-15 12:20:26 -0700183 .output_mode = CX22702_SERIAL_OUTPUT,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 .pll_address = 0x60,
185 .pll_desc = &dvb_pll_thomson_dtt7579,
186};
187
188static struct cx22702_config hauppauge_novat_config = {
189 .demod_address = 0x43,
Patrick Boettcher38d84c32005-07-15 12:20:26 -0700190 .output_mode = CX22702_SERIAL_OUTPUT,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191 .pll_address = 0x61,
192 .pll_desc = &dvb_pll_thomson_dtt759x,
193};
194#endif
195
Michael Krufky29780bb2005-07-27 11:45:59 -0700196#ifdef HAVE_OR51132
Linus Torvalds1da177e2005-04-16 15:20:36 -0700197static int or51132_set_ts_param(struct dvb_frontend* fe,
198 int is_punctured)
199{
200 struct cx8802_dev *dev= fe->dvb->priv;
201 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
202 return 0;
203}
204
Adrian Bunk408b6642005-05-01 08:59:29 -0700205static struct or51132_config pchdtv_hd3000 = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700206 .demod_address = 0x15,
207 .pll_address = 0x61,
208 .pll_desc = &dvb_pll_thomson_dtt7610,
209 .set_ts_params = or51132_set_ts_param,
210};
211#endif
212
Michael Krufky6ddcc912005-07-27 11:46:00 -0700213#ifdef HAVE_LGDT330X
214static int lgdt330x_pll_set(struct dvb_frontend* fe,
Michael Krufky1963c902005-08-08 09:22:43 -0700215 struct dvb_frontend_parameters* params)
Michael Krufkyb6aef072005-07-27 11:45:54 -0700216{
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700217 /* FIXME make this routine use the tuner-simple code.
218 * It could probably be shared with a number of ATSC
219 * frontends. Many share the same tuner with analog TV. */
220
Michael Krufkyb6aef072005-07-27 11:45:54 -0700221 struct cx8802_dev *dev= fe->dvb->priv;
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700222 struct cx88_core *core = dev->core;
Michael Krufky1963c902005-08-08 09:22:43 -0700223 u8 buf[4];
224 struct i2c_msg msg =
225 { .addr = dev->core->pll_addr, .flags = 0, .buf = buf, .len = 4 };
226 int err;
Michael Krufkyb6aef072005-07-27 11:45:54 -0700227
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700228 /* Put the analog decoder in standby to keep it quiet */
Mauro Carvalho Chehab93352f52005-09-13 01:25:42 -0700229 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700230
231 dvb_pll_configure(core->pll_desc, buf, params->frequency, 0);
Michael Krufky1963c902005-08-08 09:22:43 -0700232 dprintk(1, "%s: tuner at 0x%02x bytes: 0x%02x 0x%02x 0x%02x 0x%02x\n",
233 __FUNCTION__, msg.addr, buf[0],buf[1],buf[2],buf[3]);
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700234 if ((err = i2c_transfer(&core->i2c_adap, &msg, 1)) != 1) {
Michael Krufky1963c902005-08-08 09:22:43 -0700235 printk(KERN_WARNING "cx88-dvb: %s error "
236 "(addr %02x <- %02x, err = %i)\n",
237 __FUNCTION__, buf[0], buf[1], err);
238 if (err < 0)
239 return err;
240 else
241 return -EREMOTEIO;
242 }
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700243 if (core->tuner_type == TUNER_LG_TDVS_H062F) {
244 /* Set the Auxiliary Byte. */
245 buf[2] &= ~0x20;
246 buf[2] |= 0x18;
247 buf[3] = 0x50;
248 i2c_transfer(&core->i2c_adap, &msg, 1);
249 }
Michael Krufkyb6aef072005-07-27 11:45:54 -0700250 return 0;
251}
252
Michael Krufky6ddcc912005-07-27 11:46:00 -0700253static int lgdt330x_pll_rf_set(struct dvb_frontend* fe, int index)
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700254{
255 struct cx8802_dev *dev= fe->dvb->priv;
256 struct cx88_core *core = dev->core;
257
258 dprintk(1, "%s: index = %d\n", __FUNCTION__, index);
259 if (index == 0)
260 cx_clear(MO_GP0_IO, 8);
261 else
262 cx_set(MO_GP0_IO, 8);
263 return 0;
264}
265
Michael Krufky6ddcc912005-07-27 11:46:00 -0700266static int lgdt330x_set_ts_param(struct dvb_frontend* fe, int is_punctured)
Michael Krufkyf1798492005-07-07 17:58:39 -0700267{
268 struct cx8802_dev *dev= fe->dvb->priv;
269 if (is_punctured)
270 dev->ts_gen_cntrl |= 0x04;
271 else
272 dev->ts_gen_cntrl &= ~0x04;
273 return 0;
274}
275
Michael Krufky6ddcc912005-07-27 11:46:00 -0700276static struct lgdt330x_config fusionhdtv_3_gold = {
Michael Krufkyf1798492005-07-07 17:58:39 -0700277 .demod_address = 0x0e,
Michael Krufky1963c902005-08-08 09:22:43 -0700278 .demod_chip = LGDT3302,
279 .serial_mpeg = 0x04, /* TPSERIAL for 3302 in TOP_CONTROL */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700280 .pll_set = lgdt330x_pll_set,
281 .set_ts_params = lgdt330x_set_ts_param,
Michael Krufky0d723c02005-07-07 17:58:42 -0700282};
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700283
284static struct lgdt330x_config fusionhdtv_5_gold = {
285 .demod_address = 0x0e,
286 .demod_chip = LGDT3303,
287 .serial_mpeg = 0x40, /* TPSERIAL for 3303 in TOP_CONTROL */
288 .pll_set = lgdt330x_pll_set,
289 .set_ts_params = lgdt330x_set_ts_param,
290};
Michael Krufkyf1798492005-07-07 17:58:39 -0700291#endif
292
Kirk Laprayfde6d312005-11-08 21:38:18 -0800293#ifdef HAVE_NXT200X
294static int nxt200x_set_ts_param(struct dvb_frontend* fe,
295 int is_punctured)
296{
297 struct cx8802_dev *dev= fe->dvb->priv;
298 dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
299 return 0;
300}
301
Kirk Laprayd4c34aa2005-11-08 21:38:40 -0800302static int nxt200x_set_pll_input(u8* buf, int input)
303{
304 if (input)
305 buf[3] |= 0x08;
306 else
307 buf[3] &= ~0x08;
308 return 0;
309}
310
Kirk Laprayfde6d312005-11-08 21:38:18 -0800311static struct nxt200x_config ati_hdtvwonder = {
312 .demod_address = 0x0a,
313 .pll_address = 0x61,
314 .pll_desc = &dvb_pll_tuv1236d,
Kirk Laprayd4c34aa2005-11-08 21:38:40 -0800315 .set_pll_input = nxt200x_set_pll_input,
Kirk Laprayfde6d312005-11-08 21:38:18 -0800316 .set_ts_params = nxt200x_set_ts_param,
317};
318#endif
319
Steven Toth0fa14aa2006-01-09 15:25:02 -0200320#ifdef HAVE_CX24123
321static int cx24123_set_ts_param(struct dvb_frontend* fe,
322 int is_punctured)
323{
324 struct cx8802_dev *dev= fe->dvb->priv;
325 dev->ts_gen_cntrl = 0x2;
326 return 0;
327}
328
329static struct cx24123_config hauppauge_novas_config = {
330 .demod_address = 0x55,
331 .set_ts_params = cx24123_set_ts_param,
332};
333#endif
334
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335static int dvb_register(struct cx8802_dev *dev)
336{
337 /* init struct videobuf_dvb */
338 dev->dvb.name = dev->core->name;
339 dev->ts_gen_cntrl = 0x0c;
340
341 /* init frontend */
342 switch (dev->core->board) {
Michael Krufky29780bb2005-07-27 11:45:59 -0700343#ifdef HAVE_CX22702
Linus Torvalds1da177e2005-04-16 15:20:36 -0700344 case CX88_BOARD_HAUPPAUGE_DVB_T1:
345 dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
346 &dev->core->i2c_adap);
347 break;
Michael Krufkye057ee12005-07-07 17:58:40 -0700348 case CX88_BOARD_TERRATEC_CINERGY_1400_DVB_T1:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700349 case CX88_BOARD_CONEXANT_DVB_T1:
David Shirley2b5200a2005-11-08 21:37:22 -0800350 case CX88_BOARD_WINFAST_DTV1000:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
352 &dev->core->i2c_adap);
353 break;
354#endif
Michael Krufky29780bb2005-07-27 11:45:59 -0700355#ifdef HAVE_MT352
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
357 dev->core->pll_addr = 0x61;
358 dev->core->pll_desc = &dvb_pll_lg_z201;
359 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
360 &dev->core->i2c_adap);
361 break;
362 case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
363 dev->core->pll_addr = 0x60;
364 dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
365 dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
366 &dev->core->i2c_adap);
367 break;
368 case CX88_BOARD_KWORLD_DVB_T:
369 case CX88_BOARD_DNTV_LIVE_DVB_T:
Mauro Carvalho Chehaba82decf2005-07-07 17:58:36 -0700370 case CX88_BOARD_ADSTECH_DVB_T_PCI:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 dev->core->pll_addr = 0x61;
372 dev->core->pll_desc = &dvb_pll_unknown_1;
373 dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
374 &dev->core->i2c_adap);
375 break;
Mauro Carvalho Chehab41ef7c12005-07-12 13:58:44 -0700376#endif
Michael Krufky29780bb2005-07-27 11:45:59 -0700377#ifdef HAVE_OR51132
Linus Torvalds1da177e2005-04-16 15:20:36 -0700378 case CX88_BOARD_PCHDTV_HD3000:
379 dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
380 &dev->core->i2c_adap);
381 break;
382#endif
Michael Krufky6ddcc912005-07-27 11:46:00 -0700383#ifdef HAVE_LGDT330X
Michael Krufkyf1798492005-07-07 17:58:39 -0700384 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_Q:
385 dev->ts_gen_cntrl = 0x08;
386 {
387 /* Do a hardware reset of chip before using it. */
388 struct cx88_core *core = dev->core;
389
390 cx_clear(MO_GP0_IO, 1);
391 mdelay(100);
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700392 cx_set(MO_GP0_IO, 1);
Michael Krufkyf1798492005-07-07 17:58:39 -0700393 mdelay(200);
Michael Krufky0ccef6d2005-07-27 11:45:55 -0700394
395 /* Select RF connector callback */
Michael Krufky6ddcc912005-07-27 11:46:00 -0700396 fusionhdtv_3_gold.pll_rf_set = lgdt330x_pll_rf_set;
Michael Krufkyb6aef072005-07-27 11:45:54 -0700397 dev->core->pll_addr = 0x61;
398 dev->core->pll_desc = &dvb_pll_microtune_4042;
Michael Krufky6ddcc912005-07-27 11:46:00 -0700399 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
Michael Krufkyf1798492005-07-07 17:58:39 -0700400 &dev->core->i2c_adap);
401 }
402 break;
Michael Krufky0d723c02005-07-07 17:58:42 -0700403 case CX88_BOARD_DVICO_FUSIONHDTV_3_GOLD_T:
404 dev->ts_gen_cntrl = 0x08;
405 {
406 /* Do a hardware reset of chip before using it. */
407 struct cx88_core *core = dev->core;
408
409 cx_clear(MO_GP0_IO, 1);
410 mdelay(100);
Michael Krufkyd9758722005-07-27 11:45:56 -0700411 cx_set(MO_GP0_IO, 9);
Michael Krufky0d723c02005-07-07 17:58:42 -0700412 mdelay(200);
Michael Krufkyb6aef072005-07-27 11:45:54 -0700413 dev->core->pll_addr = 0x61;
414 dev->core->pll_desc = &dvb_pll_thomson_dtt7611;
Michael Krufky6ddcc912005-07-27 11:46:00 -0700415 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_3_gold,
Michael Krufky0d723c02005-07-07 17:58:42 -0700416 &dev->core->i2c_adap);
417 }
418 break;
Mauro Carvalho Chehabe52e98a2005-09-09 13:03:41 -0700419 case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
420 dev->ts_gen_cntrl = 0x08;
421 {
422 /* Do a hardware reset of chip before using it. */
423 struct cx88_core *core = dev->core;
424
425 cx_clear(MO_GP0_IO, 1);
426 mdelay(100);
427 cx_set(MO_GP0_IO, 1);
428 mdelay(200);
429 dev->core->pll_addr = 0x61;
430 dev->core->pll_desc = &dvb_pll_tdvs_tua6034;
431 dev->dvb.frontend = lgdt330x_attach(&fusionhdtv_5_gold,
432 &dev->core->i2c_adap);
433 }
434 break;
Michael Krufkyf1798492005-07-07 17:58:39 -0700435#endif
Kirk Laprayfde6d312005-11-08 21:38:18 -0800436#ifdef HAVE_NXT200X
437 case CX88_BOARD_ATI_HDTVWONDER:
438 dev->dvb.frontend = nxt200x_attach(&ati_hdtvwonder,
439 &dev->core->i2c_adap);
440 break;
441#endif
Steven Toth0fa14aa2006-01-09 15:25:02 -0200442#ifdef HAVE_CX24123
443 case CX88_BOARD_HAUPPAUGE_NOVASPLUS_S1:
444 case CX88_BOARD_HAUPPAUGE_NOVASE2_S1:
445 dev->dvb.frontend = cx24123_attach(&hauppauge_novas_config,
446 &dev->core->i2c_adap);
447 break;
448#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 default:
Gerd Knorr1622c3f2005-05-01 08:59:19 -0700450 printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
451 dev->core->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452 break;
453 }
454 if (NULL == dev->dvb.frontend) {
455 printk("%s: frontend initialization failed\n",dev->core->name);
456 return -1;
457 }
458
459 if (dev->core->pll_desc) {
460 dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min;
461 dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
462 }
463
Mauro Carvalho Chehab93352f52005-09-13 01:25:42 -0700464 /* Put the analog decoder in standby to keep it quiet */
465 cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
466
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 /* register everything */
468 return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
469}
470
471/* ----------------------------------------------------------- */
472
473static int __devinit dvb_probe(struct pci_dev *pci_dev,
474 const struct pci_device_id *pci_id)
475{
476 struct cx8802_dev *dev;
477 struct cx88_core *core;
478 int err;
479
480 /* general setup */
481 core = cx88_core_get(pci_dev);
482 if (NULL == core)
483 return -EINVAL;
484
485 err = -ENODEV;
486 if (!cx88_boards[core->board].dvb)
487 goto fail_core;
488
489 err = -ENOMEM;
490 dev = kmalloc(sizeof(*dev),GFP_KERNEL);
491 if (NULL == dev)
492 goto fail_core;
493 memset(dev,0,sizeof(*dev));
494 dev->pci = pci_dev;
495 dev->core = core;
496
497 err = cx8802_init_common(dev);
498 if (0 != err)
499 goto fail_free;
500
501 /* dvb stuff */
502 printk("%s/2: cx2388x based dvb card\n", core->name);
503 videobuf_queue_init(&dev->dvb.dvbq, &dvb_qops,
504 dev->pci, &dev->slock,
505 V4L2_BUF_TYPE_VIDEO_CAPTURE,
506 V4L2_FIELD_TOP,
507 sizeof(struct cx88_buffer),
508 dev);
509 err = dvb_register(dev);
510 if (0 != err)
Gerd Knorr1622c3f2005-05-01 08:59:19 -0700511 goto fail_fini;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700512 return 0;
513
Gerd Knorr1622c3f2005-05-01 08:59:19 -0700514 fail_fini:
515 cx8802_fini_common(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 fail_free:
517 kfree(dev);
518 fail_core:
519 cx88_core_put(core,pci_dev);
520 return err;
521}
522
523static void __devexit dvb_remove(struct pci_dev *pci_dev)
524{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800525 struct cx8802_dev *dev = pci_get_drvdata(pci_dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700526
527 /* dvb */
528 videobuf_dvb_unregister(&dev->dvb);
529
530 /* common */
531 cx8802_fini_common(dev);
532 cx88_core_put(dev->core,dev->pci);
533 kfree(dev);
534}
535
536static struct pci_device_id cx8802_pci_tbl[] = {
537 {
538 .vendor = 0x14f1,
539 .device = 0x8802,
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800540 .subvendor = PCI_ANY_ID,
541 .subdevice = PCI_ANY_ID,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 },{
543 /* --- end of list --- */
544 }
545};
546MODULE_DEVICE_TABLE(pci, cx8802_pci_tbl);
547
548static struct pci_driver dvb_pci_driver = {
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800549 .name = "cx88-dvb",
550 .id_table = cx8802_pci_tbl,
551 .probe = dvb_probe,
552 .remove = __devexit_p(dvb_remove),
Linus Torvalds1da177e2005-04-16 15:20:36 -0700553 .suspend = cx8802_suspend_common,
554 .resume = cx8802_resume_common,
555};
556
557static int dvb_init(void)
558{
559 printk(KERN_INFO "cx2388x dvb driver version %d.%d.%d loaded\n",
560 (CX88_VERSION_CODE >> 16) & 0xff,
561 (CX88_VERSION_CODE >> 8) & 0xff,
562 CX88_VERSION_CODE & 0xff);
563#ifdef SNAPSHOT
564 printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
565 SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
566#endif
567 return pci_register_driver(&dvb_pci_driver);
568}
569
570static void dvb_fini(void)
571{
572 pci_unregister_driver(&dvb_pci_driver);
573}
574
575module_init(dvb_init);
576module_exit(dvb_fini);
577
578/*
579 * Local variables:
580 * c-basic-offset: 8
581 * compile-command: "make DVB=1"
582 * End:
583 */