summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/au8522_dig.c
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-11 07:00:36 +0100
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 17:43:24 +0200
commit209fdf66b8699a6b2998b58e572d67230dae507f (patch)
treea2b287bf353d610d50b1d041d15e3f8a927fe70c /drivers/media/dvb/frontends/au8522_dig.c
parentV4L/DVB (11063): au8522: power down the digital demod when not in use (diff)
downloadlinux-209fdf66b8699a6b2998b58e572d67230dae507f.tar.xz
linux-209fdf66b8699a6b2998b58e572d67230dae507f.zip
V4L/DVB (11064): au8522: make use of hybrid framework so analog/digital demod can share state
Make use of the hybrid tuner framework so the analog and digital parts of the au8522 demodulator can make use of the same shared state. Thanks to Michael Krufky <mkrufky@linuxtv.org> and Steven Toth <stoth@linuxtv.org> for providing sample hardware, engineering level support, and testing. Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/frontends/au8522_dig.c')
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c45
1 files changed, 38 insertions, 7 deletions
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c
index fa3ecbed1e58..b04346687c68 100644
--- a/drivers/media/dvb/frontends/au8522_dig.c
+++ b/drivers/media/dvb/frontends/au8522_dig.c
@@ -31,6 +31,10 @@
static int debug;
+/* Despite the name "hybrid_tuner", the framework works just as well for
+ hybrid demodulators as well... */
+static LIST_HEAD(hybrid_tuner_instance_list);
+
#define dprintk(arg...) do { \
if (debug) \
printk(arg); \
@@ -786,23 +790,50 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
return 0;
}
+static struct dvb_frontend_ops au8522_ops;
+
+int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
+ u8 client_address)
+{
+ return hybrid_tuner_request_state(struct au8522_state, (*state),
+ hybrid_tuner_instance_list,
+ i2c, client_address, "au8522");
+}
+
+void au8522_release_state(struct au8522_state *state)
+{
+ if (state != NULL)
+ hybrid_tuner_release_state(state);
+}
+
+
static void au8522_release(struct dvb_frontend *fe)
{
struct au8522_state *state = fe->demodulator_priv;
- kfree(state);
+ au8522_release_state(state);
}
-static struct dvb_frontend_ops au8522_ops;
-
struct dvb_frontend *au8522_attach(const struct au8522_config *config,
struct i2c_adapter *i2c)
{
struct au8522_state *state = NULL;
+ int instance;
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
- if (state == NULL)
- goto error;
+ instance = au8522_get_state(&state, i2c, config->demod_address);
+ switch (instance) {
+ case 0:
+ dprintk("%s state allocation failed\n", __func__);
+ break;
+ case 1:
+ /* new demod instance */
+ dprintk("%s using new instance\n", __func__);
+ break;
+ default:
+ /* existing demod instance */
+ dprintk("%s using existing instance\n", __func__);
+ break;
+ }
/* setup the state */
state->config = config;
@@ -824,7 +855,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
return &state->frontend;
error:
- kfree(state);
+ au8522_release_state(state);
return NULL;
}
EXPORT_SYMBOL(au8522_attach);