diff options
-rw-r--r-- | drivers/media/dvb/frontends/Kconfig | 22 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/Makefile | 5 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/au8522_common.c | 258 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/au8522_dig.c | 215 | ||||
-rw-r--r-- | drivers/media/dvb/frontends/au8522_priv.h | 2 | ||||
-rw-r--r-- | drivers/media/video/au0828/Kconfig | 3 |
6 files changed, 283 insertions, 222 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig index e11adb64e9e6..f47983472aed 100644 --- a/drivers/media/dvb/frontends/Kconfig +++ b/drivers/media/dvb/frontends/Kconfig | |||
@@ -540,12 +540,26 @@ config DVB_S5H1409 | |||
540 | to support this frontend. | 540 | to support this frontend. |
541 | 541 | ||
542 | config DVB_AU8522 | 542 | config DVB_AU8522 |
543 | tristate "Auvitek AU8522 based" | 543 | depends on I2C |
544 | depends on DVB_CORE && I2C && VIDEO_V4L2 | 544 | tristate |
545 | |||
546 | config DVB_AU8522_DTV | ||
547 | tristate "Auvitek AU8522 based DTV demod" | ||
548 | depends on DVB_CORE && I2C | ||
549 | select DVB_AU8522 | ||
545 | default m if DVB_FE_CUSTOMISE | 550 | default m if DVB_FE_CUSTOMISE |
546 | help | 551 | help |
547 | An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want | 552 | An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when |
548 | to support this frontend. | 553 | you want to enable DTV demodulation support for this frontend. |
554 | |||
555 | config DVB_AU8522_V4L | ||
556 | tristate "Auvitek AU8522 based ATV demod" | ||
557 | depends on VIDEO_V4L2 && I2C | ||
558 | select DVB_AU8522 | ||
559 | default m if DVB_FE_CUSTOMISE | ||
560 | help | ||
561 | An ATSC 8VSB, QAM64/256 & NTSC demodulator module. Say Y when | ||
562 | you want to enable ATV demodulation support for this frontend. | ||
549 | 563 | ||
550 | config DVB_S5H1411 | 564 | config DVB_S5H1411 |
551 | tristate "Samsung S5H1411 based" | 565 | tristate "Samsung S5H1411 based" |
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile index 6ca75578ecac..b0381dc8e176 100644 --- a/drivers/media/dvb/frontends/Makefile +++ b/drivers/media/dvb/frontends/Makefile | |||
@@ -7,7 +7,6 @@ ccflags-y += -I$(srctree)/drivers/media/common/tuners/ | |||
7 | 7 | ||
8 | stb0899-objs = stb0899_drv.o stb0899_algo.o | 8 | stb0899-objs = stb0899_drv.o stb0899_algo.o |
9 | stv0900-objs = stv0900_core.o stv0900_sw.o | 9 | stv0900-objs = stv0900_core.o stv0900_sw.o |
10 | au8522-objs = au8522_dig.o au8522_decoder.o | ||
11 | drxd-objs = drxd_firm.o drxd_hard.o | 10 | drxd-objs = drxd_firm.o drxd_hard.o |
12 | cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o | 11 | cxd2820r-objs = cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o |
13 | drxk-objs := drxk_hard.o | 12 | drxk-objs := drxk_hard.o |
@@ -63,7 +62,9 @@ obj-$(CONFIG_DVB_TUNER_DIB0090) += dib0090.o | |||
63 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o | 62 | obj-$(CONFIG_DVB_TUA6100) += tua6100.o |
64 | obj-$(CONFIG_DVB_S5H1409) += s5h1409.o | 63 | obj-$(CONFIG_DVB_S5H1409) += s5h1409.o |
65 | obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o | 64 | obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o |
66 | obj-$(CONFIG_DVB_AU8522) += au8522.o | 65 | obj-$(CONFIG_DVB_AU8522) += au8522_common.o |
66 | obj-$(CONFIG_DVB_AU8522_DTV) += au8522_dig.o | ||
67 | obj-$(CONFIG_DVB_AU8522_V4L) += au8522_decoder.o | ||
67 | obj-$(CONFIG_DVB_TDA10048) += tda10048.o | 68 | obj-$(CONFIG_DVB_TDA10048) += tda10048.o |
68 | obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o | 69 | obj-$(CONFIG_DVB_TUNER_CX24113) += cx24113.o |
69 | obj-$(CONFIG_DVB_S5H1411) += s5h1411.o | 70 | obj-$(CONFIG_DVB_S5H1411) += s5h1411.o |
diff --git a/drivers/media/dvb/frontends/au8522_common.c b/drivers/media/dvb/frontends/au8522_common.c new file mode 100644 index 000000000000..befdff919a89 --- /dev/null +++ b/drivers/media/dvb/frontends/au8522_common.c | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | Auvitek AU8522 QAM/8VSB demodulator driver | ||
3 | |||
4 | Copyright (C) 2008 Steven Toth <stoth@linuxtv.org> | ||
5 | Copyright (C) 2008 Devin Heitmueller <dheitmueller@linuxtv.org> | ||
6 | Copyright (C) 2005-2008 Auvitek International, Ltd. | ||
7 | Copyright (C) 2012 Michael Krufky <mkrufky@linuxtv.org> | ||
8 | |||
9 | This program is free software; you can redistribute it and/or modify | ||
10 | it under the terms of the GNU General Public License as published by | ||
11 | the Free Software Foundation; either version 2 of the License, or | ||
12 | (at your option) any later version. | ||
13 | |||
14 | This program is distributed in the hope that it will be useful, | ||
15 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
17 | GNU General Public License for more details. | ||
18 | |||
19 | You should have received a copy of the GNU General Public License | ||
20 | along with this program; if not, write to the Free Software | ||
21 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
22 | |||
23 | */ | ||
24 | |||
25 | #include <linux/i2c.h> | ||
26 | #include "dvb_frontend.h" | ||
27 | #include "au8522_priv.h" | ||
28 | |||
29 | static int debug; | ||
30 | |||
31 | #define dprintk(arg...)\ | ||
32 | do { if (debug)\ | ||
33 | printk(arg);\ | ||
34 | } while (0) | ||
35 | |||
36 | /* Despite the name "hybrid_tuner", the framework works just as well for | ||
37 | hybrid demodulators as well... */ | ||
38 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
39 | static DEFINE_MUTEX(au8522_list_mutex); | ||
40 | |||
41 | /* 16 bit registers, 8 bit values */ | ||
42 | int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) | ||
43 | { | ||
44 | int ret; | ||
45 | u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; | ||
46 | |||
47 | struct i2c_msg msg = { .addr = state->config->demod_address, | ||
48 | .flags = 0, .buf = buf, .len = 3 }; | ||
49 | |||
50 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
51 | |||
52 | if (ret != 1) | ||
53 | printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " | ||
54 | "ret == %i)\n", __func__, reg, data, ret); | ||
55 | |||
56 | return (ret != 1) ? -1 : 0; | ||
57 | } | ||
58 | EXPORT_SYMBOL(au8522_writereg); | ||
59 | |||
60 | u8 au8522_readreg(struct au8522_state *state, u16 reg) | ||
61 | { | ||
62 | int ret; | ||
63 | u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; | ||
64 | u8 b1[] = { 0 }; | ||
65 | |||
66 | struct i2c_msg msg[] = { | ||
67 | { .addr = state->config->demod_address, .flags = 0, | ||
68 | .buf = b0, .len = 2 }, | ||
69 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
70 | .buf = b1, .len = 1 } }; | ||
71 | |||
72 | ret = i2c_transfer(state->i2c, msg, 2); | ||
73 | |||
74 | if (ret != 2) | ||
75 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", | ||
76 | __func__, ret); | ||
77 | return b1[0]; | ||
78 | } | ||
79 | EXPORT_SYMBOL(au8522_readreg); | ||
80 | |||
81 | int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
82 | { | ||
83 | struct au8522_state *state = fe->demodulator_priv; | ||
84 | |||
85 | dprintk("%s(%d)\n", __func__, enable); | ||
86 | |||
87 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
88 | /* We're being asked to manage the gate even though we're | ||
89 | not in digital mode. This can occur if we get switched | ||
90 | over to analog mode before the dvb_frontend kernel thread | ||
91 | has completely shutdown */ | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | if (enable) | ||
96 | return au8522_writereg(state, 0x106, 1); | ||
97 | else | ||
98 | return au8522_writereg(state, 0x106, 0); | ||
99 | } | ||
100 | EXPORT_SYMBOL(au8522_i2c_gate_ctrl); | ||
101 | |||
102 | /* Reset the demod hardware and reset all of the configuration registers | ||
103 | to a default state. */ | ||
104 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | ||
105 | u8 client_address) | ||
106 | { | ||
107 | int ret; | ||
108 | |||
109 | mutex_lock(&au8522_list_mutex); | ||
110 | ret = hybrid_tuner_request_state(struct au8522_state, (*state), | ||
111 | hybrid_tuner_instance_list, | ||
112 | i2c, client_address, "au8522"); | ||
113 | mutex_unlock(&au8522_list_mutex); | ||
114 | |||
115 | return ret; | ||
116 | } | ||
117 | EXPORT_SYMBOL(au8522_get_state); | ||
118 | |||
119 | void au8522_release_state(struct au8522_state *state) | ||
120 | { | ||
121 | mutex_lock(&au8522_list_mutex); | ||
122 | if (state != NULL) | ||
123 | hybrid_tuner_release_state(state); | ||
124 | mutex_unlock(&au8522_list_mutex); | ||
125 | } | ||
126 | EXPORT_SYMBOL(au8522_release_state); | ||
127 | |||
128 | int au8522_led_gpio_enable(struct au8522_state *state, int onoff) | ||
129 | { | ||
130 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
131 | u8 val; | ||
132 | |||
133 | /* bail out if we can't control an LED */ | ||
134 | if (!led_config || !led_config->gpio_output || | ||
135 | !led_config->gpio_output_enable || !led_config->gpio_output_disable) | ||
136 | return 0; | ||
137 | |||
138 | val = au8522_readreg(state, 0x4000 | | ||
139 | (led_config->gpio_output & ~0xc000)); | ||
140 | if (onoff) { | ||
141 | /* enable GPIO output */ | ||
142 | val &= ~((led_config->gpio_output_enable >> 8) & 0xff); | ||
143 | val |= (led_config->gpio_output_enable & 0xff); | ||
144 | } else { | ||
145 | /* disable GPIO output */ | ||
146 | val &= ~((led_config->gpio_output_disable >> 8) & 0xff); | ||
147 | val |= (led_config->gpio_output_disable & 0xff); | ||
148 | } | ||
149 | return au8522_writereg(state, 0x8000 | | ||
150 | (led_config->gpio_output & ~0xc000), val); | ||
151 | } | ||
152 | EXPORT_SYMBOL(au8522_led_gpio_enable); | ||
153 | |||
154 | /* led = 0 | off | ||
155 | * led = 1 | signal ok | ||
156 | * led = 2 | signal strong | ||
157 | * led < 0 | only light led if leds are currently off | ||
158 | */ | ||
159 | int au8522_led_ctrl(struct au8522_state *state, int led) | ||
160 | { | ||
161 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
162 | int i, ret = 0; | ||
163 | |||
164 | /* bail out if we can't control an LED */ | ||
165 | if (!led_config || !led_config->gpio_leds || | ||
166 | !led_config->num_led_states || !led_config->led_states) | ||
167 | return 0; | ||
168 | |||
169 | if (led < 0) { | ||
170 | /* if LED is already lit, then leave it as-is */ | ||
171 | if (state->led_state) | ||
172 | return 0; | ||
173 | else | ||
174 | led *= -1; | ||
175 | } | ||
176 | |||
177 | /* toggle LED if changing state */ | ||
178 | if (state->led_state != led) { | ||
179 | u8 val; | ||
180 | |||
181 | dprintk("%s: %d\n", __func__, led); | ||
182 | |||
183 | au8522_led_gpio_enable(state, 1); | ||
184 | |||
185 | val = au8522_readreg(state, 0x4000 | | ||
186 | (led_config->gpio_leds & ~0xc000)); | ||
187 | |||
188 | /* start with all leds off */ | ||
189 | for (i = 0; i < led_config->num_led_states; i++) | ||
190 | val &= ~led_config->led_states[i]; | ||
191 | |||
192 | /* set selected LED state */ | ||
193 | if (led < led_config->num_led_states) | ||
194 | val |= led_config->led_states[led]; | ||
195 | else if (led_config->num_led_states) | ||
196 | val |= | ||
197 | led_config->led_states[led_config->num_led_states - 1]; | ||
198 | |||
199 | ret = au8522_writereg(state, 0x8000 | | ||
200 | (led_config->gpio_leds & ~0xc000), val); | ||
201 | if (ret < 0) | ||
202 | return ret; | ||
203 | |||
204 | state->led_state = led; | ||
205 | |||
206 | if (led == 0) | ||
207 | au8522_led_gpio_enable(state, 0); | ||
208 | } | ||
209 | |||
210 | return 0; | ||
211 | } | ||
212 | EXPORT_SYMBOL(au8522_led_ctrl); | ||
213 | |||
214 | int au8522_init(struct dvb_frontend *fe) | ||
215 | { | ||
216 | struct au8522_state *state = fe->demodulator_priv; | ||
217 | dprintk("%s()\n", __func__); | ||
218 | |||
219 | state->operational_mode = AU8522_DIGITAL_MODE; | ||
220 | |||
221 | /* Clear out any state associated with the digital side of the | ||
222 | chip, so that when it gets powered back up it won't think | ||
223 | that it is already tuned */ | ||
224 | state->current_frequency = 0; | ||
225 | |||
226 | au8522_writereg(state, 0xa4, 1 << 5); | ||
227 | |||
228 | au8522_i2c_gate_ctrl(fe, 1); | ||
229 | |||
230 | return 0; | ||
231 | } | ||
232 | EXPORT_SYMBOL(au8522_init); | ||
233 | |||
234 | int au8522_sleep(struct dvb_frontend *fe) | ||
235 | { | ||
236 | struct au8522_state *state = fe->demodulator_priv; | ||
237 | dprintk("%s()\n", __func__); | ||
238 | |||
239 | /* Only power down if the digital side is currently using the chip */ | ||
240 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
241 | /* We're not in one of the expected power modes, which means | ||
242 | that the DVB thread is probably telling us to go to sleep | ||
243 | even though the analog frontend has already started using | ||
244 | the chip. So ignore the request */ | ||
245 | return 0; | ||
246 | } | ||
247 | |||
248 | /* turn off led */ | ||
249 | au8522_led_ctrl(state, 0); | ||
250 | |||
251 | /* Power down the chip */ | ||
252 | au8522_writereg(state, 0xa4, 1 << 5); | ||
253 | |||
254 | state->current_frequency = 0; | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | EXPORT_SYMBOL(au8522_sleep); | ||
diff --git a/drivers/media/dvb/frontends/au8522_dig.c b/drivers/media/dvb/frontends/au8522_dig.c index 25f650934c73..5fc70d6cd04f 100644 --- a/drivers/media/dvb/frontends/au8522_dig.c +++ b/drivers/media/dvb/frontends/au8522_dig.c | |||
@@ -30,74 +30,11 @@ | |||
30 | 30 | ||
31 | static int debug; | 31 | static int debug; |
32 | 32 | ||
33 | /* Despite the name "hybrid_tuner", the framework works just as well for | ||
34 | hybrid demodulators as well... */ | ||
35 | static LIST_HEAD(hybrid_tuner_instance_list); | ||
36 | static DEFINE_MUTEX(au8522_list_mutex); | ||
37 | |||
38 | #define dprintk(arg...)\ | 33 | #define dprintk(arg...)\ |
39 | do { if (debug)\ | 34 | do { if (debug)\ |
40 | printk(arg);\ | 35 | printk(arg);\ |
41 | } while (0) | 36 | } while (0) |
42 | 37 | ||
43 | /* 16 bit registers, 8 bit values */ | ||
44 | int au8522_writereg(struct au8522_state *state, u16 reg, u8 data) | ||
45 | { | ||
46 | int ret; | ||
47 | u8 buf[] = { (reg >> 8) | 0x80, reg & 0xff, data }; | ||
48 | |||
49 | struct i2c_msg msg = { .addr = state->config->demod_address, | ||
50 | .flags = 0, .buf = buf, .len = 3 }; | ||
51 | |||
52 | ret = i2c_transfer(state->i2c, &msg, 1); | ||
53 | |||
54 | if (ret != 1) | ||
55 | printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, " | ||
56 | "ret == %i)\n", __func__, reg, data, ret); | ||
57 | |||
58 | return (ret != 1) ? -1 : 0; | ||
59 | } | ||
60 | |||
61 | u8 au8522_readreg(struct au8522_state *state, u16 reg) | ||
62 | { | ||
63 | int ret; | ||
64 | u8 b0[] = { (reg >> 8) | 0x40, reg & 0xff }; | ||
65 | u8 b1[] = { 0 }; | ||
66 | |||
67 | struct i2c_msg msg[] = { | ||
68 | { .addr = state->config->demod_address, .flags = 0, | ||
69 | .buf = b0, .len = 2 }, | ||
70 | { .addr = state->config->demod_address, .flags = I2C_M_RD, | ||
71 | .buf = b1, .len = 1 } }; | ||
72 | |||
73 | ret = i2c_transfer(state->i2c, msg, 2); | ||
74 | |||
75 | if (ret != 2) | ||
76 | printk(KERN_ERR "%s: readreg error (ret == %i)\n", | ||
77 | __func__, ret); | ||
78 | return b1[0]; | ||
79 | } | ||
80 | |||
81 | static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable) | ||
82 | { | ||
83 | struct au8522_state *state = fe->demodulator_priv; | ||
84 | |||
85 | dprintk("%s(%d)\n", __func__, enable); | ||
86 | |||
87 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
88 | /* We're being asked to manage the gate even though we're | ||
89 | not in digital mode. This can occur if we get switched | ||
90 | over to analog mode before the dvb_frontend kernel thread | ||
91 | has completely shutdown */ | ||
92 | return 0; | ||
93 | } | ||
94 | |||
95 | if (enable) | ||
96 | return au8522_writereg(state, 0x106, 1); | ||
97 | else | ||
98 | return au8522_writereg(state, 0x106, 0); | ||
99 | } | ||
100 | |||
101 | struct mse2snr_tab { | 38 | struct mse2snr_tab { |
102 | u16 val; | 39 | u16 val; |
103 | u16 data; | 40 | u16 data; |
@@ -609,136 +546,6 @@ static int au8522_set_frontend(struct dvb_frontend *fe) | |||
609 | return 0; | 546 | return 0; |
610 | } | 547 | } |
611 | 548 | ||
612 | /* Reset the demod hardware and reset all of the configuration registers | ||
613 | to a default state. */ | ||
614 | int au8522_init(struct dvb_frontend *fe) | ||
615 | { | ||
616 | struct au8522_state *state = fe->demodulator_priv; | ||
617 | dprintk("%s()\n", __func__); | ||
618 | |||
619 | state->operational_mode = AU8522_DIGITAL_MODE; | ||
620 | |||
621 | /* Clear out any state associated with the digital side of the | ||
622 | chip, so that when it gets powered back up it won't think | ||
623 | that it is already tuned */ | ||
624 | state->current_frequency = 0; | ||
625 | |||
626 | au8522_writereg(state, 0xa4, 1 << 5); | ||
627 | |||
628 | au8522_i2c_gate_ctrl(fe, 1); | ||
629 | |||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | static int au8522_led_gpio_enable(struct au8522_state *state, int onoff) | ||
634 | { | ||
635 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
636 | u8 val; | ||
637 | |||
638 | /* bail out if we can't control an LED */ | ||
639 | if (!led_config || !led_config->gpio_output || | ||
640 | !led_config->gpio_output_enable || !led_config->gpio_output_disable) | ||
641 | return 0; | ||
642 | |||
643 | val = au8522_readreg(state, 0x4000 | | ||
644 | (led_config->gpio_output & ~0xc000)); | ||
645 | if (onoff) { | ||
646 | /* enable GPIO output */ | ||
647 | val &= ~((led_config->gpio_output_enable >> 8) & 0xff); | ||
648 | val |= (led_config->gpio_output_enable & 0xff); | ||
649 | } else { | ||
650 | /* disable GPIO output */ | ||
651 | val &= ~((led_config->gpio_output_disable >> 8) & 0xff); | ||
652 | val |= (led_config->gpio_output_disable & 0xff); | ||
653 | } | ||
654 | return au8522_writereg(state, 0x8000 | | ||
655 | (led_config->gpio_output & ~0xc000), val); | ||
656 | } | ||
657 | |||
658 | /* led = 0 | off | ||
659 | * led = 1 | signal ok | ||
660 | * led = 2 | signal strong | ||
661 | * led < 0 | only light led if leds are currently off | ||
662 | */ | ||
663 | static int au8522_led_ctrl(struct au8522_state *state, int led) | ||
664 | { | ||
665 | struct au8522_led_config *led_config = state->config->led_cfg; | ||
666 | int i, ret = 0; | ||
667 | |||
668 | /* bail out if we can't control an LED */ | ||
669 | if (!led_config || !led_config->gpio_leds || | ||
670 | !led_config->num_led_states || !led_config->led_states) | ||
671 | return 0; | ||
672 | |||
673 | if (led < 0) { | ||
674 | /* if LED is already lit, then leave it as-is */ | ||
675 | if (state->led_state) | ||
676 | return 0; | ||
677 | else | ||
678 | led *= -1; | ||
679 | } | ||
680 | |||
681 | /* toggle LED if changing state */ | ||
682 | if (state->led_state != led) { | ||
683 | u8 val; | ||
684 | |||
685 | dprintk("%s: %d\n", __func__, led); | ||
686 | |||
687 | au8522_led_gpio_enable(state, 1); | ||
688 | |||
689 | val = au8522_readreg(state, 0x4000 | | ||
690 | (led_config->gpio_leds & ~0xc000)); | ||
691 | |||
692 | /* start with all leds off */ | ||
693 | for (i = 0; i < led_config->num_led_states; i++) | ||
694 | val &= ~led_config->led_states[i]; | ||
695 | |||
696 | /* set selected LED state */ | ||
697 | if (led < led_config->num_led_states) | ||
698 | val |= led_config->led_states[led]; | ||
699 | else if (led_config->num_led_states) | ||
700 | val |= | ||
701 | led_config->led_states[led_config->num_led_states - 1]; | ||
702 | |||
703 | ret = au8522_writereg(state, 0x8000 | | ||
704 | (led_config->gpio_leds & ~0xc000), val); | ||
705 | if (ret < 0) | ||
706 | return ret; | ||
707 | |||
708 | state->led_state = led; | ||
709 | |||
710 | if (led == 0) | ||
711 | au8522_led_gpio_enable(state, 0); | ||
712 | } | ||
713 | |||
714 | return 0; | ||
715 | } | ||
716 | |||
717 | int au8522_sleep(struct dvb_frontend *fe) | ||
718 | { | ||
719 | struct au8522_state *state = fe->demodulator_priv; | ||
720 | dprintk("%s()\n", __func__); | ||
721 | |||
722 | /* Only power down if the digital side is currently using the chip */ | ||
723 | if (state->operational_mode == AU8522_ANALOG_MODE) { | ||
724 | /* We're not in one of the expected power modes, which means | ||
725 | that the DVB thread is probably telling us to go to sleep | ||
726 | even though the analog frontend has already started using | ||
727 | the chip. So ignore the request */ | ||
728 | return 0; | ||
729 | } | ||
730 | |||
731 | /* turn off led */ | ||
732 | au8522_led_ctrl(state, 0); | ||
733 | |||
734 | /* Power down the chip */ | ||
735 | au8522_writereg(state, 0xa4, 1 << 5); | ||
736 | |||
737 | state->current_frequency = 0; | ||
738 | |||
739 | return 0; | ||
740 | } | ||
741 | |||
742 | static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) | 549 | static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status) |
743 | { | 550 | { |
744 | struct au8522_state *state = fe->demodulator_priv; | 551 | struct au8522_state *state = fe->demodulator_priv; |
@@ -931,28 +738,6 @@ static int au8522_get_tune_settings(struct dvb_frontend *fe, | |||
931 | 738 | ||
932 | static struct dvb_frontend_ops au8522_ops; | 739 | static struct dvb_frontend_ops au8522_ops; |
933 | 740 | ||
934 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | ||
935 | u8 client_address) | ||
936 | { | ||
937 | int ret; | ||
938 | |||
939 | mutex_lock(&au8522_list_mutex); | ||
940 | ret = hybrid_tuner_request_state(struct au8522_state, (*state), | ||
941 | hybrid_tuner_instance_list, | ||
942 | i2c, client_address, "au8522"); | ||
943 | mutex_unlock(&au8522_list_mutex); | ||
944 | |||
945 | return ret; | ||
946 | } | ||
947 | |||
948 | void au8522_release_state(struct au8522_state *state) | ||
949 | { | ||
950 | mutex_lock(&au8522_list_mutex); | ||
951 | if (state != NULL) | ||
952 | hybrid_tuner_release_state(state); | ||
953 | mutex_unlock(&au8522_list_mutex); | ||
954 | } | ||
955 | |||
956 | 741 | ||
957 | static void au8522_release(struct dvb_frontend *fe) | 742 | static void au8522_release(struct dvb_frontend *fe) |
958 | { | 743 | { |
diff --git a/drivers/media/dvb/frontends/au8522_priv.h b/drivers/media/dvb/frontends/au8522_priv.h index 751e17d692a9..6e4a438732b5 100644 --- a/drivers/media/dvb/frontends/au8522_priv.h +++ b/drivers/media/dvb/frontends/au8522_priv.h | |||
@@ -81,6 +81,8 @@ int au8522_sleep(struct dvb_frontend *fe); | |||
81 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, | 81 | int au8522_get_state(struct au8522_state **state, struct i2c_adapter *i2c, |
82 | u8 client_address); | 82 | u8 client_address); |
83 | void au8522_release_state(struct au8522_state *state); | 83 | void au8522_release_state(struct au8522_state *state); |
84 | int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable); | ||
85 | int au8522_led_ctrl(struct au8522_state *state, int led); | ||
84 | 86 | ||
85 | /* REGISTERS */ | 87 | /* REGISTERS */ |
86 | #define AU8522_INPUT_CONTROL_REG081H 0x081 | 88 | #define AU8522_INPUT_CONTROL_REG081H 0x081 |
diff --git a/drivers/media/video/au0828/Kconfig b/drivers/media/video/au0828/Kconfig index 81ba9d9d1b52..23f7fd22f0eb 100644 --- a/drivers/media/video/au0828/Kconfig +++ b/drivers/media/video/au0828/Kconfig | |||
@@ -6,7 +6,8 @@ config VIDEO_AU0828 | |||
6 | select I2C_ALGOBIT | 6 | select I2C_ALGOBIT |
7 | select VIDEO_TVEEPROM | 7 | select VIDEO_TVEEPROM |
8 | select VIDEOBUF_VMALLOC | 8 | select VIDEOBUF_VMALLOC |
9 | select DVB_AU8522 if !DVB_FE_CUSTOMISE | 9 | select DVB_AU8522_DTV if !DVB_FE_CUSTOMISE |
10 | select DVB_AU8522_V4L if !DVB_FE_CUSTOMISE | ||
10 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE | 11 | select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE |
11 | select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE | 12 | select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE |
12 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE | 13 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE |