/*
- * $Id: cx88-dvb.c,v 1.19 2004/11/07 14:44:59 kraxel Exp $
+ * $Id: cx88-dvb.c,v 1.31 2005/03/07 15:58:05 kraxel Exp $
*
* device driver for Conexant 2388x based TV cards
* MPEG Transport Stream (DVB) routines
#include <linux/file.h>
#include <linux/suspend.h>
+/* those two frontends need merging via linuxtv cvs ... */
+#define HAVE_CX22702 1
+#define HAVE_OR51132 1
+
#include "cx88.h"
-#include "cx22702.h"
+#include "dvb-pll.h"
#include "mt352.h"
-#include "mt352_priv.h" /* FIXME */
+#include "mt352_priv.h"
+#if HAVE_CX22702
+# include "cx22702.h"
+#endif
+#if HAVE_OR51132
+# include "or51132.h"
+#endif
MODULE_DESCRIPTION("driver for cx2388x based DVB cards");
MODULE_AUTHOR("Chris Pascoe <c.pascoe@itee.uq.edu.au>");
cx88_free_buffer(dev->pci, (struct cx88_buffer*)vb);
}
-struct videobuf_queue_ops dvb_qops = {
+static struct videobuf_queue_ops dvb_qops = {
.buf_setup = dvb_buf_setup,
.buf_prepare = dvb_buf_prepare,
.buf_queue = dvb_buf_queue,
return 0;
}
-#define IF_FREQUENCYx6 217 /* 6 * 36.16666666667MHz */
-
-static int lg_z201_pll_set(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params, u8* pllbuf)
+static int dntv_live_dvbt_demod_init(struct dvb_frontend* fe)
{
- u32 div;
- unsigned char cp = 0;
- unsigned char bs = 0;
-
- div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
- if (params->frequency < 542000000) cp = 0xbc;
- else if (params->frequency < 830000000) cp = 0xf4;
- else cp = 0xfc;
+ static u8 clock_config [] = { 0x89, 0x38, 0x39 };
+ static u8 reset [] = { 0x50, 0x80 };
+ static u8 adc_ctl_1_cfg [] = { 0x8E, 0x40 };
+ static u8 agc_cfg [] = { 0x67, 0x10, 0x23, 0x00, 0xFF, 0xFF,
+ 0x00, 0xFF, 0x00, 0x40, 0x40 };
+ static u8 dntv_extra[] = { 0xB5, 0x7A };
+ static u8 capt_range_cfg[] = { 0x75, 0x32 };
- if (params->frequency == 0) bs = 0x03;
- else if (params->frequency < 157500000) bs = 0x01;
- else if (params->frequency < 443250000) bs = 0x02;
- else bs = 0x04;
+ mt352_write(fe, clock_config, sizeof(clock_config));
+ udelay(2000);
+ mt352_write(fe, reset, sizeof(reset));
+ mt352_write(fe, adc_ctl_1_cfg, sizeof(adc_ctl_1_cfg));
- pllbuf[0] = 0xC2; /* Note: non-linux standard PLL I2C address */
- pllbuf[1] = div >> 8;
- pllbuf[2] = div & 0xff;
- pllbuf[3] = cp;
- pllbuf[4] = bs;
+ mt352_write(fe, agc_cfg, sizeof(agc_cfg));
+ udelay(2000);
+ mt352_write(fe, dntv_extra, sizeof(dntv_extra));
+ mt352_write(fe, capt_range_cfg, sizeof(capt_range_cfg));
return 0;
}
-static int thomson_dtt7579_pll_set(struct dvb_frontend* fe,
- struct dvb_frontend_parameters* params,
- u8* pllbuf)
+static int mt352_pll_set(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters* params,
+ u8* pllbuf)
{
- u32 div;
- unsigned char cp = 0;
- unsigned char bs = 0;
-
- div = (((params->frequency + 83333) * 3) / 500000) + IF_FREQUENCYx6;
-
- if (params->frequency < 542000000) cp = 0xb4;
- else if (params->frequency < 771000000) cp = 0xbc;
- else cp = 0xf4;
-
- if (params->frequency == 0) bs = 0x03;
- else if (params->frequency < 443250000) bs = 0x02;
- else bs = 0x08;
-
- pllbuf[0] = 0xc0; // Note: non-linux standard PLL i2c address
- pllbuf[1] = div >> 8;
- pllbuf[2] = div & 0xff;
- pllbuf[3] = cp;
- pllbuf[4] = bs;
+ struct cx8802_dev *dev= fe->dvb->priv;
+ pllbuf[0] = dev->core->pll_addr << 1;
+ dvb_pll_configure(dev->core->pll_desc, pllbuf+1,
+ params->frequency,
+ params->u.ofdm.bandwidth);
return 0;
}
-struct mt352_config dvico_fusionhdtv_dvbt1 = {
+static struct mt352_config dvico_fusionhdtv = {
.demod_address = 0x0F,
.demod_init = dvico_fusionhdtv_demod_init,
- .pll_set = lg_z201_pll_set,
+ .pll_set = mt352_pll_set,
};
-struct mt352_config dvico_fusionhdtv_dvbt_plus = {
- .demod_address = 0x0F,
- .demod_init = dvico_fusionhdtv_demod_init,
- .pll_set = thomson_dtt7579_pll_set,
+static struct mt352_config dntv_live_dvbt_config = {
+ .demod_address = 0x0f,
+ .demod_init = dntv_live_dvbt_demod_init,
+ .pll_set = mt352_pll_set,
+};
+
+#if HAVE_CX22702
+static struct cx22702_config connexant_refboard_config = {
+ .demod_address = 0x43,
+ .pll_address = 0x60,
+ .pll_desc = &dvb_pll_thomson_dtt7579,
};
+static struct cx22702_config hauppauge_novat_config = {
+ .demod_address = 0x43,
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_thomson_dtt759x,
+};
+#endif
+
+#if HAVE_OR51132
+static int or51132_set_ts_param(struct dvb_frontend* fe,
+ int is_punctured)
+{
+ struct cx8802_dev *dev= fe->dvb->priv;
+ dev->ts_gen_cntrl = is_punctured ? 0x04 : 0x00;
+ return 0;
+}
+
+static struct or51132_config pchdtv_hd3000 = {
+ .demod_address = 0x15,
+ .pll_address = 0x61,
+ .pll_desc = &dvb_pll_thomson_dtt7610,
+ .set_ts_params = or51132_set_ts_param,
+};
+#endif
+
static int dvb_register(struct cx8802_dev *dev)
{
/* init struct videobuf_dvb */
dev->dvb.name = dev->core->name;
+ dev->ts_gen_cntrl = 0x0c;
/* init frontend */
switch (dev->core->board) {
+#if HAVE_CX22702
case CX88_BOARD_HAUPPAUGE_DVB_T1:
+ dev->dvb.frontend = cx22702_attach(&hauppauge_novat_config,
+ &dev->core->i2c_adap);
+ break;
case CX88_BOARD_CONEXANT_DVB_T1:
- dev->dvb.frontend = cx22702_create(&dev->core->i2c_adap,
- dev->core->pll_addr,
- dev->core->pll_type,
- dev->core->demod_addr);
+ dev->dvb.frontend = cx22702_attach(&connexant_refboard_config,
+ &dev->core->i2c_adap);
break;
+#endif
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T1:
- dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt1,
+ dev->core->pll_addr = 0x61;
+ dev->core->pll_desc = &dvb_pll_lg_z201;
+ dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
&dev->core->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops->info.frequency_min = 174000000;
- dev->dvb.frontend->ops->info.frequency_max = 862000000;
- }
break;
case CX88_BOARD_DVICO_FUSIONHDTV_DVB_T_PLUS:
- dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv_dvbt_plus,
+ dev->core->pll_addr = 0x60;
+ dev->core->pll_desc = &dvb_pll_thomson_dtt7579;
+ dev->dvb.frontend = mt352_attach(&dvico_fusionhdtv,
&dev->core->i2c_adap);
- if (dev->dvb.frontend) {
- dev->dvb.frontend->ops->info.frequency_min = 174000000;
- dev->dvb.frontend->ops->info.frequency_max = 862000000;
- }
break;
+ case CX88_BOARD_KWORLD_DVB_T:
+ case CX88_BOARD_DNTV_LIVE_DVB_T:
+ dev->core->pll_addr = 0x61;
+ dev->core->pll_desc = &dvb_pll_unknown_1;
+ dev->dvb.frontend = mt352_attach(&dntv_live_dvbt_config,
+ &dev->core->i2c_adap);
+ break;
+#if HAVE_OR51132
+ case CX88_BOARD_PCHDTV_HD3000:
+ dev->dvb.frontend = or51132_attach(&pchdtv_hd3000,
+ &dev->core->i2c_adap);
+ break;
+#endif
default:
- printk("%s: FIXME: frontend handling not here yet ...\n",
+ printk("%s: The frontend of your DVB/ATSC card isn't supported yet\n",
dev->core->name);
break;
}
- if (NULL == dev->dvb.frontend)
+ if (NULL == dev->dvb.frontend) {
+ printk("%s: frontend initialization failed\n",dev->core->name);
return -1;
+ }
+
+ if (dev->core->pll_desc) {
+ dev->dvb.frontend->ops->info.frequency_min = dev->core->pll_desc->min;
+ dev->dvb.frontend->ops->info.frequency_max = dev->core->pll_desc->max;
+ }
/* Copy the board name into the DVB structure */
strlcpy(dev->dvb.frontend->ops->info.name,
sizeof(dev->dvb.frontend->ops->info.name));
/* register everything */
- return videobuf_dvb_register(&dev->dvb);
+ return videobuf_dvb_register(&dev->dvb, THIS_MODULE, dev);
}
/* ----------------------------------------------------------- */
dev);
err = dvb_register(dev);
if (0 != err)
- goto fail_free;
+ goto fail_fini;
return 0;
+ fail_fini:
+ cx8802_fini_common(dev);
fail_free:
kfree(dev);
fail_core:
printk(KERN_INFO "cx2388x: snapshot date %04d-%02d-%02d\n",
SNAPSHOT/10000, (SNAPSHOT/100)%100, SNAPSHOT%100);
#endif
- return pci_module_init(&dvb_pci_driver);
+ return pci_register_driver(&dvb_pci_driver);
}
static void dvb_fini(void)