diff options
-rw-r--r-- | sound/pci/oxygen/oxygen.c | 63 |
1 files changed, 53 insertions, 10 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 1d8e2b29745d..72db4c39007f 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * C-Media CMI8788 driver for C-Media's reference design and for the X-Meridian | 2 | * C-Media CMI8788 driver for C-Media's reference design and similar models |
3 | * | 3 | * |
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | 4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> |
5 | * | 5 | * |
@@ -26,6 +26,7 @@ | |||
26 | * | 26 | * |
27 | * GPIO 0 -> DFS0 of AK5385 | 27 | * GPIO 0 -> DFS0 of AK5385 |
28 | * GPIO 1 -> DFS1 of AK5385 | 28 | * GPIO 1 -> DFS1 of AK5385 |
29 | * GPIO 8 -> enable headphone amplifier on HT-Omega models | ||
29 | */ | 30 | */ |
30 | 31 | ||
31 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
@@ -61,7 +62,8 @@ MODULE_PARM_DESC(enable, "enable card"); | |||
61 | enum { | 62 | enum { |
62 | MODEL_CMEDIA_REF, /* C-Media's reference design */ | 63 | MODEL_CMEDIA_REF, /* C-Media's reference design */ |
63 | MODEL_MERIDIAN, /* AuzenTech X-Meridian */ | 64 | MODEL_MERIDIAN, /* AuzenTech X-Meridian */ |
64 | MODEL_HALO, /* HT-Omega Claro halo */ | 65 | MODEL_CLARO, /* HT-Omega Claro */ |
66 | MODEL_CLARO_HALO, /* HT-Omega Claro halo */ | ||
65 | }; | 67 | }; |
66 | 68 | ||
67 | static struct pci_device_id oxygen_ids[] __devinitdata = { | 69 | static struct pci_device_id oxygen_ids[] __devinitdata = { |
@@ -74,8 +76,8 @@ static struct pci_device_id oxygen_ids[] __devinitdata = { | |||
74 | { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, | 76 | { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, |
75 | { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, | 77 | { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, |
76 | { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, | 78 | { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, |
77 | { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, | 79 | { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, |
78 | { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_HALO }, | 80 | { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO }, |
79 | { } | 81 | { } |
80 | }; | 82 | }; |
81 | MODULE_DEVICE_TABLE(pci, oxygen_ids); | 83 | MODULE_DEVICE_TABLE(pci, oxygen_ids); |
@@ -86,6 +88,8 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); | |||
86 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 | 88 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 |
87 | #define GPIO_AK5385_DFS_QUAD 0x0002 | 89 | #define GPIO_AK5385_DFS_QUAD 0x0002 |
88 | 90 | ||
91 | #define GPIO_CLARO_HP 0x0100 | ||
92 | |||
89 | struct generic_data { | 93 | struct generic_data { |
90 | u8 ak4396_ctl2; | 94 | u8 ak4396_ctl2; |
91 | u16 saved_wm8785_registers[2]; | 95 | u16 saved_wm8785_registers[2]; |
@@ -196,16 +200,46 @@ static void meridian_init(struct oxygen *chip) | |||
196 | ak5385_init(chip); | 200 | ak5385_init(chip); |
197 | } | 201 | } |
198 | 202 | ||
199 | static void halo_init(struct oxygen *chip) | 203 | static void claro_enable_hp(struct oxygen *chip) |
204 | { | ||
205 | msleep(300); | ||
206 | oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_CLARO_HP); | ||
207 | oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP); | ||
208 | } | ||
209 | |||
210 | static void claro_init(struct oxygen *chip) | ||
211 | { | ||
212 | ak4396_init(chip); | ||
213 | wm8785_init(chip); | ||
214 | claro_enable_hp(chip); | ||
215 | } | ||
216 | |||
217 | static void claro_halo_init(struct oxygen *chip) | ||
200 | { | 218 | { |
201 | ak4396_init(chip); | 219 | ak4396_init(chip); |
202 | ak5385_init(chip); | 220 | ak5385_init(chip); |
221 | claro_enable_hp(chip); | ||
203 | } | 222 | } |
204 | 223 | ||
205 | static void generic_cleanup(struct oxygen *chip) | 224 | static void generic_cleanup(struct oxygen *chip) |
206 | { | 225 | { |
207 | } | 226 | } |
208 | 227 | ||
228 | static void claro_disable_hp(struct oxygen *chip) | ||
229 | { | ||
230 | oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_CLARO_HP); | ||
231 | } | ||
232 | |||
233 | static void claro_cleanup(struct oxygen *chip) | ||
234 | { | ||
235 | claro_disable_hp(chip); | ||
236 | } | ||
237 | |||
238 | static void claro_suspend(struct oxygen *chip) | ||
239 | { | ||
240 | claro_disable_hp(chip); | ||
241 | } | ||
242 | |||
209 | static void generic_resume(struct oxygen *chip) | 243 | static void generic_resume(struct oxygen *chip) |
210 | { | 244 | { |
211 | ak4396_registers_init(chip); | 245 | ak4396_registers_init(chip); |
@@ -217,9 +251,10 @@ static void meridian_resume(struct oxygen *chip) | |||
217 | ak4396_registers_init(chip); | 251 | ak4396_registers_init(chip); |
218 | } | 252 | } |
219 | 253 | ||
220 | static void halo_resume(struct oxygen *chip) | 254 | static void claro_resume(struct oxygen *chip) |
221 | { | 255 | { |
222 | ak4396_registers_init(chip); | 256 | ak4396_registers_init(chip); |
257 | claro_enable_hp(chip); | ||
223 | } | 258 | } |
224 | 259 | ||
225 | static void set_ak4396_params(struct oxygen *chip, | 260 | static void set_ak4396_params(struct oxygen *chip, |
@@ -346,14 +381,22 @@ static int __devinit get_oxygen_model(struct oxygen *chip, | |||
346 | CAPTURE_0_FROM_I2S_2 | | 381 | CAPTURE_0_FROM_I2S_2 | |
347 | CAPTURE_1_FROM_SPDIF; | 382 | CAPTURE_1_FROM_SPDIF; |
348 | break; | 383 | break; |
349 | case MODEL_HALO: | 384 | case MODEL_CLARO: |
350 | chip->model.init = halo_init; | 385 | chip->model.init = claro_init; |
351 | chip->model.resume = halo_resume; | 386 | chip->model.cleanup = claro_cleanup; |
387 | chip->model.suspend = claro_suspend; | ||
388 | chip->model.resume = claro_resume; | ||
389 | break; | ||
390 | case MODEL_CLARO_HALO: | ||
391 | chip->model.init = claro_halo_init; | ||
392 | chip->model.cleanup = claro_cleanup; | ||
393 | chip->model.suspend = claro_suspend; | ||
394 | chip->model.resume = claro_resume; | ||
352 | chip->model.set_adc_params = set_ak5385_params; | 395 | chip->model.set_adc_params = set_ak5385_params; |
353 | break; | 396 | break; |
354 | } | 397 | } |
355 | if (id->driver_data == MODEL_MERIDIAN || | 398 | if (id->driver_data == MODEL_MERIDIAN || |
356 | id->driver_data == MODEL_HALO) { | 399 | id->driver_data == MODEL_CLARO_HALO) { |
357 | chip->model.misc_flags = OXYGEN_MISC_MIDI; | 400 | chip->model.misc_flags = OXYGEN_MISC_MIDI; |
358 | chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; | 401 | chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; |
359 | } | 402 | } |