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.c84
1 files changed, 37 insertions, 47 deletions
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c
index cce704c275c6..55cdf2982020 100644
--- a/sound/soc/codecs/wm9081.c
+++ b/sound/soc/codecs/wm9081.c
@@ -167,10 +167,10 @@ struct wm9081_priv {
167 int fll_fref; 167 int fll_fref;
168 int fll_fout; 168 int fll_fout;
169 int tdm_width; 169 int tdm_width;
170 struct wm9081_retune_mobile_config *retune; 170 struct wm9081_pdata pdata;
171}; 171};
172 172
173static int wm9081_volatile_register(unsigned int reg) 173static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
174{ 174{
175 switch (reg) { 175 switch (reg) {
176 case WM9081_SOFTWARE_RESET: 176 case WM9081_SOFTWARE_RESET:
@@ -389,27 +389,6 @@ SOC_DAPM_SINGLE("IN2 Switch", WM9081_ANALOGUE_MIXER, 2, 1, 0),
389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0), 389SOC_DAPM_SINGLE("Playback Switch", WM9081_ANALOGUE_MIXER, 4, 1, 0),
390}; 390};
391 391
392static int speaker_event(struct snd_soc_dapm_widget *w,
393 struct snd_kcontrol *kcontrol, int event)
394{
395 struct snd_soc_codec *codec = w->codec;
396 unsigned int reg = snd_soc_read(codec, WM9081_POWER_MANAGEMENT);
397
398 switch (event) {
399 case SND_SOC_DAPM_POST_PMU:
400 reg |= WM9081_SPK_ENA;
401 break;
402
403 case SND_SOC_DAPM_PRE_PMD:
404 reg &= ~WM9081_SPK_ENA;
405 break;
406 }
407
408 snd_soc_write(codec, WM9081_POWER_MANAGEMENT, reg);
409
410 return 0;
411}
412
413struct _fll_div { 392struct _fll_div {
414 u16 fll_fratio; 393 u16 fll_fratio;
415 u16 fll_outdiv; 394 u16 fll_outdiv;
@@ -747,9 +726,8 @@ SND_SOC_DAPM_MIXER_NAMED_CTL("Mixer", SND_SOC_NOPM, 0, 0,
747 726
748SND_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),
749 728
750SND_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),
751 speaker_event, 730SND_SOC_DAPM_PGA("Speaker", WM9081_POWER_MANAGEMENT, 1, 0, NULL, 0),
752 SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD),
753 731
754SND_SOC_DAPM_OUTPUT("LINEOUT"), 732SND_SOC_DAPM_OUTPUT("LINEOUT"),
755SND_SOC_DAPM_OUTPUT("SPKN"), 733SND_SOC_DAPM_OUTPUT("SPKN"),
@@ -762,7 +740,7 @@ SND_SOC_DAPM_SUPPLY("TOCLK", WM9081_CLOCK_CONTROL_3, 2, 0, NULL, 0),
762}; 740};
763 741
764 742
765static const struct snd_soc_dapm_route audio_paths[] = { 743static const struct snd_soc_dapm_route wm9081_audio_paths[] = {
766 { "DAC", NULL, "CLK_SYS" }, 744 { "DAC", NULL, "CLK_SYS" },
767 { "DAC", NULL, "CLK_DSP" }, 745 { "DAC", NULL, "CLK_DSP" },
768 746
@@ -780,8 +758,10 @@ static const struct snd_soc_dapm_route audio_paths[] = {
780 { "Speaker PGA", NULL, "TOCLK" }, 758 { "Speaker PGA", NULL, "TOCLK" },
781 { "Speaker PGA", NULL, "CLK_SYS" }, 759 { "Speaker PGA", NULL, "CLK_SYS" },
782 760
783 { "SPKN", NULL, "Speaker PGA" }, 761 { "Speaker", NULL, "Speaker PGA" },
784 { "SPKP", NULL, "Speaker PGA" }, 762
763 { "SPKN", NULL, "Speaker" },
764 { "SPKP", NULL, "Speaker" },
785}; 765};
786 766
787static int wm9081_set_bias_level(struct snd_soc_codec *codec, 767static int wm9081_set_bias_level(struct snd_soc_codec *codec,
@@ -1082,21 +1062,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
1082 aif4 |= wm9081->bclk / wm9081->fs; 1062 aif4 |= wm9081->bclk / wm9081->fs;
1083 1063
1084 /* Apply a ReTune Mobile configuration if it's in use */ 1064 /* Apply a ReTune Mobile configuration if it's in use */
1085 if (wm9081->retune) { 1065 if (wm9081->pdata.num_retune_configs) {
1086 struct wm9081_retune_mobile_config *retune = wm9081->retune; 1066 struct wm9081_pdata *pdata = &wm9081->pdata;
1087 struct wm9081_retune_mobile_setting *s; 1067 struct wm9081_retune_mobile_setting *s;
1088 int eq1; 1068 int eq1;
1089 1069
1090 best = 0; 1070 best = 0;
1091 best_val = abs(retune->configs[0].rate - wm9081->fs); 1071 best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
1092 for (i = 0; i < retune->num_configs; i++) { 1072 for (i = 0; i < pdata->num_retune_configs; i++) {
1093 cur_val = abs(retune->configs[i].rate - wm9081->fs); 1073 cur_val = abs(pdata->retune_configs[i].rate -
1074 wm9081->fs);
1094 if (cur_val < best_val) { 1075 if (cur_val < best_val) {
1095 best_val = cur_val; 1076 best_val = cur_val;
1096 best = i; 1077 best = i;
1097 } 1078 }
1098 } 1079 }
1099 s = &retune->configs[best]; 1080 s = &pdata->retune_configs[best];
1100 1081
1101 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", 1082 dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
1102 s->name, s->rate); 1083 s->name, s->rate);
@@ -1139,10 +1120,9 @@ static int wm9081_digital_mute(struct snd_soc_dai *codec_dai, int mute)
1139 return 0; 1120 return 0;
1140} 1121}
1141 1122
1142static int wm9081_set_sysclk(struct snd_soc_dai *codec_dai, 1123static int wm9081_set_sysclk(struct snd_soc_codec *codec,
1143 int clk_id, unsigned int freq, int dir) 1124 int clk_id, unsigned int freq, int dir)
1144{ 1125{
1145 struct snd_soc_codec *codec = codec_dai->codec;
1146 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1126 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1147 1127
1148 switch (clk_id) { 1128 switch (clk_id) {
@@ -1207,7 +1187,6 @@ static int wm9081_set_tdm_slot(struct snd_soc_dai *dai,
1207 1187
1208static struct snd_soc_dai_ops wm9081_dai_ops = { 1188static struct snd_soc_dai_ops wm9081_dai_ops = {
1209 .hw_params = wm9081_hw_params, 1189 .hw_params = wm9081_hw_params,
1210 .set_sysclk = wm9081_set_sysclk,
1211 .set_fmt = wm9081_set_dai_fmt, 1190 .set_fmt = wm9081_set_dai_fmt,
1212 .digital_mute = wm9081_digital_mute, 1191 .digital_mute = wm9081_digital_mute,
1213 .set_tdm_slot = wm9081_set_tdm_slot, 1192 .set_tdm_slot = wm9081_set_tdm_slot,
@@ -1231,7 +1210,6 @@ static struct snd_soc_dai_driver wm9081_dai = {
1231static int wm9081_probe(struct snd_soc_codec *codec) 1210static int wm9081_probe(struct snd_soc_codec *codec)
1232{ 1211{
1233 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); 1212 struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec);
1234 struct snd_soc_dapm_context *dapm = &codec->dapm;
1235 int ret; 1213 int ret;
1236 u16 reg; 1214 u16 reg;
1237 1215
@@ -1255,6 +1233,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1255 return ret; 1233 return ret;
1256 } 1234 }
1257 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
1258 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 1244 wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
1259 1245
1260 /* Enable zero cross by default */ 1246 /* Enable zero cross by default */
@@ -1266,17 +1252,13 @@ static int wm9081_probe(struct snd_soc_codec *codec)
1266 1252
1267 snd_soc_add_controls(codec, wm9081_snd_controls, 1253 snd_soc_add_controls(codec, wm9081_snd_controls,
1268 ARRAY_SIZE(wm9081_snd_controls)); 1254 ARRAY_SIZE(wm9081_snd_controls));
1269 if (!wm9081->retune) { 1255 if (!wm9081->pdata.num_retune_configs) {
1270 dev_dbg(codec->dev, 1256 dev_dbg(codec->dev,
1271 "No ReTune Mobile data, using normal EQ\n"); 1257 "No ReTune Mobile data, using normal EQ\n");
1272 snd_soc_add_controls(codec, wm9081_eq_controls, 1258 snd_soc_add_controls(codec, wm9081_eq_controls,
1273 ARRAY_SIZE(wm9081_eq_controls)); 1259 ARRAY_SIZE(wm9081_eq_controls));
1274 } 1260 }
1275 1261
1276 snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets,
1277 ARRAY_SIZE(wm9081_dapm_widgets));
1278 snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths));
1279
1280 return ret; 1262 return ret;
1281} 1263}
1282 1264
@@ -1320,11 +1302,19 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9081 = {
1320 .remove = wm9081_remove, 1302 .remove = wm9081_remove,
1321 .suspend = wm9081_suspend, 1303 .suspend = wm9081_suspend,
1322 .resume = wm9081_resume, 1304 .resume = wm9081_resume,
1305
1306 .set_sysclk = wm9081_set_sysclk,
1323 .set_bias_level = wm9081_set_bias_level, 1307 .set_bias_level = wm9081_set_bias_level,
1308
1324 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults), 1309 .reg_cache_size = ARRAY_SIZE(wm9081_reg_defaults),
1325 .reg_word_size = sizeof(u16), 1310 .reg_word_size = sizeof(u16),
1326 .reg_cache_default = wm9081_reg_defaults, 1311 .reg_cache_default = wm9081_reg_defaults,
1327 .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),
1328}; 1318};
1329 1319
1330#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) 1320#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
@@ -1343,8 +1333,8 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
1343 wm9081->control_data = i2c; 1333 wm9081->control_data = i2c;
1344 1334
1345 if (dev_get_platdata(&i2c->dev)) 1335 if (dev_get_platdata(&i2c->dev))
1346 memcpy(&wm9081->retune, dev_get_platdata(&i2c->dev), 1336 memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
1347 sizeof(wm9081->retune)); 1337 sizeof(wm9081->pdata));
1348 1338
1349 ret = snd_soc_register_codec(&i2c->dev, 1339 ret = snd_soc_register_codec(&i2c->dev,
1350 &soc_codec_dev_wm9081, &wm9081_dai, 1); 1340 &soc_codec_dev_wm9081, &wm9081_dai, 1);
@@ -1368,7 +1358,7 @@ MODULE_DEVICE_TABLE(i2c, wm9081_i2c_id);
1368 1358
1369static struct i2c_driver wm9081_i2c_driver = { 1359static struct i2c_driver wm9081_i2c_driver = {
1370 .driver = { 1360 .driver = {
1371 .name = "wm9081-codec", 1361 .name = "wm9081",
1372 .owner = THIS_MODULE, 1362 .owner = THIS_MODULE,
1373 }, 1363 },
1374 .probe = wm9081_i2c_probe, 1364 .probe = wm9081_i2c_probe,