| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8731.c -- WM8731 ALSA SoC Audio driver | 2 * wm8731.c -- WM8731 ALSA SoC Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2005 Openedhand Ltd. | 4 * Copyright 2005 Openedhand Ltd. |
| 5 * | 5 * |
| 6 * Author: Richard Purdie <richard@openedhand.com> | 6 * Author: Richard Purdie <richard@openedhand.com> |
| 7 * | 7 * |
| 8 * Based on wm8753.c by Liam Girdwood | 8 * Based on wm8753.c by Liam Girdwood |
| 9 * | 9 * |
| 10 * This program is free software; you can redistribute it and/or modify | 10 * This program is free software; you can redistribute it and/or modify |
| 11 * it under the terms of the GNU General Public License version 2 as | 11 * it under the terms of the GNU General Public License version 2 as |
| 12 * published by the Free Software Foundation. | 12 * published by the Free Software Foundation. |
| 13 */ | 13 */ |
| 14 | 14 |
| 15 #include <linux/module.h> | 15 #include <linux/module.h> |
| 16 #include <linux/moduleparam.h> | 16 #include <linux/moduleparam.h> |
| 17 #include <linux/init.h> | 17 #include <linux/init.h> |
| 18 #include <linux/delay.h> | 18 #include <linux/delay.h> |
| 19 #include <linux/pm.h> | 19 #include <linux/pm.h> |
| 20 #include <linux/i2c.h> | 20 #include <linux/i2c.h> |
| 21 #include <linux/slab.h> | 21 #include <linux/slab.h> |
| 22 #include <linux/platform_device.h> | 22 #include <linux/platform_device.h> |
| 23 #include <linux/regulator/consumer.h> | 23 #include <linux/regulator/consumer.h> |
| 24 #include <linux/spi/spi.h> | 24 #include <linux/spi/spi.h> |
| 25 #include <sound/core.h> | 25 #include <sound/core.h> |
| 26 #include <sound/pcm.h> | 26 #include <sound/pcm.h> |
| 27 #include <sound/pcm_params.h> | 27 #include <sound/pcm_params.h> |
| 28 #include <sound/soc.h> | 28 #include <sound/soc.h> |
| 29 #include <sound/soc-dapm.h> | |
| 30 #include <sound/initval.h> | 29 #include <sound/initval.h> |
| 31 #include <sound/tlv.h> | 30 #include <sound/tlv.h> |
| 32 | 31 |
| 33 #include "wm8731.h" | 32 #include "wm8731.h" |
| 34 | 33 |
| 35 #define WM8731_NUM_SUPPLIES 4 | 34 #define WM8731_NUM_SUPPLIES 4 |
| 36 static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { | 35 static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { |
| 37 "AVDD", | 36 "AVDD", |
| 38 "HPVDD", | 37 "HPVDD", |
| 39 "DCVDD", | 38 "DCVDD", |
| 40 "DBVDD", | 39 "DBVDD", |
| 41 }; | 40 }; |
| 42 | 41 |
| 43 /* codec private data */ | 42 /* codec private data */ |
| 44 struct wm8731_priv { | 43 struct wm8731_priv { |
| 45 enum snd_soc_control_type control_type; | 44 enum snd_soc_control_type control_type; |
| 46 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; | 45 struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; |
| 47 u16 reg_cache[WM8731_CACHEREGNUM]; | |
| 48 unsigned int sysclk; | 46 unsigned int sysclk; |
| 49 int sysclk_type; | 47 int sysclk_type; |
| 48 int playback_fs; |
| 49 bool deemph; |
| 50 }; | 50 }; |
| 51 | 51 |
| 52 | 52 |
| 53 /* | 53 /* |
| 54 * wm8731 register cache | 54 * wm8731 register cache |
| 55 * We can't read the WM8731 register space when we are | 55 * We can't read the WM8731 register space when we are |
| 56 * using 2 wire for device control, so we cache them instead. | 56 * using 2 wire for device control, so we cache them instead. |
| 57 * There is no point in caching the reset register | 57 * There is no point in caching the reset register |
| 58 */ | 58 */ |
| 59 static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { | 59 static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { |
| 60 0x0097, 0x0097, 0x0079, 0x0079, | 60 0x0097, 0x0097, 0x0079, 0x0079, |
| 61 0x000a, 0x0008, 0x009f, 0x000a, | 61 0x000a, 0x0008, 0x009f, 0x000a, |
| 62 0x0000, 0x0000 | 62 0x0000, 0x0000 |
| 63 }; | 63 }; |
| 64 | 64 |
| 65 #define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) | 65 #define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) |
| 66 | 66 |
| 67 static const char *wm8731_input_select[] = {"Line In", "Mic"}; | 67 static const char *wm8731_input_select[] = {"Line In", "Mic"}; |
| 68 static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; | |
| 69 | 68 |
| 70 static const struct soc_enum wm8731_enum[] = { | 69 static const struct soc_enum wm8731_insel_enum = |
| 71 » SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select), | 70 » SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select); |
| 72 » SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), | 71 |
| 73 }; | 72 static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; |
| 73 |
| 74 static int wm8731_set_deemph(struct snd_soc_codec *codec) |
| 75 { |
| 76 » struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 77 » int val, i, best; |
| 78 |
| 79 » /* If we're using deemphasis select the nearest available sample |
| 80 » * rate. |
| 81 » */ |
| 82 » if (wm8731->deemph) { |
| 83 » » best = 1; |
| 84 » » for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) { |
| 85 » » » if (abs(wm8731_deemph[i] - wm8731->playback_fs) < |
| 86 » » » abs(wm8731_deemph[best] - wm8731->playback_fs)) |
| 87 » » » » best = i; |
| 88 » » } |
| 89 |
| 90 » » val = best << 1; |
| 91 » } else { |
| 92 » » best = 0; |
| 93 » » val = 0; |
| 94 » } |
| 95 |
| 96 » dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", |
| 97 » » best, wm8731_deemph[best]); |
| 98 |
| 99 » return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val); |
| 100 } |
| 101 |
| 102 static int wm8731_get_deemph(struct snd_kcontrol *kcontrol, |
| 103 » » » struct snd_ctl_elem_value *ucontrol) |
| 104 { |
| 105 » struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 106 » struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 107 |
| 108 » ucontrol->value.enumerated.item[0] = wm8731->deemph; |
| 109 |
| 110 » return 0; |
| 111 } |
| 112 |
| 113 static int wm8731_put_deemph(struct snd_kcontrol *kcontrol, |
| 114 » » » struct snd_ctl_elem_value *ucontrol) |
| 115 { |
| 116 » struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
| 117 » struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 118 » int deemph = ucontrol->value.enumerated.item[0]; |
| 119 » int ret = 0; |
| 120 |
| 121 » if (deemph > 1) |
| 122 » » return -EINVAL; |
| 123 |
| 124 » mutex_lock(&codec->mutex); |
| 125 » if (wm8731->deemph != deemph) { |
| 126 » » wm8731->deemph = deemph; |
| 127 |
| 128 » » wm8731_set_deemph(codec); |
| 129 |
| 130 » » ret = 1; |
| 131 » } |
| 132 » mutex_unlock(&codec->mutex); |
| 133 |
| 134 » return ret; |
| 135 } |
| 74 | 136 |
| 75 static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); | 137 static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); |
| 76 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); | 138 static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); |
| 77 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 139 static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
| 140 static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0); |
| 78 | 141 |
| 79 static const struct snd_kcontrol_new wm8731_snd_controls[] = { | 142 static const struct snd_kcontrol_new wm8731_snd_controls[] = { |
| 80 | 143 |
| 81 SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, | 144 SOC_DOUBLE_R_TLV("Master Playback Volume", WM8731_LOUT1V, WM8731_ROUT1V, |
| 82 0, 127, 0, out_tlv), | 145 0, 127, 0, out_tlv), |
| 83 SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V, | 146 SOC_DOUBLE_R("Master Playback ZC Switch", WM8731_LOUT1V, WM8731_ROUT1V, |
| 84 7, 1, 0), | 147 7, 1, 0), |
| 85 | 148 |
| 86 SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0, | 149 SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0, |
| 87 in_tlv), | 150 in_tlv), |
| 88 SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), | 151 SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), |
| 89 | 152 |
| 90 SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), | 153 SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv), |
| 91 SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), | 154 SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), |
| 92 | 155 |
| 93 SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, | 156 SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, |
| 94 sidetone_tlv), | 157 sidetone_tlv), |
| 95 | 158 |
| 96 SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), | 159 SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), |
| 97 SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), | 160 SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), |
| 98 | 161 |
| 99 SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), | 162 SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, |
| 163 » » wm8731_get_deemph, wm8731_put_deemph), |
| 100 }; | 164 }; |
| 101 | 165 |
| 102 /* Output Mixer */ | 166 /* Output Mixer */ |
| 103 static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { | 167 static const struct snd_kcontrol_new wm8731_output_mixer_controls[] = { |
| 104 SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), | 168 SOC_DAPM_SINGLE("Line Bypass Switch", WM8731_APANA, 3, 1, 0), |
| 105 SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), | 169 SOC_DAPM_SINGLE("Mic Sidetone Switch", WM8731_APANA, 5, 1, 0), |
| 106 SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), | 170 SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), |
| 107 }; | 171 }; |
| 108 | 172 |
| 109 /* Input mux */ | 173 /* Input mux */ |
| 110 static const struct snd_kcontrol_new wm8731_input_mux_controls = | 174 static const struct snd_kcontrol_new wm8731_input_mux_controls = |
| 111 SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); | 175 SOC_DAPM_ENUM("Input Select", wm8731_insel_enum); |
| 112 | 176 |
| 113 static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { | 177 static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { |
| 114 SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), | 178 SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), |
| 115 SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, | 179 SND_SOC_DAPM_MIXER("Output Mixer", WM8731_PWR, 4, 1, |
| 116 &wm8731_output_mixer_controls[0], | 180 &wm8731_output_mixer_controls[0], |
| 117 ARRAY_SIZE(wm8731_output_mixer_controls)), | 181 ARRAY_SIZE(wm8731_output_mixer_controls)), |
| 118 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1), | 182 SND_SOC_DAPM_DAC("DAC", "HiFi Playback", WM8731_PWR, 3, 1), |
| 119 SND_SOC_DAPM_OUTPUT("LOUT"), | 183 SND_SOC_DAPM_OUTPUT("LOUT"), |
| 120 SND_SOC_DAPM_OUTPUT("LHPOUT"), | 184 SND_SOC_DAPM_OUTPUT("LHPOUT"), |
| 121 SND_SOC_DAPM_OUTPUT("ROUT"), | 185 SND_SOC_DAPM_OUTPUT("ROUT"), |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 {"ADC", NULL, "Input Mux"}, | 222 {"ADC", NULL, "Input Mux"}, |
| 159 | 223 |
| 160 /* inputs */ | 224 /* inputs */ |
| 161 {"Line Input", NULL, "LLINEIN"}, | 225 {"Line Input", NULL, "LLINEIN"}, |
| 162 {"Line Input", NULL, "RLINEIN"}, | 226 {"Line Input", NULL, "RLINEIN"}, |
| 163 {"Mic Bias", NULL, "MICIN"}, | 227 {"Mic Bias", NULL, "MICIN"}, |
| 164 }; | 228 }; |
| 165 | 229 |
| 166 static int wm8731_add_widgets(struct snd_soc_codec *codec) | 230 static int wm8731_add_widgets(struct snd_soc_codec *codec) |
| 167 { | 231 { |
| 168 » snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, | 232 » struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 233 |
| 234 » snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, |
| 169 ARRAY_SIZE(wm8731_dapm_widgets)); | 235 ARRAY_SIZE(wm8731_dapm_widgets)); |
| 170 | 236 » snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); |
| 171 » snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); | |
| 172 | 237 |
| 173 return 0; | 238 return 0; |
| 174 } | 239 } |
| 175 | 240 |
| 176 struct _coeff_div { | 241 struct _coeff_div { |
| 177 u32 mclk; | 242 u32 mclk; |
| 178 u32 rate; | 243 u32 rate; |
| 179 u16 fs; | 244 u16 fs; |
| 180 u8 sr:4; | 245 u8 sr:4; |
| 181 u8 bosr:1; | 246 u8 bosr:1; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 232 struct snd_pcm_hw_params *params, | 297 struct snd_pcm_hw_params *params, |
| 233 struct snd_soc_dai *dai) | 298 struct snd_soc_dai *dai) |
| 234 { | 299 { |
| 235 struct snd_soc_codec *codec = dai->codec; | 300 struct snd_soc_codec *codec = dai->codec; |
| 236 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 301 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 237 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; | 302 u16 iface = snd_soc_read(codec, WM8731_IFACE) & 0xfff3; |
| 238 int i = get_coeff(wm8731->sysclk, params_rate(params)); | 303 int i = get_coeff(wm8731->sysclk, params_rate(params)); |
| 239 u16 srate = (coeff_div[i].sr << 2) | | 304 u16 srate = (coeff_div[i].sr << 2) | |
| 240 (coeff_div[i].bosr << 1) | coeff_div[i].usb; | 305 (coeff_div[i].bosr << 1) | coeff_div[i].usb; |
| 241 | 306 |
| 307 wm8731->playback_fs = params_rate(params); |
| 308 |
| 242 snd_soc_write(codec, WM8731_SRATE, srate); | 309 snd_soc_write(codec, WM8731_SRATE, srate); |
| 243 | 310 |
| 244 /* bit size */ | 311 /* bit size */ |
| 245 switch (params_format(params)) { | 312 switch (params_format(params)) { |
| 246 case SNDRV_PCM_FORMAT_S16_LE: | 313 case SNDRV_PCM_FORMAT_S16_LE: |
| 247 break; | 314 break; |
| 248 case SNDRV_PCM_FORMAT_S20_3LE: | 315 case SNDRV_PCM_FORMAT_S20_3LE: |
| 249 iface |= 0x0004; | 316 iface |= 0x0004; |
| 250 break; | 317 break; |
| 251 case SNDRV_PCM_FORMAT_S24_LE: | 318 case SNDRV_PCM_FORMAT_S24_LE: |
| 252 iface |= 0x0008; | 319 iface |= 0x0008; |
| 253 break; | 320 break; |
| 254 } | 321 } |
| 255 | 322 |
| 323 wm8731_set_deemph(codec); |
| 324 |
| 256 snd_soc_write(codec, WM8731_IFACE, iface); | 325 snd_soc_write(codec, WM8731_IFACE, iface); |
| 257 return 0; | 326 return 0; |
| 258 } | 327 } |
| 259 | 328 |
| 260 static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, | 329 static int wm8731_pcm_prepare(struct snd_pcm_substream *substream, |
| 261 struct snd_soc_dai *dai) | 330 struct snd_soc_dai *dai) |
| 262 { | 331 { |
| 263 struct snd_soc_codec *codec = dai->codec; | 332 struct snd_soc_codec *codec = dai->codec; |
| 264 | 333 |
| 265 /* set active */ | 334 /* set active */ |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 case 12000000: | 381 case 12000000: |
| 313 case 12288000: | 382 case 12288000: |
| 314 case 16934400: | 383 case 16934400: |
| 315 case 18432000: | 384 case 18432000: |
| 316 wm8731->sysclk = freq; | 385 wm8731->sysclk = freq; |
| 317 break; | 386 break; |
| 318 default: | 387 default: |
| 319 return -EINVAL; | 388 return -EINVAL; |
| 320 } | 389 } |
| 321 | 390 |
| 322 » snd_soc_dapm_sync(codec); | 391 » snd_soc_dapm_sync(&codec->dapm); |
| 323 | 392 |
| 324 return 0; | 393 return 0; |
| 325 } | 394 } |
| 326 | 395 |
| 327 | 396 |
| 328 static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, | 397 static int wm8731_set_dai_fmt(struct snd_soc_dai *codec_dai, |
| 329 unsigned int fmt) | 398 unsigned int fmt) |
| 330 { | 399 { |
| 331 struct snd_soc_codec *codec = codec_dai->codec; | 400 struct snd_soc_codec *codec = codec_dai->codec; |
| 332 u16 iface = 0; | 401 u16 iface = 0; |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 392 u8 data[2]; | 461 u8 data[2]; |
| 393 u16 *cache = codec->reg_cache; | 462 u16 *cache = codec->reg_cache; |
| 394 u16 reg; | 463 u16 reg; |
| 395 | 464 |
| 396 switch (level) { | 465 switch (level) { |
| 397 case SND_SOC_BIAS_ON: | 466 case SND_SOC_BIAS_ON: |
| 398 break; | 467 break; |
| 399 case SND_SOC_BIAS_PREPARE: | 468 case SND_SOC_BIAS_PREPARE: |
| 400 break; | 469 break; |
| 401 case SND_SOC_BIAS_STANDBY: | 470 case SND_SOC_BIAS_STANDBY: |
| 402 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 471 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 403 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies)
, | 472 ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies)
, |
| 404 wm8731->supplies); | 473 wm8731->supplies); |
| 405 if (ret != 0) | 474 if (ret != 0) |
| 406 return ret; | 475 return ret; |
| 407 | 476 |
| 408 /* Sync reg_cache with the hardware */ | 477 /* Sync reg_cache with the hardware */ |
| 409 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { | 478 for (i = 0; i < ARRAY_SIZE(wm8731_reg); i++) { |
| 410 if (cache[i] == wm8731_reg[i]) | 479 if (cache[i] == wm8731_reg[i]) |
| 411 continue; | 480 continue; |
| 412 | 481 |
| 413 data[0] = (i << 1) | ((cache[i] >> 8) | 482 data[0] = (i << 1) | ((cache[i] >> 8) |
| 414 & 0x0001); | 483 & 0x0001); |
| 415 data[1] = cache[i] & 0x00ff; | 484 data[1] = cache[i] & 0x00ff; |
| 416 codec->hw_write(codec->control_data, data, 2); | 485 codec->hw_write(codec->control_data, data, 2); |
| 417 } | 486 } |
| 418 } | 487 } |
| 419 | 488 |
| 420 /* Clear PWROFF, gate CLKOUT, everything else as-is */ | 489 /* Clear PWROFF, gate CLKOUT, everything else as-is */ |
| 421 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f; | 490 reg = snd_soc_read(codec, WM8731_PWR) & 0xff7f; |
| 422 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); | 491 snd_soc_write(codec, WM8731_PWR, reg | 0x0040); |
| 423 break; | 492 break; |
| 424 case SND_SOC_BIAS_OFF: | 493 case SND_SOC_BIAS_OFF: |
| 425 snd_soc_write(codec, WM8731_ACTIVE, 0x0); | 494 snd_soc_write(codec, WM8731_ACTIVE, 0x0); |
| 426 snd_soc_write(codec, WM8731_PWR, 0xffff); | 495 snd_soc_write(codec, WM8731_PWR, 0xffff); |
| 427 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), | 496 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), |
| 428 wm8731->supplies); | 497 wm8731->supplies); |
| 429 break; | 498 break; |
| 430 } | 499 } |
| 431 » codec->bias_level = level; | 500 » codec->dapm.bias_level = level; |
| 432 return 0; | 501 return 0; |
| 433 } | 502 } |
| 434 | 503 |
| 435 #define WM8731_RATES SNDRV_PCM_RATE_8000_96000 | 504 #define WM8731_RATES SNDRV_PCM_RATE_8000_96000 |
| 436 | 505 |
| 437 #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ | 506 #define WM8731_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
| 438 SNDRV_PCM_FMTBIT_S24_LE) | 507 SNDRV_PCM_FMTBIT_S24_LE) |
| 439 | 508 |
| 440 static struct snd_soc_dai_ops wm8731_dai_ops = { | 509 static struct snd_soc_dai_ops wm8731_dai_ops = { |
| 441 .prepare = wm8731_pcm_prepare, | 510 .prepare = wm8731_pcm_prepare, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 535 /* Regulators will have been enabled by bias management */ | 604 /* Regulators will have been enabled by bias management */ |
| 536 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 605 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
| 537 | 606 |
| 538 return 0; | 607 return 0; |
| 539 | 608 |
| 540 err_regulator_enable: | 609 err_regulator_enable: |
| 541 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 610 regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
| 542 err_regulator_get: | 611 err_regulator_get: |
| 543 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); | 612 regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); |
| 544 | 613 |
| 545 kfree(wm8731); | |
| 546 return ret; | 614 return ret; |
| 547 } | 615 } |
| 548 | 616 |
| 549 /* power down chip */ | 617 /* power down chip */ |
| 550 static int wm8731_remove(struct snd_soc_codec *codec) | 618 static int wm8731_remove(struct snd_soc_codec *codec) |
| 551 { | 619 { |
| 552 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); | 620 struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); |
| 553 | 621 |
| 554 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); | 622 wm8731_set_bias_level(codec, SND_SOC_BIAS_OFF); |
| 555 | 623 |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 680 #endif | 748 #endif |
| 681 #if defined(CONFIG_SPI_MASTER) | 749 #if defined(CONFIG_SPI_MASTER) |
| 682 spi_unregister_driver(&wm8731_spi_driver); | 750 spi_unregister_driver(&wm8731_spi_driver); |
| 683 #endif | 751 #endif |
| 684 } | 752 } |
| 685 module_exit(wm8731_exit); | 753 module_exit(wm8731_exit); |
| 686 | 754 |
| 687 MODULE_DESCRIPTION("ASoC WM8731 driver"); | 755 MODULE_DESCRIPTION("ASoC WM8731 driver"); |
| 688 MODULE_AUTHOR("Richard Purdie"); | 756 MODULE_AUTHOR("Richard Purdie"); |
| 689 MODULE_LICENSE("GPL"); | 757 MODULE_LICENSE("GPL"); |
| OLD | NEW |