Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f21e0d7f authored by Michael Krufky's avatar Michael Krufky Committed by Mauro Carvalho Chehab
Browse files

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: default avatarMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 59067f7e
Loading
Loading
Loading
Loading
+76 −6
Original line number Diff line number Diff line
@@ -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;
+1 −22
Original line number Diff line number Diff line
@@ -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,
+10 −8
Original line number Diff line number Diff line
@@ -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;
+28 −2
Original line number Diff line number Diff line
@@ -24,21 +24,47 @@
#include <linux/i2c.h>
#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;
+11 −1
Original line number Diff line number Diff line
@@ -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:
Loading