aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm9081.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm9081.c')
-rw-r--r--sound/soc/codecs/wm9081.c99
1 files changed, 49 insertions, 50 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index ecc7c37180c7..91c6b39de50c 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -15,6 +15,7 @@
15#include <linux/moduleparam.h> 15#include <linux/moduleparam.h>
16#include <linux/init.h> 16#include <linux/init.h>
17#include <linux/delay.h> 17#include <linux/delay.h>
18#include <linux/device.h>
18#include <linux/pm.h> 19#include <linux/pm.h>
19#include <linux/i2c.h> 20#include <linux/i2c.h>
20#include <linux/platform_device.h> 21#include <linux/platform_device.h>
@@ -23,7 +24,6 @@
23#include <sound/pcm.h> 24#include <sound/pcm.h>
24#include <sound/pcm_params.h> 25#include <sound/pcm_params.h>
25#include <sound/soc.h> 26#include <sound/soc.h>
26#include <sound/soc-dapm.h>
27#include <sound/initval.h> 27#include <sound/initval.h>
28#include <sound/tlv.h> 28#include <sound/tlv.h>
29 29
@@ -158,7 +158,6 @@ static struct {
158struct wm9081_priv { 158struct wm9081_priv {
159 enum snd_soc_control_type control_type; 159 enum snd_soc_control_type control_type;
160 void *control_data; 160 void *control_data;
161 u16 reg_cache[WM9081_MAX_REGISTER + 1];
162 int sysclk_source; 161 int sysclk_source;
163 int mclk_rate; 162 int mclk_rate;
164 int sysclk_rate; 163 int sysclk_rate;
@@ -168,10 +167,10 @@ struct wm9081_priv {
168 int fll_fref; 167 int fll_fref;
169 int fll_fout; 168 int fll_fout;
170 int tdm_width; 169 int tdm_width;
171 struct wm9081_retune_mobile_config *retune; 170 struct wm9081_pdata pdata;
172}; 171};
173 172
174static int wm9081_volatile_register(unsigned int reg) 173static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
175{ 174{
176 switch (reg) { 175 switch (reg) {
177 case WM9081_SOFTWARE_RESET: 176 case WM9081_SOFTWARE_RESET:
@@ -306,7 +305,7 @@ static int speaker_mode_get(struct snd_kcontrol *kcontrol,
306/* 305/*
307 * Stop any attempts to change speaker mode while the speaker is enabled. 306 * Stop any attempts to change speaker mode while the speaker is enabled.
308 * 307 *
309 * We also have some special anti-pop controls dependant on speaker 308 * We also have some special anti-pop controls dependent on speaker
310 * mode which must be changed along with the mode. 309 * mode which must be changed along with the mode.
311 */ 310 */
312static int speaker_mode_put(struct snd_kcontrol *kcontrol, 311static int speaker_mode_put(struct snd_kcontrol *kcontrol,
@@ -390,27 +389,6 @@ SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
390SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), 389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
391}; 390};
392 391
393static int speaker_event(struct snd_soc_dapm_widget *w,
394 struct snd_kcontrol *kcontrol, int event)
395{
396 struct snd_soc_codec *codec = w->codec;
397 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
398
399 switch (event) {
400 case SND_SOC_DAPM_POST_PMU:
401 reg |= WM9081_SPK_ENA;
402 break;
403
404 case SND_SOC_DAPM_PRE_PMD:
405 reg &= ~WM9081_SPK_ENA;
406 break;
407 }
408
409 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
410
411 return 0;
412}
413
414struct _fll_div { 392struct _fll_div {
415 u16 fll_fratio; 393 u16 fll_fratio;
416 u16 fll_outdiv; 394 u16 fll_outdiv;
@@ -478,7 +456,7 @@ static int fll_factors(struct _fll_div *fll_div, unsigned int Fref,
478 456
479 pr_debug("Fvco=%dHz\n", target); 457 pr_debug("Fvco=%dHz\n", target);
480 458
481 /* Find an appropraite FLL_FRATIO and factor it out of the target */ 459 /* Find an appropriate FLL_FRATIO and factor it out of the target */
482 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) { 460 for (i = 0; i < ARRAY_SIZE(fll_fratios); i++) {
483 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) { 461 if (fll_fratios[i].min <= Fref && Fref <= fll_fratios[i].max) {
484 fll_div->fll_fratio = fll_fratios[i].fll_fratio; 462 fll_div->fll_fratio = fll_fratios[i].fll_fratio;
@@ -591,6 +569,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id,
591 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; 569 reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT;
592 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5); 570 snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5);
593 571
572 /* Set gain to the recommended value */
573 snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4,
574 WM9081_FLL_GAIN_MASK, 0);
575
594 /* Enable the FLL */ 576 /* Enable the FLL */
595 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); 577 snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA);
596 578
@@ -744,9 +726,8 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
744 726
745SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0), 727SND_SOC_DAPM_PGA("LINEOUT PGA", WM9081_POWER_MANAGEMENT, 4, 0, NULL, 0),
746 728
747SND_SOC_DAPM_PGA_E("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0, 729SND_SOC_DAPM_PGA("Speaker PGA", WM9081_POWER_MANAGEMENT, 2, 0, NULL, 0),
748 speaker_event, 730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
749 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
750 731
751SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
752SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -759,7 +740,7 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
759}; 740};
760 741
761 742
762static const struct snd_soc_dapm_route audio_paths[] = { 743static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
763 { "DAC", NULL, "CLK_SYS" }, 744 { "DAC", NULL, "CLK_SYS" },
764 { "DAC", NULL, "CLK_DSP" }, 745 { "DAC", NULL, "CLK_DSP" },
765 746
@@ -777,8 +758,10 @@ static const struct snd_soc_dapm_route audio_paths[] = {
777 { "Speaker PGA", NULL, "TOCLK" }, 758 { "Speaker PGA", NULL, "TOCLK" },
778 { "Speaker PGA", NULL, "CLK_SYS" }, 759 { "Speaker PGA", NULL, "CLK_SYS" },
779 760
780 { "SPKN", NULL, "Speaker PGA" }, 761 { "Speaker", NULL, "Speaker PGA" },
781 { "SPKP", NULL, "Speaker PGA" }, 762
763 { "SPKN", NULL, "Speaker" },
764 { "SPKP", NULL, "Speaker" },
782}; 765};
783 766
784static int wm9081_set_bias_level(struct snd_soc_codec *codec, 767static int wm9081_set_bias_level(struct snd_soc_codec *codec,
@@ -805,7 +788,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
805 788
806 case SND_SOC_BIAS_STANDBY: 789 case SND_SOC_BIAS_STANDBY:
807 /* Initial cold start */ 790 /* Initial cold start */
808 if (codec->bias_level == SND_SOC_BIAS_OFF) { 791 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) {
809 /* Disable LINEOUT discharge */ 792 /* Disable LINEOUT discharge */
810 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); 793 reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL);
811 reg &= ~WM9081_LINEOUT_DISCH; 794 reg &= ~WM9081_LINEOUT_DISCH;
@@ -865,7 +848,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec,
865 break; 848 break;
866 } 849 }
867 850
868 codec->bias_level = level; 851 codec->dapm.bias_level = level;
869 852
870 return 0; 853 return 0;
871} 854}
@@ -1079,21 +1062,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1079 aif4 |= wm9081->bclk / wm9081->fs; 1062 aif4 |= wm9081->bclk / wm9081->fs;
1080 1063
1081 /* Apply a ReTune Mobile configuration if it's in use */ 1064 /* Apply a ReTune Mobile configuration if it's in use */
1082 if (wm9081->retune) { 1065 if (wm9081->pdata.num_retune_configs) {
1083 struct wm9081_retune_mobile_config *retune = wm9081->retune; 1066 struct wm9081_pdata *pdata = &wm9081->pdata;
1084 struct wm9081_retune_mobile_setting *s; 1067 struct wm9081_retune_mobile_setting *s;
1085 int eq1; 1068 int eq1;
1086 1069
1087 best = 0; 1070 best = 0;
1088 best_val = abs(retune->configs[0].rate - wm9081->fs); 1071 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
1089 for (i = 0; i < retune->num_configs; i++) { 1072 for (i = 0; i < pdata->num_retune_configs; i++) {
1090 cur_val = abs(retune->configs[i].rate - wm9081->fs); 1073 cur_val = abs(pdata->retune_configs[i].rate -
1074 wm9081->fs);
1091 if (cur_val < best_val) { 1075 if (cur_val < best_val) {
1092 best_val = cur_val; 1076 best_val = cur_val;
1093 best = i; 1077 best = i;
1094 } 1078 }
1095 } 1079 }
1096 s = &retune->configs[best]; 1080 s = &pdata->retune_configs[best];
1097 1081
1098 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", 1082 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1099 s->name, s->rate); 1083 s->name, s->rate);
@@ -1136,10 +1120,9 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1136 return 0; 1120 return 0;
1137} 1121}
1138 1122
1139static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec,
1140 int clk_id, unsigned int freq, int dir) 1124 int clk_id, unsigned int freq, int dir)
1141{ 1125{
1142 struct snd_soc_codec *codec = codec_dai->codec;
1143 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1144 1127
1145 switch (clk_id) { 1128 switch (clk_id) {
@@ -1204,7 +1187,6 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1204 1187
1205static struct snd_soc_dai_ops wm9081_dai_ops = { 1188static struct snd_soc_dai_ops wm9081_dai_ops = {
1206 .hw_params = wm9081_hw_params, 1189 .hw_params = wm9081_hw_params,
1207 .set_sysclk = wm9081_set_sysclk,
1208 .set_fmt = wm9081_set_dai_fmt, 1190 .set_fmt = wm9081_set_dai_fmt,
1209 .digital_mute = wm9081_digital_mute, 1191 .digital_mute = wm9081_digital_mute,
1210 .set_tdm_slot = wm9081_set_tdm_slot, 1192 .set_tdm_slot = wm9081_set_tdm_slot,
@@ -1251,6 +1233,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1251 return ret; 1233 return ret;
1252 } 1234 }
1253 1235
1236 reg = 0;
1237 if (wm9081->pdata.irq_high)
1238 reg |= WM9081_IRQ_POL;
1239 if (!wm9081->pdata.irq_cmos)
1240 reg |= WM9081_IRQ_OP_CTRL;
1241 snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
1242 WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
1243
1254 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1244 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1255 1245
1256 /* Enable zero cross by default */ 1246 /* Enable zero cross by default */
@@ -1262,17 +1252,13 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1262 1252
1263 snd_soc_add_controls(codec, wm9081_snd_controls, 1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1264 ARRAY_SIZE(wm9081_snd_controls)); 1254 ARRAY_SIZE(wm9081_snd_controls));
1265 if (!wm9081->retune) { 1255 if (!wm9081->pdata.num_retune_configs) {
1266 dev_dbg(codec->dev, 1256 dev_dbg(codec->dev,
1267 "No ReTune Mobile data, using normal EQ\n"); 1257 "No ReTune Mobile data, using normal EQ\n");
1268 snd_soc_add_controls(codec, wm9081_eq_controls, 1258 snd_soc_add_controls(codec, wm9081_eq_controls,
1269 ARRAY_SIZE(wm9081_eq_controls)); 1259 ARRAY_SIZE(wm9081_eq_controls));
1270 } 1260 }
1271 1261
1272 snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets,
1273 ARRAY_SIZE(wm9081_dapm_widgets));
1274 snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths));
1275
1276 return ret; 1262 return ret;
1277} 1263}
1278 1264
@@ -1316,11 +1302,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1316 .remove = wm9081_remove, 1302 .remove = wm9081_remove,
1317 .suspend = wm9081_suspend, 1303 .suspend = wm9081_suspend,
1318 .resume = wm9081_resume, 1304 .resume = wm9081_resume,
1305
1306 .set_sysclk = wm9081_set_sysclk,
1319 .set_bias_level = wm9081_set_bias_level, 1307 .set_bias_level = wm9081_set_bias_level,
1308
1320 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), 1309 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
1321 .reg_word_size = sizeof(u16), 1310 .reg_word_size = sizeof(u16),
1322 .reg_cache_default = wm9081_reg_defaults, 1311 .reg_cache_default = wm9081_reg_defaults,
1323 .volatile_register = wm9081_volatile_register, 1312 .volatile_register = wm9081_volatile_register,
1313
1314 .dapm_widgets = wm9081_dapm_widgets,
1315 .num_dapm_widgets = ARRAY_SIZE(wm9081_dapm_widgets),
1316 .dapm_routes = wm9081_audio_paths,
1317 .num_dapm_routes = ARRAY_SIZE(wm9081_audio_paths),
1324}; 1318};
1325 1319
1326#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1320#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1335,8 +1329,13 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1335 return -ENOMEM; 1329 return -ENOMEM;
1336 1330
1337 i2c_set_clientdata(i2c, wm9081); 1331 i2c_set_clientdata(i2c, wm9081);
1332 wm9081->control_type = SND_SOC_I2C;
1338 wm9081->control_data = i2c; 1333 wm9081->control_data = i2c;
1339 1334
1335 if (dev_get_platdata(&i2c->dev))
1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1337 sizeof(wm9081->pdata));
1338
1340 ret = snd_soc_register_codec(&i2c->dev, 1339 ret = snd_soc_register_codec(&i2c->dev,
1341 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1340 &soc_codec_dev_wm9081, &wm9081_dai, 1);
1342 if (ret < 0) 1341 if (ret < 0)
@@ -1359,7 +1358,7 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1359 1358
1360static struct i2c_driver wm9081_i2c_driver = { 1359static struct i2c_driver wm9081_i2c_driver = {
1361 .driver = { 1360 .driver = {
1362 .name = "wm9081-codec", 1361 .name = "wm9081",
1363 .owner = THIS_MODULE, 1362 .owner = THIS_MODULE,
1364 }, 1363 },
1365 .probe = wm9081_i2c_probe, 1364 .probe = wm9081_i2c_probe,