diff options
| -rw-r--r-- | sound/pci/oxygen/oxygen.c | 73 |
1 files changed, 71 insertions, 2 deletions
diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 3ad9eb00aebd..acbedebcffd9 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c | |||
| @@ -98,7 +98,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); | |||
| 98 | 98 | ||
| 99 | struct generic_data { | 99 | struct generic_data { |
| 100 | u8 ak4396_regs[4][5]; | 100 | u8 ak4396_regs[4][5]; |
| 101 | u16 wm8785_regs[1]; | 101 | u16 wm8785_regs[3]; |
| 102 | }; | 102 | }; |
| 103 | 103 | ||
| 104 | static void ak4396_write(struct oxygen *chip, unsigned int codec, | 104 | static void ak4396_write(struct oxygen *chip, unsigned int codec, |
| @@ -184,6 +184,7 @@ static void wm8785_registers_init(struct oxygen *chip) | |||
| 184 | 184 | ||
| 185 | wm8785_write(chip, WM8785_R7, 0); | 185 | wm8785_write(chip, WM8785_R7, 0); |
| 186 | wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]); | 186 | wm8785_write(chip, WM8785_R0, data->wm8785_regs[0]); |
| 187 | wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]); | ||
| 187 | } | 188 | } |
| 188 | 189 | ||
| 189 | static void wm8785_init(struct oxygen *chip) | 190 | static void wm8785_init(struct oxygen *chip) |
| @@ -192,6 +193,7 @@ static void wm8785_init(struct oxygen *chip) | |||
| 192 | 193 | ||
| 193 | data->wm8785_regs[0] = | 194 | data->wm8785_regs[0] = |
| 194 | WM8785_MCR_SLAVE | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; | 195 | WM8785_MCR_SLAVE | WM8785_OSR_SINGLE | WM8785_FORMAT_LJUST; |
| 196 | data->wm8785_regs[2] = WM8785_HPFR | WM8785_HPFL; | ||
| 195 | wm8785_registers_init(chip); | 197 | wm8785_registers_init(chip); |
| 196 | snd_component_add(chip->card, "WM8785"); | 198 | snd_component_add(chip->card, "WM8785"); |
| 197 | } | 199 | } |
| @@ -334,6 +336,7 @@ static void set_wm8785_params(struct oxygen *chip, | |||
| 334 | if (value != data->wm8785_regs[0]) { | 336 | if (value != data->wm8785_regs[0]) { |
| 335 | wm8785_write(chip, WM8785_R7, 0); | 337 | wm8785_write(chip, WM8785_R7, 0); |
| 336 | wm8785_write(chip, WM8785_R0, value); | 338 | wm8785_write(chip, WM8785_R0, value); |
| 339 | wm8785_write(chip, WM8785_R2, data->wm8785_regs[2]); | ||
| 337 | } | 340 | } |
| 338 | } | 341 | } |
| 339 | 342 | ||
| @@ -411,11 +414,75 @@ static const struct snd_kcontrol_new rolloff_control = { | |||
| 411 | .put = rolloff_put, | 414 | .put = rolloff_put, |
| 412 | }; | 415 | }; |
| 413 | 416 | ||
| 417 | static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) | ||
| 418 | { | ||
| 419 | static const char *const names[2] = { | ||
| 420 | "None", "High-pass Filter" | ||
| 421 | }; | ||
| 422 | |||
| 423 | info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
| 424 | info->count = 1; | ||
| 425 | info->value.enumerated.items = 2; | ||
| 426 | if (info->value.enumerated.item >= 2) | ||
| 427 | info->value.enumerated.item = 1; | ||
| 428 | strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); | ||
| 429 | return 0; | ||
| 430 | } | ||
| 431 | |||
| 432 | static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | ||
| 433 | { | ||
| 434 | struct oxygen *chip = ctl->private_data; | ||
| 435 | struct generic_data *data = chip->model_data; | ||
| 436 | |||
| 437 | value->value.enumerated.item[0] = | ||
| 438 | (data->wm8785_regs[WM8785_R2] & WM8785_HPFR) != 0; | ||
| 439 | return 0; | ||
| 440 | } | ||
| 441 | |||
| 442 | static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) | ||
| 443 | { | ||
| 444 | struct oxygen *chip = ctl->private_data; | ||
| 445 | struct generic_data *data = chip->model_data; | ||
| 446 | unsigned int reg; | ||
| 447 | int changed; | ||
| 448 | |||
| 449 | mutex_lock(&chip->mutex); | ||
| 450 | reg = data->wm8785_regs[WM8785_R2] & ~(WM8785_HPFR | WM8785_HPFL); | ||
| 451 | if (value->value.enumerated.item[0]) | ||
| 452 | reg |= WM8785_HPFR | WM8785_HPFL; | ||
| 453 | changed = reg != data->wm8785_regs[WM8785_R2]; | ||
| 454 | if (changed) | ||
| 455 | wm8785_write(chip, WM8785_R2, reg); | ||
| 456 | mutex_unlock(&chip->mutex); | ||
| 457 | return changed; | ||
| 458 | } | ||
| 459 | |||
| 460 | static const struct snd_kcontrol_new hpf_control = { | ||
| 461 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
| 462 | .name = "ADC Filter Capture Enum", | ||
| 463 | .info = hpf_info, | ||
| 464 | .get = hpf_get, | ||
| 465 | .put = hpf_put, | ||
| 466 | }; | ||
| 467 | |||
| 414 | static int generic_mixer_init(struct oxygen *chip) | 468 | static int generic_mixer_init(struct oxygen *chip) |
| 415 | { | 469 | { |
| 416 | return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); | 470 | return snd_ctl_add(chip->card, snd_ctl_new1(&rolloff_control, chip)); |
| 417 | } | 471 | } |
| 418 | 472 | ||
| 473 | static int generic_wm8785_mixer_init(struct oxygen *chip) | ||
| 474 | { | ||
| 475 | int err; | ||
| 476 | |||
| 477 | err = generic_mixer_init(chip); | ||
| 478 | if (err < 0) | ||
| 479 | return err; | ||
| 480 | err = snd_ctl_add(chip->card, snd_ctl_new1(&hpf_control, chip)); | ||
| 481 | if (err < 0) | ||
| 482 | return err; | ||
| 483 | return 0; | ||
| 484 | } | ||
| 485 | |||
| 419 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); | 486 | static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); |
| 420 | 487 | ||
| 421 | static const struct oxygen_model model_generic = { | 488 | static const struct oxygen_model model_generic = { |
| @@ -423,7 +490,7 @@ static const struct oxygen_model model_generic = { | |||
| 423 | .longname = "C-Media Oxygen HD Audio", | 490 | .longname = "C-Media Oxygen HD Audio", |
| 424 | .chip = "CMI8788", | 491 | .chip = "CMI8788", |
| 425 | .init = generic_init, | 492 | .init = generic_init, |
| 426 | .mixer_init = generic_mixer_init, | 493 | .mixer_init = generic_wm8785_mixer_init, |
| 427 | .cleanup = generic_cleanup, | 494 | .cleanup = generic_cleanup, |
| 428 | .resume = generic_resume, | 495 | .resume = generic_resume, |
| 429 | .get_i2s_mclk = oxygen_default_i2s_mclk, | 496 | .get_i2s_mclk = oxygen_default_i2s_mclk, |
| @@ -455,6 +522,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, | |||
| 455 | switch (id->driver_data) { | 522 | switch (id->driver_data) { |
| 456 | case MODEL_MERIDIAN: | 523 | case MODEL_MERIDIAN: |
| 457 | chip->model.init = meridian_init; | 524 | chip->model.init = meridian_init; |
| 525 | chip->model.mixer_init = generic_mixer_init; | ||
| 458 | chip->model.resume = meridian_resume; | 526 | chip->model.resume = meridian_resume; |
| 459 | chip->model.set_adc_params = set_ak5385_params; | 527 | chip->model.set_adc_params = set_ak5385_params; |
| 460 | chip->model.device_config = PLAYBACK_0_TO_I2S | | 528 | chip->model.device_config = PLAYBACK_0_TO_I2S | |
| @@ -470,6 +538,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, | |||
| 470 | break; | 538 | break; |
| 471 | case MODEL_CLARO_HALO: | 539 | case MODEL_CLARO_HALO: |
| 472 | chip->model.init = claro_halo_init; | 540 | chip->model.init = claro_halo_init; |
| 541 | chip->model.mixer_init = generic_mixer_init; | ||
| 473 | chip->model.cleanup = claro_cleanup; | 542 | chip->model.cleanup = claro_cleanup; |
| 474 | chip->model.suspend = claro_suspend; | 543 | chip->model.suspend = claro_suspend; |
| 475 | chip->model.resume = claro_resume; | 544 | chip->model.resume = claro_resume; |
