Loading Documentation/devicetree/bindings/sound/wm8580.txt +2 −2 Original line number Diff line number Diff line WM8580 audio CODEC WM8580 and WM8581 audio CODEC This device supports I2C only. Required properties: - compatible : "wlf,wm8580" - compatible : "wlf,wm8580", "wlf,wm8581" - reg : the I2C address of the device. Loading sound/soc/codecs/Kconfig +3 −1 Original line number Diff line number Diff line Loading @@ -938,7 +938,7 @@ config SND_SOC_WM8523 depends on I2C config SND_SOC_WM8580 tristate "Wolfson Microelectronics WM8523 CODEC" tristate "Wolfson Microelectronics WM8580 and WM8581 CODECs" depends on I2C config SND_SOC_WM8711 Loading Loading @@ -1072,12 +1072,14 @@ config SND_SOC_WM8998 config SND_SOC_WM9081 tristate depends on I2C config SND_SOC_WM9090 tristate config SND_SOC_WM9705 tristate select REGMAP_AC97 config SND_SOC_WM9712 tristate Loading sound/soc/codecs/wm8580.c +90 −33 Original line number Diff line number Diff line /* * wm8580.c -- WM8580 ALSA Soc Audio driver * wm8580.c -- WM8580 and WM8581 ALSA Soc Audio driver * * Copyright 2008-12 Wolfson Microelectronics PLC. * Loading @@ -12,6 +12,9 @@ * The WM8580 is a multichannel codec with S/PDIF support, featuring six * DAC channels and two ADC channels. * * The WM8581 is a multichannel codec with S/PDIF support, featuring eight * DAC channels and two ADC channels. * * Currently only the primary audio interface is supported - S/PDIF and * the secondary audio interfaces are not. */ Loading Loading @@ -65,6 +68,8 @@ #define WM8580_DIGITAL_ATTENUATION_DACR2 0x17 #define WM8580_DIGITAL_ATTENUATION_DACL3 0x18 #define WM8580_DIGITAL_ATTENUATION_DACR3 0x19 #define WM8581_DIGITAL_ATTENUATION_DACL4 0x1A #define WM8581_DIGITAL_ATTENUATION_DACR4 0x1B #define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C #define WM8580_ADC_CONTROL1 0x1D #define WM8580_SPDTXCHAN0 0x1E Loading Loading @@ -236,12 +241,17 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = { "PVDD", }; struct wm8580_driver_data { int num_dacs; }; /* codec private data */ struct wm8580_priv { struct regmap *regmap; struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; struct pll_state a; struct pll_state b; const struct wm8580_driver_data *drvdata; int sysclk[2]; }; Loading Loading @@ -306,6 +316,19 @@ SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1), SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), }; static const struct snd_kcontrol_new wm8581_snd_controls[] = { SOC_DOUBLE_R_EXT_TLV("DAC4 Playback Volume", WM8581_DIGITAL_ATTENUATION_DACL4, WM8581_DIGITAL_ATTENUATION_DACR4, 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv), SOC_SINGLE("DAC4 Deemphasis Switch", WM8580_DAC_CONTROL3, 3, 1, 0), SOC_DOUBLE("DAC4 Invert Switch", WM8580_DAC_CONTROL4, 8, 7, 1, 0), SOC_SINGLE("DAC4 Switch", WM8580_DAC_CONTROL5, 3, 1, 1), }; static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), Loading @@ -324,6 +347,13 @@ SND_SOC_DAPM_INPUT("AINL"), SND_SOC_DAPM_INPUT("AINR"), }; static const struct snd_soc_dapm_widget wm8581_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC4", "Playback", WM8580_PWRDN1, 5, 1), SND_SOC_DAPM_OUTPUT("VOUT4L"), SND_SOC_DAPM_OUTPUT("VOUT4R"), }; static const struct snd_soc_dapm_route wm8580_dapm_routes[] = { { "VOUT1L", NULL, "DAC1" }, { "VOUT1R", NULL, "DAC1" }, Loading @@ -338,6 +368,11 @@ static const struct snd_soc_dapm_route wm8580_dapm_routes[] = { { "ADC", NULL, "AINR" }, }; static const struct snd_soc_dapm_route wm8581_dapm_routes[] = { { "VOUT4L", NULL, "DAC4" }, { "VOUT4R", NULL, "DAC4" }, }; /* PLL divisors */ struct _pll_div { u32 prescale:1; Loading Loading @@ -815,10 +850,21 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, return 0; } static int wm8580_playback_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 1, wm8580->drvdata->num_dacs * 2); } #define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops wm8580_dai_ops_playback = { .startup = wm8580_playback_startup, .set_sysclk = wm8580_set_sysclk, .hw_params = wm8580_paif_hw_params, .set_fmt = wm8580_set_paif_dai_fmt, Loading @@ -842,7 +888,6 @@ static struct snd_soc_dai_driver wm8580_dai[] = { .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 6, .rates = SNDRV_PCM_RATE_8000_192000, .formats = WM8580_FORMATS, }, Loading @@ -865,8 +910,22 @@ static struct snd_soc_dai_driver wm8580_dai[] = { static int wm8580_probe(struct snd_soc_codec *codec) { struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); int ret = 0; switch (wm8580->drvdata->num_dacs) { case 4: snd_soc_add_codec_controls(codec, wm8581_snd_controls, ARRAY_SIZE(wm8581_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8581_dapm_widgets, ARRAY_SIZE(wm8581_dapm_widgets)); snd_soc_dapm_add_routes(dapm, wm8581_dapm_routes, ARRAY_SIZE(wm8581_dapm_routes)); break; default: break; } ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); if (ret != 0) { Loading Loading @@ -914,12 +973,6 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = { }, }; static const struct of_device_id wm8580_of_match[] = { { .compatible = "wlf,wm8580" }, { }, }; MODULE_DEVICE_TABLE(of, wm8580_of_match); static const struct regmap_config wm8580_regmap = { .reg_bits = 7, .val_bits = 9, Loading @@ -932,10 +985,25 @@ static const struct regmap_config wm8580_regmap = { .volatile_reg = wm8580_volatile, }; #if IS_ENABLED(CONFIG_I2C) static const struct wm8580_driver_data wm8580_data = { .num_dacs = 3, }; static const struct wm8580_driver_data wm8581_data = { .num_dacs = 4, }; static const struct of_device_id wm8580_of_match[] = { { .compatible = "wlf,wm8580", .data = &wm8580_data }, { .compatible = "wlf,wm8581", .data = &wm8581_data }, { }, }; MODULE_DEVICE_TABLE(of, wm8580_of_match); static int wm8580_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { const struct of_device_id *of_id; struct wm8580_priv *wm8580; int ret, i; Loading @@ -960,6 +1028,15 @@ static int wm8580_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8580); of_id = of_match_device(wm8580_of_match, &i2c->dev); if (of_id) wm8580->drvdata = of_id->data; if (!wm8580->drvdata) { dev_err(&i2c->dev, "failed to find driver data\n"); return -EINVAL; } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai)); Loading @@ -973,7 +1050,8 @@ static int wm8580_i2c_remove(struct i2c_client *client) } static const struct i2c_device_id wm8580_i2c_id[] = { { "wm8580", 0 }, { "wm8580", (kernel_ulong_t)&wm8580_data }, { "wm8581", (kernel_ulong_t)&wm8581_data }, { } }; MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id); Loading @@ -987,31 +1065,10 @@ static struct i2c_driver wm8580_i2c_driver = { .remove = wm8580_i2c_remove, .id_table = wm8580_i2c_id, }; #endif static int __init wm8580_modinit(void) { int ret = 0; #if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8580_i2c_driver); if (ret != 0) { pr_err("Failed to register WM8580 I2C driver: %d\n", ret); } #endif return ret; } module_init(wm8580_modinit); static void __exit wm8580_exit(void) { #if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8580_i2c_driver); #endif } module_exit(wm8580_exit); module_i2c_driver(wm8580_i2c_driver); MODULE_DESCRIPTION("ASoC WM8580 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_AUTHOR("Matt Flax <flatmax@flatmax.org>"); MODULE_LICENSE("GPL"); sound/soc/codecs/wm8753.h +0 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,4 @@ #define WM8753_VXCLK_DIV_8 (3 << 6) #define WM8753_VXCLK_DIV_16 (4 << 6) #define WM8753_DAI_HIFI 0 #define WM8753_DAI_VOICE 1 #endif sound/soc/codecs/wm8978.h +1 −1 Original line number Diff line number Diff line Loading @@ -78,8 +78,8 @@ enum wm8978_clk_id { }; enum wm8978_sysclk_src { WM8978_MCLK = 0, WM8978_PLL, WM8978_MCLK }; #endif /* __WM8978_H__ */ Loading
Documentation/devicetree/bindings/sound/wm8580.txt +2 −2 Original line number Diff line number Diff line WM8580 audio CODEC WM8580 and WM8581 audio CODEC This device supports I2C only. Required properties: - compatible : "wlf,wm8580" - compatible : "wlf,wm8580", "wlf,wm8581" - reg : the I2C address of the device. Loading
sound/soc/codecs/Kconfig +3 −1 Original line number Diff line number Diff line Loading @@ -938,7 +938,7 @@ config SND_SOC_WM8523 depends on I2C config SND_SOC_WM8580 tristate "Wolfson Microelectronics WM8523 CODEC" tristate "Wolfson Microelectronics WM8580 and WM8581 CODECs" depends on I2C config SND_SOC_WM8711 Loading Loading @@ -1072,12 +1072,14 @@ config SND_SOC_WM8998 config SND_SOC_WM9081 tristate depends on I2C config SND_SOC_WM9090 tristate config SND_SOC_WM9705 tristate select REGMAP_AC97 config SND_SOC_WM9712 tristate Loading
sound/soc/codecs/wm8580.c +90 −33 Original line number Diff line number Diff line /* * wm8580.c -- WM8580 ALSA Soc Audio driver * wm8580.c -- WM8580 and WM8581 ALSA Soc Audio driver * * Copyright 2008-12 Wolfson Microelectronics PLC. * Loading @@ -12,6 +12,9 @@ * The WM8580 is a multichannel codec with S/PDIF support, featuring six * DAC channels and two ADC channels. * * The WM8581 is a multichannel codec with S/PDIF support, featuring eight * DAC channels and two ADC channels. * * Currently only the primary audio interface is supported - S/PDIF and * the secondary audio interfaces are not. */ Loading Loading @@ -65,6 +68,8 @@ #define WM8580_DIGITAL_ATTENUATION_DACR2 0x17 #define WM8580_DIGITAL_ATTENUATION_DACL3 0x18 #define WM8580_DIGITAL_ATTENUATION_DACR3 0x19 #define WM8581_DIGITAL_ATTENUATION_DACL4 0x1A #define WM8581_DIGITAL_ATTENUATION_DACR4 0x1B #define WM8580_MASTER_DIGITAL_ATTENUATION 0x1C #define WM8580_ADC_CONTROL1 0x1D #define WM8580_SPDTXCHAN0 0x1E Loading Loading @@ -236,12 +241,17 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = { "PVDD", }; struct wm8580_driver_data { int num_dacs; }; /* codec private data */ struct wm8580_priv { struct regmap *regmap; struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; struct pll_state a; struct pll_state b; const struct wm8580_driver_data *drvdata; int sysclk[2]; }; Loading Loading @@ -306,6 +316,19 @@ SOC_DOUBLE("Capture Switch", WM8580_ADC_CONTROL1, 0, 1, 1, 1), SOC_SINGLE("Capture High-Pass Filter Switch", WM8580_ADC_CONTROL1, 4, 1, 0), }; static const struct snd_kcontrol_new wm8581_snd_controls[] = { SOC_DOUBLE_R_EXT_TLV("DAC4 Playback Volume", WM8581_DIGITAL_ATTENUATION_DACL4, WM8581_DIGITAL_ATTENUATION_DACR4, 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv), SOC_SINGLE("DAC4 Deemphasis Switch", WM8580_DAC_CONTROL3, 3, 1, 0), SOC_DOUBLE("DAC4 Invert Switch", WM8580_DAC_CONTROL4, 8, 7, 1, 0), SOC_SINGLE("DAC4 Switch", WM8580_DAC_CONTROL5, 3, 1, 1), }; static const struct snd_soc_dapm_widget wm8580_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC1", "Playback", WM8580_PWRDN1, 2, 1), SND_SOC_DAPM_DAC("DAC2", "Playback", WM8580_PWRDN1, 3, 1), Loading @@ -324,6 +347,13 @@ SND_SOC_DAPM_INPUT("AINL"), SND_SOC_DAPM_INPUT("AINR"), }; static const struct snd_soc_dapm_widget wm8581_dapm_widgets[] = { SND_SOC_DAPM_DAC("DAC4", "Playback", WM8580_PWRDN1, 5, 1), SND_SOC_DAPM_OUTPUT("VOUT4L"), SND_SOC_DAPM_OUTPUT("VOUT4R"), }; static const struct snd_soc_dapm_route wm8580_dapm_routes[] = { { "VOUT1L", NULL, "DAC1" }, { "VOUT1R", NULL, "DAC1" }, Loading @@ -338,6 +368,11 @@ static const struct snd_soc_dapm_route wm8580_dapm_routes[] = { { "ADC", NULL, "AINR" }, }; static const struct snd_soc_dapm_route wm8581_dapm_routes[] = { { "VOUT4L", NULL, "DAC4" }, { "VOUT4R", NULL, "DAC4" }, }; /* PLL divisors */ struct _pll_div { u32 prescale:1; Loading Loading @@ -815,10 +850,21 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, return 0; } static int wm8580_playback_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); return snd_pcm_hw_constraint_minmax(substream->runtime, SNDRV_PCM_HW_PARAM_CHANNELS, 1, wm8580->drvdata->num_dacs * 2); } #define WM8580_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) static const struct snd_soc_dai_ops wm8580_dai_ops_playback = { .startup = wm8580_playback_startup, .set_sysclk = wm8580_set_sysclk, .hw_params = wm8580_paif_hw_params, .set_fmt = wm8580_set_paif_dai_fmt, Loading @@ -842,7 +888,6 @@ static struct snd_soc_dai_driver wm8580_dai[] = { .playback = { .stream_name = "Playback", .channels_min = 1, .channels_max = 6, .rates = SNDRV_PCM_RATE_8000_192000, .formats = WM8580_FORMATS, }, Loading @@ -865,8 +910,22 @@ static struct snd_soc_dai_driver wm8580_dai[] = { static int wm8580_probe(struct snd_soc_codec *codec) { struct wm8580_priv *wm8580 = snd_soc_codec_get_drvdata(codec); struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); int ret = 0; switch (wm8580->drvdata->num_dacs) { case 4: snd_soc_add_codec_controls(codec, wm8581_snd_controls, ARRAY_SIZE(wm8581_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8581_dapm_widgets, ARRAY_SIZE(wm8581_dapm_widgets)); snd_soc_dapm_add_routes(dapm, wm8581_dapm_routes, ARRAY_SIZE(wm8581_dapm_routes)); break; default: break; } ret = regulator_bulk_enable(ARRAY_SIZE(wm8580->supplies), wm8580->supplies); if (ret != 0) { Loading Loading @@ -914,12 +973,6 @@ static const struct snd_soc_codec_driver soc_codec_dev_wm8580 = { }, }; static const struct of_device_id wm8580_of_match[] = { { .compatible = "wlf,wm8580" }, { }, }; MODULE_DEVICE_TABLE(of, wm8580_of_match); static const struct regmap_config wm8580_regmap = { .reg_bits = 7, .val_bits = 9, Loading @@ -932,10 +985,25 @@ static const struct regmap_config wm8580_regmap = { .volatile_reg = wm8580_volatile, }; #if IS_ENABLED(CONFIG_I2C) static const struct wm8580_driver_data wm8580_data = { .num_dacs = 3, }; static const struct wm8580_driver_data wm8581_data = { .num_dacs = 4, }; static const struct of_device_id wm8580_of_match[] = { { .compatible = "wlf,wm8580", .data = &wm8580_data }, { .compatible = "wlf,wm8581", .data = &wm8581_data }, { }, }; MODULE_DEVICE_TABLE(of, wm8580_of_match); static int wm8580_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { const struct of_device_id *of_id; struct wm8580_priv *wm8580; int ret, i; Loading @@ -960,6 +1028,15 @@ static int wm8580_i2c_probe(struct i2c_client *i2c, i2c_set_clientdata(i2c, wm8580); of_id = of_match_device(wm8580_of_match, &i2c->dev); if (of_id) wm8580->drvdata = of_id->data; if (!wm8580->drvdata) { dev_err(&i2c->dev, "failed to find driver data\n"); return -EINVAL; } ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_wm8580, wm8580_dai, ARRAY_SIZE(wm8580_dai)); Loading @@ -973,7 +1050,8 @@ static int wm8580_i2c_remove(struct i2c_client *client) } static const struct i2c_device_id wm8580_i2c_id[] = { { "wm8580", 0 }, { "wm8580", (kernel_ulong_t)&wm8580_data }, { "wm8581", (kernel_ulong_t)&wm8581_data }, { } }; MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id); Loading @@ -987,31 +1065,10 @@ static struct i2c_driver wm8580_i2c_driver = { .remove = wm8580_i2c_remove, .id_table = wm8580_i2c_id, }; #endif static int __init wm8580_modinit(void) { int ret = 0; #if IS_ENABLED(CONFIG_I2C) ret = i2c_add_driver(&wm8580_i2c_driver); if (ret != 0) { pr_err("Failed to register WM8580 I2C driver: %d\n", ret); } #endif return ret; } module_init(wm8580_modinit); static void __exit wm8580_exit(void) { #if IS_ENABLED(CONFIG_I2C) i2c_del_driver(&wm8580_i2c_driver); #endif } module_exit(wm8580_exit); module_i2c_driver(wm8580_i2c_driver); MODULE_DESCRIPTION("ASoC WM8580 driver"); MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); MODULE_AUTHOR("Matt Flax <flatmax@flatmax.org>"); MODULE_LICENSE("GPL");
sound/soc/codecs/wm8753.h +0 −3 Original line number Diff line number Diff line Loading @@ -112,7 +112,4 @@ #define WM8753_VXCLK_DIV_8 (3 << 6) #define WM8753_VXCLK_DIV_16 (4 << 6) #define WM8753_DAI_HIFI 0 #define WM8753_DAI_VOICE 1 #endif
sound/soc/codecs/wm8978.h +1 −1 Original line number Diff line number Diff line Loading @@ -78,8 +78,8 @@ enum wm8978_clk_id { }; enum wm8978_sysclk_src { WM8978_MCLK = 0, WM8978_PLL, WM8978_MCLK }; #endif /* __WM8978_H__ */