aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8580.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8580.c')
-rw-r--r--sound/soc/codecs/wm8580.c69
1 files changed, 30 insertions, 39 deletions
diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c
index 4bbc0a79f01e..8212b3c8bfdd 100644
--- a/sound/soc/codecs/wm8580.c
+++ b/sound/soc/codecs/wm8580.c
@@ -26,6 +26,7 @@
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <linux/regulator/consumer.h> 27#include <linux/regulator/consumer.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/of_device.h>
29 30
30#include <sound/core.h> 31#include <sound/core.h>
31#include <sound/pcm.h> 32#include <sound/pcm.h>
@@ -212,7 +213,7 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
212 reg_cache[reg] = 0; 213 reg_cache[reg] = 0;
213 reg_cache[reg2] = 0; 214 reg_cache[reg2] = 0;
214 215
215 ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); 216 ret = snd_soc_put_volsw(kcontrol, ucontrol);
216 if (ret < 0) 217 if (ret < 0)
217 return ret; 218 return ret;
218 219
@@ -223,31 +224,19 @@ static int wm8580_out_vu(struct snd_kcontrol *kcontrol,
223 return 0; 224 return 0;
224} 225}
225 226
226#define SOC_WM8580_OUT_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax, \
227 xinvert, tlv_array) \
228{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \
229 .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\
230 SNDRV_CTL_ELEM_ACCESS_READWRITE, \
231 .tlv.p = (tlv_array), \
232 .info = snd_soc_info_volsw_2r, \
233 .get = snd_soc_get_volsw_2r, .put = wm8580_out_vu, \
234 .private_value = (unsigned long)&(struct soc_mixer_control) \
235 {.reg = reg_left, .rreg = reg_right, .shift = xshift, \
236 .max = xmax, .invert = xinvert} }
237
238static const struct snd_kcontrol_new wm8580_snd_controls[] = { 227static const struct snd_kcontrol_new wm8580_snd_controls[] = {
239SOC_WM8580_OUT_DOUBLE_R_TLV("DAC1 Playback Volume", 228SOC_DOUBLE_R_EXT_TLV("DAC1 Playback Volume",
240 WM8580_DIGITAL_ATTENUATION_DACL1, 229 WM8580_DIGITAL_ATTENUATION_DACL1,
241 WM8580_DIGITAL_ATTENUATION_DACR1, 230 WM8580_DIGITAL_ATTENUATION_DACR1,
242 0, 0xff, 0, dac_tlv), 231 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
243SOC_WM8580_OUT_DOUBLE_R_TLV("DAC2 Playback Volume", 232SOC_DOUBLE_R_EXT_TLV("DAC2 Playback Volume",
244 WM8580_DIGITAL_ATTENUATION_DACL2, 233 WM8580_DIGITAL_ATTENUATION_DACL2,
245 WM8580_DIGITAL_ATTENUATION_DACR2, 234 WM8580_DIGITAL_ATTENUATION_DACR2,
246 0, 0xff, 0, dac_tlv), 235 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
247SOC_WM8580_OUT_DOUBLE_R_TLV("DAC3 Playback Volume", 236SOC_DOUBLE_R_EXT_TLV("DAC3 Playback Volume",
248 WM8580_DIGITAL_ATTENUATION_DACL3, 237 WM8580_DIGITAL_ATTENUATION_DACL3,
249 WM8580_DIGITAL_ATTENUATION_DACR3, 238 WM8580_DIGITAL_ATTENUATION_DACR3,
250 0, 0xff, 0, dac_tlv), 239 0, 0xff, 0, snd_soc_get_volsw, wm8580_out_vu, dac_tlv),
251 240
252SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0), 241SOC_SINGLE("DAC1 Deemphasis Switch", WM8580_DAC_CONTROL3, 0, 1, 0),
253SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0), 242SOC_SINGLE("DAC2 Deemphasis Switch", WM8580_DAC_CONTROL3, 1, 1, 0),
@@ -441,8 +430,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
441 /* Always disable the PLL - it is not safe to leave it running 430 /* Always disable the PLL - it is not safe to leave it running
442 * while reprogramming it. 431 * while reprogramming it.
443 */ 432 */
444 reg = snd_soc_read(codec, WM8580_PWRDN2); 433 snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, pwr_mask);
445 snd_soc_write(codec, WM8580_PWRDN2, reg | pwr_mask);
446 434
447 if (!freq_in || !freq_out) 435 if (!freq_in || !freq_out)
448 return 0; 436 return 0;
@@ -460,8 +448,7 @@ static int wm8580_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id,
460 snd_soc_write(codec, WM8580_PLLA4 + offset, reg); 448 snd_soc_write(codec, WM8580_PLLA4 + offset, reg);
461 449
462 /* All done, turn it on */ 450 /* All done, turn it on */
463 reg = snd_soc_read(codec, WM8580_PWRDN2); 451 snd_soc_update_bits(codec, WM8580_PWRDN2, pwr_mask, 0);
464 snd_soc_write(codec, WM8580_PWRDN2, reg & ~pwr_mask);
465 452
466 return 0; 453 return 0;
467} 454}
@@ -759,7 +746,6 @@ static int wm8580_digital_mute(struct snd_soc_dai *codec_dai, int mute)
759static int wm8580_set_bias_level(struct snd_soc_codec *codec, 746static int wm8580_set_bias_level(struct snd_soc_codec *codec,
760 enum snd_soc_bias_level level) 747 enum snd_soc_bias_level level)
761{ 748{
762 u16 reg;
763 switch (level) { 749 switch (level) {
764 case SND_SOC_BIAS_ON: 750 case SND_SOC_BIAS_ON:
765 case SND_SOC_BIAS_PREPARE: 751 case SND_SOC_BIAS_PREPARE:
@@ -768,20 +754,19 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec,
768 case SND_SOC_BIAS_STANDBY: 754 case SND_SOC_BIAS_STANDBY:
769 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { 755 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
770 /* Power up and get individual control of the DACs */ 756 /* Power up and get individual control of the DACs */
771 reg = snd_soc_read(codec, WM8580_PWRDN1); 757 snd_soc_update_bits(codec, WM8580_PWRDN1,
772 reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); 758 WM8580_PWRDN1_PWDN |
773 snd_soc_write(codec, WM8580_PWRDN1, reg); 759 WM8580_PWRDN1_ALLDACPD, 0);
774 760
775 /* Make VMID high impedance */ 761 /* Make VMID high impedance */
776 reg = snd_soc_read(codec, WM8580_ADC_CONTROL1); 762 snd_soc_update_bits(codec, WM8580_ADC_CONTROL1,
777 reg &= ~0x100; 763 0x100, 0);
778 snd_soc_write(codec, WM8580_ADC_CONTROL1, reg);
779 } 764 }
780 break; 765 break;
781 766
782 case SND_SOC_BIAS_OFF: 767 case SND_SOC_BIAS_OFF:
783 reg = snd_soc_read(codec, WM8580_PWRDN1); 768 snd_soc_update_bits(codec, WM8580_PWRDN1,
784 snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); 769 WM8580_PWRDN1_PWDN, WM8580_PWRDN1_PWDN);
785 break; 770 break;
786 } 771 }
787 codec->dapm.bias_level = level; 772 codec->dapm.bias_level = level;
@@ -907,6 +892,11 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = {
907 .reg_cache_default = wm8580_reg, 892 .reg_cache_default = wm8580_reg,
908}; 893};
909 894
895static const struct of_device_id wm8580_of_match[] = {
896 { .compatible = "wlf,wm8580" },
897 { },
898};
899
910#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 900#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
911static int wm8580_i2c_probe(struct i2c_client *i2c, 901static int wm8580_i2c_probe(struct i2c_client *i2c,
912 const struct i2c_device_id *id) 902 const struct i2c_device_id *id)
@@ -943,8 +933,9 @@ MODULE_DEVICE_TABLE(i2c, wm8580_i2c_id);
943 933
944static struct i2c_driver wm8580_i2c_driver = { 934static struct i2c_driver wm8580_i2c_driver = {
945 .driver = { 935 .driver = {
946 .name = "wm8580-codec", 936 .name = "wm8580",
947 .owner = THIS_MODULE, 937 .owner = THIS_MODULE,
938 .of_match_table = wm8580_of_match,
948 }, 939 },
949 .probe = wm8580_i2c_probe, 940 .probe = wm8580_i2c_probe,
950 .remove = wm8580_i2c_remove, 941 .remove = wm8580_i2c_remove,