wm8731.c (59f7297014b7e96779493f132eed04a3d44565df) | wm8731.c (dd31b310b9104327fb6bf7d2fe3b0f0f6fde4dd7) |
---|---|
1/* 2 * wm8731.c -- WM8731 ALSA SoC Audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <richard@openedhand.com> 7 * 8 * Based on wm8753.c by Liam Girdwood --- 32 unchanged lines hidden (view full) --- 41 42/* codec private data */ 43struct wm8731_priv { 44 enum snd_soc_control_type control_type; 45 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 46 u16 reg_cache[WM8731_CACHEREGNUM]; 47 unsigned int sysclk; 48 int sysclk_type; | 1/* 2 * wm8731.c -- WM8731 ALSA SoC Audio driver 3 * 4 * Copyright 2005 Openedhand Ltd. 5 * 6 * Author: Richard Purdie <richard@openedhand.com> 7 * 8 * Based on wm8753.c by Liam Girdwood --- 32 unchanged lines hidden (view full) --- 41 42/* codec private data */ 43struct wm8731_priv { 44 enum snd_soc_control_type control_type; 45 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; 46 u16 reg_cache[WM8731_CACHEREGNUM]; 47 unsigned int sysclk; 48 int sysclk_type; |
49 int playback_fs; 50 bool deemph; |
|
49}; 50 51 52/* 53 * wm8731 register cache 54 * We can't read the WM8731 register space when we are 55 * using 2 wire for device control, so we cache them instead. 56 * There is no point in caching the reset register 57 */ 58static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 59 0x0097, 0x0097, 0x0079, 0x0079, 60 0x000a, 0x0008, 0x009f, 0x000a, 61 0x0000, 0x0000 62}; 63 64#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) 65 66static const char *wm8731_input_select[] = {"Line In", "Mic"}; 67 | 51}; 52 53 54/* 55 * wm8731 register cache 56 * We can't read the WM8731 register space when we are 57 * using 2 wire for device control, so we cache them instead. 58 * There is no point in caching the reset register 59 */ 60static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { 61 0x0097, 0x0097, 0x0079, 0x0079, 62 0x000a, 0x0008, 0x009f, 0x000a, 63 0x0000, 0x0000 64}; 65 66#define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) 67 68static const char *wm8731_input_select[] = {"Line In", "Mic"}; 69 |
68static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; 69 | |
70static const struct soc_enum wm8731_insel_enum = 71 SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select); 72 | 70static const struct soc_enum wm8731_insel_enum = 71 SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select); 72 |
73static const struct soc_enum wm8731_deemph_enum = 74 SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph); | 73static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; |
75 | 74 |
75static int wm8731_set_deemph(struct snd_soc_codec *codec) 76{ 77 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 78 int val, i, best; |
|
76 | 79 |
80 /* If we're using deemphasis select the nearest available sample 81 * rate. 82 */ 83 if (wm8731->deemph) { 84 best = 1; 85 for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) { 86 if (abs(wm8731_deemph[i] - wm8731->playback_fs) < 87 abs(wm8731_deemph[best] - wm8731->playback_fs)) 88 best = i; 89 } 90 91 val = best << 1; 92 } else { 93 best = 0; 94 val = 0; 95 } 96 97 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", 98 best, wm8731_deemph[best]); 99 100 return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val); 101} 102 103static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, 104 struct snd_ctl_elem_value *ucontrol) 105{ 106 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 107 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 108 109 ucontrol->value.enumerated.item[0] = wm8731->deemph; 110 111 return 0; 112} 113 114static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, 115 struct snd_ctl_elem_value *ucontrol) 116{ 117 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 118 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 119 int deemph = ucontrol->value.enumerated.item[0]; 120 int ret = 0; 121 122 if (deemph > 1) 123 return -EINVAL; 124 125 mutex_lock(&codec->mutex); 126 if (wm8731->deemph != deemph) { 127 wm8731->deemph = deemph; 128 129 wm8731_set_deemph(codec); 130 131 ret = 1; 132 } 133 mutex_unlock(&codec->mutex); 134 135 return ret; 136} 137 |
|
77static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); 78static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); 79static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 80static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0); 81 82static const struct snd_kcontrol_new wm8731_snd_controls[] = { 83 84SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, --- 9 unchanged lines hidden (view full) --- 94SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), 95 96SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, 97 sidetone_tlv), 98 99SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 100SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 101 | 138static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); 139static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); 140static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); 141static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0); 142 143static const struct snd_kcontrol_new wm8731_snd_controls[] = { 144 145SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, --- 9 unchanged lines hidden (view full) --- 155SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), 156 157SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, 158 sidetone_tlv), 159 160SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), 161SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), 162 |
102SOC_ENUM("Playback De-emphasis", wm8731_deemph_enum), | 163SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, 164 wm8731_get_deemph, wm8731_put_deemph), |
103}; 104 105/* Output Mixer */ 106static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { 107SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), 108SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), 109SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), 110}; --- 127 unchanged lines hidden (view full) --- 238{ 239 struct snd_soc_codec *codec = dai->codec; 240 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 241 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 242 int i = get_coeff(wm8731->sysclk, params_rate(params)); 243 u16 srate = (coeff_div[i].sr << 2) | 244 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 245 | 165}; 166 167/* Output Mixer */ 168static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { 169SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), 170SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), 171SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), 172}; --- 127 unchanged lines hidden (view full) --- 300{ 301 struct snd_soc_codec *codec = dai->codec; 302 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); 303 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; 304 int i = get_coeff(wm8731->sysclk, params_rate(params)); 305 u16 srate = (coeff_div[i].sr << 2) | 306 (coeff_div[i].bosr << 1) | coeff_div[i].usb; 307 |
308 wm8731->playback_fs = params_rate(params); 309 |
|
246 snd_soc_write(codec, WM8731_SRATE, srate); 247 248 /* bit size */ 249 switch (params_format(params)) { 250 case SNDRV_PCM_FORMAT_S16_LE: 251 break; 252 case SNDRV_PCM_FORMAT_S20_3LE: 253 iface |= 0x0004; 254 break; 255 case SNDRV_PCM_FORMAT_S24_LE: 256 iface |= 0x0008; 257 break; 258 } 259 | 310 snd_soc_write(codec, WM8731_SRATE, srate); 311 312 /* bit size */ 313 switch (params_format(params)) { 314 case SNDRV_PCM_FORMAT_S16_LE: 315 break; 316 case SNDRV_PCM_FORMAT_S20_3LE: 317 iface |= 0x0004; 318 break; 319 case SNDRV_PCM_FORMAT_S24_LE: 320 iface |= 0x0008; 321 break; 322 } 323 |
324 wm8731_set_deemph(codec); 325 |
|
260 snd_soc_write(codec, WM8731_IFACE, iface); 261 return 0; 262} 263 264static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, 265 struct snd_soc_dai *dai) 266{ 267 struct snd_soc_codec *codec = dai->codec; --- 425 unchanged lines hidden --- | 326 snd_soc_write(codec, WM8731_IFACE, iface); 327 return 0; 328} 329 330static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, 331 struct snd_soc_dai *dai) 332{ 333 struct snd_soc_codec *codec = dai->codec; --- 425 unchanged lines hidden --- |