From f21e0d7f0513e743b14df3197fdeeb9a9b7edbb2 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Wed, 2 Jan 2008 03:01:54 -0300 Subject: [PATCH] V4L/DVB (6962): tda18271: allow device-specific configuration of IF frequency and std bits Allow drivers to pass device-specific configuration parameters during attach. If these parameters are omitted, default values will be used. Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda18271-fe.c | 82 +++++++++++++++++-- drivers/media/dvb/frontends/tda18271-priv.h | 23 +----- drivers/media/dvb/frontends/tda18271-tables.c | 18 ++-- drivers/media/dvb/frontends/tda18271.h | 30 ++++++- drivers/media/video/cx23885/cx23885-dvb.c | 12 ++- drivers/media/video/tda8290.c | 6 +- 6 files changed, 131 insertions(+), 40 deletions(-) diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/dvb/frontends/tda18271-fe.c index 537d520de22f..b17ab4ace08c 100644 --- a/drivers/media/dvb/frontends/tda18271-fe.c +++ b/drivers/media/dvb/frontends/tda18271-fe.c @@ -768,12 +768,12 @@ static int tda18271_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params) { struct tda18271_priv *priv = fe->tuner_priv; - struct tda18271_std_map *std_map = priv->std; + struct tda18271_std_map *std_map = &priv->std; u8 std; u32 bw, sgIF = 0; u32 freq = params->frequency; - BUG_ON(!priv->tune || !priv->std); + BUG_ON(!priv->tune); priv->mode = TDA18271_DIGITAL; @@ -832,12 +832,12 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe, struct analog_parameters *params) { struct tda18271_priv *priv = fe->tuner_priv; - struct tda18271_std_map *std_map = priv->std; + struct tda18271_std_map *std_map = &priv->std; char *mode; u8 std; u32 sgIF, freq = params->frequency * 62500; - BUG_ON(!priv->tune || !priv->std); + BUG_ON(!priv->tune); priv->mode = TDA18271_ANALOG; @@ -901,6 +901,69 @@ static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth) return 0; } +/* ------------------------------------------------------------------ */ + +#define tda18271_update_std(std_cfg, name) do { \ + if (map->std_cfg.if_freq + map->std_cfg.std_bits > 0) { \ + tda_dbg("Using custom std config for %s\n", name); \ + memcpy(&std->std_cfg, &map->std_cfg, \ + sizeof(struct tda18271_std_map_item)); \ + } } while (0) + +#define tda18271_dump_std_item(std_cfg, name) do { \ + tda_dbg("(%s) if freq = %d, std bits = 0x%02x\n", \ + name, std->std_cfg.if_freq, std->std_cfg.std_bits); \ + } while (0) + +static int tda18271_dump_std_map(struct dvb_frontend *fe) +{ + struct tda18271_priv *priv = fe->tuner_priv; + struct tda18271_std_map *std = &priv->std; + + tda_dbg("========== STANDARD MAP SETTINGS ==========\n"); + tda18271_dump_std_item(atv_b, "pal b"); + tda18271_dump_std_item(atv_dk, "pal dk"); + tda18271_dump_std_item(atv_gh, "pal gh"); + tda18271_dump_std_item(atv_i, "pal i"); + tda18271_dump_std_item(atv_l, "pal l"); + tda18271_dump_std_item(atv_lc, "pal l'"); + tda18271_dump_std_item(atv_mn, "atv mn"); + tda18271_dump_std_item(atsc_6, "atsc 6"); + tda18271_dump_std_item(dvbt_6, "dvbt 6"); + tda18271_dump_std_item(dvbt_7, "dvbt 7"); + tda18271_dump_std_item(dvbt_8, "dvbt 8"); + tda18271_dump_std_item(qam_6, "qam 6"); + tda18271_dump_std_item(qam_8, "qam 8"); + + return 0; +} + +static int tda18271_update_std_map(struct dvb_frontend *fe, + struct tda18271_std_map *map) +{ + struct tda18271_priv *priv = fe->tuner_priv; + struct tda18271_std_map *std = &priv->std; + + if (!map) + return -EINVAL; + + tda18271_update_std(atv_b, "atv b"); + tda18271_update_std(atv_dk, "atv dk"); + tda18271_update_std(atv_gh, "atv gh"); + tda18271_update_std(atv_i, "atv i"); + tda18271_update_std(atv_l, "atv l"); + tda18271_update_std(atv_lc, "atv l'"); + tda18271_update_std(atv_mn, "atv mn"); + tda18271_update_std(atsc_6, "atsc 6"); + tda18271_update_std(dvbt_6, "dvbt 6"); + tda18271_update_std(dvbt_7, "dvbt 7"); + tda18271_update_std(dvbt_8, "dvbt 8"); + tda18271_update_std(qam_6, "qam 6"); + tda18271_update_std(qam_8, "qam 8"); + + return 0; +} + static int tda18271_get_id(struct dvb_frontend *fe) { struct tda18271_priv *priv = fe->tuner_priv; @@ -951,7 +1014,7 @@ static struct dvb_tuner_ops tda18271_tuner_ops = { struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, struct i2c_adapter *i2c, - enum tda18271_i2c_gate gate) + struct tda18271_config *cfg) { struct tda18271_priv *priv = NULL; @@ -961,7 +1024,7 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, priv->i2c_addr = addr; priv->i2c_adap = i2c; - priv->gate = gate; + priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->cal_initialized = false; fe->tuner_priv = priv; @@ -975,6 +1038,13 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops, sizeof(struct dvb_tuner_ops)); + /* override default std map with values in config struct */ + if ((cfg) && (cfg->std_map)) + tda18271_update_std_map(fe, cfg->std_map); + + if (tda18271_debug & DBG_MAP) + tda18271_dump_std_map(fe); + tda18271_init_regs(fe); return fe; diff --git a/drivers/media/dvb/frontends/tda18271-priv.h b/drivers/media/dvb/frontends/tda18271-priv.h index deb375ea253e..6e04258ca6f9 100644 --- a/drivers/media/dvb/frontends/tda18271-priv.h +++ b/drivers/media/dvb/frontends/tda18271-priv.h @@ -84,27 +84,6 @@ struct tda18271_rf_tracking_filter_cal { int rf_b2; }; -struct tda18271_std_map_item { - u32 if_freq; - u8 std_bits; -}; - -struct tda18271_std_map { - struct tda18271_std_map_item atv_b; - struct tda18271_std_map_item atv_dk; - struct tda18271_std_map_item atv_gh; - struct tda18271_std_map_item atv_i; - struct tda18271_std_map_item atv_l; - struct tda18271_std_map_item atv_lc; - struct tda18271_std_map_item atv_mn; - struct tda18271_std_map_item atsc_6; - struct tda18271_std_map_item dvbt_6; - struct tda18271_std_map_item dvbt_7; - struct tda18271_std_map_item dvbt_8; - struct tda18271_std_map_item qam_6; - struct tda18271_std_map_item qam_8; -}; - enum tda18271_mode { TDA18271_ANALOG, TDA18271_DIGITAL, @@ -128,8 +107,8 @@ struct tda18271_priv { unsigned int cal_initialized:1; - struct tda18271_std_map *std; struct tda18271_map_layout *maps; + struct tda18271_std_map std; struct tda18271_rf_tracking_filter_cal rf_cal_state[8]; int (*tune) (struct dvb_frontend *fe, diff --git a/drivers/media/dvb/frontends/tda18271-tables.c b/drivers/media/dvb/frontends/tda18271-tables.c index 46f1d4ddda34..2f8ea72bcabb 100644 --- a/drivers/media/dvb/frontends/tda18271-tables.c +++ b/drivers/media/dvb/frontends/tda18271-tables.c @@ -1194,11 +1194,11 @@ static struct tda18271_std_map tda18271c1_std_map = { .atv_l = { .if_freq = 7750000, .std_bits = 0x0f }, .atv_lc = { .if_freq = 1250000, .std_bits = 0x0f }, .atv_mn = { .if_freq = 5750000, .std_bits = 0x0d }, - .atsc_6 = { .if_freq = 5380000, .std_bits = 0x1b }, - .dvbt_6 = { .if_freq = 3300000, .std_bits = 0x1b }, - .dvbt_7 = { .if_freq = 3800000, .std_bits = 0x19 }, - .dvbt_8 = { .if_freq = 4300000, .std_bits = 0x1a }, - .qam_6 = { .if_freq = 4000000, .std_bits = 0x18 }, + .atsc_6 = { .if_freq = 3250000, .std_bits = 0x1c }, + .dvbt_6 = { .if_freq = 3300000, .std_bits = 0x1c }, + .dvbt_7 = { .if_freq = 3800000, .std_bits = 0x1d }, + .dvbt_8 = { .if_freq = 4300000, .std_bits = 0x1e }, + .qam_6 = { .if_freq = 4000000, .std_bits = 0x1d }, .qam_8 = { .if_freq = 5000000, .std_bits = 0x1f }, }; @@ -1210,7 +1210,7 @@ static struct tda18271_std_map tda18271c2_std_map = { .atv_l = { .if_freq = 6900000, .std_bits = 0x0e }, .atv_lc = { .if_freq = 1250000, .std_bits = 0x0e }, .atv_mn = { .if_freq = 5400000, .std_bits = 0x0c }, - .atsc_6 = { .if_freq = 5380000, .std_bits = 0x1b }, + .atsc_6 = { .if_freq = 3250000, .std_bits = 0x1c }, .dvbt_6 = { .if_freq = 3300000, .std_bits = 0x1c }, .dvbt_7 = { .if_freq = 3500000, .std_bits = 0x1c }, .dvbt_8 = { .if_freq = 4000000, .std_bits = 0x1d }, @@ -1256,11 +1256,13 @@ int tda18271_assign_map_layout(struct dvb_frontend *fe) switch (priv->id) { case TDA18271HDC1: priv->maps = &tda18271c1_map_layout; - priv->std = &tda18271c1_std_map; + memcpy(&priv->std, &tda18271c1_std_map, + sizeof(struct tda18271_std_map)); break; case TDA18271HDC2: priv->maps = &tda18271c2_map_layout; - priv->std = &tda18271c2_std_map; + memcpy(&priv->std, &tda18271c2_std_map, + sizeof(struct tda18271_std_map)); break; default: ret = -EINVAL; diff --git a/drivers/media/dvb/frontends/tda18271.h b/drivers/media/dvb/frontends/tda18271.h index f53568103311..36a3a548a6f5 100644 --- a/drivers/media/dvb/frontends/tda18271.h +++ b/drivers/media/dvb/frontends/tda18271.h @@ -24,21 +24,47 @@ #include #include "dvb_frontend.h" +struct tda18271_std_map_item { + u32 if_freq; + u8 std_bits; +}; + +struct tda18271_std_map { + struct tda18271_std_map_item atv_b; + struct tda18271_std_map_item atv_dk; + struct tda18271_std_map_item atv_gh; + struct tda18271_std_map_item atv_i; + struct tda18271_std_map_item atv_l; + struct tda18271_std_map_item atv_lc; + struct tda18271_std_map_item atv_mn; + struct tda18271_std_map_item atsc_6; + struct tda18271_std_map_item dvbt_6; + struct tda18271_std_map_item dvbt_7; + struct tda18271_std_map_item dvbt_8; + struct tda18271_std_map_item qam_6; + struct tda18271_std_map_item qam_8; +}; + enum tda18271_i2c_gate { TDA18271_GATE_AUTO = 0, TDA18271_GATE_ANALOG, TDA18271_GATE_DIGITAL, }; +struct tda18271_config { + struct tda18271_std_map *std_map; + enum tda18271_i2c_gate gate; +}; + #if defined(CONFIG_DVB_TDA18271) || (defined(CONFIG_DVB_TDA18271_MODULE) && defined(MODULE)) extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, struct i2c_adapter *i2c, - enum tda18271_i2c_gate gate); + struct tda18271_config *cfg); #else static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, struct i2c_adapter *i2c, - enum tda18271_i2c_gate gate) + struct tda18271_config *cfg) { printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__); return NULL; diff --git a/drivers/media/video/cx23885/cx23885-dvb.c b/drivers/media/video/cx23885/cx23885-dvb.c index 81dd47f6f654..948a7fb7ed06 100644 --- a/drivers/media/video/cx23885/cx23885-dvb.c +++ b/drivers/media/video/cx23885/cx23885-dvb.c @@ -183,6 +183,16 @@ static struct tda829x_config tda829x_no_probe = { .probe_tuner = TDA829X_DONT_PROBE, }; +static struct tda18271_std_map hauppauge_tda18271_std_map = { + .atsc_6 = { .if_freq = 5380000, .std_bits = 0x1b }, + .qam_6 = { .if_freq = 4000000, .std_bits = 0x18 }, +}; + +static struct tda18271_config hauppauge_tda18271_config = { + .std_map = &hauppauge_tda18271_std_map, + .gate = TDA18271_GATE_ANALOG, +}; + static int cx23885_hvr1500_xc3028_callback(void *ptr, int command, int arg) { struct cx23885_tsport *port = ptr; @@ -248,7 +258,7 @@ static int dvb_register(struct cx23885_tsport *port) &tda829x_no_probe); dvb_attach(tda18271_attach, port->dvb.frontend, 0x60, &dev->i2c_bus[1].i2c_adap, - TDA18271_GATE_ANALOG); + &hauppauge_tda18271_config); } break; case 0: diff --git a/drivers/media/video/tda8290.c b/drivers/media/video/tda8290.c index 54d261a2f25a..eab530708a49 100644 --- a/drivers/media/video/tda8290.c +++ b/drivers/media/video/tda8290.c @@ -509,6 +509,10 @@ static void tda829x_release(struct dvb_frontend *fe) fe->analog_demod_priv = NULL; } +static struct tda18271_config tda829x_tda18271_config = { + .gate = TDA18271_GATE_ANALOG, +}; + static int tda829x_find_tuner(struct dvb_frontend *fe) { struct tda8290_priv *priv = fe->analog_demod_priv; @@ -574,7 +578,7 @@ static int tda829x_find_tuner(struct dvb_frontend *fe) priv->ver |= TDA18271; tda18271_attach(fe, priv->tda827x_addr, priv->i2c_props.adap, - TDA18271_GATE_ANALOG); + &tda829x_tda18271_config); } else { if ((data & 0x3c) == 0) priv->ver |= TDA8275; -- 2.39.5