diff options
author | Clemens Ladisch <clemens@ladisch.de> | 2008-01-28 02:36:55 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:30:18 -0500 |
commit | 7c0141591fcf92ddc96a4ee04e35783a15bd68c8 (patch) | |
tree | 22b2ce1e76144b5ff0d0fb420668e18820f8adf2 /sound/pci/oxygen/virtuoso.c | |
parent | 5f7b9b457751efc9f3ad120d0ebdb19fe753e9d0 (diff) |
[ALSA] virtuoso: monitor external power on D2X
On the Xonar D2X, monitor the GPIO pin that indicates whether external
power is present.
Signed-off-by: Clemens Ladisch <clemens@ladisch.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/oxygen/virtuoso.c')
-rw-r--r-- | sound/pci/oxygen/virtuoso.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 2e1a6996fa86..40e92f5cd69c 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c | |||
@@ -136,6 +136,11 @@ MODULE_DEVICE_TABLE(pci, xonar_ids); | |||
136 | /* register 23 */ | 136 | /* register 23 */ |
137 | #define PCM1796_ID_MASK 0x1f | 137 | #define PCM1796_ID_MASK 0x1f |
138 | 138 | ||
139 | struct xonar_data { | ||
140 | u8 is_d2x; | ||
141 | u8 has_power; | ||
142 | }; | ||
143 | |||
139 | static void pcm1796_write(struct oxygen *chip, unsigned int codec, | 144 | static void pcm1796_write(struct oxygen *chip, unsigned int codec, |
140 | u8 reg, u8 value) | 145 | u8 reg, u8 value) |
141 | { | 146 | { |
@@ -153,8 +158,11 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec, | |||
153 | 158 | ||
154 | static void xonar_init(struct oxygen *chip) | 159 | static void xonar_init(struct oxygen *chip) |
155 | { | 160 | { |
161 | struct xonar_data *data = chip->model_data; | ||
156 | unsigned int i; | 162 | unsigned int i; |
157 | 163 | ||
164 | data->is_d2x = chip->pci->subsystem_device == 0x82b7; | ||
165 | |||
158 | for (i = 0; i < 4; ++i) { | 166 | for (i = 0; i < 4; ++i) { |
159 | pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD); | 167 | pcm1796_write(chip, i, 18, PCM1796_FMT_24_LJUST | PCM1796_ATLD); |
160 | pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); | 168 | pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); |
@@ -169,6 +177,15 @@ static void xonar_init(struct oxygen *chip) | |||
169 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, | 177 | oxygen_write16_masked(chip, OXYGEN_GPIO_DATA, |
170 | GPIO_CS5381_M_SINGLE, | 178 | GPIO_CS5381_M_SINGLE, |
171 | GPIO_CS5381_M_MASK | GPIO_ALT); | 179 | GPIO_CS5381_M_MASK | GPIO_ALT); |
180 | if (data->is_d2x) { | ||
181 | oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, | ||
182 | GPIO_EXT_POWER); | ||
183 | oxygen_set_bits16(chip, OXYGEN_GPIO_INTERRUPT_MASK, | ||
184 | GPIO_EXT_POWER); | ||
185 | chip->interrupt_mask |= OXYGEN_INT_GPIO; | ||
186 | data->has_power = !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) | ||
187 | & GPIO_EXT_POWER); | ||
188 | } | ||
172 | oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); | 189 | oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); |
173 | oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE); | 190 | oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE); |
174 | msleep(300); | 191 | msleep(300); |
@@ -234,6 +251,27 @@ static void set_cs5381_params(struct oxygen *chip, | |||
234 | value, GPIO_CS5381_M_MASK); | 251 | value, GPIO_CS5381_M_MASK); |
235 | } | 252 | } |
236 | 253 | ||
254 | static void xonar_gpio_changed(struct oxygen *chip) | ||
255 | { | ||
256 | struct xonar_data *data = chip->model_data; | ||
257 | u8 has_power; | ||
258 | |||
259 | if (!data->is_d2x) | ||
260 | return; | ||
261 | has_power = !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) | ||
262 | & GPIO_EXT_POWER); | ||
263 | if (has_power != data->has_power) { | ||
264 | data->has_power = has_power; | ||
265 | if (has_power) { | ||
266 | snd_printk(KERN_NOTICE "power restored\n"); | ||
267 | } else { | ||
268 | snd_printk(KERN_CRIT | ||
269 | "Hey! Don't unplug the power cable!\n"); | ||
270 | /* TODO: stop PCMs */ | ||
271 | } | ||
272 | } | ||
273 | } | ||
274 | |||
237 | static void mute_ac97_ctl(struct oxygen *chip, unsigned int control) | 275 | static void mute_ac97_ctl(struct oxygen *chip, unsigned int control) |
238 | { | 276 | { |
239 | unsigned int index = chip->controls[control]->private_value & 0xff; | 277 | unsigned int index = chip->controls[control]->private_value & 0xff; |
@@ -360,6 +398,8 @@ static const struct oxygen_model model_xonar = { | |||
360 | .update_dac_volume = update_pcm1796_volume, | 398 | .update_dac_volume = update_pcm1796_volume, |
361 | .update_dac_mute = update_pcm1796_mute, | 399 | .update_dac_mute = update_pcm1796_mute, |
362 | .ac97_switch_hook = xonar_ac97_switch_hook, | 400 | .ac97_switch_hook = xonar_ac97_switch_hook, |
401 | .gpio_changed = xonar_gpio_changed, | ||
402 | .model_data_size = sizeof(struct xonar_data), | ||
363 | .dac_channels = 8, | 403 | .dac_channels = 8, |
364 | .used_channels = OXYGEN_CHANNEL_B | | 404 | .used_channels = OXYGEN_CHANNEL_B | |
365 | OXYGEN_CHANNEL_C | | 405 | OXYGEN_CHANNEL_C | |