diff options
author | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-11 02:00:36 -0400 |
---|---|---|
committer | Devin Heitmueller <dheitmueller@linuxtv.org> | 2009-03-11 02:00:36 -0400 |
commit | 552d2a4fdce766a81187b285e8114ee089b7a721 (patch) | |
tree | 7df364df166f32bc097e949e3aa54d7599c08e23 | |
parent | c55d671ee9eb267b04c218863cd9a577fa036dbc (diff) | |
download | mediapointer-dvb-s2-552d2a4fdce766a81187b285e8114ee089b7a721.tar.gz mediapointer-dvb-s2-552d2a4fdce766a81187b285e8114ee089b7a721.tar.bz2 |
au8522: make use of hybrid framework so analog/digital demod can share state
From: Devin Heitmueller <dheitmueller@linuxtv.org>
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.
Priority: normal
Signed-off-by: Devin Heitmueller <dheitmueller@linuxtv.org>
Signed-off-by: Michael Krufky <mkrufky@linuxtv.org>
-rw-r--r-- | linux/drivers/media/dvb/frontends/au8522_dig.c | 45 | ||||
-rw-r--r-- | linux/drivers/media/dvb/frontends/au8522_priv.h | 8 |
2 files changed, 46 insertions, 7 deletions
diff --git a/linux/drivers/media/dvb/frontends/au8522_dig.c b/linux/drivers/media/dvb/frontends/au8522_dig.c index a78636286..00d783ce2 100644 --- a/linux/drivers/media/dvb/frontends/au8522_dig.c +++ b/linux/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; @@ -830,7 +861,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); diff --git a/linux/drivers/media/dvb/frontends/au8522_priv.h b/linux/drivers/media/dvb/frontends/au8522_priv.h index 569675d29..98b09caa2 100644 --- a/linux/drivers/media/dvb/frontends/au8522_priv.h +++ b/linux/drivers/media/dvb/frontends/au8522_priv.h @@ -37,6 +37,10 @@ struct au8522_state { struct i2c_adapter *i2c; + /* Used for sharing of the state between analog and digital mode */ + struct tuner_i2c_props i2c_props; + struct list_head hybrid_tuner_instance_list; + /* configuration settings */ const struct au8522_config *config; @@ -55,3 +59,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data); u8 au8522_readreg(struct au8522_state *state, u16 reg); int au8522_init(struct dvb_frontend *fe); int au8522_sleep(struct dvb_frontend *fe); + +int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, + u8 client_address); +void au8522_release_state(struct au8522_state *state); |