aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends/au8522_dig.c
diff options
context:
space:
mode:
authorDevin Heitmueller <dheitmueller@linuxtv.org>2009-03-11 02:00:36 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:24 -0400
commit209fdf66b8699a6b2998b58e572d67230dae507f (patch)
treea2b287bf353d610d50b1d041d15e3f8a927fe70c /drivers/media/dvb/frontends/au8522_dig.c
parent7bf63eda681e095ca3c39d075354053107febf80 (diff)
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 @@
31 31
32static int debug; 32static int debug;
33 33
34/* Despite the name "hybrid_tuner", the framework works just as well for
35 hybrid demodulators as well... */
36static LIST_HEAD(hybrid_tuner_instance_list);
37
34#define dprintk(arg...) do { \ 38#define dprintk(arg...) do { \
35 if (debug) \ 39 if (debug) \
36 printk(arg); \ 40 printk(arg); \
@@ -786,23 +790,50 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe,
786 return 0; 790 return 0;
787} 791}
788 792
793static struct dvb_frontend_ops au8522_ops;
794
795int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
796 u8 client_address)
797{
798 return hybrid_tuner_request_state(struct au8522_state, (*state),
799 hybrid_tuner_instance_list,
800 i2c, client_address, "au8522");
801}
802
803void au8522_release_state(struct au8522_state *state)
804{
805 if (state != NULL)
806 hybrid_tuner_release_state(state);
807}
808
809
789static void au8522_release(struct dvb_frontend *fe) 810static void au8522_release(struct dvb_frontend *fe)
790{ 811{
791 struct au8522_state *state = fe->demodulator_priv; 812 struct au8522_state *state = fe->demodulator_priv;
792 kfree(state); 813 au8522_release_state(state);
793} 814}
794 815
795static struct dvb_frontend_ops au8522_ops;
796
797struct dvb_frontend *au8522_attach(const struct au8522_config *config, 816struct dvb_frontend *au8522_attach(const struct au8522_config *config,
798 struct i2c_adapter *i2c) 817 struct i2c_adapter *i2c)
799{ 818{
800 struct au8522_state *state = NULL; 819 struct au8522_state *state = NULL;
820 int instance;
801 821
802 /* allocate memory for the internal state */ 822 /* allocate memory for the internal state */
803 state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL); 823 instance = au8522_get_state(&state, i2c, config->demod_address);
804 if (state == NULL) 824 switch (instance) {
805 goto error; 825 case 0:
826 dprintk("%s state allocation failed\n", __func__);
827 break;
828 case 1:
829 /* new demod instance */
830 dprintk("%s using new instance\n", __func__);
831 break;
832 default:
833 /* existing demod instance */
834 dprintk("%s using existing instance\n", __func__);
835 break;
836 }
806 837
807 /* setup the state */ 838 /* setup the state */
808 state->config = config; 839 state->config = config;
@@ -824,7 +855,7 @@ struct dvb_frontend *au8522_attach(const struct au8522_config *config,
824 return &state->frontend; 855 return &state->frontend;
825 856
826error: 857error:
827 kfree(state); 858 au8522_release_state(state);
828 return NULL; 859 return NULL;
829} 860}
830EXPORT_SYMBOL(au8522_attach); 861EXPORT_SYMBOL(au8522_attach);