提交 f9e315a1 编写于 作者: M Michael Krufky 提交者: Mauro Carvalho Chehab

V4L/DVB (7136): tda18271: use hybrid_tuner_request_state to manage tuner instances

Convert tda18271 to use the new hybrid_tuner_request_state and
hybrid_tuner_release_state macros to manage state sharing between
hybrid tuner instances.
Signed-off-by: NMichael Krufky <mkrufky@linuxtv.org>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 2756665c
...@@ -125,16 +125,16 @@ int tda18271_read_regs(struct dvb_frontend *fe) ...@@ -125,16 +125,16 @@ int tda18271_read_regs(struct dvb_frontend *fe)
unsigned char buf = 0x00; unsigned char buf = 0x00;
int ret; int ret;
struct i2c_msg msg[] = { struct i2c_msg msg[] = {
{ .addr = priv->i2c_addr, .flags = 0, { .addr = priv->i2c_props.addr, .flags = 0,
.buf = &buf, .len = 1 }, .buf = &buf, .len = 1 },
{ .addr = priv->i2c_addr, .flags = I2C_M_RD, { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
.buf = regs, .len = 16 } .buf = regs, .len = 16 }
}; };
tda18271_i2c_gate_ctrl(fe, 1); tda18271_i2c_gate_ctrl(fe, 1);
/* read all registers */ /* read all registers */
ret = i2c_transfer(priv->i2c_adap, msg, 2); ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
tda18271_i2c_gate_ctrl(fe, 0); tda18271_i2c_gate_ctrl(fe, 0);
...@@ -155,16 +155,16 @@ int tda18271_read_extended(struct dvb_frontend *fe) ...@@ -155,16 +155,16 @@ int tda18271_read_extended(struct dvb_frontend *fe)
unsigned char buf = 0x00; unsigned char buf = 0x00;
int ret, i; int ret, i;
struct i2c_msg msg[] = { struct i2c_msg msg[] = {
{ .addr = priv->i2c_addr, .flags = 0, { .addr = priv->i2c_props.addr, .flags = 0,
.buf = &buf, .len = 1 }, .buf = &buf, .len = 1 },
{ .addr = priv->i2c_addr, .flags = I2C_M_RD, { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
.buf = regdump, .len = TDA18271_NUM_REGS } .buf = regdump, .len = TDA18271_NUM_REGS }
}; };
tda18271_i2c_gate_ctrl(fe, 1); tda18271_i2c_gate_ctrl(fe, 1);
/* read all registers */ /* read all registers */
ret = i2c_transfer(priv->i2c_adap, msg, 2); ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
tda18271_i2c_gate_ctrl(fe, 0); tda18271_i2c_gate_ctrl(fe, 0);
...@@ -192,7 +192,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) ...@@ -192,7 +192,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
struct tda18271_priv *priv = fe->tuner_priv; struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs; unsigned char *regs = priv->tda18271_regs;
unsigned char buf[TDA18271_NUM_REGS + 1]; unsigned char buf[TDA18271_NUM_REGS + 1];
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0, struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
.buf = buf, .len = len + 1 }; .buf = buf, .len = len + 1 };
int i, ret; int i, ret;
...@@ -205,7 +205,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len) ...@@ -205,7 +205,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
tda18271_i2c_gate_ctrl(fe, 1); tda18271_i2c_gate_ctrl(fe, 1);
/* write registers */ /* write registers */
ret = i2c_transfer(priv->i2c_adap, &msg, 1); ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
tda18271_i2c_gate_ctrl(fe, 0); tda18271_i2c_gate_ctrl(fe, 0);
...@@ -223,7 +223,8 @@ int tda18271_init_regs(struct dvb_frontend *fe) ...@@ -223,7 +223,8 @@ int tda18271_init_regs(struct dvb_frontend *fe)
unsigned char *regs = priv->tda18271_regs; unsigned char *regs = priv->tda18271_regs;
tda_dbg("initializing registers for device @ %d-%04x\n", tda_dbg("initializing registers for device @ %d-%04x\n",
i2c_adapter_id(priv->i2c_adap), priv->i2c_addr); i2c_adapter_id(priv->i2c_props.adap),
priv->i2c_props.addr);
/* initialize registers */ /* initialize registers */
switch (priv->id) { switch (priv->id) {
......
...@@ -31,8 +31,8 @@ static int tda18271_cal_on_startup; ...@@ -31,8 +31,8 @@ static int tda18271_cal_on_startup;
module_param_named(cal, tda18271_cal_on_startup, int, 0644); module_param_named(cal, tda18271_cal_on_startup, int, 0644);
MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup"); MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
static LIST_HEAD(tda18271_list);
static DEFINE_MUTEX(tda18271_list_mutex); static DEFINE_MUTEX(tda18271_list_mutex);
static LIST_HEAD(hybrid_tuner_instance_list);
/*---------------------------------------------------------------------*/ /*---------------------------------------------------------------------*/
...@@ -986,16 +986,9 @@ static int tda18271_release(struct dvb_frontend *fe) ...@@ -986,16 +986,9 @@ static int tda18271_release(struct dvb_frontend *fe)
mutex_lock(&tda18271_list_mutex); mutex_lock(&tda18271_list_mutex);
priv->count--; if (priv)
hybrid_tuner_release_state(priv);
if (!priv->count) {
tda_dbg("destroying instance @ %d-%04x\n",
i2c_adapter_id(priv->i2c_adap),
priv->i2c_addr);
list_del(&priv->tda18271_list);
kfree(priv);
}
mutex_unlock(&tda18271_list_mutex); mutex_unlock(&tda18271_list_mutex);
fe->tuner_priv = NULL; fe->tuner_priv = NULL;
...@@ -1109,7 +1102,8 @@ static int tda18271_get_id(struct dvb_frontend *fe) ...@@ -1109,7 +1102,8 @@ static int tda18271_get_id(struct dvb_frontend *fe)
} }
tda_info("%s detected @ %d-%04x%s\n", name, tda_info("%s detected @ %d-%04x%s\n", name,
i2c_adapter_id(priv->i2c_adap), priv->i2c_addr, i2c_adapter_id(priv->i2c_props.adap),
priv->i2c_props.addr,
(0 == ret) ? "" : ", device not supported."); (0 == ret) ? "" : ", device not supported.");
return ret; return ret;
...@@ -1136,46 +1130,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, ...@@ -1136,46 +1130,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
struct tda18271_config *cfg) struct tda18271_config *cfg)
{ {
struct tda18271_priv *priv = NULL; struct tda18271_priv *priv = NULL;
int state_found = 0; int instance;
mutex_lock(&tda18271_list_mutex); mutex_lock(&tda18271_list_mutex);
list_for_each_entry(priv, &tda18271_list, tda18271_list) { instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
if ((i2c_adapter_id(priv->i2c_adap) == i2c_adapter_id(i2c)) && hybrid_tuner_instance_list,
(priv->i2c_addr == addr)) { i2c, addr, "tda18271");
tda_dbg("attaching existing tuner @ %d-%04x\n", switch (instance) {
i2c_adapter_id(priv->i2c_adap), case 0:
priv->i2c_addr); goto fail;
priv->count++; break;
fe->tuner_priv = priv; case 1:
state_found = 1; /* new tuner instance */
/* allow dvb driver to override i2c gate setting */
if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
priv->gate = cfg->gate;
break;
}
}
if (state_found == 0) {
tda_dbg("creating new tuner instance @ %d-%04x\n",
i2c_adapter_id(i2c), addr);
priv = kzalloc(sizeof(struct tda18271_priv), GFP_KERNEL);
if (priv == NULL) {
mutex_unlock(&tda18271_list_mutex);
return NULL;
}
priv->i2c_addr = addr;
priv->i2c_adap = i2c;
priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
priv->cal_initialized = false; priv->cal_initialized = false;
mutex_init(&priv->lock); mutex_init(&priv->lock);
priv->count++;
fe->tuner_priv = priv; fe->tuner_priv = priv;
list_add_tail(&priv->tda18271_list, &tda18271_list);
if (tda18271_get_id(fe) < 0) if (tda18271_get_id(fe) < 0)
goto fail; goto fail;
...@@ -1189,6 +1162,15 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr, ...@@ -1189,6 +1162,15 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
tda18271_rf_cal_init(fe); tda18271_rf_cal_init(fe);
mutex_unlock(&priv->lock); mutex_unlock(&priv->lock);
break;
default:
/* existing tuner instance */
fe->tuner_priv = priv;
/* allow dvb driver to override i2c gate setting */
if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
priv->gate = cfg->gate;
break;
} }
/* override default std map with values in config struct */ /* override default std map with values in config struct */
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include "tuner-i2c.h"
#include "tda18271.h" #include "tda18271.h"
#define R_ID 0x00 /* ID byte */ #define R_ID 0x00 /* ID byte */
...@@ -98,17 +99,15 @@ enum tda18271_ver { ...@@ -98,17 +99,15 @@ enum tda18271_ver {
}; };
struct tda18271_priv { struct tda18271_priv {
u8 i2c_addr;
struct i2c_adapter *i2c_adap;
unsigned char tda18271_regs[TDA18271_NUM_REGS]; unsigned char tda18271_regs[TDA18271_NUM_REGS];
struct list_head tda18271_list; struct list_head hybrid_tuner_instance_list;
struct tuner_i2c_props i2c_props;
enum tda18271_mode mode; enum tda18271_mode mode;
enum tda18271_i2c_gate gate; enum tda18271_i2c_gate gate;
enum tda18271_ver id; enum tda18271_ver id;
unsigned int count;
unsigned int tm_rfcal; unsigned int tm_rfcal;
unsigned int cal_initialized:1; unsigned int cal_initialized:1;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册