diff options
Diffstat (limited to 'sound/soc/codecs/wm8903.c')
-rw-r--r-- | sound/soc/codecs/wm8903.c | 1148 |
1 files changed, 686 insertions, 462 deletions
diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index bf08282d5ee5..43e3d760766f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * wm8903.c -- WM8903 ALSA SoC Audio driver | 2 | * wm8903.c -- WM8903 ALSA SoC Audio driver |
3 | * | 3 | * |
4 | * Copyright 2008 Wolfson Microelectronics | 4 | * Copyright 2008 Wolfson Microelectronics |
5 | * Copyright 2011 NVIDIA, Inc. | ||
5 | * | 6 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 7 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 8 | * |
@@ -19,6 +20,7 @@ | |||
19 | #include <linux/init.h> | 20 | #include <linux/init.h> |
20 | #include <linux/completion.h> | 21 | #include <linux/completion.h> |
21 | #include <linux/delay.h> | 22 | #include <linux/delay.h> |
23 | #include <linux/gpio.h> | ||
22 | #include <linux/pm.h> | 24 | #include <linux/pm.h> |
23 | #include <linux/i2c.h> | 25 | #include <linux/i2c.h> |
24 | #include <linux/platform_device.h> | 26 | #include <linux/platform_device.h> |
@@ -29,9 +31,9 @@ | |||
29 | #include <sound/pcm_params.h> | 31 | #include <sound/pcm_params.h> |
30 | #include <sound/tlv.h> | 32 | #include <sound/tlv.h> |
31 | #include <sound/soc.h> | 33 | #include <sound/soc.h> |
32 | #include <sound/soc-dapm.h> | ||
33 | #include <sound/initval.h> | 34 | #include <sound/initval.h> |
34 | #include <sound/wm8903.h> | 35 | #include <sound/wm8903.h> |
36 | #include <trace/events/asoc.h> | ||
35 | 37 | ||
36 | #include "wm8903.h" | 38 | #include "wm8903.h" |
37 | 39 | ||
@@ -213,17 +215,19 @@ static u16 wm8903_reg_defaults[] = { | |||
213 | }; | 215 | }; |
214 | 216 | ||
215 | struct wm8903_priv { | 217 | struct wm8903_priv { |
216 | struct snd_soc_codec codec; | 218 | struct snd_soc_codec *codec; |
217 | u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)]; | ||
218 | 219 | ||
219 | int sysclk; | 220 | int sysclk; |
221 | int irq; | ||
220 | 222 | ||
221 | /* Reference counts */ | 223 | int fs; |
222 | int class_w_users; | 224 | int deemph; |
223 | int playback_active; | ||
224 | int capture_active; | ||
225 | 225 | ||
226 | struct completion wseq; | 226 | int dcs_pending; |
227 | int dcs_cache[4]; | ||
228 | |||
229 | /* Reference count */ | ||
230 | int class_w_users; | ||
227 | 231 | ||
228 | struct snd_soc_jack *mic_jack; | 232 | struct snd_soc_jack *mic_jack; |
229 | int mic_det; | 233 | int mic_det; |
@@ -231,17 +235,22 @@ struct wm8903_priv { | |||
231 | int mic_last_report; | 235 | int mic_last_report; |
232 | int mic_delay; | 236 | int mic_delay; |
233 | 237 | ||
234 | struct snd_pcm_substream *master_substream; | 238 | #ifdef CONFIG_GPIOLIB |
235 | struct snd_pcm_substream *slave_substream; | 239 | struct gpio_chip gpio_chip; |
240 | #endif | ||
236 | }; | 241 | }; |
237 | 242 | ||
238 | static int wm8903_volatile_register(unsigned int reg) | 243 | static int wm8903_volatile_register(struct snd_soc_codec *codec, unsigned int reg) |
239 | { | 244 | { |
240 | switch (reg) { | 245 | switch (reg) { |
241 | case WM8903_SW_RESET_AND_ID: | 246 | case WM8903_SW_RESET_AND_ID: |
242 | case WM8903_REVISION_NUMBER: | 247 | case WM8903_REVISION_NUMBER: |
243 | case WM8903_INTERRUPT_STATUS_1: | 248 | case WM8903_INTERRUPT_STATUS_1: |
244 | case WM8903_WRITE_SEQUENCER_4: | 249 | case WM8903_WRITE_SEQUENCER_4: |
250 | case WM8903_DC_SERVO_READBACK_1: | ||
251 | case WM8903_DC_SERVO_READBACK_2: | ||
252 | case WM8903_DC_SERVO_READBACK_3: | ||
253 | case WM8903_DC_SERVO_READBACK_4: | ||
245 | return 1; | 254 | return 1; |
246 | 255 | ||
247 | default: | 256 | default: |
@@ -249,51 +258,6 @@ static int wm8903_volatile_register(unsigned int reg) | |||
249 | } | 258 | } |
250 | } | 259 | } |
251 | 260 | ||
252 | static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start) | ||
253 | { | ||
254 | u16 reg[5]; | ||
255 | struct i2c_client *i2c = codec->control_data; | ||
256 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
257 | |||
258 | BUG_ON(start > 48); | ||
259 | |||
260 | /* Enable the sequencer if it's not already on */ | ||
261 | reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0); | ||
262 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, | ||
263 | reg[0] | WM8903_WSEQ_ENA); | ||
264 | |||
265 | dev_dbg(&i2c->dev, "Starting sequence at %d\n", start); | ||
266 | |||
267 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_3, | ||
268 | start | WM8903_WSEQ_START); | ||
269 | |||
270 | /* Wait for it to complete. If we have the interrupt wired up then | ||
271 | * that will break us out of the poll early. | ||
272 | */ | ||
273 | do { | ||
274 | wait_for_completion_timeout(&wm8903->wseq, | ||
275 | msecs_to_jiffies(10)); | ||
276 | |||
277 | reg[4] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_4); | ||
278 | } while (reg[4] & WM8903_WSEQ_BUSY); | ||
279 | |||
280 | dev_dbg(&i2c->dev, "Sequence complete\n"); | ||
281 | |||
282 | /* Disable the sequencer again if we enabled it */ | ||
283 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]); | ||
284 | |||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | static void wm8903_sync_reg_cache(struct snd_soc_codec *codec, u16 *cache) | ||
289 | { | ||
290 | int i; | ||
291 | |||
292 | /* There really ought to be something better we can do here :/ */ | ||
293 | for (i = 0; i < ARRAY_SIZE(wm8903_reg_defaults); i++) | ||
294 | cache[i] = codec->hw_read(codec, i); | ||
295 | } | ||
296 | |||
297 | static void wm8903_reset(struct snd_soc_codec *codec) | 261 | static void wm8903_reset(struct snd_soc_codec *codec) |
298 | { | 262 | { |
299 | snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); | 263 | snd_soc_write(codec, WM8903_SW_RESET_AND_ID, 0); |
@@ -301,11 +265,6 @@ static void wm8903_reset(struct snd_soc_codec *codec) | |||
301 | sizeof(wm8903_reg_defaults)); | 265 | sizeof(wm8903_reg_defaults)); |
302 | } | 266 | } |
303 | 267 | ||
304 | #define WM8903_OUTPUT_SHORT 0x8 | ||
305 | #define WM8903_OUTPUT_OUT 0x4 | ||
306 | #define WM8903_OUTPUT_INT 0x2 | ||
307 | #define WM8903_OUTPUT_IN 0x1 | ||
308 | |||
309 | static int wm8903_cp_event(struct snd_soc_dapm_widget *w, | 268 | static int wm8903_cp_event(struct snd_soc_dapm_widget *w, |
310 | struct snd_kcontrol *kcontrol, int event) | 269 | struct snd_kcontrol *kcontrol, int event) |
311 | { | 270 | { |
@@ -315,97 +274,101 @@ static int wm8903_cp_event(struct snd_soc_dapm_widget *w, | |||
315 | return 0; | 274 | return 0; |
316 | } | 275 | } |
317 | 276 | ||
318 | /* | 277 | static int wm8903_dcs_event(struct snd_soc_dapm_widget *w, |
319 | * Event for headphone and line out amplifier power changes. Special | 278 | struct snd_kcontrol *kcontrol, int event) |
320 | * power up/down sequences are required in order to maximise pop/click | ||
321 | * performance. | ||
322 | */ | ||
323 | static int wm8903_output_event(struct snd_soc_dapm_widget *w, | ||
324 | struct snd_kcontrol *kcontrol, int event) | ||
325 | { | 279 | { |
326 | struct snd_soc_codec *codec = w->codec; | 280 | struct snd_soc_codec *codec = w->codec; |
327 | u16 val; | 281 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
328 | u16 reg; | ||
329 | u16 dcs_reg; | ||
330 | u16 dcs_bit; | ||
331 | int shift; | ||
332 | |||
333 | switch (w->reg) { | ||
334 | case WM8903_POWER_MANAGEMENT_2: | ||
335 | reg = WM8903_ANALOGUE_HP_0; | ||
336 | dcs_bit = 0 + w->shift; | ||
337 | break; | ||
338 | case WM8903_POWER_MANAGEMENT_3: | ||
339 | reg = WM8903_ANALOGUE_LINEOUT_0; | ||
340 | dcs_bit = 2 + w->shift; | ||
341 | break; | ||
342 | default: | ||
343 | BUG(); | ||
344 | return -EINVAL; /* Spurious warning from some compilers */ | ||
345 | } | ||
346 | 282 | ||
347 | switch (w->shift) { | 283 | switch (event) { |
348 | case 0: | 284 | case SND_SOC_DAPM_POST_PMU: |
349 | shift = 0; | 285 | wm8903->dcs_pending |= 1 << w->shift; |
350 | break; | 286 | break; |
351 | case 1: | 287 | case SND_SOC_DAPM_PRE_PMD: |
352 | shift = 4; | 288 | snd_soc_update_bits(codec, WM8903_DC_SERVO_0, |
289 | 1 << w->shift, 0); | ||
353 | break; | 290 | break; |
354 | default: | ||
355 | BUG(); | ||
356 | return -EINVAL; /* Spurious warning from some compilers */ | ||
357 | } | 291 | } |
358 | 292 | ||
359 | if (event & SND_SOC_DAPM_PRE_PMU) { | 293 | return 0; |
360 | val = snd_soc_read(codec, reg); | 294 | } |
295 | |||
296 | #define WM8903_DCS_MODE_WRITE_STOP 0 | ||
297 | #define WM8903_DCS_MODE_START_STOP 2 | ||
361 | 298 | ||
362 | /* Short the output */ | 299 | static void wm8903_seq_notifier(struct snd_soc_dapm_context *dapm, |
363 | val &= ~(WM8903_OUTPUT_SHORT << shift); | 300 | enum snd_soc_dapm_type event, int subseq) |
364 | snd_soc_write(codec, reg, val); | 301 | { |
365 | } | 302 | struct snd_soc_codec *codec = container_of(dapm, |
303 | struct snd_soc_codec, dapm); | ||
304 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
305 | int dcs_mode = WM8903_DCS_MODE_WRITE_STOP; | ||
306 | int i, val; | ||
366 | 307 | ||
367 | if (event & SND_SOC_DAPM_POST_PMU) { | 308 | /* Complete any pending DC servo starts */ |
368 | val = snd_soc_read(codec, reg); | 309 | if (wm8903->dcs_pending) { |
310 | dev_dbg(codec->dev, "Starting DC servo for %x\n", | ||
311 | wm8903->dcs_pending); | ||
369 | 312 | ||
370 | val |= (WM8903_OUTPUT_IN << shift); | 313 | /* If we've no cached values then we need to do startup */ |
371 | snd_soc_write(codec, reg, val); | 314 | for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) { |
315 | if (!(wm8903->dcs_pending & (1 << i))) | ||
316 | continue; | ||
372 | 317 | ||
373 | val |= (WM8903_OUTPUT_INT << shift); | 318 | if (wm8903->dcs_cache[i]) { |
374 | snd_soc_write(codec, reg, val); | 319 | dev_dbg(codec->dev, |
320 | "Restore DC servo %d value %x\n", | ||
321 | 3 - i, wm8903->dcs_cache[i]); | ||
322 | |||
323 | snd_soc_write(codec, WM8903_DC_SERVO_4 + i, | ||
324 | wm8903->dcs_cache[i] & 0xff); | ||
325 | } else { | ||
326 | dev_dbg(codec->dev, | ||
327 | "Calibrate DC servo %d\n", 3 - i); | ||
328 | dcs_mode = WM8903_DCS_MODE_START_STOP; | ||
329 | } | ||
330 | } | ||
375 | 331 | ||
376 | /* Turn on the output ENA_OUTP */ | 332 | /* Don't trust the cache for analogue */ |
377 | val |= (WM8903_OUTPUT_OUT << shift); | 333 | if (wm8903->class_w_users) |
378 | snd_soc_write(codec, reg, val); | 334 | dcs_mode = WM8903_DCS_MODE_START_STOP; |
379 | 335 | ||
380 | /* Enable the DC servo */ | 336 | snd_soc_update_bits(codec, WM8903_DC_SERVO_2, |
381 | dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); | 337 | WM8903_DCS_MODE_MASK, dcs_mode); |
382 | dcs_reg |= dcs_bit; | ||
383 | snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg); | ||
384 | 338 | ||
385 | /* Remove the short */ | 339 | snd_soc_update_bits(codec, WM8903_DC_SERVO_0, |
386 | val |= (WM8903_OUTPUT_SHORT << shift); | 340 | WM8903_DCS_ENA_MASK, wm8903->dcs_pending); |
387 | snd_soc_write(codec, reg, val); | ||
388 | } | ||
389 | 341 | ||
390 | if (event & SND_SOC_DAPM_PRE_PMD) { | 342 | switch (dcs_mode) { |
391 | val = snd_soc_read(codec, reg); | 343 | case WM8903_DCS_MODE_WRITE_STOP: |
344 | break; | ||
392 | 345 | ||
393 | /* Short the output */ | 346 | case WM8903_DCS_MODE_START_STOP: |
394 | val &= ~(WM8903_OUTPUT_SHORT << shift); | 347 | msleep(270); |
395 | snd_soc_write(codec, reg, val); | ||
396 | 348 | ||
397 | /* Disable the DC servo */ | 349 | /* Cache the measured offsets for digital */ |
398 | dcs_reg = snd_soc_read(codec, WM8903_DC_SERVO_0); | 350 | if (wm8903->class_w_users) |
399 | dcs_reg &= ~dcs_bit; | 351 | break; |
400 | snd_soc_write(codec, WM8903_DC_SERVO_0, dcs_reg); | ||
401 | 352 | ||
402 | /* Then disable the intermediate and output stages */ | 353 | for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) { |
403 | val &= ~((WM8903_OUTPUT_OUT | WM8903_OUTPUT_INT | | 354 | if (!(wm8903->dcs_pending & (1 << i))) |
404 | WM8903_OUTPUT_IN) << shift); | 355 | continue; |
405 | snd_soc_write(codec, reg, val); | ||
406 | } | ||
407 | 356 | ||
408 | return 0; | 357 | val = snd_soc_read(codec, |
358 | WM8903_DC_SERVO_READBACK_1 + i); | ||
359 | dev_dbg(codec->dev, "DC servo %d: %x\n", | ||
360 | 3 - i, val); | ||
361 | wm8903->dcs_cache[i] = val; | ||
362 | } | ||
363 | break; | ||
364 | |||
365 | default: | ||
366 | pr_warn("DCS mode %d delay not set\n", dcs_mode); | ||
367 | break; | ||
368 | } | ||
369 | |||
370 | wm8903->dcs_pending = 0; | ||
371 | } | ||
409 | } | 372 | } |
410 | 373 | ||
411 | /* | 374 | /* |
@@ -419,10 +382,10 @@ static int wm8903_output_event(struct snd_soc_dapm_widget *w, | |||
419 | static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, | 382 | static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, |
420 | struct snd_ctl_elem_value *ucontrol) | 383 | struct snd_ctl_elem_value *ucontrol) |
421 | { | 384 | { |
422 | struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); | 385 | struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol); |
386 | struct snd_soc_dapm_widget *widget = wlist->widgets[0]; | ||
423 | struct snd_soc_codec *codec = widget->codec; | 387 | struct snd_soc_codec *codec = widget->codec; |
424 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 388 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
425 | struct i2c_client *i2c = codec->control_data; | ||
426 | u16 reg; | 389 | u16 reg; |
427 | int ret; | 390 | int ret; |
428 | 391 | ||
@@ -431,7 +394,7 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, | |||
431 | /* Turn it off if we're about to enable bypass */ | 394 | /* Turn it off if we're about to enable bypass */ |
432 | if (ucontrol->value.integer.value[0]) { | 395 | if (ucontrol->value.integer.value[0]) { |
433 | if (wm8903->class_w_users == 0) { | 396 | if (wm8903->class_w_users == 0) { |
434 | dev_dbg(&i2c->dev, "Disabling Class W\n"); | 397 | dev_dbg(codec->dev, "Disabling Class W\n"); |
435 | snd_soc_write(codec, WM8903_CLASS_W_0, reg & | 398 | snd_soc_write(codec, WM8903_CLASS_W_0, reg & |
436 | ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); | 399 | ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); |
437 | } | 400 | } |
@@ -444,14 +407,14 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, | |||
444 | /* If we've just disabled the last bypass path turn Class W on */ | 407 | /* If we've just disabled the last bypass path turn Class W on */ |
445 | if (!ucontrol->value.integer.value[0]) { | 408 | if (!ucontrol->value.integer.value[0]) { |
446 | if (wm8903->class_w_users == 1) { | 409 | if (wm8903->class_w_users == 1) { |
447 | dev_dbg(&i2c->dev, "Enabling Class W\n"); | 410 | dev_dbg(codec->dev, "Enabling Class W\n"); |
448 | snd_soc_write(codec, WM8903_CLASS_W_0, reg | | 411 | snd_soc_write(codec, WM8903_CLASS_W_0, reg | |
449 | WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); | 412 | WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); |
450 | } | 413 | } |
451 | wm8903->class_w_users--; | 414 | wm8903->class_w_users--; |
452 | } | 415 | } |
453 | 416 | ||
454 | dev_dbg(&i2c->dev, "Bypass use count now %d\n", | 417 | dev_dbg(codec->dev, "Bypass use count now %d\n", |
455 | wm8903->class_w_users); | 418 | wm8903->class_w_users); |
456 | 419 | ||
457 | return ret; | 420 | return ret; |
@@ -464,6 +427,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, | |||
464 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } | 427 | .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } |
465 | 428 | ||
466 | 429 | ||
430 | static int wm8903_deemph[] = { 0, 32000, 44100, 48000 }; | ||
431 | |||
432 | static int wm8903_set_deemph(struct snd_soc_codec *codec) | ||
433 | { | ||
434 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
435 | int val, i, best; | ||
436 | |||
437 | /* If we're using deemphasis select the nearest available sample | ||
438 | * rate. | ||
439 | */ | ||
440 | if (wm8903->deemph) { | ||
441 | best = 1; | ||
442 | for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) { | ||
443 | if (abs(wm8903_deemph[i] - wm8903->fs) < | ||
444 | abs(wm8903_deemph[best] - wm8903->fs)) | ||
445 | best = i; | ||
446 | } | ||
447 | |||
448 | val = best << WM8903_DEEMPH_SHIFT; | ||
449 | } else { | ||
450 | best = 0; | ||
451 | val = 0; | ||
452 | } | ||
453 | |||
454 | dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", | ||
455 | best, wm8903_deemph[best]); | ||
456 | |||
457 | return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, | ||
458 | WM8903_DEEMPH_MASK, val); | ||
459 | } | ||
460 | |||
461 | static int wm8903_get_deemph(struct snd_kcontrol *kcontrol, | ||
462 | struct snd_ctl_elem_value *ucontrol) | ||
463 | { | ||
464 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
465 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
466 | |||
467 | ucontrol->value.enumerated.item[0] = wm8903->deemph; | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static int wm8903_put_deemph(struct snd_kcontrol *kcontrol, | ||
473 | struct snd_ctl_elem_value *ucontrol) | ||
474 | { | ||
475 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | ||
476 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
477 | int deemph = ucontrol->value.enumerated.item[0]; | ||
478 | int ret = 0; | ||
479 | |||
480 | if (deemph > 1) | ||
481 | return -EINVAL; | ||
482 | |||
483 | mutex_lock(&codec->mutex); | ||
484 | if (wm8903->deemph != deemph) { | ||
485 | wm8903->deemph = deemph; | ||
486 | |||
487 | wm8903_set_deemph(codec); | ||
488 | |||
489 | ret = 1; | ||
490 | } | ||
491 | mutex_unlock(&codec->mutex); | ||
492 | |||
493 | return ret; | ||
494 | } | ||
495 | |||
467 | /* ALSA can only do steps of .01dB */ | 496 | /* ALSA can only do steps of .01dB */ |
468 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); | 497 | static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); |
469 | 498 | ||
@@ -476,6 +505,23 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0); | |||
476 | static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); | 505 | static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); |
477 | static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); | 506 | static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); |
478 | 507 | ||
508 | static const char *hpf_mode_text[] = { | ||
509 | "Hi-fi", "Voice 1", "Voice 2", "Voice 3" | ||
510 | }; | ||
511 | |||
512 | static const struct soc_enum hpf_mode = | ||
513 | SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text); | ||
514 | |||
515 | static const char *osr_text[] = { | ||
516 | "Low power", "High performance" | ||
517 | }; | ||
518 | |||
519 | static const struct soc_enum adc_osr = | ||
520 | SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text); | ||
521 | |||
522 | static const struct soc_enum dac_osr = | ||
523 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text); | ||
524 | |||
479 | static const char *drc_slope_text[] = { | 525 | static const char *drc_slope_text[] = { |
480 | "1", "1/2", "1/4", "1/8", "1/16", "0" | 526 | "1", "1/2", "1/4", "1/8", "1/16", "0" |
481 | }; | 527 | }; |
@@ -538,13 +584,6 @@ static const char *mute_mode_text[] = { | |||
538 | static const struct soc_enum mute_mode = | 584 | static const struct soc_enum mute_mode = |
539 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); | 585 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); |
540 | 586 | ||
541 | static const char *dac_deemphasis_text[] = { | ||
542 | "Disabled", "32kHz", "44.1kHz", "48kHz" | ||
543 | }; | ||
544 | |||
545 | static const struct soc_enum dac_deemphasis = | ||
546 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text); | ||
547 | |||
548 | static const char *companding_text[] = { | 587 | static const char *companding_text[] = { |
549 | "ulaw", "alaw" | 588 | "ulaw", "alaw" |
550 | }; | 589 | }; |
@@ -596,6 +635,29 @@ static const struct soc_enum lsidetone_enum = | |||
596 | static const struct soc_enum rsidetone_enum = | 635 | static const struct soc_enum rsidetone_enum = |
597 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); | 636 | SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_0, 0, 3, sidetone_text); |
598 | 637 | ||
638 | static const char *adcinput_text[] = { | ||
639 | "ADC", "DMIC" | ||
640 | }; | ||
641 | |||
642 | static const struct soc_enum adcinput_enum = | ||
643 | SOC_ENUM_SINGLE(WM8903_CLOCK_RATE_TEST_4, 9, 2, adcinput_text); | ||
644 | |||
645 | static const char *aif_text[] = { | ||
646 | "Left", "Right" | ||
647 | }; | ||
648 | |||
649 | static const struct soc_enum lcapture_enum = | ||
650 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 7, 2, aif_text); | ||
651 | |||
652 | static const struct soc_enum rcapture_enum = | ||
653 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 6, 2, aif_text); | ||
654 | |||
655 | static const struct soc_enum lplay_enum = | ||
656 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 5, 2, aif_text); | ||
657 | |||
658 | static const struct soc_enum rplay_enum = | ||
659 | SOC_ENUM_SINGLE(WM8903_AUDIO_INTERFACE_0, 4, 2, aif_text); | ||
660 | |||
599 | static const struct snd_kcontrol_new wm8903_snd_controls[] = { | 661 | static const struct snd_kcontrol_new wm8903_snd_controls[] = { |
600 | 662 | ||
601 | /* Input PGAs - No TLV since the scale depends on PGA mode */ | 663 | /* Input PGAs - No TLV since the scale depends on PGA mode */ |
@@ -614,6 +676,9 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, | |||
614 | 6, 1, 0), | 676 | 6, 1, 0), |
615 | 677 | ||
616 | /* ADCs */ | 678 | /* ADCs */ |
679 | SOC_ENUM("ADC OSR", adc_osr), | ||
680 | SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0), | ||
681 | SOC_ENUM("HPF Mode", hpf_mode), | ||
617 | SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), | 682 | SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), |
618 | SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), | 683 | SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), |
619 | SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), | 684 | SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), |
@@ -635,7 +700,7 @@ SOC_ENUM("DRC Smoothing Threshold", drc_smoothing), | |||
635 | SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), | 700 | SOC_SINGLE_TLV("DRC Startup Volume", WM8903_DRC_0, 6, 18, 0, drc_tlv_startup), |
636 | 701 | ||
637 | SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, | 702 | SOC_DOUBLE_R_TLV("Digital Capture Volume", WM8903_ADC_DIGITAL_VOLUME_LEFT, |
638 | WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 96, 0, digital_tlv), | 703 | WM8903_ADC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), |
639 | SOC_ENUM("ADC Companding Mode", adc_companding), | 704 | SOC_ENUM("ADC Companding Mode", adc_companding), |
640 | SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), | 705 | SOC_SINGLE("ADC Companding Switch", WM8903_AUDIO_INTERFACE_0, 3, 1, 0), |
641 | 706 | ||
@@ -643,14 +708,16 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8, | |||
643 | 12, 0, digital_sidetone_tlv), | 708 | 12, 0, digital_sidetone_tlv), |
644 | 709 | ||
645 | /* DAC */ | 710 | /* DAC */ |
711 | SOC_ENUM("DAC OSR", dac_osr), | ||
646 | SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, | 712 | SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, |
647 | WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), | 713 | WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), |
648 | SOC_ENUM("DAC Soft Mute Rate", soft_mute), | 714 | SOC_ENUM("DAC Soft Mute Rate", soft_mute), |
649 | SOC_ENUM("DAC Mute Mode", mute_mode), | 715 | SOC_ENUM("DAC Mute Mode", mute_mode), |
650 | SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), | 716 | SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), |
651 | SOC_ENUM("DAC De-emphasis", dac_deemphasis), | ||
652 | SOC_ENUM("DAC Companding Mode", dac_companding), | 717 | SOC_ENUM("DAC Companding Mode", dac_companding), |
653 | SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), | 718 | SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), |
719 | SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, | ||
720 | wm8903_get_deemph, wm8903_put_deemph), | ||
654 | 721 | ||
655 | /* Headphones */ | 722 | /* Headphones */ |
656 | SOC_DOUBLE_R("Headphone Switch", | 723 | SOC_DOUBLE_R("Headphone Switch", |
@@ -708,6 +775,21 @@ static const struct snd_kcontrol_new lsidetone_mux = | |||
708 | static const struct snd_kcontrol_new rsidetone_mux = | 775 | static const struct snd_kcontrol_new rsidetone_mux = |
709 | SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); | 776 | SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum); |
710 | 777 | ||
778 | static const struct snd_kcontrol_new adcinput_mux = | ||
779 | SOC_DAPM_ENUM("ADC Input", adcinput_enum); | ||
780 | |||
781 | static const struct snd_kcontrol_new lcapture_mux = | ||
782 | SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum); | ||
783 | |||
784 | static const struct snd_kcontrol_new rcapture_mux = | ||
785 | SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum); | ||
786 | |||
787 | static const struct snd_kcontrol_new lplay_mux = | ||
788 | SOC_DAPM_ENUM("Left Playback Mux", lplay_enum); | ||
789 | |||
790 | static const struct snd_kcontrol_new rplay_mux = | ||
791 | SOC_DAPM_ENUM("Right Playback Mux", rplay_enum); | ||
792 | |||
711 | static const struct snd_kcontrol_new left_output_mixer[] = { | 793 | static const struct snd_kcontrol_new left_output_mixer[] = { |
712 | SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), | 794 | SOC_DAPM_SINGLE("DACL Switch", WM8903_ANALOGUE_LEFT_MIX_0, 3, 1, 0), |
713 | SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), | 795 | SOC_DAPM_SINGLE("DACR Switch", WM8903_ANALOGUE_LEFT_MIX_0, 2, 1, 0), |
@@ -746,6 +828,7 @@ SND_SOC_DAPM_INPUT("IN2L"), | |||
746 | SND_SOC_DAPM_INPUT("IN2R"), | 828 | SND_SOC_DAPM_INPUT("IN2R"), |
747 | SND_SOC_DAPM_INPUT("IN3L"), | 829 | SND_SOC_DAPM_INPUT("IN3L"), |
748 | SND_SOC_DAPM_INPUT("IN3R"), | 830 | SND_SOC_DAPM_INPUT("IN3R"), |
831 | SND_SOC_DAPM_INPUT("DMICDAT"), | ||
749 | 832 | ||
750 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | 833 | SND_SOC_DAPM_OUTPUT("HPOUTL"), |
751 | SND_SOC_DAPM_OUTPUT("HPOUTR"), | 834 | SND_SOC_DAPM_OUTPUT("HPOUTR"), |
@@ -771,14 +854,29 @@ SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux), | |||
771 | SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), | 854 | SND_SOC_DAPM_PGA("Left Input PGA", WM8903_POWER_MANAGEMENT_0, 1, 0, NULL, 0), |
772 | SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), | 855 | SND_SOC_DAPM_PGA("Right Input PGA", WM8903_POWER_MANAGEMENT_0, 0, 0, NULL, 0), |
773 | 856 | ||
774 | SND_SOC_DAPM_ADC("ADCL", "Left HiFi Capture", WM8903_POWER_MANAGEMENT_6, 1, 0), | 857 | SND_SOC_DAPM_MUX("Left ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux), |
775 | SND_SOC_DAPM_ADC("ADCR", "Right HiFi Capture", WM8903_POWER_MANAGEMENT_6, 0, 0), | 858 | SND_SOC_DAPM_MUX("Right ADC Input", SND_SOC_NOPM, 0, 0, &adcinput_mux), |
859 | |||
860 | SND_SOC_DAPM_ADC("ADCL", NULL, WM8903_POWER_MANAGEMENT_6, 1, 0), | ||
861 | SND_SOC_DAPM_ADC("ADCR", NULL, WM8903_POWER_MANAGEMENT_6, 0, 0), | ||
862 | |||
863 | SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux), | ||
864 | SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux), | ||
865 | |||
866 | SND_SOC_DAPM_AIF_OUT("AIFTXL", "Left HiFi Capture", 0, SND_SOC_NOPM, 0, 0), | ||
867 | SND_SOC_DAPM_AIF_OUT("AIFTXR", "Right HiFi Capture", 0, SND_SOC_NOPM, 0, 0), | ||
776 | 868 | ||
777 | SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), | 869 | SND_SOC_DAPM_MUX("DACL Sidetone", SND_SOC_NOPM, 0, 0, &lsidetone_mux), |
778 | SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), | 870 | SND_SOC_DAPM_MUX("DACR Sidetone", SND_SOC_NOPM, 0, 0, &rsidetone_mux), |
779 | 871 | ||
780 | SND_SOC_DAPM_DAC("DACL", "Left Playback", WM8903_POWER_MANAGEMENT_6, 3, 0), | 872 | SND_SOC_DAPM_AIF_IN("AIFRXL", "Left Playback", 0, SND_SOC_NOPM, 0, 0), |
781 | SND_SOC_DAPM_DAC("DACR", "Right Playback", WM8903_POWER_MANAGEMENT_6, 2, 0), | 873 | SND_SOC_DAPM_AIF_IN("AIFRXR", "Right Playback", 0, SND_SOC_NOPM, 0, 0), |
874 | |||
875 | SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux), | ||
876 | SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux), | ||
877 | |||
878 | SND_SOC_DAPM_DAC("DACL", NULL, WM8903_POWER_MANAGEMENT_6, 3, 0), | ||
879 | SND_SOC_DAPM_DAC("DACR", NULL, WM8903_POWER_MANAGEMENT_6, 2, 0), | ||
782 | 880 | ||
783 | SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, | 881 | SND_SOC_DAPM_MIXER("Left Output Mixer", WM8903_POWER_MANAGEMENT_1, 1, 0, |
784 | left_output_mixer, ARRAY_SIZE(left_output_mixer)), | 882 | left_output_mixer, ARRAY_SIZE(left_output_mixer)), |
@@ -790,23 +888,51 @@ SND_SOC_DAPM_MIXER("Left Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 1, 0, | |||
790 | SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, | 888 | SND_SOC_DAPM_MIXER("Right Speaker Mixer", WM8903_POWER_MANAGEMENT_4, 0, 0, |
791 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), | 889 | right_speaker_mixer, ARRAY_SIZE(right_speaker_mixer)), |
792 | 890 | ||
793 | SND_SOC_DAPM_PGA_E("Left Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, | 891 | SND_SOC_DAPM_PGA_S("Left Headphone Output PGA", 0, WM8903_POWER_MANAGEMENT_2, |
794 | 1, 0, NULL, 0, wm8903_output_event, | 892 | 1, 0, NULL, 0), |
795 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 893 | SND_SOC_DAPM_PGA_S("Right Headphone Output PGA", 0, WM8903_POWER_MANAGEMENT_2, |
796 | SND_SOC_DAPM_PRE_PMD), | 894 | 0, 0, NULL, 0), |
797 | SND_SOC_DAPM_PGA_E("Right Headphone Output PGA", WM8903_POWER_MANAGEMENT_2, | 895 | |
798 | 0, 0, NULL, 0, wm8903_output_event, | 896 | SND_SOC_DAPM_PGA_S("Left Line Output PGA", 0, WM8903_POWER_MANAGEMENT_3, 1, 0, |
799 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 897 | NULL, 0), |
800 | SND_SOC_DAPM_PRE_PMD), | 898 | SND_SOC_DAPM_PGA_S("Right Line Output PGA", 0, WM8903_POWER_MANAGEMENT_3, 0, 0, |
801 | 899 | NULL, 0), | |
802 | SND_SOC_DAPM_PGA_E("Left Line Output PGA", WM8903_POWER_MANAGEMENT_3, 1, 0, | 900 | |
803 | NULL, 0, wm8903_output_event, | 901 | SND_SOC_DAPM_PGA_S("HPL_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 7, 0, NULL, 0), |
804 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 902 | SND_SOC_DAPM_PGA_S("HPL_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 6, 0, NULL, 0), |
805 | SND_SOC_DAPM_PRE_PMD), | 903 | SND_SOC_DAPM_PGA_S("HPL_ENA_DLY", 2, WM8903_ANALOGUE_HP_0, 5, 0, NULL, 0), |
806 | SND_SOC_DAPM_PGA_E("Right Line Output PGA", WM8903_POWER_MANAGEMENT_3, 0, 0, | 904 | SND_SOC_DAPM_PGA_S("HPL_ENA", 1, WM8903_ANALOGUE_HP_0, 4, 0, NULL, 0), |
807 | NULL, 0, wm8903_output_event, | 905 | SND_SOC_DAPM_PGA_S("HPR_RMV_SHORT", 4, WM8903_ANALOGUE_HP_0, 3, 0, NULL, 0), |
808 | SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMU | | 906 | SND_SOC_DAPM_PGA_S("HPR_ENA_OUTP", 3, WM8903_ANALOGUE_HP_0, 2, 0, NULL, 0), |
809 | SND_SOC_DAPM_PRE_PMD), | 907 | SND_SOC_DAPM_PGA_S("HPR_ENA_DLY", 2, WM8903_ANALOGUE_HP_0, 1, 0, NULL, 0), |
908 | SND_SOC_DAPM_PGA_S("HPR_ENA", 1, WM8903_ANALOGUE_HP_0, 0, 0, NULL, 0), | ||
909 | |||
910 | SND_SOC_DAPM_PGA_S("LINEOUTL_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 7, 0, | ||
911 | NULL, 0), | ||
912 | SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 6, 0, | ||
913 | NULL, 0), | ||
914 | SND_SOC_DAPM_PGA_S("LINEOUTL_ENA_DLY", 2, WM8903_ANALOGUE_LINEOUT_0, 5, 0, | ||
915 | NULL, 0), | ||
916 | SND_SOC_DAPM_PGA_S("LINEOUTL_ENA", 1, WM8903_ANALOGUE_LINEOUT_0, 4, 0, | ||
917 | NULL, 0), | ||
918 | SND_SOC_DAPM_PGA_S("LINEOUTR_RMV_SHORT", 4, WM8903_ANALOGUE_LINEOUT_0, 3, 0, | ||
919 | NULL, 0), | ||
920 | SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_OUTP", 3, WM8903_ANALOGUE_LINEOUT_0, 2, 0, | ||
921 | NULL, 0), | ||
922 | SND_SOC_DAPM_PGA_S("LINEOUTR_ENA_DLY", 2, WM8903_ANALOGUE_LINEOUT_0, 1, 0, | ||
923 | NULL, 0), | ||
924 | SND_SOC_DAPM_PGA_S("LINEOUTR_ENA", 1, WM8903_ANALOGUE_LINEOUT_0, 0, 0, | ||
925 | NULL, 0), | ||
926 | |||
927 | SND_SOC_DAPM_SUPPLY("DCS Master", WM8903_DC_SERVO_0, 4, 0, NULL, 0), | ||
928 | SND_SOC_DAPM_PGA_S("HPL_DCS", 3, SND_SOC_NOPM, 3, 0, wm8903_dcs_event, | ||
929 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
930 | SND_SOC_DAPM_PGA_S("HPR_DCS", 3, SND_SOC_NOPM, 2, 0, wm8903_dcs_event, | ||
931 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
932 | SND_SOC_DAPM_PGA_S("LINEOUTL_DCS", 3, SND_SOC_NOPM, 1, 0, wm8903_dcs_event, | ||
933 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
934 | SND_SOC_DAPM_PGA_S("LINEOUTR_DCS", 3, SND_SOC_NOPM, 0, 0, wm8903_dcs_event, | ||
935 | SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), | ||
810 | 936 | ||
811 | SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, | 937 | SND_SOC_DAPM_PGA("Left Speaker PGA", WM8903_POWER_MANAGEMENT_5, 1, 0, |
812 | NULL, 0), | 938 | NULL, 0), |
@@ -816,9 +942,17 @@ SND_SOC_DAPM_PGA("Right Speaker PGA", WM8903_POWER_MANAGEMENT_5, 0, 0, | |||
816 | SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, | 942 | SND_SOC_DAPM_SUPPLY("Charge Pump", WM8903_CHARGE_PUMP_0, 0, 0, |
817 | wm8903_cp_event, SND_SOC_DAPM_POST_PMU), | 943 | wm8903_cp_event, SND_SOC_DAPM_POST_PMU), |
818 | SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), | 944 | SND_SOC_DAPM_SUPPLY("CLK_DSP", WM8903_CLOCK_RATES_2, 1, 0, NULL, 0), |
945 | SND_SOC_DAPM_SUPPLY("CLK_SYS", WM8903_CLOCK_RATES_2, 2, 0, NULL, 0), | ||
819 | }; | 946 | }; |
820 | 947 | ||
821 | static const struct snd_soc_dapm_route intercon[] = { | 948 | static const struct snd_soc_dapm_route wm8903_intercon[] = { |
949 | |||
950 | { "CLK_DSP", NULL, "CLK_SYS" }, | ||
951 | { "Mic Bias", NULL, "CLK_SYS" }, | ||
952 | { "HPL_DCS", NULL, "CLK_SYS" }, | ||
953 | { "HPR_DCS", NULL, "CLK_SYS" }, | ||
954 | { "LINEOUTL_DCS", NULL, "CLK_SYS" }, | ||
955 | { "LINEOUTR_DCS", NULL, "CLK_SYS" }, | ||
822 | 956 | ||
823 | { "Left Input Mux", "IN1L", "IN1L" }, | 957 | { "Left Input Mux", "IN1L", "IN1L" }, |
824 | { "Left Input Mux", "IN2L", "IN2L" }, | 958 | { "Left Input Mux", "IN2L", "IN2L" }, |
@@ -860,18 +994,41 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
860 | { "Left Input PGA", NULL, "Left Input Mode Mux" }, | 994 | { "Left Input PGA", NULL, "Left Input Mode Mux" }, |
861 | { "Right Input PGA", NULL, "Right Input Mode Mux" }, | 995 | { "Right Input PGA", NULL, "Right Input Mode Mux" }, |
862 | 996 | ||
863 | { "ADCL", NULL, "Left Input PGA" }, | 997 | { "Left ADC Input", "ADC", "Left Input PGA" }, |
998 | { "Left ADC Input", "DMIC", "DMICDAT" }, | ||
999 | { "Right ADC Input", "ADC", "Right Input PGA" }, | ||
1000 | { "Right ADC Input", "DMIC", "DMICDAT" }, | ||
1001 | |||
1002 | { "Left Capture Mux", "Left", "ADCL" }, | ||
1003 | { "Left Capture Mux", "Right", "ADCR" }, | ||
1004 | |||
1005 | { "Right Capture Mux", "Left", "ADCL" }, | ||
1006 | { "Right Capture Mux", "Right", "ADCR" }, | ||
1007 | |||
1008 | { "AIFTXL", NULL, "Left Capture Mux" }, | ||
1009 | { "AIFTXR", NULL, "Right Capture Mux" }, | ||
1010 | |||
1011 | { "ADCL", NULL, "Left ADC Input" }, | ||
864 | { "ADCL", NULL, "CLK_DSP" }, | 1012 | { "ADCL", NULL, "CLK_DSP" }, |
865 | { "ADCR", NULL, "Right Input PGA" }, | 1013 | { "ADCR", NULL, "Right ADC Input" }, |
866 | { "ADCR", NULL, "CLK_DSP" }, | 1014 | { "ADCR", NULL, "CLK_DSP" }, |
867 | 1015 | ||
1016 | { "Left Playback Mux", "Left", "AIFRXL" }, | ||
1017 | { "Left Playback Mux", "Right", "AIFRXR" }, | ||
1018 | |||
1019 | { "Right Playback Mux", "Left", "AIFRXL" }, | ||
1020 | { "Right Playback Mux", "Right", "AIFRXR" }, | ||
1021 | |||
868 | { "DACL Sidetone", "Left", "ADCL" }, | 1022 | { "DACL Sidetone", "Left", "ADCL" }, |
869 | { "DACL Sidetone", "Right", "ADCR" }, | 1023 | { "DACL Sidetone", "Right", "ADCR" }, |
870 | { "DACR Sidetone", "Left", "ADCL" }, | 1024 | { "DACR Sidetone", "Left", "ADCL" }, |
871 | { "DACR Sidetone", "Right", "ADCR" }, | 1025 | { "DACR Sidetone", "Right", "ADCR" }, |
872 | 1026 | ||
1027 | { "DACL", NULL, "Left Playback Mux" }, | ||
873 | { "DACL", NULL, "DACL Sidetone" }, | 1028 | { "DACL", NULL, "DACL Sidetone" }, |
874 | { "DACL", NULL, "CLK_DSP" }, | 1029 | { "DACL", NULL, "CLK_DSP" }, |
1030 | |||
1031 | { "DACR", NULL, "Right Playback Mux" }, | ||
875 | { "DACR", NULL, "DACR Sidetone" }, | 1032 | { "DACR", NULL, "DACR Sidetone" }, |
876 | { "DACR", NULL, "CLK_DSP" }, | 1033 | { "DACR", NULL, "CLK_DSP" }, |
877 | 1034 | ||
@@ -904,11 +1061,39 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
904 | { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, | 1061 | { "Left Speaker PGA", NULL, "Left Speaker Mixer" }, |
905 | { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, | 1062 | { "Right Speaker PGA", NULL, "Right Speaker Mixer" }, |
906 | 1063 | ||
907 | { "HPOUTL", NULL, "Left Headphone Output PGA" }, | 1064 | { "HPL_ENA", NULL, "Left Headphone Output PGA" }, |
908 | { "HPOUTR", NULL, "Right Headphone Output PGA" }, | 1065 | { "HPR_ENA", NULL, "Right Headphone Output PGA" }, |
909 | 1066 | { "HPL_ENA_DLY", NULL, "HPL_ENA" }, | |
910 | { "LINEOUTL", NULL, "Left Line Output PGA" }, | 1067 | { "HPR_ENA_DLY", NULL, "HPR_ENA" }, |
911 | { "LINEOUTR", NULL, "Right Line Output PGA" }, | 1068 | { "LINEOUTL_ENA", NULL, "Left Line Output PGA" }, |
1069 | { "LINEOUTR_ENA", NULL, "Right Line Output PGA" }, | ||
1070 | { "LINEOUTL_ENA_DLY", NULL, "LINEOUTL_ENA" }, | ||
1071 | { "LINEOUTR_ENA_DLY", NULL, "LINEOUTR_ENA" }, | ||
1072 | |||
1073 | { "HPL_DCS", NULL, "DCS Master" }, | ||
1074 | { "HPR_DCS", NULL, "DCS Master" }, | ||
1075 | { "LINEOUTL_DCS", NULL, "DCS Master" }, | ||
1076 | { "LINEOUTR_DCS", NULL, "DCS Master" }, | ||
1077 | |||
1078 | { "HPL_DCS", NULL, "HPL_ENA_DLY" }, | ||
1079 | { "HPR_DCS", NULL, "HPR_ENA_DLY" }, | ||
1080 | { "LINEOUTL_DCS", NULL, "LINEOUTL_ENA_DLY" }, | ||
1081 | { "LINEOUTR_DCS", NULL, "LINEOUTR_ENA_DLY" }, | ||
1082 | |||
1083 | { "HPL_ENA_OUTP", NULL, "HPL_DCS" }, | ||
1084 | { "HPR_ENA_OUTP", NULL, "HPR_DCS" }, | ||
1085 | { "LINEOUTL_ENA_OUTP", NULL, "LINEOUTL_DCS" }, | ||
1086 | { "LINEOUTR_ENA_OUTP", NULL, "LINEOUTR_DCS" }, | ||
1087 | |||
1088 | { "HPL_RMV_SHORT", NULL, "HPL_ENA_OUTP" }, | ||
1089 | { "HPR_RMV_SHORT", NULL, "HPR_ENA_OUTP" }, | ||
1090 | { "LINEOUTL_RMV_SHORT", NULL, "LINEOUTL_ENA_OUTP" }, | ||
1091 | { "LINEOUTR_RMV_SHORT", NULL, "LINEOUTR_ENA_OUTP" }, | ||
1092 | |||
1093 | { "HPOUTL", NULL, "HPL_RMV_SHORT" }, | ||
1094 | { "HPOUTR", NULL, "HPR_RMV_SHORT" }, | ||
1095 | { "LINEOUTL", NULL, "LINEOUTL_RMV_SHORT" }, | ||
1096 | { "LINEOUTR", NULL, "LINEOUTR_RMV_SHORT" }, | ||
912 | 1097 | ||
913 | { "LOP", NULL, "Left Speaker PGA" }, | 1098 | { "LOP", NULL, "Left Speaker PGA" }, |
914 | { "LON", NULL, "Left Speaker PGA" }, | 1099 | { "LON", NULL, "Left Speaker PGA" }, |
@@ -922,78 +1107,116 @@ static const struct snd_soc_dapm_route intercon[] = { | |||
922 | { "Right Line Output PGA", NULL, "Charge Pump" }, | 1107 | { "Right Line Output PGA", NULL, "Charge Pump" }, |
923 | }; | 1108 | }; |
924 | 1109 | ||
925 | static int wm8903_add_widgets(struct snd_soc_codec *codec) | ||
926 | { | ||
927 | snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, | ||
928 | ARRAY_SIZE(wm8903_dapm_widgets)); | ||
929 | |||
930 | snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); | ||
931 | |||
932 | return 0; | ||
933 | } | ||
934 | |||
935 | static int wm8903_set_bias_level(struct snd_soc_codec *codec, | 1110 | static int wm8903_set_bias_level(struct snd_soc_codec *codec, |
936 | enum snd_soc_bias_level level) | 1111 | enum snd_soc_bias_level level) |
937 | { | 1112 | { |
938 | struct i2c_client *i2c = codec->control_data; | ||
939 | u16 reg, reg2; | ||
940 | |||
941 | switch (level) { | 1113 | switch (level) { |
942 | case SND_SOC_BIAS_ON: | 1114 | case SND_SOC_BIAS_ON: |
1115 | break; | ||
1116 | |||
943 | case SND_SOC_BIAS_PREPARE: | 1117 | case SND_SOC_BIAS_PREPARE: |
944 | reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); | 1118 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
945 | reg &= ~(WM8903_VMID_RES_MASK); | 1119 | WM8903_VMID_RES_MASK, |
946 | reg |= WM8903_VMID_RES_50K; | 1120 | WM8903_VMID_RES_50K); |
947 | snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg); | ||
948 | break; | 1121 | break; |
949 | 1122 | ||
950 | case SND_SOC_BIAS_STANDBY: | 1123 | case SND_SOC_BIAS_STANDBY: |
951 | if (codec->bias_level == SND_SOC_BIAS_OFF) { | 1124 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
952 | snd_soc_write(codec, WM8903_CLOCK_RATES_2, | 1125 | snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
953 | WM8903_CLK_SYS_ENA); | 1126 | WM8903_POBCTRL | WM8903_ISEL_MASK | |
954 | 1127 | WM8903_STARTUP_BIAS_ENA | | |
955 | /* Change DC servo dither level in startup sequence */ | 1128 | WM8903_BIAS_ENA, |
956 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, 0x11); | 1129 | WM8903_POBCTRL | |
957 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_1, 0x1257); | 1130 | (2 << WM8903_ISEL_SHIFT) | |
958 | snd_soc_write(codec, WM8903_WRITE_SEQUENCER_2, 0x2); | 1131 | WM8903_STARTUP_BIAS_ENA); |
959 | 1132 | ||
960 | wm8903_run_sequence(codec, 0); | 1133 | snd_soc_update_bits(codec, |
961 | wm8903_sync_reg_cache(codec, codec->reg_cache); | 1134 | WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0, |
962 | 1135 | WM8903_SPK_DISCHARGE, | |
963 | /* Enable low impedence charge pump output */ | 1136 | WM8903_SPK_DISCHARGE); |
964 | reg = snd_soc_read(codec, | 1137 | |
965 | WM8903_CONTROL_INTERFACE_TEST_1); | 1138 | msleep(33); |
966 | snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, | 1139 | |
967 | reg | WM8903_TEST_KEY); | 1140 | snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5, |
968 | reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1); | 1141 | WM8903_SPKL_ENA | WM8903_SPKR_ENA, |
969 | snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1, | 1142 | WM8903_SPKL_ENA | WM8903_SPKR_ENA); |
970 | reg2 | WM8903_CP_SW_KELVIN_MODE_MASK); | 1143 | |
971 | snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, | 1144 | snd_soc_update_bits(codec, |
972 | reg); | 1145 | WM8903_ANALOGUE_SPK_OUTPUT_CONTROL_0, |
1146 | WM8903_SPK_DISCHARGE, 0); | ||
1147 | |||
1148 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1149 | WM8903_VMID_TIE_ENA | | ||
1150 | WM8903_BUFIO_ENA | | ||
1151 | WM8903_VMID_IO_ENA | | ||
1152 | WM8903_VMID_SOFT_MASK | | ||
1153 | WM8903_VMID_RES_MASK | | ||
1154 | WM8903_VMID_BUF_ENA, | ||
1155 | WM8903_VMID_TIE_ENA | | ||
1156 | WM8903_BUFIO_ENA | | ||
1157 | WM8903_VMID_IO_ENA | | ||
1158 | (2 << WM8903_VMID_SOFT_SHIFT) | | ||
1159 | WM8903_VMID_RES_250K | | ||
1160 | WM8903_VMID_BUF_ENA); | ||
1161 | |||
1162 | msleep(129); | ||
1163 | |||
1164 | snd_soc_update_bits(codec, WM8903_POWER_MANAGEMENT_5, | ||
1165 | WM8903_SPKL_ENA | WM8903_SPKR_ENA, | ||
1166 | 0); | ||
1167 | |||
1168 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1169 | WM8903_VMID_SOFT_MASK, 0); | ||
1170 | |||
1171 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1172 | WM8903_VMID_RES_MASK, | ||
1173 | WM8903_VMID_RES_50K); | ||
1174 | |||
1175 | snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, | ||
1176 | WM8903_BIAS_ENA | WM8903_POBCTRL, | ||
1177 | WM8903_BIAS_ENA); | ||
973 | 1178 | ||
974 | /* By default no bypass paths are enabled so | 1179 | /* By default no bypass paths are enabled so |
975 | * enable Class W support. | 1180 | * enable Class W support. |
976 | */ | 1181 | */ |
977 | dev_dbg(&i2c->dev, "Enabling Class W\n"); | 1182 | dev_dbg(codec->dev, "Enabling Class W\n"); |
978 | snd_soc_write(codec, WM8903_CLASS_W_0, reg | | 1183 | snd_soc_update_bits(codec, WM8903_CLASS_W_0, |
979 | WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); | 1184 | WM8903_CP_DYN_FREQ | |
1185 | WM8903_CP_DYN_V, | ||
1186 | WM8903_CP_DYN_FREQ | | ||
1187 | WM8903_CP_DYN_V); | ||
980 | } | 1188 | } |
981 | 1189 | ||
982 | reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); | 1190 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
983 | reg &= ~(WM8903_VMID_RES_MASK); | 1191 | WM8903_VMID_RES_MASK, |
984 | reg |= WM8903_VMID_RES_250K; | 1192 | WM8903_VMID_RES_250K); |
985 | snd_soc_write(codec, WM8903_VMID_CONTROL_0, reg); | ||
986 | break; | 1193 | break; |
987 | 1194 | ||
988 | case SND_SOC_BIAS_OFF: | 1195 | case SND_SOC_BIAS_OFF: |
989 | wm8903_run_sequence(codec, 32); | 1196 | snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, |
990 | reg = snd_soc_read(codec, WM8903_CLOCK_RATES_2); | 1197 | WM8903_BIAS_ENA, 0); |
991 | reg &= ~WM8903_CLK_SYS_ENA; | 1198 | |
992 | snd_soc_write(codec, WM8903_CLOCK_RATES_2, reg); | 1199 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, |
1200 | WM8903_VMID_SOFT_MASK, | ||
1201 | 2 << WM8903_VMID_SOFT_SHIFT); | ||
1202 | |||
1203 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1204 | WM8903_VMID_BUF_ENA, 0); | ||
1205 | |||
1206 | msleep(290); | ||
1207 | |||
1208 | snd_soc_update_bits(codec, WM8903_VMID_CONTROL_0, | ||
1209 | WM8903_VMID_TIE_ENA | WM8903_BUFIO_ENA | | ||
1210 | WM8903_VMID_IO_ENA | WM8903_VMID_RES_MASK | | ||
1211 | WM8903_VMID_SOFT_MASK | | ||
1212 | WM8903_VMID_BUF_ENA, 0); | ||
1213 | |||
1214 | snd_soc_update_bits(codec, WM8903_BIAS_CONTROL_0, | ||
1215 | WM8903_STARTUP_BIAS_ENA, 0); | ||
993 | break; | 1216 | break; |
994 | } | 1217 | } |
995 | 1218 | ||
996 | codec->bias_level = level; | 1219 | codec->dapm.bias_level = level; |
997 | 1220 | ||
998 | return 0; | 1221 | return 0; |
999 | } | 1222 | } |
@@ -1224,70 +1447,13 @@ static struct { | |||
1224 | { 0, 0 }, | 1447 | { 0, 0 }, |
1225 | }; | 1448 | }; |
1226 | 1449 | ||
1227 | static int wm8903_startup(struct snd_pcm_substream *substream, | ||
1228 | struct snd_soc_dai *dai) | ||
1229 | { | ||
1230 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
1231 | struct snd_soc_device *socdev = rtd->socdev; | ||
1232 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1233 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1234 | struct i2c_client *i2c = codec->control_data; | ||
1235 | struct snd_pcm_runtime *master_runtime; | ||
1236 | |||
1237 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1238 | wm8903->playback_active++; | ||
1239 | else | ||
1240 | wm8903->capture_active++; | ||
1241 | |||
1242 | /* The DAI has shared clocks so if we already have a playback or | ||
1243 | * capture going then constrain this substream to match it. | ||
1244 | */ | ||
1245 | if (wm8903->master_substream) { | ||
1246 | master_runtime = wm8903->master_substream->runtime; | ||
1247 | |||
1248 | dev_dbg(&i2c->dev, "Constraining to %d bits\n", | ||
1249 | master_runtime->sample_bits); | ||
1250 | |||
1251 | snd_pcm_hw_constraint_minmax(substream->runtime, | ||
1252 | SNDRV_PCM_HW_PARAM_SAMPLE_BITS, | ||
1253 | master_runtime->sample_bits, | ||
1254 | master_runtime->sample_bits); | ||
1255 | |||
1256 | wm8903->slave_substream = substream; | ||
1257 | } else | ||
1258 | wm8903->master_substream = substream; | ||
1259 | |||
1260 | return 0; | ||
1261 | } | ||
1262 | |||
1263 | static void wm8903_shutdown(struct snd_pcm_substream *substream, | ||
1264 | struct snd_soc_dai *dai) | ||
1265 | { | ||
1266 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
1267 | struct snd_soc_device *socdev = rtd->socdev; | ||
1268 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1269 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1270 | |||
1271 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | ||
1272 | wm8903->playback_active--; | ||
1273 | else | ||
1274 | wm8903->capture_active--; | ||
1275 | |||
1276 | if (wm8903->master_substream == substream) | ||
1277 | wm8903->master_substream = wm8903->slave_substream; | ||
1278 | |||
1279 | wm8903->slave_substream = NULL; | ||
1280 | } | ||
1281 | |||
1282 | static int wm8903_hw_params(struct snd_pcm_substream *substream, | 1450 | static int wm8903_hw_params(struct snd_pcm_substream *substream, |
1283 | struct snd_pcm_hw_params *params, | 1451 | struct snd_pcm_hw_params *params, |
1284 | struct snd_soc_dai *dai) | 1452 | struct snd_soc_dai *dai) |
1285 | { | 1453 | { |
1286 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 1454 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
1287 | struct snd_soc_device *socdev = rtd->socdev; | 1455 | struct snd_soc_codec *codec =rtd->codec; |
1288 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1289 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | 1456 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
1290 | struct i2c_client *i2c = codec->control_data; | ||
1291 | int fs = params_rate(params); | 1457 | int fs = params_rate(params); |
1292 | int bclk; | 1458 | int bclk; |
1293 | int bclk_div; | 1459 | int bclk_div; |
@@ -1305,11 +1471,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, | |||
1305 | u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); | 1471 | u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); |
1306 | u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); | 1472 | u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); |
1307 | 1473 | ||
1308 | if (substream == wm8903->slave_substream) { | ||
1309 | dev_dbg(&i2c->dev, "Ignoring hw_params for slave substream\n"); | ||
1310 | return 0; | ||
1311 | } | ||
1312 | |||
1313 | /* Enable sloping stopband filter for low sample rates */ | 1474 | /* Enable sloping stopband filter for low sample rates */ |
1314 | if (fs <= 24000) | 1475 | if (fs <= 24000) |
1315 | dac_digital1 |= WM8903_DAC_SB_FILT; | 1476 | dac_digital1 |= WM8903_DAC_SB_FILT; |
@@ -1327,20 +1488,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, | |||
1327 | } | 1488 | } |
1328 | } | 1489 | } |
1329 | 1490 | ||
1330 | /* Constraints should stop us hitting this but let's make sure */ | 1491 | dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); |
1331 | if (wm8903->capture_active) | ||
1332 | switch (sample_rates[dsp_config].rate) { | ||
1333 | case 88200: | ||
1334 | case 96000: | ||
1335 | dev_err(&i2c->dev, "%dHz unsupported by ADC\n", | ||
1336 | fs); | ||
1337 | return -EINVAL; | ||
1338 | |||
1339 | default: | ||
1340 | break; | ||
1341 | } | ||
1342 | |||
1343 | dev_dbg(&i2c->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); | ||
1344 | clock1 &= ~WM8903_SAMPLE_RATE_MASK; | 1492 | clock1 &= ~WM8903_SAMPLE_RATE_MASK; |
1345 | clock1 |= sample_rates[dsp_config].value; | 1493 | clock1 |= sample_rates[dsp_config].value; |
1346 | 1494 | ||
@@ -1366,7 +1514,7 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, | |||
1366 | return -EINVAL; | 1514 | return -EINVAL; |
1367 | } | 1515 | } |
1368 | 1516 | ||
1369 | dev_dbg(&i2c->dev, "MCLK = %dHz, target sample rate = %dHz\n", | 1517 | dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n", |
1370 | wm8903->sysclk, fs); | 1518 | wm8903->sysclk, fs); |
1371 | 1519 | ||
1372 | /* We may not have an MCLK which allows us to generate exactly | 1520 | /* We may not have an MCLK which allows us to generate exactly |
@@ -1401,12 +1549,12 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, | |||
1401 | clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT; | 1549 | clock1 |= clk_sys_ratios[clk_config].rate << WM8903_CLK_SYS_RATE_SHIFT; |
1402 | clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT; | 1550 | clock1 |= clk_sys_ratios[clk_config].mode << WM8903_CLK_SYS_MODE_SHIFT; |
1403 | 1551 | ||
1404 | dev_dbg(&i2c->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n", | 1552 | dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n", |
1405 | clk_sys_ratios[clk_config].rate, | 1553 | clk_sys_ratios[clk_config].rate, |
1406 | clk_sys_ratios[clk_config].mode, | 1554 | clk_sys_ratios[clk_config].mode, |
1407 | clk_sys_ratios[clk_config].div); | 1555 | clk_sys_ratios[clk_config].div); |
1408 | 1556 | ||
1409 | dev_dbg(&i2c->dev, "Actual CLK_SYS = %dHz\n", clk_sys); | 1557 | dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys); |
1410 | 1558 | ||
1411 | /* We may not get quite the right frequency if using | 1559 | /* We may not get quite the right frequency if using |
1412 | * approximate clocks so look for the closest match that is | 1560 | * approximate clocks so look for the closest match that is |
@@ -1428,13 +1576,16 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, | |||
1428 | aif2 &= ~WM8903_BCLK_DIV_MASK; | 1576 | aif2 &= ~WM8903_BCLK_DIV_MASK; |
1429 | aif3 &= ~WM8903_LRCLK_RATE_MASK; | 1577 | aif3 &= ~WM8903_LRCLK_RATE_MASK; |
1430 | 1578 | ||
1431 | dev_dbg(&i2c->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", | 1579 | dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", |
1432 | bclk_divs[bclk_div].ratio / 10, bclk, | 1580 | bclk_divs[bclk_div].ratio / 10, bclk, |
1433 | (clk_sys * 10) / bclk_divs[bclk_div].ratio); | 1581 | (clk_sys * 10) / bclk_divs[bclk_div].ratio); |
1434 | 1582 | ||
1435 | aif2 |= bclk_divs[bclk_div].div; | 1583 | aif2 |= bclk_divs[bclk_div].div; |
1436 | aif3 |= bclk / fs; | 1584 | aif3 |= bclk / fs; |
1437 | 1585 | ||
1586 | wm8903->fs = params_rate(params); | ||
1587 | wm8903_set_deemph(codec); | ||
1588 | |||
1438 | snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); | 1589 | snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); |
1439 | snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); | 1590 | snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); |
1440 | snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); | 1591 | snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); |
@@ -1486,7 +1637,7 @@ int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, | |||
1486 | WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, | 1637 | WM8903_MICDET_EINT | WM8903_MICSHRT_EINT, |
1487 | irq_mask); | 1638 | irq_mask); |
1488 | 1639 | ||
1489 | if (det && shrt) { | 1640 | if (det || shrt) { |
1490 | /* Enable mic detection, this may not have been set through | 1641 | /* Enable mic detection, this may not have been set through |
1491 | * platform data (eg, if the defaults are OK). */ | 1642 | * platform data (eg, if the defaults are OK). */ |
1492 | snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, | 1643 | snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, |
@@ -1504,8 +1655,8 @@ EXPORT_SYMBOL_GPL(wm8903_mic_detect); | |||
1504 | 1655 | ||
1505 | static irqreturn_t wm8903_irq(int irq, void *data) | 1656 | static irqreturn_t wm8903_irq(int irq, void *data) |
1506 | { | 1657 | { |
1507 | struct wm8903_priv *wm8903 = data; | 1658 | struct snd_soc_codec *codec = data; |
1508 | struct snd_soc_codec *codec = &wm8903->codec; | 1659 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); |
1509 | int mic_report; | 1660 | int mic_report; |
1510 | int int_pol; | 1661 | int int_pol; |
1511 | int int_val = 0; | 1662 | int int_val = 0; |
@@ -1514,8 +1665,7 @@ static irqreturn_t wm8903_irq(int irq, void *data) | |||
1514 | int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; | 1665 | int_val = snd_soc_read(codec, WM8903_INTERRUPT_STATUS_1) & mask; |
1515 | 1666 | ||
1516 | if (int_val & WM8903_WSEQ_BUSY_EINT) { | 1667 | if (int_val & WM8903_WSEQ_BUSY_EINT) { |
1517 | dev_dbg(codec->dev, "Write sequencer done\n"); | 1668 | dev_warn(codec->dev, "Write sequencer done\n"); |
1518 | complete(&wm8903->wseq); | ||
1519 | } | 1669 | } |
1520 | 1670 | ||
1521 | /* | 1671 | /* |
@@ -1528,6 +1678,11 @@ static irqreturn_t wm8903_irq(int irq, void *data) | |||
1528 | mic_report = wm8903->mic_last_report; | 1678 | mic_report = wm8903->mic_last_report; |
1529 | int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); | 1679 | int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); |
1530 | 1680 | ||
1681 | #ifndef CONFIG_SND_SOC_WM8903_MODULE | ||
1682 | if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) | ||
1683 | trace_snd_soc_jack_irq(dev_name(codec->dev)); | ||
1684 | #endif | ||
1685 | |||
1531 | if (int_val & WM8903_MICSHRT_EINT) { | 1686 | if (int_val & WM8903_MICSHRT_EINT) { |
1532 | dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); | 1687 | dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); |
1533 | 1688 | ||
@@ -1578,16 +1733,14 @@ static irqreturn_t wm8903_irq(int irq, void *data) | |||
1578 | SNDRV_PCM_FMTBIT_S24_LE) | 1733 | SNDRV_PCM_FMTBIT_S24_LE) |
1579 | 1734 | ||
1580 | static struct snd_soc_dai_ops wm8903_dai_ops = { | 1735 | static struct snd_soc_dai_ops wm8903_dai_ops = { |
1581 | .startup = wm8903_startup, | ||
1582 | .shutdown = wm8903_shutdown, | ||
1583 | .hw_params = wm8903_hw_params, | 1736 | .hw_params = wm8903_hw_params, |
1584 | .digital_mute = wm8903_digital_mute, | 1737 | .digital_mute = wm8903_digital_mute, |
1585 | .set_fmt = wm8903_set_dai_fmt, | 1738 | .set_fmt = wm8903_set_dai_fmt, |
1586 | .set_sysclk = wm8903_set_dai_sysclk, | 1739 | .set_sysclk = wm8903_set_dai_sysclk, |
1587 | }; | 1740 | }; |
1588 | 1741 | ||
1589 | struct snd_soc_dai wm8903_dai = { | 1742 | static struct snd_soc_dai_driver wm8903_dai = { |
1590 | .name = "WM8903", | 1743 | .name = "wm8903-hifi", |
1591 | .playback = { | 1744 | .playback = { |
1592 | .stream_name = "Playback", | 1745 | .stream_name = "Playback", |
1593 | .channels_min = 2, | 1746 | .channels_min = 2, |
@@ -1605,23 +1758,16 @@ struct snd_soc_dai wm8903_dai = { | |||
1605 | .ops = &wm8903_dai_ops, | 1758 | .ops = &wm8903_dai_ops, |
1606 | .symmetric_rates = 1, | 1759 | .symmetric_rates = 1, |
1607 | }; | 1760 | }; |
1608 | EXPORT_SYMBOL_GPL(wm8903_dai); | ||
1609 | 1761 | ||
1610 | static int wm8903_suspend(struct platform_device *pdev, pm_message_t state) | 1762 | static int wm8903_suspend(struct snd_soc_codec *codec, pm_message_t state) |
1611 | { | 1763 | { |
1612 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1613 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1614 | |||
1615 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | 1764 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); |
1616 | 1765 | ||
1617 | return 0; | 1766 | return 0; |
1618 | } | 1767 | } |
1619 | 1768 | ||
1620 | static int wm8903_resume(struct platform_device *pdev) | 1769 | static int wm8903_resume(struct snd_soc_codec *codec) |
1621 | { | 1770 | { |
1622 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1623 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1624 | struct i2c_client *i2c = codec->control_data; | ||
1625 | int i; | 1771 | int i; |
1626 | u16 *reg_cache = codec->reg_cache; | 1772 | u16 *reg_cache = codec->reg_cache; |
1627 | u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), | 1773 | u16 *tmp_cache = kmemdup(reg_cache, sizeof(wm8903_reg_defaults), |
@@ -1637,77 +1783,177 @@ static int wm8903_resume(struct platform_device *pdev) | |||
1637 | snd_soc_write(codec, i, tmp_cache[i]); | 1783 | snd_soc_write(codec, i, tmp_cache[i]); |
1638 | kfree(tmp_cache); | 1784 | kfree(tmp_cache); |
1639 | } else { | 1785 | } else { |
1640 | dev_err(&i2c->dev, "Failed to allocate temporary cache\n"); | 1786 | dev_err(codec->dev, "Failed to allocate temporary cache\n"); |
1641 | } | 1787 | } |
1642 | 1788 | ||
1643 | return 0; | 1789 | return 0; |
1644 | } | 1790 | } |
1645 | 1791 | ||
1646 | static struct snd_soc_codec *wm8903_codec; | 1792 | #ifdef CONFIG_GPIOLIB |
1793 | static inline struct wm8903_priv *gpio_to_wm8903(struct gpio_chip *chip) | ||
1794 | { | ||
1795 | return container_of(chip, struct wm8903_priv, gpio_chip); | ||
1796 | } | ||
1647 | 1797 | ||
1648 | static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | 1798 | static int wm8903_gpio_request(struct gpio_chip *chip, unsigned offset) |
1649 | const struct i2c_device_id *id) | ||
1650 | { | 1799 | { |
1651 | struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); | 1800 | if (offset >= WM8903_NUM_GPIO) |
1652 | struct wm8903_priv *wm8903; | 1801 | return -EINVAL; |
1653 | struct snd_soc_codec *codec; | ||
1654 | int ret, i; | ||
1655 | int trigger, irq_pol; | ||
1656 | u16 val; | ||
1657 | 1802 | ||
1658 | wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); | 1803 | return 0; |
1659 | if (wm8903 == NULL) | 1804 | } |
1660 | return -ENOMEM; | ||
1661 | 1805 | ||
1662 | codec = &wm8903->codec; | 1806 | static int wm8903_gpio_direction_in(struct gpio_chip *chip, unsigned offset) |
1807 | { | ||
1808 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | ||
1809 | struct snd_soc_codec *codec = wm8903->codec; | ||
1810 | unsigned int mask, val; | ||
1663 | 1811 | ||
1664 | mutex_init(&codec->mutex); | 1812 | mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK; |
1665 | INIT_LIST_HEAD(&codec->dapm_widgets); | 1813 | val = (WM8903_GPn_FN_GPIO_INPUT << WM8903_GP1_FN_SHIFT) | |
1666 | INIT_LIST_HEAD(&codec->dapm_paths); | 1814 | WM8903_GP1_DIR; |
1667 | 1815 | ||
1668 | codec->dev = &i2c->dev; | 1816 | return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, |
1669 | codec->name = "WM8903"; | 1817 | mask, val); |
1670 | codec->owner = THIS_MODULE; | 1818 | } |
1671 | codec->bias_level = SND_SOC_BIAS_OFF; | 1819 | |
1672 | codec->set_bias_level = wm8903_set_bias_level; | 1820 | static int wm8903_gpio_get(struct gpio_chip *chip, unsigned offset) |
1673 | codec->dai = &wm8903_dai; | 1821 | { |
1674 | codec->num_dai = 1; | 1822 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); |
1675 | codec->reg_cache_size = ARRAY_SIZE(wm8903->reg_cache); | 1823 | struct snd_soc_codec *codec = wm8903->codec; |
1676 | codec->reg_cache = &wm8903->reg_cache[0]; | 1824 | int reg; |
1677 | snd_soc_codec_set_drvdata(codec, wm8903); | ||
1678 | codec->volatile_register = wm8903_volatile_register; | ||
1679 | init_completion(&wm8903->wseq); | ||
1680 | 1825 | ||
1681 | i2c_set_clientdata(i2c, codec); | 1826 | reg = snd_soc_read(codec, WM8903_GPIO_CONTROL_1 + offset); |
1682 | codec->control_data = i2c; | 1827 | |
1828 | return (reg & WM8903_GP1_LVL_MASK) >> WM8903_GP1_LVL_SHIFT; | ||
1829 | } | ||
1830 | |||
1831 | static int wm8903_gpio_direction_out(struct gpio_chip *chip, | ||
1832 | unsigned offset, int value) | ||
1833 | { | ||
1834 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | ||
1835 | struct snd_soc_codec *codec = wm8903->codec; | ||
1836 | unsigned int mask, val; | ||
1837 | |||
1838 | mask = WM8903_GP1_FN_MASK | WM8903_GP1_DIR_MASK | WM8903_GP1_LVL_MASK; | ||
1839 | val = (WM8903_GPn_FN_GPIO_OUTPUT << WM8903_GP1_FN_SHIFT) | | ||
1840 | (value << WM8903_GP2_LVL_SHIFT); | ||
1841 | |||
1842 | return snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, | ||
1843 | mask, val); | ||
1844 | } | ||
1845 | |||
1846 | static void wm8903_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | ||
1847 | { | ||
1848 | struct wm8903_priv *wm8903 = gpio_to_wm8903(chip); | ||
1849 | struct snd_soc_codec *codec = wm8903->codec; | ||
1850 | |||
1851 | snd_soc_update_bits(codec, WM8903_GPIO_CONTROL_1 + offset, | ||
1852 | WM8903_GP1_LVL_MASK, | ||
1853 | !!value << WM8903_GP1_LVL_SHIFT); | ||
1854 | } | ||
1855 | |||
1856 | static struct gpio_chip wm8903_template_chip = { | ||
1857 | .label = "wm8903", | ||
1858 | .owner = THIS_MODULE, | ||
1859 | .request = wm8903_gpio_request, | ||
1860 | .direction_input = wm8903_gpio_direction_in, | ||
1861 | .get = wm8903_gpio_get, | ||
1862 | .direction_output = wm8903_gpio_direction_out, | ||
1863 | .set = wm8903_gpio_set, | ||
1864 | .can_sleep = 1, | ||
1865 | }; | ||
1866 | |||
1867 | static void wm8903_init_gpio(struct snd_soc_codec *codec) | ||
1868 | { | ||
1869 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1870 | struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); | ||
1871 | int ret; | ||
1872 | |||
1873 | wm8903->gpio_chip = wm8903_template_chip; | ||
1874 | wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; | ||
1875 | wm8903->gpio_chip.dev = codec->dev; | ||
1876 | |||
1877 | if (pdata && pdata->gpio_base) | ||
1878 | wm8903->gpio_chip.base = pdata->gpio_base; | ||
1879 | else | ||
1880 | wm8903->gpio_chip.base = -1; | ||
1881 | |||
1882 | ret = gpiochip_add(&wm8903->gpio_chip); | ||
1883 | if (ret != 0) | ||
1884 | dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); | ||
1885 | } | ||
1886 | |||
1887 | static void wm8903_free_gpio(struct snd_soc_codec *codec) | ||
1888 | { | ||
1889 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1890 | int ret; | ||
1891 | |||
1892 | ret = gpiochip_remove(&wm8903->gpio_chip); | ||
1893 | if (ret != 0) | ||
1894 | dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); | ||
1895 | } | ||
1896 | #else | ||
1897 | static void wm8903_init_gpio(struct snd_soc_codec *codec) | ||
1898 | { | ||
1899 | } | ||
1900 | |||
1901 | static void wm8903_free_gpio(struct snd_soc_codec *codec) | ||
1902 | { | ||
1903 | } | ||
1904 | #endif | ||
1905 | |||
1906 | static int wm8903_probe(struct snd_soc_codec *codec) | ||
1907 | { | ||
1908 | struct wm8903_platform_data *pdata = dev_get_platdata(codec->dev); | ||
1909 | struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); | ||
1910 | int ret, i; | ||
1911 | int trigger, irq_pol; | ||
1912 | u16 val; | ||
1913 | |||
1914 | wm8903->codec = codec; | ||
1683 | 1915 | ||
1684 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); | 1916 | ret = snd_soc_codec_set_cache_io(codec, 8, 16, SND_SOC_I2C); |
1685 | if (ret != 0) { | 1917 | if (ret != 0) { |
1686 | dev_err(&i2c->dev, "Failed to set cache I/O: %d\n", ret); | 1918 | dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
1687 | goto err; | 1919 | return ret; |
1688 | } | 1920 | } |
1689 | 1921 | ||
1690 | val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); | 1922 | val = snd_soc_read(codec, WM8903_SW_RESET_AND_ID); |
1691 | if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { | 1923 | if (val != wm8903_reg_defaults[WM8903_SW_RESET_AND_ID]) { |
1692 | dev_err(&i2c->dev, | 1924 | dev_err(codec->dev, |
1693 | "Device with ID register %x is not a WM8903\n", val); | 1925 | "Device with ID register %x is not a WM8903\n", val); |
1694 | return -ENODEV; | 1926 | return -ENODEV; |
1695 | } | 1927 | } |
1696 | 1928 | ||
1697 | val = snd_soc_read(codec, WM8903_REVISION_NUMBER); | 1929 | val = snd_soc_read(codec, WM8903_REVISION_NUMBER); |
1698 | dev_info(&i2c->dev, "WM8903 revision %d\n", | 1930 | dev_info(codec->dev, "WM8903 revision %c\n", |
1699 | val & WM8903_CHIP_REV_MASK); | 1931 | (val & WM8903_CHIP_REV_MASK) + 'A'); |
1700 | 1932 | ||
1701 | wm8903_reset(codec); | 1933 | wm8903_reset(codec); |
1702 | 1934 | ||
1703 | /* Set up GPIOs and microphone detection */ | 1935 | /* Set up GPIOs and microphone detection */ |
1704 | if (pdata) { | 1936 | if (pdata) { |
1937 | bool mic_gpio = false; | ||
1938 | |||
1705 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { | 1939 | for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { |
1706 | if (!pdata->gpio_cfg[i]) | 1940 | if (pdata->gpio_cfg[i] == WM8903_GPIO_NO_CONFIG) |
1707 | continue; | 1941 | continue; |
1708 | 1942 | ||
1709 | snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, | 1943 | snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i, |
1710 | pdata->gpio_cfg[i] & 0xffff); | 1944 | pdata->gpio_cfg[i] & 0xffff); |
1945 | |||
1946 | val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) | ||
1947 | >> WM8903_GP1_FN_SHIFT; | ||
1948 | |||
1949 | switch (val) { | ||
1950 | case WM8903_GPn_FN_MICBIAS_CURRENT_DETECT: | ||
1951 | case WM8903_GPn_FN_MICBIAS_SHORT_DETECT: | ||
1952 | mic_gpio = true; | ||
1953 | break; | ||
1954 | default: | ||
1955 | break; | ||
1956 | } | ||
1711 | } | 1957 | } |
1712 | 1958 | ||
1713 | snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, | 1959 | snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0, |
@@ -1718,10 +1964,18 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
1718 | snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, | 1964 | snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0, |
1719 | WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); | 1965 | WM8903_WSEQ_ENA, WM8903_WSEQ_ENA); |
1720 | 1966 | ||
1967 | /* If microphone detection is enabled by pdata but | ||
1968 | * detected via IRQ then interrupts can be lost before | ||
1969 | * the machine driver has set up microphone detection | ||
1970 | * IRQs as the IRQs are clear on read. The detection | ||
1971 | * will be enabled when the machine driver configures. | ||
1972 | */ | ||
1973 | WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); | ||
1974 | |||
1721 | wm8903->mic_delay = pdata->micdet_delay; | 1975 | wm8903->mic_delay = pdata->micdet_delay; |
1722 | } | 1976 | } |
1723 | 1977 | ||
1724 | if (i2c->irq) { | 1978 | if (wm8903->irq) { |
1725 | if (pdata && pdata->irq_active_low) { | 1979 | if (pdata && pdata->irq_active_low) { |
1726 | trigger = IRQF_TRIGGER_LOW; | 1980 | trigger = IRQF_TRIGGER_LOW; |
1727 | irq_pol = WM8903_IRQ_POL; | 1981 | irq_pol = WM8903_IRQ_POL; |
@@ -1733,13 +1987,13 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
1733 | snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, | 1987 | snd_soc_update_bits(codec, WM8903_INTERRUPT_CONTROL, |
1734 | WM8903_IRQ_POL, irq_pol); | 1988 | WM8903_IRQ_POL, irq_pol); |
1735 | 1989 | ||
1736 | ret = request_threaded_irq(i2c->irq, NULL, wm8903_irq, | 1990 | ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq, |
1737 | trigger | IRQF_ONESHOT, | 1991 | trigger | IRQF_ONESHOT, |
1738 | "wm8903", wm8903); | 1992 | "wm8903", codec); |
1739 | if (ret != 0) { | 1993 | if (ret != 0) { |
1740 | dev_err(&i2c->dev, "Failed to request IRQ: %d\n", | 1994 | dev_err(codec->dev, "Failed to request IRQ: %d\n", |
1741 | ret); | 1995 | ret); |
1742 | goto err; | 1996 | return ret; |
1743 | } | 1997 | } |
1744 | 1998 | ||
1745 | /* Enable write sequencer interrupts */ | 1999 | /* Enable write sequencer interrupts */ |
@@ -1777,137 +2031,107 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | |||
1777 | snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); | 2031 | snd_soc_write(codec, WM8903_ANALOGUE_OUT3_RIGHT, val); |
1778 | 2032 | ||
1779 | /* Enable DAC soft mute by default */ | 2033 | /* Enable DAC soft mute by default */ |
1780 | val = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); | 2034 | snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, |
1781 | val |= WM8903_DAC_MUTEMODE; | 2035 | WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE, |
1782 | snd_soc_write(codec, WM8903_DAC_DIGITAL_1, val); | 2036 | WM8903_DAC_MUTEMODE | WM8903_DAC_MUTE); |
1783 | 2037 | ||
1784 | wm8903_dai.dev = &i2c->dev; | 2038 | snd_soc_add_controls(codec, wm8903_snd_controls, |
1785 | wm8903_codec = codec; | 2039 | ARRAY_SIZE(wm8903_snd_controls)); |
1786 | |||
1787 | ret = snd_soc_register_codec(codec); | ||
1788 | if (ret != 0) { | ||
1789 | dev_err(&i2c->dev, "Failed to register codec: %d\n", ret); | ||
1790 | goto err_irq; | ||
1791 | } | ||
1792 | |||
1793 | ret = snd_soc_register_dai(&wm8903_dai); | ||
1794 | if (ret != 0) { | ||
1795 | dev_err(&i2c->dev, "Failed to register DAI: %d\n", ret); | ||
1796 | goto err_codec; | ||
1797 | } | ||
1798 | 2040 | ||
1799 | return ret; | 2041 | wm8903_init_gpio(codec); |
1800 | 2042 | ||
1801 | err_codec: | ||
1802 | snd_soc_unregister_codec(codec); | ||
1803 | err_irq: | ||
1804 | if (i2c->irq) | ||
1805 | free_irq(i2c->irq, wm8903); | ||
1806 | err: | ||
1807 | wm8903_codec = NULL; | ||
1808 | kfree(wm8903); | ||
1809 | return ret; | 2043 | return ret; |
1810 | } | 2044 | } |
1811 | 2045 | ||
1812 | static __devexit int wm8903_i2c_remove(struct i2c_client *client) | 2046 | /* power down chip */ |
2047 | static int wm8903_remove(struct snd_soc_codec *codec) | ||
1813 | { | 2048 | { |
1814 | struct snd_soc_codec *codec = i2c_get_clientdata(client); | 2049 | wm8903_free_gpio(codec); |
1815 | struct wm8903_priv *priv = snd_soc_codec_get_drvdata(codec); | 2050 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); |
2051 | return 0; | ||
2052 | } | ||
1816 | 2053 | ||
1817 | snd_soc_unregister_dai(&wm8903_dai); | 2054 | static struct snd_soc_codec_driver soc_codec_dev_wm8903 = { |
1818 | snd_soc_unregister_codec(codec); | 2055 | .probe = wm8903_probe, |
2056 | .remove = wm8903_remove, | ||
2057 | .suspend = wm8903_suspend, | ||
2058 | .resume = wm8903_resume, | ||
2059 | .set_bias_level = wm8903_set_bias_level, | ||
2060 | .reg_cache_size = ARRAY_SIZE(wm8903_reg_defaults), | ||
2061 | .reg_word_size = sizeof(u16), | ||
2062 | .reg_cache_default = wm8903_reg_defaults, | ||
2063 | .volatile_register = wm8903_volatile_register, | ||
2064 | .seq_notifier = wm8903_seq_notifier, | ||
2065 | .dapm_widgets = wm8903_dapm_widgets, | ||
2066 | .num_dapm_widgets = ARRAY_SIZE(wm8903_dapm_widgets), | ||
2067 | .dapm_routes = wm8903_intercon, | ||
2068 | .num_dapm_routes = ARRAY_SIZE(wm8903_intercon), | ||
2069 | }; | ||
1819 | 2070 | ||
1820 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | 2071 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
2072 | static __devinit int wm8903_i2c_probe(struct i2c_client *i2c, | ||
2073 | const struct i2c_device_id *id) | ||
2074 | { | ||
2075 | struct wm8903_priv *wm8903; | ||
2076 | int ret; | ||
1821 | 2077 | ||
1822 | if (client->irq) | 2078 | wm8903 = kzalloc(sizeof(struct wm8903_priv), GFP_KERNEL); |
1823 | free_irq(client->irq, priv); | 2079 | if (wm8903 == NULL) |
2080 | return -ENOMEM; | ||
1824 | 2081 | ||
1825 | kfree(priv); | 2082 | i2c_set_clientdata(i2c, wm8903); |
2083 | wm8903->irq = i2c->irq; | ||
1826 | 2084 | ||
1827 | wm8903_codec = NULL; | 2085 | ret = snd_soc_register_codec(&i2c->dev, |
1828 | wm8903_dai.dev = NULL; | 2086 | &soc_codec_dev_wm8903, &wm8903_dai, 1); |
2087 | if (ret < 0) | ||
2088 | kfree(wm8903); | ||
2089 | return ret; | ||
2090 | } | ||
1829 | 2091 | ||
2092 | static __devexit int wm8903_i2c_remove(struct i2c_client *client) | ||
2093 | { | ||
2094 | snd_soc_unregister_codec(&client->dev); | ||
2095 | kfree(i2c_get_clientdata(client)); | ||
1830 | return 0; | 2096 | return 0; |
1831 | } | 2097 | } |
1832 | 2098 | ||
1833 | /* i2c codec control layer */ | ||
1834 | static const struct i2c_device_id wm8903_i2c_id[] = { | 2099 | static const struct i2c_device_id wm8903_i2c_id[] = { |
1835 | { "wm8903", 0 }, | 2100 | { "wm8903", 0 }, |
1836 | { } | 2101 | { } |
1837 | }; | 2102 | }; |
1838 | MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); | 2103 | MODULE_DEVICE_TABLE(i2c, wm8903_i2c_id); |
1839 | 2104 | ||
1840 | static struct i2c_driver wm8903_i2c_driver = { | 2105 | static struct i2c_driver wm8903_i2c_driver = { |
1841 | .driver = { | 2106 | .driver = { |
1842 | .name = "WM8903", | 2107 | .name = "wm8903", |
1843 | .owner = THIS_MODULE, | 2108 | .owner = THIS_MODULE, |
1844 | }, | 2109 | }, |
1845 | .probe = wm8903_i2c_probe, | 2110 | .probe = wm8903_i2c_probe, |
1846 | .remove = __devexit_p(wm8903_i2c_remove), | 2111 | .remove = __devexit_p(wm8903_i2c_remove), |
1847 | .id_table = wm8903_i2c_id, | 2112 | .id_table = wm8903_i2c_id, |
1848 | }; | 2113 | }; |
2114 | #endif | ||
1849 | 2115 | ||
1850 | static int wm8903_probe(struct platform_device *pdev) | 2116 | static int __init wm8903_modinit(void) |
1851 | { | 2117 | { |
1852 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1853 | int ret = 0; | 2118 | int ret = 0; |
1854 | 2119 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | |
1855 | if (!wm8903_codec) { | 2120 | ret = i2c_add_driver(&wm8903_i2c_driver); |
1856 | dev_err(&pdev->dev, "I2C device not yet probed\n"); | 2121 | if (ret != 0) { |
1857 | goto err; | 2122 | printk(KERN_ERR "Failed to register wm8903 I2C driver: %d\n", |
1858 | } | 2123 | ret); |
1859 | |||
1860 | socdev->card->codec = wm8903_codec; | ||
1861 | |||
1862 | /* register pcms */ | ||
1863 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | ||
1864 | if (ret < 0) { | ||
1865 | dev_err(&pdev->dev, "failed to create pcms\n"); | ||
1866 | goto err; | ||
1867 | } | 2124 | } |
1868 | 2125 | #endif | |
1869 | snd_soc_add_controls(socdev->card->codec, wm8903_snd_controls, | ||
1870 | ARRAY_SIZE(wm8903_snd_controls)); | ||
1871 | wm8903_add_widgets(socdev->card->codec); | ||
1872 | |||
1873 | return ret; | ||
1874 | |||
1875 | err: | ||
1876 | return ret; | 2126 | return ret; |
1877 | } | 2127 | } |
1878 | |||
1879 | /* power down chip */ | ||
1880 | static int wm8903_remove(struct platform_device *pdev) | ||
1881 | { | ||
1882 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | ||
1883 | struct snd_soc_codec *codec = socdev->card->codec; | ||
1884 | |||
1885 | if (codec->control_data) | ||
1886 | wm8903_set_bias_level(codec, SND_SOC_BIAS_OFF); | ||
1887 | |||
1888 | snd_soc_free_pcms(socdev); | ||
1889 | snd_soc_dapm_free(socdev); | ||
1890 | |||
1891 | return 0; | ||
1892 | } | ||
1893 | |||
1894 | struct snd_soc_codec_device soc_codec_dev_wm8903 = { | ||
1895 | .probe = wm8903_probe, | ||
1896 | .remove = wm8903_remove, | ||
1897 | .suspend = wm8903_suspend, | ||
1898 | .resume = wm8903_resume, | ||
1899 | }; | ||
1900 | EXPORT_SYMBOL_GPL(soc_codec_dev_wm8903); | ||
1901 | |||
1902 | static int __init wm8903_modinit(void) | ||
1903 | { | ||
1904 | return i2c_add_driver(&wm8903_i2c_driver); | ||
1905 | } | ||
1906 | module_init(wm8903_modinit); | 2128 | module_init(wm8903_modinit); |
1907 | 2129 | ||
1908 | static void __exit wm8903_exit(void) | 2130 | static void __exit wm8903_exit(void) |
1909 | { | 2131 | { |
2132 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | ||
1910 | i2c_del_driver(&wm8903_i2c_driver); | 2133 | i2c_del_driver(&wm8903_i2c_driver); |
2134 | #endif | ||
1911 | } | 2135 | } |
1912 | module_exit(wm8903_exit); | 2136 | module_exit(wm8903_exit); |
1913 | 2137 | ||