aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/media/dvb/frontends/au8522_dig.c45
-rw-r--r--drivers/media/dvb/frontends/au8522_priv.h8
2 files changed, 46 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);
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h
index 569675d295d5..98b09caa2123 100644
--- a/drivers/media/dvb/frontends/au8522_priv.h
+++ b/drivers/media/dvb/frontends/au8522_priv.h
@@ -37,6 +37,10 @@
37struct au8522_state { 37struct au8522_state {
38 struct i2c_adapter *i2c; 38 struct i2c_adapter *i2c;
39 39
40 /* Used for sharing of the state between analog and digital mode */
41 struct tuner_i2c_props i2c_props;
42 struct list_head hybrid_tuner_instance_list;
43
40 /* configuration settings */ 44 /* configuration settings */
41 const struct au8522_config *config; 45 const struct au8522_config *config;
42 46
@@ -55,3 +59,7 @@ int au8522_writereg(struct au8522_state *state, u16 reg, u8 data);
55u8 au8522_readreg(struct au8522_state *state, u16 reg); 59u8 au8522_readreg(struct au8522_state *state, u16 reg);
56int au8522_init(struct dvb_frontend *fe); 60int au8522_init(struct dvb_frontend *fe);
57int au8522_sleep(struct dvb_frontend *fe); 61int au8522_sleep(struct dvb_frontend *fe);
62
63int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c,
64 u8 client_address);
65void au8522_release_state(struct au8522_state *state);