diff options
-rw-r--r-- | drivers/media/dvb/frontends/au8522_dig.c | 45 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/au8522_priv.h | 8 |
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 | ||
32 | static int debug; | 32 | static int debug; |
33 | 33 | ||
34 | /* Despite the name "hybrid_tuner", the framework works just as well for | ||
35 | hybrid demodulators as well... */ | ||
36 | static 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 | ||
793 | static struct dvb_frontend_ops au8522_ops; | ||
794 | |||
795 | int 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 | |||
803 | void au8522_release_state(struct au8522_state *state) | ||
804 | { | ||
805 | if (state != NULL) | ||
806 | hybrid_tuner_release_state(state); | ||
807 | } | ||
808 | |||
809 | |||
789 | static void au8522_release(struct dvb_frontend *fe) | 810 | static 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 | ||
795 | static struct dvb_frontend_ops au8522_ops; | ||
796 | |||
797 | struct dvb_frontend *au8522_attach(const struct au8522_config *config, | 816 | struct 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 | ||
826 | error: | 857 | error: |
827 | kfree(state); | 858 | au8522_release_state(state); |
828 | return NULL; | 859 | return NULL; |
829 | } | 860 | } |
830 | EXPORT_SYMBOL(au8522_attach); | 861 | EXPORT_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 @@ | |||
37 | struct au8522_state { | 37 | struct 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); | |||
55 | u8 au8522_readreg(struct au8522_state *state, u16 reg); | 59 | u8 au8522_readreg(struct au8522_state *state, u16 reg); |
56 | int au8522_init(struct dvb_frontend *fe); | 60 | int au8522_init(struct dvb_frontend *fe); |
57 | int au8522_sleep(struct dvb_frontend *fe); | 61 | int au8522_sleep(struct dvb_frontend *fe); |
62 | |||
63 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | ||
64 | u8 client_address); | ||
65 | void au8522_release_state(struct au8522_state *state); | ||