X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fmedia%2Fdvb%2Ffrontends%2Fdvb-pll.c;h=7a25f872c094c494c7d4512a4677af0d39d46e1a;hb=75a791925da909d489ef323e3a540ad1f1bca54f;hp=ca99e439c97c26288dd10dd8d5a93f5f92eb8688;hpb=8e268f333012c62fc6a5a10e1e2a19c1c389853e;p=linux-2.6 diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c index ca99e439c9..7a25f872c0 100644 --- a/drivers/media/dvb/frontends/dvb-pll.c +++ b/drivers/media/dvb/frontends/dvb-pll.c @@ -24,12 +24,48 @@ #include "dvb-pll.h" +struct dvb_pll_priv { + /* pll number */ + int nr; + + /* i2c details */ + int pll_i2c_address; + struct i2c_adapter *i2c; + + /* the PLL descriptor */ + struct dvb_pll_desc *pll_desc; + + /* cached frequency/bandwidth */ + u32 frequency; + u32 bandwidth; +}; + +#define DVB_PLL_MAX 64 + +static unsigned int dvb_pll_devcount; + +static int debug; +module_param(debug, int, 0644); +MODULE_PARM_DESC(debug, "enable verbose debug messages"); + +static unsigned int input[DVB_PLL_MAX] = { [ 0 ... (DVB_PLL_MAX-1) ] = 0 }; +module_param_array(input, int, NULL, 0644); +MODULE_PARM_DESC(input,"specify rf input choice, 0 for autoselect (default)"); + +static unsigned int id[DVB_PLL_MAX] = + { [ 0 ... (DVB_PLL_MAX-1) ] = DVB_PLL_UNDEFINED }; +module_param_array(id, int, NULL, 0644); +MODULE_PARM_DESC(id, "force pll id to use (DEBUG ONLY)"); + +/* ----------------------------------------------------------- */ + struct dvb_pll_desc { char *name; u32 min; u32 max; u32 iffreq; - void (*set)(u8 *buf, const struct dvb_frontend_parameters *params); + void (*set)(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params); u8 *initdata; u8 *sleepdata; int count; @@ -44,16 +80,6 @@ struct dvb_pll_desc { /* ----------------------------------------------------------- */ /* descriptions */ -/* Set AGC TOP value to 103 dBuV: - 0x80 = Control Byte - 0x40 = 250 uA charge pump (irrelevant) - 0x18 = Aux Byte to follow - 0x06 = 64.5 kHz divider (irrelevant) - 0x01 = Disable Vt (aka sleep) - - 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA) - 0x50 = AGC Take over point = 103 dBuV */ -static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 }; /* 0x04 = 166.67 kHz divider @@ -76,20 +102,8 @@ static struct dvb_pll_desc dvb_pll_thomson_dtt7579 = { }, }; -static struct dvb_pll_desc dvb_pll_thomson_dtt7610 = { - .name = "Thomson dtt7610", - .min = 44000000, - .max = 958000000, - .iffreq= 44000000, - .count = 3, - .entries = { - { 157250000, 62500, 0x8e, 0x39 }, - { 454000000, 62500, 0x8e, 0x3a }, - { 999999999, 62500, 0x8e, 0x3c }, - }, -}; -static void thomson_dtt759x_bw(u8 *buf, +static void thomson_dtt759x_bw(struct dvb_frontend *fe, u8 *buf, const struct dvb_frontend_parameters *params) { if (BANDWIDTH_7_MHZ == params->u.ofdm.bandwidth) @@ -129,33 +143,6 @@ static struct dvb_pll_desc dvb_pll_lg_z201 = { }, }; -static struct dvb_pll_desc dvb_pll_microtune_4042 = { - .name = "Microtune 4042 FI5", - .min = 57000000, - .max = 858000000, - .iffreq= 44000000, - .count = 3, - .entries = { - { 162000000, 62500, 0x8e, 0xa1 }, - { 457000000, 62500, 0x8e, 0x91 }, - { 999999999, 62500, 0x8e, 0x31 }, - }, -}; - -static struct dvb_pll_desc dvb_pll_thomson_dtt761x = { - /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */ - .name = "Thomson dtt761x", - .min = 57000000, - .max = 863000000, - .iffreq= 44000000, - .count = 3, - .initdata = tua603x_agc103, - .entries = { - { 147000000, 62500, 0x8e, 0x39 }, - { 417000000, 62500, 0x8e, 0x3a }, - { 999999999, 62500, 0x8e, 0x3c }, - }, -}; static struct dvb_pll_desc dvb_pll_unknown_1 = { .name = "unknown 1", /* used by dntv live dvb-t */ @@ -210,7 +197,8 @@ static struct dvb_pll_desc dvb_pll_env57h1xd5 = { /* Philips TDA6650/TDA6651 * used in Panasonic ENV77H11D5 */ -static void tda665x_bw(u8 *buf, const struct dvb_frontend_parameters *params) +static void tda665x_bw(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) buf[3] |= 0x08; @@ -243,7 +231,8 @@ static struct dvb_pll_desc dvb_pll_tda665x = { /* Infineon TUA6034 * used in LG TDTP E102P */ -static void tua6034_bw(u8 *buf, const struct dvb_frontend_parameters *params) +static void tua6034_bw(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { if (BANDWIDTH_7_MHZ != params->u.ofdm.bandwidth) buf[3] |= 0x08; @@ -263,27 +252,12 @@ static struct dvb_pll_desc dvb_pll_tua6034 = { }, }; -/* Infineon TUA6034 - * used in LG TDVS-H061F, LG TDVS-H062F and LG TDVS-H064F - */ -static struct dvb_pll_desc dvb_pll_lg_tdvs_h06xf = { - .name = "LG TDVS-H06xF", - .min = 54000000, - .max = 863000000, - .iffreq= 44000000, - .initdata = tua603x_agc103, - .count = 3, - .entries = { - { 165000000, 62500, 0xce, 0x01 }, - { 450000000, 62500, 0xce, 0x02 }, - { 999999999, 62500, 0xce, 0x04 }, - }, -}; /* Philips FMD1216ME * used in Medion Hybrid PCMCIA card and USB Box */ -static void fmd1216me_bw(u8 *buf, const struct dvb_frontend_parameters *params) +static void fmd1216me_bw(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ && params->frequency >= 158870000) @@ -313,7 +287,8 @@ static struct dvb_pll_desc dvb_pll_fmd1216me = { /* ALPS TDED4 * used in Nebula-Cards and USB boxes */ -static void tded4_bw(u8 *buf, const struct dvb_frontend_parameters *params) +static void tded4_bw(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) buf[3] |= 0x04; @@ -354,16 +329,35 @@ static struct dvb_pll_desc dvb_pll_tdhu2 = { /* Philips TUV1236D * used in ATI HDTV Wonder */ -static void tuv1236d_rf(u8 *buf, const struct dvb_frontend_parameters *params) +static void tuv1236d_rf(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { - switch (params->u.vsb.modulation) { - case QAM_64: - case QAM_256: + struct dvb_pll_priv *priv = fe->tuner_priv; + unsigned int new_rf = input[priv->nr]; + + if ((new_rf == 0) || (new_rf > 2)) { + switch (params->u.vsb.modulation) { + case QAM_64: + case QAM_256: + new_rf = 1; + break; + case VSB_8: + default: + new_rf = 2; + } + } + + switch (new_rf) { + case 1: buf[3] |= 0x08; break; - case VSB_8: - default: + case 2: buf[3] &= ~0x08; + break; + default: + printk(KERN_WARNING + "%s: unhandled rf input selection: %d", + __FUNCTION__, new_rf); } } @@ -420,7 +414,8 @@ static struct dvb_pll_desc dvb_pll_philips_sd1878_tda8261 = { /* * Philips TD1316 Tuner. */ -static void td1316_bw(u8 *buf, const struct dvb_frontend_parameters *params) +static void td1316_bw(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { u8 band; @@ -459,22 +454,9 @@ static struct dvb_pll_desc dvb_pll_philips_td1316 = { }, }; -/* FE6600 used on DViCO Hybrid */ -static struct dvb_pll_desc dvb_pll_thomson_fe6600 = { - .name = "Thomson FE6600", - .min = 44250000, - .max = 858000000, - .iffreq= 36125000, - .count = 4, - .entries = { - { 250000000, 166667, 0xb4, 0x12 }, - { 455000000, 166667, 0xfe, 0x11 }, - { 775500000, 166667, 0xbc, 0x18 }, - { 999999999, 166667, 0xf4, 0x18 }, - } -}; -static void opera1_bw(u8 *buf, const struct dvb_frontend_parameters *params) +static void opera1_bw(struct dvb_frontend *fe, u8 *buf, + const struct dvb_frontend_parameters *params) { if (params->u.ofdm.bandwidth == BANDWIDTH_8_MHZ) buf[2] |= 0x08; @@ -499,23 +481,6 @@ static struct dvb_pll_desc dvb_pll_opera1 = { } }; -/* Philips FCV1236D - */ -static struct dvb_pll_desc dvb_pll_fcv1236d = { -/* Bit_0: RF Input select - * Bit_1: 0=digital, 1=analog - */ - .name = "Philips FCV1236D", - .min = 53000000, - .max = 803000000, - .iffreq= 44000000, - .count = 3, - .entries = { - { 159000000, 62500, 0x8e, 0xa0 }, - { 453000000, 62500, 0x8e, 0x90 }, - { 999999999, 62500, 0x8e, 0x30 }, - }, -}; /* ----------------------------------------------------------- */ @@ -523,15 +488,11 @@ static struct dvb_pll_desc *pll_list[] = { [DVB_PLL_UNDEFINED] = NULL, [DVB_PLL_THOMSON_DTT7579] = &dvb_pll_thomson_dtt7579, [DVB_PLL_THOMSON_DTT759X] = &dvb_pll_thomson_dtt759x, - [DVB_PLL_THOMSON_DTT7610] = &dvb_pll_thomson_dtt7610, [DVB_PLL_LG_Z201] = &dvb_pll_lg_z201, - [DVB_PLL_MICROTUNE_4042] = &dvb_pll_microtune_4042, - [DVB_PLL_THOMSON_DTT761X] = &dvb_pll_thomson_dtt761x, [DVB_PLL_UNKNOWN_1] = &dvb_pll_unknown_1, [DVB_PLL_TUA6010XS] = &dvb_pll_tua6010xs, [DVB_PLL_ENV57H1XD5] = &dvb_pll_env57h1xd5, [DVB_PLL_TUA6034] = &dvb_pll_tua6034, - [DVB_PLL_LG_TDVS_H06XF] = &dvb_pll_lg_tdvs_h06xf, [DVB_PLL_TDA665X] = &dvb_pll_tda665x, [DVB_PLL_FMD1216ME] = &dvb_pll_fmd1216me, [DVB_PLL_TDED4] = &dvb_pll_tded4, @@ -540,36 +501,17 @@ static struct dvb_pll_desc *pll_list[] = { [DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv, [DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261, [DVB_PLL_PHILIPS_TD1316] = &dvb_pll_philips_td1316, - [DVB_PLL_THOMSON_FE6600] = &dvb_pll_thomson_fe6600, [DVB_PLL_OPERA1] = &dvb_pll_opera1, - [DVB_PLL_FCV1236D] = &dvb_pll_fcv1236d, -}; - -/* ----------------------------------------------------------- */ - -struct dvb_pll_priv { - /* i2c details */ - int pll_i2c_address; - struct i2c_adapter *i2c; - - /* the PLL descriptor */ - struct dvb_pll_desc *pll_desc; - - /* cached frequency/bandwidth */ - u32 frequency; - u32 bandwidth; }; /* ----------------------------------------------------------- */ /* code */ -static int debug = 0; -module_param(debug, int, 0644); -MODULE_PARM_DESC(debug, "enable verbose debug messages"); - -static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, +static int dvb_pll_configure(struct dvb_frontend *fe, u8 *buf, const struct dvb_frontend_parameters *params) { + struct dvb_pll_priv *priv = fe->tuner_priv; + struct dvb_pll_desc *desc = priv->pll_desc; u32 div; int i; @@ -597,7 +539,7 @@ static int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf, buf[3] = desc->entries[i].cb; if (desc->set) - desc->set(buf, params); + desc->set(fe, buf, params); if (debug) printk("pll: %s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n", @@ -654,7 +596,7 @@ static int dvb_pll_set_params(struct dvb_frontend *fe, if (priv->i2c == NULL) return -EINVAL; - if ((result = dvb_pll_configure(priv->pll_desc, buf, params)) < 0) + if ((result = dvb_pll_configure(fe, buf, params)) < 0) return result; else frequency = result; @@ -682,7 +624,7 @@ static int dvb_pll_calc_regs(struct dvb_frontend *fe, if (buf_len < 5) return -EINVAL; - if ((result = dvb_pll_configure(priv->pll_desc, buf+1, params)) < 0) + if ((result = dvb_pll_configure(fe, buf+1, params)) < 0) return result; else frequency = result; @@ -755,6 +697,10 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, int ret; struct dvb_pll_desc *desc; + if ((id[dvb_pll_devcount] > DVB_PLL_UNDEFINED) && + (id[dvb_pll_devcount] < ARRAY_SIZE(pll_list))) + pll_desc_id = id[dvb_pll_devcount]; + BUG_ON(pll_desc_id < 1 || pll_desc_id >= ARRAY_SIZE(pll_list)); desc = pll_list[pll_desc_id]; @@ -777,6 +723,7 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, priv->pll_i2c_address = pll_addr; priv->i2c = i2c; priv->pll_desc = desc; + priv->nr = dvb_pll_devcount++; memcpy(&fe->ops.tuner_ops, &dvb_pll_tuner_ops, sizeof(struct dvb_tuner_ops)); @@ -784,13 +731,37 @@ struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, strncpy(fe->ops.tuner_ops.info.name, desc->name, sizeof(fe->ops.tuner_ops.info.name)); fe->ops.tuner_ops.info.frequency_min = desc->min; - fe->ops.tuner_ops.info.frequency_min = desc->max; + fe->ops.tuner_ops.info.frequency_max = desc->max; if (!desc->initdata) fe->ops.tuner_ops.init = NULL; if (!desc->sleepdata) fe->ops.tuner_ops.sleep = NULL; fe->tuner_priv = priv; + + if ((debug) || (id[priv->nr] == pll_desc_id)) { + printk("dvb-pll[%d]", priv->nr); + if (i2c != NULL) + printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); + printk(": id# %d (%s) attached, %s\n", pll_desc_id, desc->name, + id[priv->nr] == pll_desc_id ? + "insmod option" : "autodetected"); + } + if ((debug) || (input[priv->nr] > 0)) { + printk("dvb-pll[%d]", priv->nr); + if (i2c != NULL) + printk(" %d-%04x", i2c_adapter_id(i2c), pll_addr); + printk(": tuner rf input will be "); + switch (input[priv->nr]) { + case 0: + printk("autoselected\n"); + break; + default: + printk("set to input %d (insmod option)\n", + input[priv->nr]); + } + } + return fe; } EXPORT_SYMBOL(dvb_pll_attach);