13 #include <linux/module.h>
15 #include <linux/kernel.h>
19 #include <linux/i2c.h>
21 #include <linux/slab.h>
37 static const struct reg_default wm8510_reg_defaults[] = {
96 static bool wm8510_volatile(
struct device *
dev,
unsigned int reg)
106 #define WM8510_POWER1_BIASEN 0x08
107 #define WM8510_POWER1_BUFIOEN 0x10
109 #define wm8510_reset(c) snd_soc_write(c, WM8510_RESET, 0)
116 static const char *wm8510_companding[] = {
"Off",
"NC",
"u-law",
"A-law" };
117 static const char *wm8510_deemp[] = {
"None",
"32kHz",
"44.1kHz",
"48kHz" };
118 static const char *wm8510_alc[] = {
"ALC",
"Limiter" };
120 static const struct soc_enum wm8510_enum[] = {
131 SOC_ENUM(
"DAC Companding", wm8510_enum[1]),
132 SOC_ENUM(
"ADC Companding", wm8510_enum[0]),
134 SOC_ENUM(
"Playback De-emphasis", wm8510_enum[2]),
160 SOC_ENUM(
"ALC Capture Mode", wm8510_enum[3]),
207 &wm8510_speaker_mixer_controls[0],
210 &wm8510_mono_mixer_controls[0],
220 &wm8510_micpga_controls[0],
223 &wm8510_boost_controls[0],
238 {
"Mono Mixer",
"PCM Playback Switch",
"DAC"},
239 {
"Mono Mixer",
"Aux Playback Switch",
"Aux Input"},
240 {
"Mono Mixer",
"Line Bypass Switch",
"Boost Mixer"},
243 {
"Speaker Mixer",
"PCM Playback Switch",
"DAC"},
244 {
"Speaker Mixer",
"Aux Playback Switch",
"Aux Input"},
245 {
"Speaker Mixer",
"Line Bypass Switch",
"Boost Mixer"},
248 {
"Mono Out",
NULL,
"Mono Mixer"},
249 {
"MONOOUT",
NULL,
"Mono Out"},
250 {
"SpkN Out",
NULL,
"Speaker Mixer"},
251 {
"SpkP Out",
NULL,
"Speaker Mixer"},
252 {
"SPKOUTN",
NULL,
"SpkN Out"},
253 {
"SPKOUTP",
NULL,
"SpkP Out"},
256 {
"Mic PGA",
"MICN Switch",
"MICN"},
257 {
"Mic PGA",
"MICP Switch",
"MICP"},
258 {
"Mic PGA",
"AUX Switch",
"Aux Input" },
261 {
"Boost Mixer",
"Mic PGA Switch",
"Mic PGA"},
262 {
"Boost Mixer",
"Mic Volume",
"MICP"},
263 {
"Boost Mixer",
"Aux Volume",
"Aux Input"},
265 {
"ADC",
NULL,
"Boost Mixer"},
278 #define FIXED_PLL_SIZE ((1 << 24) * 10)
282 unsigned long long Kpart;
283 unsigned int K, Ndiv, Nmod;
293 if ((Ndiv < 6) || (Ndiv > 12))
295 "WM8510 N value %u outwith recommended range!d\n",
304 K = Kpart & 0xFFFFFFFF;
316 static int wm8510_set_dai_pll(
struct snd_soc_dai *codec_dai,
int pll_id,
317 int source,
unsigned int freq_in,
unsigned int freq_out)
322 if (freq_in == 0 || freq_out == 0) {
352 static int wm8510_set_dai_clkdiv(
struct snd_soc_dai *codec_dai,
386 static int wm8510_set_dai_fmt(
struct snd_soc_dai *codec_dai,
506 static int wm8510_set_bias_level(
struct snd_soc_codec *codec,
509 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
545 #define WM8510_RATES (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 |\
546 SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_22050 |\
547 SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000)
549 #define WM8510_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
550 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
553 .hw_params = wm8510_pcm_hw_params,
554 .digital_mute = wm8510_mute,
555 .set_fmt = wm8510_set_dai_fmt,
556 .set_clkdiv = wm8510_set_dai_clkdiv,
557 .set_pll = wm8510_set_dai_pll,
561 .name =
"wm8510-hifi",
563 .stream_name =
"Playback",
569 .stream_name =
"Capture",
574 .ops = &wm8510_dai_ops,
575 .symmetric_rates = 1,
611 struct wm8510_priv *wm8510 = snd_soc_codec_get_drvdata(codec);
619 .probe = wm8510_probe,
620 .remove = wm8510_remove,
621 .suspend = wm8510_suspend,
622 .resume = wm8510_resume,
623 .set_bias_level = wm8510_set_bias_level,
625 .controls = wm8510_snd_controls,
626 .num_controls =
ARRAY_SIZE(wm8510_snd_controls),
627 .dapm_widgets = wm8510_dapm_widgets,
628 .num_dapm_widgets =
ARRAY_SIZE(wm8510_dapm_widgets),
629 .dapm_routes = wm8510_dapm_routes,
630 .num_dapm_routes =
ARRAY_SIZE(wm8510_dapm_routes),
634 { .compatible =
"wlf,wm8510" },
638 static const struct regmap_config wm8510_regmap = {
643 .reg_defaults = wm8510_reg_defaults,
644 .num_reg_defaults =
ARRAY_SIZE(wm8510_reg_defaults),
647 .volatile_reg = wm8510_volatile,
650 #if defined(CONFIG_SPI_MASTER)
662 if (IS_ERR(wm8510->
regmap))
663 return PTR_ERR(wm8510->
regmap);
665 spi_set_drvdata(spi, wm8510);
668 &soc_codec_dev_wm8510, &wm8510_dai, 1);
679 static struct spi_driver wm8510_spi_driver = {
683 .of_match_table = wm8510_of_match,
685 .probe = wm8510_spi_probe,
690 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
703 if (IS_ERR(wm8510->
regmap))
704 return PTR_ERR(wm8510->
regmap);
706 i2c_set_clientdata(i2c, wm8510);
709 &soc_codec_dev_wm8510, &wm8510_dai, 1);
726 static struct i2c_driver wm8510_i2c_driver = {
730 .of_match_table = wm8510_of_match,
732 .probe = wm8510_i2c_probe,
734 .id_table = wm8510_i2c_id,
738 static int __init wm8510_modinit(
void)
741 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
742 ret = i2c_add_driver(&wm8510_i2c_driver);
748 #if defined(CONFIG_SPI_MASTER)
759 static void __exit wm8510_exit(
void)
761 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
764 #if defined(CONFIG_SPI_MASTER)
765 spi_unregister_driver(&wm8510_spi_driver);