wm8731.c (0cce284537fb42d9c28b9b31038ffc9b464555f5) | wm8731.c (cde596c7c07343789e3e0f1c09fc7d3c756c88d0) |
---|---|
1/* 2 * wm8731.c -- WM8731 ALSA SoC Audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2006-12 Wolfson Microelectronics, plc 6 * 7 * Author: Richard Purdie <richard@openedhand.com> 8 * --- 74 unchanged lines hidden (view full) --- 83 84static const char *wm8731_input_select[] = {"Line In", "Mic"}; 85 86static SOC_ENUM_SINGLE_DECL(wm8731_insel_enum, 87 WM8731_APANA, 2, wm8731_input_select); 88 89static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; 90 | 1/* 2 * wm8731.c -- WM8731 ALSA SoC Audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * Copyright 2006-12 Wolfson Microelectronics, plc 6 * 7 * Author: Richard Purdie <richard@openedhand.com> 8 * --- 74 unchanged lines hidden (view full) --- 83 84static const char *wm8731_input_select[] = {"Line In", "Mic"}; 85 86static SOC_ENUM_SINGLE_DECL(wm8731_insel_enum, 87 WM8731_APANA, 2, wm8731_input_select); 88 89static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; 90 |
91static int wm8731_set_deemph(struct snd_soc_codec *codec) | 91static int wm8731_set_deemph(struct snd_soc_component *component) |
92{ | 92{ |
93 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 93 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); |
94 int val, i, best; 95 96 /* If we're using deemphasis select the nearest available sample 97 * rate. 98 */ 99 if (wm8731->deemph) { 100 best = 1; 101 for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) { 102 if (abs(wm8731_deemph[i] - wm8731->playback_fs) < 103 abs(wm8731_deemph[best] - wm8731->playback_fs)) 104 best = i; 105 } 106 107 val = best << 1; 108 } else { 109 best = 0; 110 val = 0; 111 } 112 | 94 int val, i, best; 95 96 /* If we're using deemphasis select the nearest available sample 97 * rate. 98 */ 99 if (wm8731->deemph) { 100 best = 1; 101 for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) { 102 if (abs(wm8731_deemph[i] - wm8731->playback_fs) < 103 abs(wm8731_deemph[best] - wm8731->playback_fs)) 104 best = i; 105 } 106 107 val = best << 1; 108 } else { 109 best = 0; 110 val = 0; 111 } 112 |
113 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", | 113 dev_dbg(component->dev, "Set deemphasis %d (%dHz)\n", |
114 best, wm8731_deemph[best]); 115 | 114 best, wm8731_deemph[best]); 115 |
116 return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val); | 116 return snd_soc_component_update_bits(component, WM8731_APDIGI, 0x6, val); |
117} 118 119static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, 120 struct snd_ctl_elem_value *ucontrol) 121{ | 117} 118 119static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, 120 struct snd_ctl_elem_value *ucontrol) 121{ |
122 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 123 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 122 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 123 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); |
124 125 ucontrol->value.integer.value[0] = wm8731->deemph; 126 127 return 0; 128} 129 130static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, 131 struct snd_ctl_elem_value *ucontrol) 132{ | 124 125 ucontrol->value.integer.value[0] = wm8731->deemph; 126 127 return 0; 128} 129 130static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, 131 struct snd_ctl_elem_value *ucontrol) 132{ |
133 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 134 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 133 struct snd_soc_component *component = snd_soc_kcontrol_component(kcontrol); 134 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); |
135 unsigned int deemph = ucontrol->value.integer.value[0]; 136 int ret = 0; 137 138 if (deemph > 1) 139 return -EINVAL; 140 141 mutex_lock(&wm8731->lock); 142 if (wm8731->deemph != deemph) { 143 wm8731->deemph = deemph; 144 | 135 unsigned int deemph = ucontrol->value.integer.value[0]; 136 int ret = 0; 137 138 if (deemph > 1) 139 return -EINVAL; 140 141 mutex_lock(&wm8731->lock); 142 if (wm8731->deemph != deemph) { 143 wm8731->deemph = deemph; 144 |
145 wm8731_set_deemph(codec); | 145 wm8731_set_deemph(component); |
146 147 ret = 1; 148 } 149 mutex_unlock(&wm8731->lock); 150 151 return ret; 152} 153 --- 55 unchanged lines hidden (view full) --- 209SND_SOC_DAPM_INPUT("MICIN"), 210SND_SOC_DAPM_INPUT("RLINEIN"), 211SND_SOC_DAPM_INPUT("LLINEIN"), 212}; 213 214static int wm8731_check_osc(struct snd_soc_dapm_widget *source, 215 struct snd_soc_dapm_widget *sink) 216{ | 146 147 ret = 1; 148 } 149 mutex_unlock(&wm8731->lock); 150 151 return ret; 152} 153 --- 55 unchanged lines hidden (view full) --- 209SND_SOC_DAPM_INPUT("MICIN"), 210SND_SOC_DAPM_INPUT("RLINEIN"), 211SND_SOC_DAPM_INPUT("LLINEIN"), 212}; 213 214static int wm8731_check_osc(struct snd_soc_dapm_widget *source, 215 struct snd_soc_dapm_widget *sink) 216{ |
217 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(source->dapm); 218 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 217 struct snd_soc_component *component = snd_soc_dapm_to_component(source->dapm); 218 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); |
219 220 return wm8731->sysclk_type == WM8731_SYSCLK_XTAL; 221} 222 223static const struct snd_soc_dapm_route wm8731_intercon[] = { 224 {"DAC", NULL, "OSC", wm8731_check_osc}, 225 {"ADC", NULL, "OSC", wm8731_check_osc}, 226 {"DAC", NULL, "ACTIVE"}, --- 105 unchanged lines hidden (view full) --- 332 } 333 return 0; 334} 335 336static int wm8731_hw_params(struct snd_pcm_substream *substream, 337 struct snd_pcm_hw_params *params, 338 struct snd_soc_dai *dai) 339{ | 219 220 return wm8731->sysclk_type == WM8731_SYSCLK_XTAL; 221} 222 223static const struct snd_soc_dapm_route wm8731_intercon[] = { 224 {"DAC", NULL, "OSC", wm8731_check_osc}, 225 {"ADC", NULL, "OSC", wm8731_check_osc}, 226 {"DAC", NULL, "ACTIVE"}, --- 105 unchanged lines hidden (view full) --- 332 } 333 return 0; 334} 335 336static int wm8731_hw_params(struct snd_pcm_substream *substream, 337 struct snd_pcm_hw_params *params, 338 struct snd_soc_dai *dai) 339{ |
340 struct snd_soc_codec *codec = dai->codec; 341 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 342 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; | 340 struct snd_soc_component *component = dai->component; 341 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); 342 u16 iface = snd_soc_component_read32(component, WM8731_IFACE) & 0xfff3; |
343 int i = get_coeff(wm8731->sysclk, params_rate(params)); 344 u16 srate = (coeff_div[i].sr << 2) | 345 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 346 347 wm8731->playback_fs = params_rate(params); 348 | 343 int i = get_coeff(wm8731->sysclk, params_rate(params)); 344 u16 srate = (coeff_div[i].sr << 2) | 345 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 346 347 wm8731->playback_fs = params_rate(params); 348 |
349 snd_soc_write(codec, WM8731_SRATE, srate); | 349 snd_soc_component_write(component, WM8731_SRATE, srate); |
350 351 /* bit size */ 352 switch (params_width(params)) { 353 case 16: 354 break; 355 case 20: 356 iface |= 0x0004; 357 break; 358 case 24: 359 iface |= 0x0008; 360 break; 361 case 32: 362 iface |= 0x000c; 363 break; 364 } 365 | 350 351 /* bit size */ 352 switch (params_width(params)) { 353 case 16: 354 break; 355 case 20: 356 iface |= 0x0004; 357 break; 358 case 24: 359 iface |= 0x0008; 360 break; 361 case 32: 362 iface |= 0x000c; 363 break; 364 } 365 |
366 wm8731_set_deemph(codec); | 366 wm8731_set_deemph(component); |
367 | 367 |
368 snd_soc_write(codec, WM8731_IFACE, iface); | 368 snd_soc_component_write(component, WM8731_IFACE, iface); |
369 return 0; 370} 371 372static int wm8731_mute(struct snd_soc_dai *dai, int mute) 373{ | 369 return 0; 370} 371 372static int wm8731_mute(struct snd_soc_dai *dai, int mute) 373{ |
374 struct snd_soc_codec *codec = dai->codec; 375 u16 mute_reg = snd_soc_read(codec, WM8731_APDIGI) & 0xfff7; | 374 struct snd_soc_component *component = dai->component; 375 u16 mute_reg = snd_soc_component_read32(component, WM8731_APDIGI) & 0xfff7; |
376 377 if (mute) | 376 377 if (mute) |
378 snd_soc_write(codec, WM8731_APDIGI, mute_reg | 0x8); | 378 snd_soc_component_write(component, WM8731_APDIGI, mute_reg | 0x8); |
379 else | 379 else |
380 snd_soc_write(codec, WM8731_APDIGI, mute_reg); | 380 snd_soc_component_write(component, WM8731_APDIGI, mute_reg); |
381 return 0; 382} 383 384static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, 385 int clk_id, unsigned int freq, int dir) 386{ | 381 return 0; 382} 383 384static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, 385 int clk_id, unsigned int freq, int dir) 386{ |
387 struct snd_soc_codec *codec = codec_dai->codec; 388 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 389 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 387 struct snd_soc_component *component = codec_dai->component; 388 struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); 389 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); |
390 391 switch (clk_id) { 392 case WM8731_SYSCLK_XTAL: 393 case WM8731_SYSCLK_MCLK: 394 if (wm8731->mclk && clk_set_rate(wm8731->mclk, freq)) 395 return -EINVAL; 396 wm8731->sysclk_type = clk_id; 397 break; --- 26 unchanged lines hidden (view full) --- 424 425 return 0; 426} 427 428 429static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, 430 unsigned int fmt) 431{ | 390 391 switch (clk_id) { 392 case WM8731_SYSCLK_XTAL: 393 case WM8731_SYSCLK_MCLK: 394 if (wm8731->mclk && clk_set_rate(wm8731->mclk, freq)) 395 return -EINVAL; 396 wm8731->sysclk_type = clk_id; 397 break; --- 26 unchanged lines hidden (view full) --- 424 425 return 0; 426} 427 428 429static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, 430 unsigned int fmt) 431{ |
432 struct snd_soc_codec *codec = codec_dai->codec; | 432 struct snd_soc_component *component = codec_dai->component; |
433 u16 iface = 0; 434 435 /* set master/slave audio interface */ 436 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 437 case SND_SOC_DAIFMT_CBM_CFM: 438 iface |= 0x0040; 439 break; 440 case SND_SOC_DAIFMT_CBS_CFS: --- 35 unchanged lines hidden (view full) --- 476 case SND_SOC_DAIFMT_NB_IF: 477 iface |= 0x0010; 478 break; 479 default: 480 return -EINVAL; 481 } 482 483 /* set iface */ | 433 u16 iface = 0; 434 435 /* set master/slave audio interface */ 436 switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 437 case SND_SOC_DAIFMT_CBM_CFM: 438 iface |= 0x0040; 439 break; 440 case SND_SOC_DAIFMT_CBS_CFS: --- 35 unchanged lines hidden (view full) --- 476 case SND_SOC_DAIFMT_NB_IF: 477 iface |= 0x0010; 478 break; 479 default: 480 return -EINVAL; 481 } 482 483 /* set iface */ |
484 snd_soc_write(codec, WM8731_IFACE, iface); | 484 snd_soc_component_write(component, WM8731_IFACE, iface); |
485 return 0; 486} 487 | 485 return 0; 486} 487 |
488static int wm8731_set_bias_level(struct snd_soc_codec *codec, | 488static int wm8731_set_bias_level(struct snd_soc_component *component, |
489 enum snd_soc_bias_level level) 490{ | 489 enum snd_soc_bias_level level) 490{ |
491 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 491 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(component); |
492 int ret; 493 u16 reg; 494 495 switch (level) { 496 case SND_SOC_BIAS_ON: 497 if (wm8731->mclk) { 498 ret = clk_prepare_enable(wm8731->mclk); 499 if (ret) 500 return ret; 501 } 502 break; 503 case SND_SOC_BIAS_PREPARE: 504 break; 505 case SND_SOC_BIAS_STANDBY: | 492 int ret; 493 u16 reg; 494 495 switch (level) { 496 case SND_SOC_BIAS_ON: 497 if (wm8731->mclk) { 498 ret = clk_prepare_enable(wm8731->mclk); 499 if (ret) 500 return ret; 501 } 502 break; 503 case SND_SOC_BIAS_PREPARE: 504 break; 505 case SND_SOC_BIAS_STANDBY: |
506 if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { | 506 if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { |
507 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 508 wm8731->supplies); 509 if (ret != 0) 510 return ret; 511 512 regcache_sync(wm8731->regmap); 513 } 514 515 /* Clear PWROFF, gate CLKOUT, everything else as-is */ | 507 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), 508 wm8731->supplies); 509 if (ret != 0) 510 return ret; 511 512 regcache_sync(wm8731->regmap); 513 } 514 515 /* Clear PWROFF, gate CLKOUT, everything else as-is */ |
516 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f; 517 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); | 516 reg = snd_soc_component_read32(component, WM8731_PWR) & 0xff7f; 517 snd_soc_component_write(component, WM8731_PWR, reg | 0x0040); |
518 break; 519 case SND_SOC_BIAS_OFF: 520 if (wm8731->mclk) 521 clk_disable_unprepare(wm8731->mclk); | 518 break; 519 case SND_SOC_BIAS_OFF: 520 if (wm8731->mclk) 521 clk_disable_unprepare(wm8731->mclk); |
522 snd_soc_write(codec, WM8731_PWR, 0xffff); | 522 snd_soc_component_write(component, WM8731_PWR, 0xffff); |
523 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 524 wm8731->supplies); 525 regcache_mark_dirty(wm8731->regmap); 526 break; 527 } 528 return 0; 529} 530 531static int wm8731_startup(struct snd_pcm_substream *substream, 532 struct snd_soc_dai *dai) 533{ | 523 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), 524 wm8731->supplies); 525 regcache_mark_dirty(wm8731->regmap); 526 break; 527 } 528 return 0; 529} 530 531static int wm8731_startup(struct snd_pcm_substream *substream, 532 struct snd_soc_dai *dai) 533{ |
534 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(dai->codec); | 534 struct wm8731_priv *wm8731 = snd_soc_component_get_drvdata(dai->component); |
535 536 if (wm8731->constraints) 537 snd_pcm_hw_constraint_list(substream->runtime, 0, 538 SNDRV_PCM_HW_PARAM_RATE, 539 wm8731->constraints); 540 541 return 0; 542} --- 80 unchanged lines hidden (view full) --- 623 624err_regulator_enable: 625 /* Regulators will be enabled by bias management */ 626 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 627 628 return ret; 629} 630 | 535 536 if (wm8731->constraints) 537 snd_pcm_hw_constraint_list(substream->runtime, 0, 538 SNDRV_PCM_HW_PARAM_RATE, 539 wm8731->constraints); 540 541 return 0; 542} --- 80 unchanged lines hidden (view full) --- 623 624err_regulator_enable: 625 /* Regulators will be enabled by bias management */ 626 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); 627 628 return ret; 629} 630 |
631static const struct snd_soc_codec_driver soc_codec_dev_wm8731 = { 632 .set_bias_level = wm8731_set_bias_level, 633 .suspend_bias_off = true, 634 635 .component_driver = { 636 .controls = wm8731_snd_controls, 637 .num_controls = ARRAY_SIZE(wm8731_snd_controls), 638 .dapm_widgets = wm8731_dapm_widgets, 639 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), 640 .dapm_routes = wm8731_intercon, 641 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), 642 }, | 631static const struct snd_soc_component_driver soc_component_dev_wm8731 = { 632 .set_bias_level = wm8731_set_bias_level, 633 .controls = wm8731_snd_controls, 634 .num_controls = ARRAY_SIZE(wm8731_snd_controls), 635 .dapm_widgets = wm8731_dapm_widgets, 636 .num_dapm_widgets = ARRAY_SIZE(wm8731_dapm_widgets), 637 .dapm_routes = wm8731_intercon, 638 .num_dapm_routes = ARRAY_SIZE(wm8731_intercon), 639 .suspend_bias_off = 1, 640 .idle_bias_on = 1, 641 .use_pmdown_time = 1, 642 .endianness = 1, 643 .non_legacy_dai_naming = 1, |
643}; 644 645static const struct of_device_id wm8731_of_match[] = { 646 { .compatible = "wlf,wm8731", }, 647 { } 648}; 649 650MODULE_DEVICE_TABLE(of, wm8731_of_match); --- 48 unchanged lines hidden (view full) --- 699 ret); 700 return ret; 701 } 702 703 ret = wm8731_hw_init(&spi->dev, wm8731); 704 if (ret != 0) 705 return ret; 706 | 644}; 645 646static const struct of_device_id wm8731_of_match[] = { 647 { .compatible = "wlf,wm8731", }, 648 { } 649}; 650 651MODULE_DEVICE_TABLE(of, wm8731_of_match); --- 48 unchanged lines hidden (view full) --- 700 ret); 701 return ret; 702 } 703 704 ret = wm8731_hw_init(&spi->dev, wm8731); 705 if (ret != 0) 706 return ret; 707 |
707 ret = snd_soc_register_codec(&spi->dev, 708 &soc_codec_dev_wm8731, &wm8731_dai, 1); | 708 ret = devm_snd_soc_register_component(&spi->dev, 709 &soc_component_dev_wm8731, &wm8731_dai, 1); |
709 if (ret != 0) { 710 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); 711 return ret; 712 } 713 714 return 0; 715} 716 717static int wm8731_spi_remove(struct spi_device *spi) 718{ | 710 if (ret != 0) { 711 dev_err(&spi->dev, "Failed to register CODEC: %d\n", ret); 712 return ret; 713 } 714 715 return 0; 716} 717 718static int wm8731_spi_remove(struct spi_device *spi) 719{ |
719 snd_soc_unregister_codec(&spi->dev); | |
720 return 0; 721} 722 723static struct spi_driver wm8731_spi_driver = { 724 .driver = { 725 .name = "wm8731", 726 .of_match_table = wm8731_of_match, 727 }, --- 42 unchanged lines hidden (view full) --- 770 ret); 771 return ret; 772 } 773 774 ret = wm8731_hw_init(&i2c->dev, wm8731); 775 if (ret != 0) 776 return ret; 777 | 720 return 0; 721} 722 723static struct spi_driver wm8731_spi_driver = { 724 .driver = { 725 .name = "wm8731", 726 .of_match_table = wm8731_of_match, 727 }, --- 42 unchanged lines hidden (view full) --- 770 ret); 771 return ret; 772 } 773 774 ret = wm8731_hw_init(&i2c->dev, wm8731); 775 if (ret != 0) 776 return ret; 777 |
778 ret = snd_soc_register_codec(&i2c->dev, 779 &soc_codec_dev_wm8731, &wm8731_dai, 1); | 778 ret = devm_snd_soc_register_component(&i2c->dev, 779 &soc_component_dev_wm8731, &wm8731_dai, 1); |
780 if (ret != 0) { 781 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); 782 return ret; 783 } 784 785 return 0; 786} 787 788static int wm8731_i2c_remove(struct i2c_client *client) 789{ | 780 if (ret != 0) { 781 dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret); 782 return ret; 783 } 784 785 return 0; 786} 787 788static int wm8731_i2c_remove(struct i2c_client *client) 789{ |
790 snd_soc_unregister_codec(&client->dev); | |
791 return 0; 792} 793 794static const struct i2c_device_id wm8731_i2c_id[] = { 795 { "wm8731", 0 }, 796 { } 797}; 798MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); --- 47 unchanged lines hidden --- | 790 return 0; 791} 792 793static const struct i2c_device_id wm8731_i2c_id[] = { 794 { "wm8731", 0 }, 795 { } 796}; 797MODULE_DEVICE_TABLE(i2c, wm8731_i2c_id); --- 47 unchanged lines hidden --- |