From c353f42f752d9b47661ff83b947986f6de948b61 Mon Sep 17 00:00:00 2001 From: Michael Krufky Date: Tue, 8 Jan 2008 10:38:10 -0300 Subject: V4L/DVB (6987): tda18271: add support for fm radio Signed-off-by: Michael Krufky Signed-off-by: Mauro Carvalho Chehab --- drivers/media/dvb/frontends/tda18271-fe.c | 42 ++++++++++++++++++--------- drivers/media/dvb/frontends/tda18271-tables.c | 2 ++ drivers/media/dvb/frontends/tda18271.h | 1 + 3 files changed, 32 insertions(+), 13 deletions(-) (limited to 'drivers/media') diff --git a/drivers/media/dvb/frontends/tda18271-fe.c b/drivers/media/dvb/frontends/tda18271-fe.c index aa93e155062..7d218819b28 100644 --- a/drivers/media/dvb/frontends/tda18271-fe.c +++ b/drivers/media/dvb/frontends/tda18271-fe.c @@ -49,7 +49,8 @@ static int tda18271_ir_cal_init(struct dvb_frontend *fe) /* ------------------------------------------------------------------ */ static int tda18271_channel_configuration(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std) + u32 ifc, u32 freq, u32 bw, u8 std, + int radio) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; @@ -76,7 +77,11 @@ static int tda18271_channel_configuration(struct dvb_frontend *fe, regs[R_MPD] |= 0x80; /* IF notch = 1 */ break; } - regs[R_EP4] &= ~0x80; /* FM_RFn: turn this bit on only for fm radio */ + + if (radio) + regs[R_EP4] |= 0x80; + else + regs[R_EP4] &= ~0x80; /* update RF_TOP / IF_TOP */ switch (priv->mode) { @@ -615,7 +620,7 @@ static int tda18271_init(struct dvb_frontend *fe) } static int tda18271c2_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std) + u32 ifc, u32 freq, u32 bw, u8 std, int radio) { struct tda18271_priv *priv = fe->tuner_priv; @@ -627,7 +632,7 @@ static int tda18271c2_tune(struct dvb_frontend *fe, tda18271_rf_tracking_filters_correction(fe, freq); - tda18271_channel_configuration(fe, ifc, freq, bw, std); + tda18271_channel_configuration(fe, ifc, freq, bw, std, radio); mutex_unlock(&priv->lock); @@ -637,7 +642,7 @@ static int tda18271c2_tune(struct dvb_frontend *fe, /* ------------------------------------------------------------------ */ static int tda18271c1_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std) + u32 ifc, u32 freq, u32 bw, u8 std, int radio) { struct tda18271_priv *priv = fe->tuner_priv; unsigned char *regs = priv->tda18271_regs; @@ -769,7 +774,10 @@ static int tda18271c1_tune(struct dvb_frontend *fe, break; } - regs[R_EP4] &= ~0x80; /* turn this bit on only for fm */ + if (radio) + regs[R_EP4] |= 0x80; + else + regs[R_EP4] &= ~0x80; /* image rejection validity */ tda18271_calc_ir_measure(fe, &freq); @@ -787,17 +795,17 @@ static int tda18271c1_tune(struct dvb_frontend *fe, } static inline int tda18271_tune(struct dvb_frontend *fe, - u32 ifc, u32 freq, u32 bw, u8 std) + u32 ifc, u32 freq, u32 bw, u8 std, int radio) { struct tda18271_priv *priv = fe->tuner_priv; int ret = -EINVAL; switch (priv->id) { case TDA18271HDC1: - ret = tda18271c1_tune(fe, ifc, freq, bw, std); + ret = tda18271c1_tune(fe, ifc, freq, bw, std, radio); break; case TDA18271HDC2: - ret = tda18271c2_tune(fe, ifc, freq, bw, std); + ret = tda18271c2_tune(fe, ifc, freq, bw, std, radio); break; } return ret; @@ -865,7 +873,7 @@ static int tda18271_set_params(struct dvb_frontend *fe, return -EINVAL; } - ret = tda18271_tune(fe, sgIF * 1000, freq, bw, std); + ret = tda18271_tune(fe, sgIF * 1000, freq, bw, std, 0); if (ret < 0) goto fail; @@ -883,14 +891,20 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe, struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_std_map *std_map = &priv->std; char *mode; - int ret; + int ret, radio = 0; u8 std; u16 sgIF; u32 freq = params->frequency * 62500; priv->mode = TDA18271_ANALOG; - if (params->std & V4L2_STD_MN) { + if (params->mode == V4L2_TUNER_RADIO) { + radio = 1; + freq = freq / 1000; + std = std_map->fm_radio.std_bits; + sgIF = std_map->fm_radio.if_freq; + mode = "fm"; + } else if (params->std & V4L2_STD_MN) { std = std_map->atv_mn.std_bits; sgIF = std_map->atv_mn.if_freq; mode = "MN"; @@ -926,7 +940,7 @@ static int tda18271_set_analog_params(struct dvb_frontend *fe, tda_dbg("setting tda18271 to system %s\n", mode); - ret = tda18271_tune(fe, sgIF * 1000, freq, 0, std); + ret = tda18271_tune(fe, sgIF * 1000, freq, 0, std, radio); if (ret < 0) goto fail; @@ -994,6 +1008,7 @@ static int tda18271_dump_std_map(struct dvb_frontend *fe) struct tda18271_std_map *std = &priv->std; tda_dbg("========== STANDARD MAP SETTINGS ==========\n"); + tda18271_dump_std_item(fm_radio, "fm"); tda18271_dump_std_item(atv_b, "pal b"); tda18271_dump_std_item(atv_dk, "pal dk"); tda18271_dump_std_item(atv_gh, "pal gh"); @@ -1020,6 +1035,7 @@ static int tda18271_update_std_map(struct dvb_frontend *fe, if (!map) return -EINVAL; + tda18271_update_std(fm_radio, "fm"); tda18271_update_std(atv_b, "atv b"); tda18271_update_std(atv_dk, "atv dk"); tda18271_update_std(atv_gh, "atv gh"); diff --git a/drivers/media/dvb/frontends/tda18271-tables.c b/drivers/media/dvb/frontends/tda18271-tables.c index 0402c7dab19..e94afcfdc5b 100644 --- a/drivers/media/dvb/frontends/tda18271-tables.c +++ b/drivers/media/dvb/frontends/tda18271-tables.c @@ -1187,6 +1187,7 @@ fail: /*---------------------------------------------------------------------*/ static struct tda18271_std_map tda18271c1_std_map = { + .fm_radio = { .if_freq = 1250, .std_bits = 0x18 }, .atv_b = { .if_freq = 6750, .std_bits = 0x0e }, .atv_dk = { .if_freq = 7750, .std_bits = 0x0f }, .atv_gh = { .if_freq = 7750, .std_bits = 0x0f }, @@ -1203,6 +1204,7 @@ static struct tda18271_std_map tda18271c1_std_map = { }; static struct tda18271_std_map tda18271c2_std_map = { + .fm_radio = { .if_freq = 1250, .std_bits = 0x18 }, .atv_b = { .if_freq = 6000, .std_bits = 0x0d }, .atv_dk = { .if_freq = 6900, .std_bits = 0x0e }, .atv_gh = { .if_freq = 7100, .std_bits = 0x0e }, diff --git a/drivers/media/dvb/frontends/tda18271.h b/drivers/media/dvb/frontends/tda18271.h index 9ccfa6e8b5a..24b0e35a2ab 100644 --- a/drivers/media/dvb/frontends/tda18271.h +++ b/drivers/media/dvb/frontends/tda18271.h @@ -30,6 +30,7 @@ struct tda18271_std_map_item { }; struct tda18271_std_map { + struct tda18271_std_map_item fm_radio; struct tda18271_std_map_item atv_b; struct tda18271_std_map_item atv_dk; struct tda18271_std_map_item atv_gh; -- cgit v1.2.3