diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 11:41:44 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-24 11:41:44 -0400 |
| commit | 38ccc197eb85cad594eb5863ba5a408655da0062 (patch) | |
| tree | 0066a0160e5dd28280a8db2a5814af7111ae3e1b /sound/pci/oxygen/oxygen.c | |
| parent | d02aacff4467806ee56f147ac8eff6911d95811a (diff) | |
| parent | 3a841d519f91463361bbbe7addc24a0c1b2e9f99 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (250 commits)
[ALSA] ice1724 - Fix IRQ lock-up with MPU access
[ALSA] Define MPU401 registers in sound/mpu401_uart.h
[ALSA] pcsp: fix wording in DEBUG_PAGEALLOC warning
[ALSA] pcsp - Fix dependency in Kconfig
[ALSA] soc - ac97 - Clean up checkpatch warnings
[ALSA] soc - wm8750 - Clean up checkpatch warnings
[ALSA] soc - wm8731 - Clean up checkpatch warnings
[ALSA] soc - pxa2xx-pcm - Fix checkpatch warnings
[ALSA] soc - spitz - Fix checkpatch warnings
[ALSA] soc - poodle - Fix checkpatch warnings
[ALSA] soc - corgi - Fix checkpatch warnings
[ALSA] soc - s3c24xx-i2s - Add missing spaces
[ALSA] soc - s3c24xx-i2s - Fix tab/space breakage
[ALSA] soc - s3c24xx-i2s - Use linux/io.h
[ALSA] hda - Fix Thinkpad X300 digital mic
pcsp - Don't build pcspkr when snd-pcsp is enabled
[ALSA] hda - Fix model for Acer Aspire 5720z
[ALSA] soc - s3c24xx - Declare suspend and resume static
[ALSA] soc - s3c24xx - Improve diagnostic output
[ALSA] Fix possible races at free_irq in PCI drivers
...
Diffstat (limited to 'sound/pci/oxygen/oxygen.c')
| -rw-r--r-- | sound/pci/oxygen/oxygen.c | 129 |
1 files changed, 28 insertions, 101 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 9a9941bb0460..63f185c1ed1e 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
| @@ -39,7 +39,7 @@ | |||
| 39 | #include <sound/tlv.h> | 39 | #include <sound/tlv.h> |
| 40 | #include "oxygen.h" | 40 | #include "oxygen.h" |
| 41 | #include "ak4396.h" | 41 | #include "ak4396.h" |
| 42 | #include "cm9780.h" | 42 | #include "wm8785.h" |
| 43 | 43 | ||
| 44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | 44 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); |
| 45 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); | 45 | MODULE_DESCRIPTION("C-Media CMI8788 driver"); |
| @@ -78,49 +78,6 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); | |||
| 78 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 | 78 | #define GPIO_AK5385_DFS_DOUBLE 0x0001 |
| 79 | #define GPIO_AK5385_DFS_QUAD 0x0002 | 79 | #define GPIO_AK5385_DFS_QUAD 0x0002 |
| 80 | 80 | ||
| 81 | #define GPIO_LINE_MUTE CM9780_GPO0 | ||
| 82 | |||
| 83 | #define WM8785_R0 0 | ||
| 84 | #define WM8785_R1 1 | ||
| 85 | #define WM8785_R2 2 | ||
| 86 | #define WM8785_R7 7 | ||
| 87 | |||
| 88 | /* R0 */ | ||
| 89 | #define WM8785_MCR_MASK 0x007 | ||
| 90 | #define WM8785_MCR_SLAVE 0x000 | ||
| 91 | #define WM8785_MCR_MASTER_128 0x001 | ||
| 92 | #define WM8785_MCR_MASTER_192 0x002 | ||
| 93 | #define WM8785_MCR_MASTER_256 0x003 | ||
| 94 | #define WM8785_MCR_MASTER_384 0x004 | ||
| 95 | #define WM8785_MCR_MASTER_512 0x005 | ||
| 96 | #define WM8785_MCR_MASTER_768 0x006 | ||
| 97 | #define WM8785_OSR_MASK 0x018 | ||
| 98 | #define WM8785_OSR_SINGLE 0x000 | ||
| 99 | #define WM8785_OSR_DOUBLE 0x008 | ||
| 100 | #define WM8785_OSR_QUAD 0x010 | ||
| 101 | #define WM8785_FORMAT_MASK 0x060 | ||
| 102 | #define WM8785_FORMAT_RJUST 0x000 | ||
| 103 | #define WM8785_FORMAT_LJUST 0x020 | ||
| 104 | #define WM8785_FORMAT_I2S 0x040 | ||
| 105 | #define WM8785_FORMAT_DSP 0x060 | ||
| 106 | /* R1 */ | ||
| 107 | #define WM8785_WL_MASK 0x003 | ||
| 108 | #define WM8785_WL_16 0x000 | ||
| 109 | #define WM8785_WL_20 0x001 | ||
| 110 | #define WM8785_WL_24 0x002 | ||
| 111 | #define WM8785_WL_32 0x003 | ||
| 112 | #define WM8785_LRP 0x004 | ||
| 113 | #define WM8785_BCLKINV 0x008 | ||
| 114 | #define WM8785_LRSWAP 0x010 | ||
| 115 | #define WM8785_DEVNO_MASK 0x0e0 | ||
| 116 | /* R2 */ | ||
| 117 | #define WM8785_HPFR 0x001 | ||
| 118 | #define WM8785_HPFL 0x002 | ||
| 119 | #define WM8785_SDODIS 0x004 | ||
| 120 | #define WM8785_PWRDNR 0x008 | ||
| 121 | #define WM8785_PWRDNL 0x010 | ||
| 122 | #define WM8785_TDM_MASK 0x1c0 | ||
| 123 | |||
| 124 | struct generic_data { | 81 | struct generic_data { |
| 125 | u8 ak4396_ctl2; | 82 | u8 ak4396_ctl2; |
| 126 | }; | 83 | }; |
| @@ -155,7 +112,7 @@ static void ak4396_init(struct oxygen *chip) | |||
| 155 | struct generic_data *data = chip->model_data; | 112 | struct generic_data *data = chip->model_data; |
| 156 | unsigned int i; | 113 | unsigned int i; |
| 157 | 114 | ||
| 158 | data->ak4396_ctl2 = AK4396_DEM_OFF | AK4396_DFS_NORMAL; | 115 | data->ak4396_ctl2 = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; |
| 159 | for (i = 0; i < 4; ++i) { | 116 | for (i = 0; i < 4; ++i) { |
| 160 | ak4396_write(chip, i, | 117 | ak4396_write(chip, i, |
| 161 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); | 118 | AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); |
| @@ -163,8 +120,8 @@ static void ak4396_init(struct oxygen *chip) | |||
| 163 | AK4396_CONTROL_2, data->ak4396_ctl2); | 120 | AK4396_CONTROL_2, data->ak4396_ctl2); |
| 164 | ak4396_write(chip, i, | 121 | ak4396_write(chip, i, |
| 165 | AK4396_CONTROL_3, AK4396_PCM); | 122 | AK4396_CONTROL_3, AK4396_PCM); |
| 166 | ak4396_write(chip, i, AK4396_LCH_ATT, 0xff); | 123 | ak4396_write(chip, i, AK4396_LCH_ATT, 0); |
| 167 | ak4396_write(chip, i, AK4396_RCH_ATT, 0xff); | 124 | ak4396_write(chip, i, AK4396_RCH_ATT, 0); |
| 168 | } | 125 | } |
| 169 | snd_component_add(chip->card, "AK4396"); | 126 | snd_component_add(chip->card, "AK4396"); |
| 170 | } | 127 | } |
| @@ -185,23 +142,16 @@ static void wm8785_init(struct oxygen *chip) | |||
| 185 | snd_component_add(chip->card, "WM8785"); | 142 | snd_component_add(chip->card, "WM8785"); |
| 186 | } | 143 | } |
| 187 | 144 | ||
| 188 | static void cmi9780_init(struct oxygen *chip) | ||
| 189 | { | ||
| 190 | oxygen_ac97_clear_bits(chip, 0, CM9780_GPIO_STATUS, GPIO_LINE_MUTE); | ||
| 191 | } | ||
| 192 | |||
| 193 | static void generic_init(struct oxygen *chip) | 145 | static void generic_init(struct oxygen *chip) |
| 194 | { | 146 | { |
| 195 | ak4396_init(chip); | 147 | ak4396_init(chip); |
| 196 | wm8785_init(chip); | 148 | wm8785_init(chip); |
| 197 | cmi9780_init(chip); | ||
| 198 | } | 149 | } |
| 199 | 150 | ||
| 200 | static void meridian_init(struct oxygen *chip) | 151 | static void meridian_init(struct oxygen *chip) |
| 201 | { | 152 | { |
| 202 | ak4396_init(chip); | 153 | ak4396_init(chip); |
| 203 | ak5385_init(chip); | 154 | ak5385_init(chip); |
| 204 | cmi9780_init(chip); | ||
| 205 | } | 155 | } |
| 206 | 156 | ||
| 207 | static void generic_cleanup(struct oxygen *chip) | 157 | static void generic_cleanup(struct oxygen *chip) |
| @@ -297,59 +247,32 @@ static void set_ak5385_params(struct oxygen *chip, | |||
| 297 | value, GPIO_AK5385_DFS_MASK); | 247 | value, GPIO_AK5385_DFS_MASK); |
| 298 | } | 248 | } |
| 299 | 249 | ||
| 300 | static void cmi9780_switch_hook(struct oxygen *chip, unsigned int codec, | ||
| 301 | unsigned int reg, int mute) | ||
| 302 | { | ||
| 303 | if (codec != 0) | ||
| 304 | return; | ||
| 305 | switch (reg) { | ||
| 306 | case AC97_LINE: | ||
| 307 | oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, | ||
| 308 | mute ? GPIO_LINE_MUTE : 0, | ||
| 309 | GPIO_LINE_MUTE); | ||
| 310 | break; | ||
| 311 | case AC97_MIC: | ||
| 312 | case AC97_CD: | ||
| 313 | case AC97_AUX: | ||
| 314 | if (!mute) | ||
| 315 | oxygen_ac97_set_bits(chip, 0, CM9780_GPIO_STATUS, | ||
| 316 | GPIO_LINE_MUTE); | ||
| 317 | break; | ||
| 318 | } | ||
| 319 | } | ||
| 320 | |||
| 321 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | 250 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); |
| 322 | 251 | ||
| 323 | static int ak4396_control_filter(struct snd_kcontrol_new *template) | ||
| 324 | { | ||
| 325 | if (!strcmp(template->name, "Master Playback Volume")) { | ||
| 326 | template->access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; | ||
| 327 | template->tlv.p = ak4396_db_scale; | ||
| 328 | } | ||
| 329 | return 0; | ||
| 330 | } | ||
| 331 | |||
| 332 | static const struct oxygen_model model_generic = { | 252 | static const struct oxygen_model model_generic = { |
| 333 | .shortname = "C-Media CMI8788", | 253 | .shortname = "C-Media CMI8788", |
| 334 | .longname = "C-Media Oxygen HD Audio", | 254 | .longname = "C-Media Oxygen HD Audio", |
| 335 | .chip = "CMI8788", | 255 | .chip = "CMI8788", |
| 336 | .owner = THIS_MODULE, | 256 | .owner = THIS_MODULE, |
| 337 | .init = generic_init, | 257 | .init = generic_init, |
| 338 | .control_filter = ak4396_control_filter, | ||
| 339 | .cleanup = generic_cleanup, | 258 | .cleanup = generic_cleanup, |
| 340 | .set_dac_params = set_ak4396_params, | 259 | .set_dac_params = set_ak4396_params, |
| 341 | .set_adc_params = set_wm8785_params, | 260 | .set_adc_params = set_wm8785_params, |
| 342 | .update_dac_volume = update_ak4396_volume, | 261 | .update_dac_volume = update_ak4396_volume, |
| 343 | .update_dac_mute = update_ak4396_mute, | 262 | .update_dac_mute = update_ak4396_mute, |
| 344 | .ac97_switch_hook = cmi9780_switch_hook, | 263 | .dac_tlv = ak4396_db_scale, |
| 345 | .model_data_size = sizeof(struct generic_data), | 264 | .model_data_size = sizeof(struct generic_data), |
| 265 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | | ||
| 266 | PLAYBACK_1_TO_SPDIF | | ||
| 267 | PLAYBACK_2_TO_AC97_1 | | ||
| 268 | CAPTURE_0_FROM_I2S_1 | | ||
| 269 | CAPTURE_1_FROM_SPDIF | | ||
| 270 | CAPTURE_2_FROM_AC97_1, | ||
| 346 | .dac_channels = 8, | 271 | .dac_channels = 8, |
| 347 | .used_channels = OXYGEN_CHANNEL_A | | 272 | .dac_volume_min = 0, |
| 348 | OXYGEN_CHANNEL_C | | 273 | .dac_volume_max = 255, |
| 349 | OXYGEN_CHANNEL_SPDIF | | 274 | .function_flags = OXYGEN_FUNCTION_SPI | |
| 350 | OXYGEN_CHANNEL_MULTICH | | 275 | OXYGEN_FUNCTION_ENABLE_SPI_4_5, |
| 351 | OXYGEN_CHANNEL_AC97, | ||
| 352 | .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, | ||
| 353 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 276 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
| 354 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 277 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
| 355 | }; | 278 | }; |
| @@ -359,21 +282,25 @@ static const struct oxygen_model model_meridian = { | |||
| 359 | .chip = "CMI8788", | 282 | .chip = "CMI8788", |
| 360 | .owner = THIS_MODULE, | 283 | .owner = THIS_MODULE, |
| 361 | .init = meridian_init, | 284 | .init = meridian_init, |
| 362 | .control_filter = ak4396_control_filter, | ||
| 363 | .cleanup = generic_cleanup, | 285 | .cleanup = generic_cleanup, |
| 364 | .set_dac_params = set_ak4396_params, | 286 | .set_dac_params = set_ak4396_params, |
| 365 | .set_adc_params = set_ak5385_params, | 287 | .set_adc_params = set_ak5385_params, |
| 366 | .update_dac_volume = update_ak4396_volume, | 288 | .update_dac_volume = update_ak4396_volume, |
| 367 | .update_dac_mute = update_ak4396_mute, | 289 | .update_dac_mute = update_ak4396_mute, |
| 368 | .ac97_switch_hook = cmi9780_switch_hook, | 290 | .dac_tlv = ak4396_db_scale, |
| 369 | .model_data_size = sizeof(struct generic_data), | 291 | .model_data_size = sizeof(struct generic_data), |
| 292 | .pcm_dev_cfg = PLAYBACK_0_TO_I2S | | ||
| 293 | PLAYBACK_1_TO_SPDIF | | ||
| 294 | PLAYBACK_2_TO_AC97_1 | | ||
| 295 | CAPTURE_0_FROM_I2S_2 | | ||
| 296 | CAPTURE_1_FROM_SPDIF | | ||
| 297 | CAPTURE_2_FROM_AC97_1, | ||
| 370 | .dac_channels = 8, | 298 | .dac_channels = 8, |
| 371 | .used_channels = OXYGEN_CHANNEL_B | | 299 | .dac_volume_min = 0, |
| 372 | OXYGEN_CHANNEL_C | | 300 | .dac_volume_max = 255, |
| 373 | OXYGEN_CHANNEL_SPDIF | | 301 | .misc_flags = OXYGEN_MISC_MIDI, |
| 374 | OXYGEN_CHANNEL_MULTICH | | 302 | .function_flags = OXYGEN_FUNCTION_SPI | |
| 375 | OXYGEN_CHANNEL_AC97, | 303 | OXYGEN_FUNCTION_ENABLE_SPI_4_5, |
| 376 | .function_flags = OXYGEN_FUNCTION_ENABLE_SPI_4_5, | ||
| 377 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 304 | .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
| 378 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, | 305 | .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, |
| 379 | }; | 306 | }; |
| @@ -392,7 +319,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci, | |||
| 392 | return -ENOENT; | 319 | return -ENOENT; |
| 393 | } | 320 | } |
| 394 | is_meridian = pci_id->driver_data; | 321 | is_meridian = pci_id->driver_data; |
| 395 | err = oxygen_pci_probe(pci, index[dev], id[dev], is_meridian, | 322 | err = oxygen_pci_probe(pci, index[dev], id[dev], |
| 396 | is_meridian ? &model_meridian : &model_generic); | 323 | is_meridian ? &model_meridian : &model_generic); |
| 397 | if (err >= 0) | 324 | if (err >= 0) |
| 398 | ++dev; | 325 | ++dev; |
