1
0
Fork 0

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: Michael Krufky <mkrufky@linuxtv.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
hifive-unleashed-5.1
Michael Krufky 2008-04-22 14:41:54 -03:00 committed by Mauro Carvalho Chehab
parent 2756665c28
commit f9e315a16a
3 changed files with 37 additions and 55 deletions

View File

@ -125,16 +125,16 @@ int tda18271_read_regs(struct dvb_frontend *fe)
unsigned char buf = 0x00;
int ret;
struct i2c_msg msg[] = {
{ .addr = priv->i2c_addr, .flags = 0,
{ .addr = priv->i2c_props.addr, .flags = 0,
.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 }
};
tda18271_i2c_gate_ctrl(fe, 1);
/* 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);
@ -155,16 +155,16 @@ int tda18271_read_extended(struct dvb_frontend *fe)
unsigned char buf = 0x00;
int ret, i;
struct i2c_msg msg[] = {
{ .addr = priv->i2c_addr, .flags = 0,
{ .addr = priv->i2c_props.addr, .flags = 0,
.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 }
};
tda18271_i2c_gate_ctrl(fe, 1);
/* 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);
@ -192,7 +192,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
struct tda18271_priv *priv = fe->tuner_priv;
unsigned char *regs = priv->tda18271_regs;
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 };
int i, ret;
@ -205,7 +205,7 @@ int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
tda18271_i2c_gate_ctrl(fe, 1);
/* 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);
@ -223,7 +223,8 @@ int tda18271_init_regs(struct dvb_frontend *fe)
unsigned char *regs = priv->tda18271_regs;
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 */
switch (priv->id) {

View File

@ -31,8 +31,8 @@ static int tda18271_cal_on_startup;
module_param_named(cal, tda18271_cal_on_startup, int, 0644);
MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
static LIST_HEAD(tda18271_list);
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)
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);
fe->tuner_priv = NULL;
@ -1109,7 +1102,8 @@ static int tda18271_get_id(struct dvb_frontend *fe)
}
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.");
return ret;
@ -1136,46 +1130,25 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
struct tda18271_config *cfg)
{
struct tda18271_priv *priv = NULL;
int state_found = 0;
int instance;
mutex_lock(&tda18271_list_mutex);
list_for_each_entry(priv, &tda18271_list, tda18271_list) {
if ((i2c_adapter_id(priv->i2c_adap) == i2c_adapter_id(i2c)) &&
(priv->i2c_addr == addr)) {
tda_dbg("attaching existing tuner @ %d-%04x\n",
i2c_adapter_id(priv->i2c_adap),
priv->i2c_addr);
priv->count++;
fe->tuner_priv = priv;
state_found = 1;
/* 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;
instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
hybrid_tuner_instance_list,
i2c, addr, "tda18271");
switch (instance) {
case 0:
goto fail;
break;
case 1:
/* new tuner instance */
priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
priv->cal_initialized = false;
mutex_init(&priv->lock);
priv->count++;
fe->tuner_priv = priv;
list_add_tail(&priv->tda18271_list, &tda18271_list);
if (tda18271_get_id(fe) < 0)
goto fail;
@ -1189,6 +1162,15 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
tda18271_rf_cal_init(fe);
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 */

View File

@ -24,6 +24,7 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include "tuner-i2c.h"
#include "tda18271.h"
#define R_ID 0x00 /* ID byte */
@ -98,17 +99,15 @@ enum tda18271_ver {
};
struct tda18271_priv {
u8 i2c_addr;
struct i2c_adapter *i2c_adap;
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_i2c_gate gate;
enum tda18271_ver id;
unsigned int count;
unsigned int tm_rfcal;
unsigned int cal_initialized:1;