aboutsummaryrefslogtreecommitdiffstats
path: root/sound/soc/codecs/wm8996.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/wm8996.c')
-rw-r--r--sound/soc/codecs/wm8996.c587
1 files changed, 215 insertions, 372 deletions
diff --git a/sound/soc/codecs/wm8996.c b/sound/soc/codecs/wm8996.c
index dc9b42b7fc4d..00f183dfa454 100644
--- a/sound/soc/codecs/wm8996.c
+++ b/sound/soc/codecs/wm8996.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * wm8996.c - WM8996 audio codec interface 2 * wm8996.c - WM8996 audio codec interface
3 * 3 *
4 * Copyright 2011 Wolfson Microelectronics PLC. 4 * Copyright 2011-2 Wolfson Microelectronics PLC.
5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 5 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
@@ -296,184 +296,6 @@ static struct reg_default wm8996_reg[] = {
296 { WM8996_RIGHT_PDM_SPEAKER, 0x1 }, 296 { WM8996_RIGHT_PDM_SPEAKER, 0x1 },
297 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 }, 297 { WM8996_PDM_SPEAKER_MUTE_SEQUENCE, 0x69 },
298 { WM8996_PDM_SPEAKER_VOLUME, 0x66 }, 298 { WM8996_PDM_SPEAKER_VOLUME, 0x66 },
299 { WM8996_WRITE_SEQUENCER_0, 0x1 },
300 { WM8996_WRITE_SEQUENCER_1, 0x1 },
301 { WM8996_WRITE_SEQUENCER_3, 0x6 },
302 { WM8996_WRITE_SEQUENCER_4, 0x40 },
303 { WM8996_WRITE_SEQUENCER_5, 0x1 },
304 { WM8996_WRITE_SEQUENCER_6, 0xf },
305 { WM8996_WRITE_SEQUENCER_7, 0x6 },
306 { WM8996_WRITE_SEQUENCER_8, 0x1 },
307 { WM8996_WRITE_SEQUENCER_9, 0x3 },
308 { WM8996_WRITE_SEQUENCER_10, 0x104 },
309 { WM8996_WRITE_SEQUENCER_12, 0x60 },
310 { WM8996_WRITE_SEQUENCER_13, 0x11 },
311 { WM8996_WRITE_SEQUENCER_14, 0x401 },
312 { WM8996_WRITE_SEQUENCER_16, 0x50 },
313 { WM8996_WRITE_SEQUENCER_17, 0x3 },
314 { WM8996_WRITE_SEQUENCER_18, 0x100 },
315 { WM8996_WRITE_SEQUENCER_20, 0x51 },
316 { WM8996_WRITE_SEQUENCER_21, 0x3 },
317 { WM8996_WRITE_SEQUENCER_22, 0x104 },
318 { WM8996_WRITE_SEQUENCER_23, 0xa },
319 { WM8996_WRITE_SEQUENCER_24, 0x60 },
320 { WM8996_WRITE_SEQUENCER_25, 0x3b },
321 { WM8996_WRITE_SEQUENCER_26, 0x502 },
322 { WM8996_WRITE_SEQUENCER_27, 0x100 },
323 { WM8996_WRITE_SEQUENCER_28, 0x2fff },
324 { WM8996_WRITE_SEQUENCER_32, 0x2fff },
325 { WM8996_WRITE_SEQUENCER_36, 0x2fff },
326 { WM8996_WRITE_SEQUENCER_40, 0x2fff },
327 { WM8996_WRITE_SEQUENCER_44, 0x2fff },
328 { WM8996_WRITE_SEQUENCER_48, 0x2fff },
329 { WM8996_WRITE_SEQUENCER_52, 0x2fff },
330 { WM8996_WRITE_SEQUENCER_56, 0x2fff },
331 { WM8996_WRITE_SEQUENCER_60, 0x2fff },
332 { WM8996_WRITE_SEQUENCER_64, 0x1 },
333 { WM8996_WRITE_SEQUENCER_65, 0x1 },
334 { WM8996_WRITE_SEQUENCER_67, 0x6 },
335 { WM8996_WRITE_SEQUENCER_68, 0x40 },
336 { WM8996_WRITE_SEQUENCER_69, 0x1 },
337 { WM8996_WRITE_SEQUENCER_70, 0xf },
338 { WM8996_WRITE_SEQUENCER_71, 0x6 },
339 { WM8996_WRITE_SEQUENCER_72, 0x1 },
340 { WM8996_WRITE_SEQUENCER_73, 0x3 },
341 { WM8996_WRITE_SEQUENCER_74, 0x104 },
342 { WM8996_WRITE_SEQUENCER_76, 0x60 },
343 { WM8996_WRITE_SEQUENCER_77, 0x11 },
344 { WM8996_WRITE_SEQUENCER_78, 0x401 },
345 { WM8996_WRITE_SEQUENCER_80, 0x50 },
346 { WM8996_WRITE_SEQUENCER_81, 0x3 },
347 { WM8996_WRITE_SEQUENCER_82, 0x100 },
348 { WM8996_WRITE_SEQUENCER_84, 0x60 },
349 { WM8996_WRITE_SEQUENCER_85, 0x3b },
350 { WM8996_WRITE_SEQUENCER_86, 0x502 },
351 { WM8996_WRITE_SEQUENCER_87, 0x100 },
352 { WM8996_WRITE_SEQUENCER_88, 0x2fff },
353 { WM8996_WRITE_SEQUENCER_92, 0x2fff },
354 { WM8996_WRITE_SEQUENCER_96, 0x2fff },
355 { WM8996_WRITE_SEQUENCER_100, 0x2fff },
356 { WM8996_WRITE_SEQUENCER_104, 0x2fff },
357 { WM8996_WRITE_SEQUENCER_108, 0x2fff },
358 { WM8996_WRITE_SEQUENCER_112, 0x2fff },
359 { WM8996_WRITE_SEQUENCER_116, 0x2fff },
360 { WM8996_WRITE_SEQUENCER_120, 0x2fff },
361 { WM8996_WRITE_SEQUENCER_124, 0x2fff },
362 { WM8996_WRITE_SEQUENCER_128, 0x1 },
363 { WM8996_WRITE_SEQUENCER_129, 0x1 },
364 { WM8996_WRITE_SEQUENCER_131, 0x6 },
365 { WM8996_WRITE_SEQUENCER_132, 0x40 },
366 { WM8996_WRITE_SEQUENCER_133, 0x1 },
367 { WM8996_WRITE_SEQUENCER_134, 0xf },
368 { WM8996_WRITE_SEQUENCER_135, 0x6 },
369 { WM8996_WRITE_SEQUENCER_136, 0x1 },
370 { WM8996_WRITE_SEQUENCER_137, 0x3 },
371 { WM8996_WRITE_SEQUENCER_138, 0x106 },
372 { WM8996_WRITE_SEQUENCER_140, 0x61 },
373 { WM8996_WRITE_SEQUENCER_141, 0x11 },
374 { WM8996_WRITE_SEQUENCER_142, 0x401 },
375 { WM8996_WRITE_SEQUENCER_144, 0x50 },
376 { WM8996_WRITE_SEQUENCER_145, 0x3 },
377 { WM8996_WRITE_SEQUENCER_146, 0x102 },
378 { WM8996_WRITE_SEQUENCER_148, 0x51 },
379 { WM8996_WRITE_SEQUENCER_149, 0x3 },
380 { WM8996_WRITE_SEQUENCER_150, 0x106 },
381 { WM8996_WRITE_SEQUENCER_151, 0xa },
382 { WM8996_WRITE_SEQUENCER_152, 0x61 },
383 { WM8996_WRITE_SEQUENCER_153, 0x3b },
384 { WM8996_WRITE_SEQUENCER_154, 0x502 },
385 { WM8996_WRITE_SEQUENCER_155, 0x100 },
386 { WM8996_WRITE_SEQUENCER_156, 0x2fff },
387 { WM8996_WRITE_SEQUENCER_160, 0x2fff },
388 { WM8996_WRITE_SEQUENCER_164, 0x2fff },
389 { WM8996_WRITE_SEQUENCER_168, 0x2fff },
390 { WM8996_WRITE_SEQUENCER_172, 0x2fff },
391 { WM8996_WRITE_SEQUENCER_176, 0x2fff },
392 { WM8996_WRITE_SEQUENCER_180, 0x2fff },
393 { WM8996_WRITE_SEQUENCER_184, 0x2fff },
394 { WM8996_WRITE_SEQUENCER_188, 0x2fff },
395 { WM8996_WRITE_SEQUENCER_192, 0x1 },
396 { WM8996_WRITE_SEQUENCER_193, 0x1 },
397 { WM8996_WRITE_SEQUENCER_195, 0x6 },
398 { WM8996_WRITE_SEQUENCER_196, 0x40 },
399 { WM8996_WRITE_SEQUENCER_197, 0x1 },
400 { WM8996_WRITE_SEQUENCER_198, 0xf },
401 { WM8996_WRITE_SEQUENCER_199, 0x6 },
402 { WM8996_WRITE_SEQUENCER_200, 0x1 },
403 { WM8996_WRITE_SEQUENCER_201, 0x3 },
404 { WM8996_WRITE_SEQUENCER_202, 0x106 },
405 { WM8996_WRITE_SEQUENCER_204, 0x61 },
406 { WM8996_WRITE_SEQUENCER_205, 0x11 },
407 { WM8996_WRITE_SEQUENCER_206, 0x401 },
408 { WM8996_WRITE_SEQUENCER_208, 0x50 },
409 { WM8996_WRITE_SEQUENCER_209, 0x3 },
410 { WM8996_WRITE_SEQUENCER_210, 0x102 },
411 { WM8996_WRITE_SEQUENCER_212, 0x61 },
412 { WM8996_WRITE_SEQUENCER_213, 0x3b },
413 { WM8996_WRITE_SEQUENCER_214, 0x502 },
414 { WM8996_WRITE_SEQUENCER_215, 0x100 },
415 { WM8996_WRITE_SEQUENCER_216, 0x2fff },
416 { WM8996_WRITE_SEQUENCER_220, 0x2fff },
417 { WM8996_WRITE_SEQUENCER_224, 0x2fff },
418 { WM8996_WRITE_SEQUENCER_228, 0x2fff },
419 { WM8996_WRITE_SEQUENCER_232, 0x2fff },
420 { WM8996_WRITE_SEQUENCER_236, 0x2fff },
421 { WM8996_WRITE_SEQUENCER_240, 0x2fff },
422 { WM8996_WRITE_SEQUENCER_244, 0x2fff },
423 { WM8996_WRITE_SEQUENCER_248, 0x2fff },
424 { WM8996_WRITE_SEQUENCER_252, 0x2fff },
425 { WM8996_WRITE_SEQUENCER_256, 0x60 },
426 { WM8996_WRITE_SEQUENCER_258, 0x601 },
427 { WM8996_WRITE_SEQUENCER_260, 0x50 },
428 { WM8996_WRITE_SEQUENCER_262, 0x100 },
429 { WM8996_WRITE_SEQUENCER_264, 0x1 },
430 { WM8996_WRITE_SEQUENCER_266, 0x104 },
431 { WM8996_WRITE_SEQUENCER_267, 0x100 },
432 { WM8996_WRITE_SEQUENCER_268, 0x2fff },
433 { WM8996_WRITE_SEQUENCER_272, 0x2fff },
434 { WM8996_WRITE_SEQUENCER_276, 0x2fff },
435 { WM8996_WRITE_SEQUENCER_280, 0x2fff },
436 { WM8996_WRITE_SEQUENCER_284, 0x2fff },
437 { WM8996_WRITE_SEQUENCER_288, 0x2fff },
438 { WM8996_WRITE_SEQUENCER_292, 0x2fff },
439 { WM8996_WRITE_SEQUENCER_296, 0x2fff },
440 { WM8996_WRITE_SEQUENCER_300, 0x2fff },
441 { WM8996_WRITE_SEQUENCER_304, 0x2fff },
442 { WM8996_WRITE_SEQUENCER_308, 0x2fff },
443 { WM8996_WRITE_SEQUENCER_312, 0x2fff },
444 { WM8996_WRITE_SEQUENCER_316, 0x2fff },
445 { WM8996_WRITE_SEQUENCER_320, 0x61 },
446 { WM8996_WRITE_SEQUENCER_322, 0x601 },
447 { WM8996_WRITE_SEQUENCER_324, 0x50 },
448 { WM8996_WRITE_SEQUENCER_326, 0x102 },
449 { WM8996_WRITE_SEQUENCER_328, 0x1 },
450 { WM8996_WRITE_SEQUENCER_330, 0x106 },
451 { WM8996_WRITE_SEQUENCER_331, 0x100 },
452 { WM8996_WRITE_SEQUENCER_332, 0x2fff },
453 { WM8996_WRITE_SEQUENCER_336, 0x2fff },
454 { WM8996_WRITE_SEQUENCER_340, 0x2fff },
455 { WM8996_WRITE_SEQUENCER_344, 0x2fff },
456 { WM8996_WRITE_SEQUENCER_348, 0x2fff },
457 { WM8996_WRITE_SEQUENCER_352, 0x2fff },
458 { WM8996_WRITE_SEQUENCER_356, 0x2fff },
459 { WM8996_WRITE_SEQUENCER_360, 0x2fff },
460 { WM8996_WRITE_SEQUENCER_364, 0x2fff },
461 { WM8996_WRITE_SEQUENCER_368, 0x2fff },
462 { WM8996_WRITE_SEQUENCER_372, 0x2fff },
463 { WM8996_WRITE_SEQUENCER_376, 0x2fff },
464 { WM8996_WRITE_SEQUENCER_380, 0x2fff },
465 { WM8996_WRITE_SEQUENCER_384, 0x60 },
466 { WM8996_WRITE_SEQUENCER_386, 0x601 },
467 { WM8996_WRITE_SEQUENCER_388, 0x61 },
468 { WM8996_WRITE_SEQUENCER_390, 0x601 },
469 { WM8996_WRITE_SEQUENCER_392, 0x50 },
470 { WM8996_WRITE_SEQUENCER_394, 0x300 },
471 { WM8996_WRITE_SEQUENCER_396, 0x1 },
472 { WM8996_WRITE_SEQUENCER_398, 0x304 },
473 { WM8996_WRITE_SEQUENCER_400, 0x40 },
474 { WM8996_WRITE_SEQUENCER_402, 0xf },
475 { WM8996_WRITE_SEQUENCER_404, 0x1 },
476 { WM8996_WRITE_SEQUENCER_407, 0x100 },
477}; 299};
478 300
479static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0); 301static const DECLARE_TLV_DB_SCALE(inpga_tlv, 0, 100, 0);
@@ -1706,18 +1528,6 @@ static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
1706 } 1528 }
1707} 1529}
1708 1530
1709static int wm8996_reset(struct wm8996_priv *wm8996)
1710{
1711 if (wm8996->pdata.ldo_ena > 0) {
1712 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1713 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
1714 return 0;
1715 } else {
1716 return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
1717 0x8915);
1718 }
1719}
1720
1721static const int bclk_divs[] = { 1531static const int bclk_divs[] = {
1722 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96 1532 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96
1723}; 1533};
@@ -1809,8 +1619,10 @@ static int wm8996_set_bias_level(struct snd_soc_codec *codec,
1809 1619
1810 case SND_SOC_BIAS_OFF: 1620 case SND_SOC_BIAS_OFF:
1811 regcache_cache_only(codec->control_data, true); 1621 regcache_cache_only(codec->control_data, true);
1812 if (wm8996->pdata.ldo_ena >= 0) 1622 if (wm8996->pdata.ldo_ena >= 0) {
1813 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 1623 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
1624 regcache_cache_only(codec->control_data, true);
1625 }
1814 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), 1626 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies),
1815 wm8996->supplies); 1627 wm8996->supplies);
1816 break; 1628 break;
@@ -2807,7 +2619,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2807 int ret; 2619 int ret;
2808 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec); 2620 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
2809 struct i2c_client *i2c = to_i2c_client(codec->dev); 2621 struct i2c_client *i2c = to_i2c_client(codec->dev);
2810 int i, irq_flags; 2622 int irq_flags;
2811 2623
2812 wm8996->codec = codec; 2624 wm8996->codec = codec;
2813 2625
@@ -2822,177 +2634,12 @@ static int wm8996_probe(struct snd_soc_codec *codec)
2822 goto err; 2634 goto err;
2823 } 2635 }
2824 2636
2825 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2826 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2827 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2828
2829 /* This should really be moved into the regulator core */
2830 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
2831 ret = regulator_register_notifier(wm8996->supplies[i].consumer,
2832 &wm8996->disable_nb[i]);
2833 if (ret != 0) {
2834 dev_err(codec->dev,
2835 "Failed to register regulator notifier: %d\n",
2836 ret);
2837 }
2838 }
2839
2840 /* Apply platform data settings */
2841 snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
2842 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
2843 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
2844 wm8996->pdata.inr_mode);
2845
2846 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
2847 if (!wm8996->pdata.gpio_default[i])
2848 continue;
2849
2850 snd_soc_write(codec, WM8996_GPIO_1 + i,
2851 wm8996->pdata.gpio_default[i] & 0xffff);
2852 }
2853
2854 if (wm8996->pdata.spkmute_seq)
2855 snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
2856 WM8996_SPK_MUTE_ENDIAN |
2857 WM8996_SPK_MUTE_SEQ1_MASK,
2858 wm8996->pdata.spkmute_seq);
2859
2860 snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
2861 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
2862 WM8996_MICD_SRC, wm8996->pdata.micdet_def);
2863
2864 /* Latch volume update bits */
2865 snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME,
2866 WM8996_IN1_VU, WM8996_IN1_VU);
2867 snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME,
2868 WM8996_IN1_VU, WM8996_IN1_VU);
2869
2870 snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME,
2871 WM8996_DAC1_VU, WM8996_DAC1_VU);
2872 snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME,
2873 WM8996_DAC1_VU, WM8996_DAC1_VU);
2874 snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME,
2875 WM8996_DAC2_VU, WM8996_DAC2_VU);
2876 snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME,
2877 WM8996_DAC2_VU, WM8996_DAC2_VU);
2878
2879 snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME,
2880 WM8996_DAC1_VU, WM8996_DAC1_VU);
2881 snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME,
2882 WM8996_DAC1_VU, WM8996_DAC1_VU);
2883 snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME,
2884 WM8996_DAC2_VU, WM8996_DAC2_VU);
2885 snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME,
2886 WM8996_DAC2_VU, WM8996_DAC2_VU);
2887
2888 snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME,
2889 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2890 snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME,
2891 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2892 snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME,
2893 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2894 snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME,
2895 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2896
2897 snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME,
2898 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2899 snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME,
2900 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2901 snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME,
2902 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2903 snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME,
2904 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2905
2906 /* No support currently for the underclocked TDM modes and
2907 * pick a default TDM layout with each channel pair working with
2908 * slots 0 and 1. */
2909 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
2910 WM8996_AIF1RX_CHAN0_SLOTS_MASK |
2911 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2912 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2913 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
2914 WM8996_AIF1RX_CHAN1_SLOTS_MASK |
2915 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
2916 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2917 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
2918 WM8996_AIF1RX_CHAN2_SLOTS_MASK |
2919 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
2920 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2921 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
2922 WM8996_AIF1RX_CHAN3_SLOTS_MASK |
2923 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2924 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2925 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
2926 WM8996_AIF1RX_CHAN4_SLOTS_MASK |
2927 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2928 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2929 snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
2930 WM8996_AIF1RX_CHAN5_SLOTS_MASK |
2931 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2932 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2933
2934 snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
2935 WM8996_AIF2RX_CHAN0_SLOTS_MASK |
2936 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
2937 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2938 snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
2939 WM8996_AIF2RX_CHAN1_SLOTS_MASK |
2940 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
2941 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2942
2943 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
2944 WM8996_AIF1TX_CHAN0_SLOTS_MASK |
2945 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2946 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2947 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2948 WM8996_AIF1TX_CHAN1_SLOTS_MASK |
2949 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2950 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2951 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
2952 WM8996_AIF1TX_CHAN2_SLOTS_MASK |
2953 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2954 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
2955 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
2956 WM8996_AIF1TX_CHAN3_SLOTS_MASK |
2957 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2958 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
2959 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
2960 WM8996_AIF1TX_CHAN4_SLOTS_MASK |
2961 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2962 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
2963 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
2964 WM8996_AIF1TX_CHAN5_SLOTS_MASK |
2965 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2966 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
2967
2968 snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
2969 WM8996_AIF2TX_CHAN0_SLOTS_MASK |
2970 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
2971 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
2972 snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2973 WM8996_AIF2TX_CHAN1_SLOTS_MASK |
2974 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
2975 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2976
2977 if (wm8996->pdata.num_retune_mobile_cfgs) 2637 if (wm8996->pdata.num_retune_mobile_cfgs)
2978 wm8996_retune_mobile_pdata(codec); 2638 wm8996_retune_mobile_pdata(codec);
2979 else 2639 else
2980 snd_soc_add_codec_controls(codec, wm8996_eq_controls, 2640 snd_soc_add_codec_controls(codec, wm8996_eq_controls,
2981 ARRAY_SIZE(wm8996_eq_controls)); 2641 ARRAY_SIZE(wm8996_eq_controls));
2982 2642
2983 /* If the TX LRCLK pins are not in LRCLK mode configure the
2984 * AIFs to source their clocks from the RX LRCLKs.
2985 */
2986 if ((snd_soc_read(codec, WM8996_GPIO_1)))
2987 snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2,
2988 WM8996_AIF1TX_LRCLK_MODE,
2989 WM8996_AIF1TX_LRCLK_MODE);
2990
2991 if ((snd_soc_read(codec, WM8996_GPIO_2)))
2992 snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2,
2993 WM8996_AIF2TX_LRCLK_MODE,
2994 WM8996_AIF2TX_LRCLK_MODE);
2995
2996 if (i2c->irq) { 2643 if (i2c->irq) {
2997 if (wm8996->pdata.irq_flags) 2644 if (wm8996->pdata.irq_flags)
2998 irq_flags = wm8996->pdata.irq_flags; 2645 irq_flags = wm8996->pdata.irq_flags;
@@ -3036,9 +2683,7 @@ err:
3036 2683
3037static int wm8996_remove(struct snd_soc_codec *codec) 2684static int wm8996_remove(struct snd_soc_codec *codec)
3038{ 2685{
3039 struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
3040 struct i2c_client *i2c = to_i2c_client(codec->dev); 2686 struct i2c_client *i2c = to_i2c_client(codec->dev);
3041 int i;
3042 2687
3043 snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL, 2688 snd_soc_update_bits(codec, WM8996_INTERRUPT_CONTROL,
3044 WM8996_IM_IRQ, WM8996_IM_IRQ); 2689 WM8996_IM_IRQ, WM8996_IM_IRQ);
@@ -3046,10 +2691,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
3046 if (i2c->irq) 2691 if (i2c->irq)
3047 free_irq(i2c->irq, codec); 2692 free_irq(i2c->irq, codec);
3048 2693
3049 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3050 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3051 &wm8996->disable_nb[i]);
3052
3053 return 0; 2694 return 0;
3054} 2695}
3055 2696
@@ -3163,6 +2804,21 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3163 goto err_gpio; 2804 goto err_gpio;
3164 } 2805 }
3165 2806
2807 wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
2808 wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
2809 wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;
2810
2811 /* This should really be moved into the regulator core */
2812 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
2813 ret = regulator_register_notifier(wm8996->supplies[i].consumer,
2814 &wm8996->disable_nb[i]);
2815 if (ret != 0) {
2816 dev_err(&i2c->dev,
2817 "Failed to register regulator notifier: %d\n",
2818 ret);
2819 }
2820 }
2821
3166 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies), 2822 ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
3167 wm8996->supplies); 2823 wm8996->supplies);
3168 if (ret != 0) { 2824 if (ret != 0) {
@@ -3175,7 +2831,7 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3175 msleep(5); 2831 msleep(5);
3176 } 2832 }
3177 2833
3178 wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap); 2834 wm8996->regmap = devm_regmap_init_i2c(i2c, &wm8996_regmap);
3179 if (IS_ERR(wm8996->regmap)) { 2835 if (IS_ERR(wm8996->regmap)) {
3180 ret = PTR_ERR(wm8996->regmap); 2836 ret = PTR_ERR(wm8996->regmap);
3181 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret); 2837 dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
@@ -3203,15 +2859,199 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3203 dev_info(&i2c->dev, "revision %c\n", 2859 dev_info(&i2c->dev, "revision %c\n",
3204 (reg & WM8996_CHIP_REV_MASK) + 'A'); 2860 (reg & WM8996_CHIP_REV_MASK) + 'A');
3205 2861
3206 ret = wm8996_reset(wm8996); 2862 if (wm8996->pdata.ldo_ena > 0) {
3207 if (ret < 0) { 2863 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3208 dev_err(&i2c->dev, "Failed to issue reset\n"); 2864 regcache_cache_only(wm8996->regmap, true);
3209 goto err_regmap; 2865 } else {
2866 ret = regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
2867 0x8915);
2868 if (ret != 0) {
2869 dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
2870 goto err_regmap;
2871 }
3210 } 2872 }
3211 2873
3212 regcache_cache_only(wm8996->regmap, true);
3213 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies); 2874 regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
3214 2875
2876 /* Apply platform data settings */
2877 regmap_update_bits(wm8996->regmap, WM8996_LINE_INPUT_CONTROL,
2878 WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
2879 wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
2880 wm8996->pdata.inr_mode);
2881
2882 for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
2883 if (!wm8996->pdata.gpio_default[i])
2884 continue;
2885
2886 regmap_write(wm8996->regmap, WM8996_GPIO_1 + i,
2887 wm8996->pdata.gpio_default[i] & 0xffff);
2888 }
2889
2890 if (wm8996->pdata.spkmute_seq)
2891 regmap_update_bits(wm8996->regmap,
2892 WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
2893 WM8996_SPK_MUTE_ENDIAN |
2894 WM8996_SPK_MUTE_SEQ1_MASK,
2895 wm8996->pdata.spkmute_seq);
2896
2897 regmap_update_bits(wm8996->regmap, WM8996_ACCESSORY_DETECT_MODE_2,
2898 WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
2899 WM8996_MICD_SRC, wm8996->pdata.micdet_def);
2900
2901 /* Latch volume update bits */
2902 regmap_update_bits(wm8996->regmap, WM8996_LEFT_LINE_INPUT_VOLUME,
2903 WM8996_IN1_VU, WM8996_IN1_VU);
2904 regmap_update_bits(wm8996->regmap, WM8996_RIGHT_LINE_INPUT_VOLUME,
2905 WM8996_IN1_VU, WM8996_IN1_VU);
2906
2907 regmap_update_bits(wm8996->regmap, WM8996_DAC1_LEFT_VOLUME,
2908 WM8996_DAC1_VU, WM8996_DAC1_VU);
2909 regmap_update_bits(wm8996->regmap, WM8996_DAC1_RIGHT_VOLUME,
2910 WM8996_DAC1_VU, WM8996_DAC1_VU);
2911 regmap_update_bits(wm8996->regmap, WM8996_DAC2_LEFT_VOLUME,
2912 WM8996_DAC2_VU, WM8996_DAC2_VU);
2913 regmap_update_bits(wm8996->regmap, WM8996_DAC2_RIGHT_VOLUME,
2914 WM8996_DAC2_VU, WM8996_DAC2_VU);
2915
2916 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_LEFT_VOLUME,
2917 WM8996_DAC1_VU, WM8996_DAC1_VU);
2918 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_RIGHT_VOLUME,
2919 WM8996_DAC1_VU, WM8996_DAC1_VU);
2920 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_LEFT_VOLUME,
2921 WM8996_DAC2_VU, WM8996_DAC2_VU);
2922 regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_RIGHT_VOLUME,
2923 WM8996_DAC2_VU, WM8996_DAC2_VU);
2924
2925 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_LEFT_VOLUME,
2926 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2927 regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_RIGHT_VOLUME,
2928 WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
2929 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_LEFT_VOLUME,
2930 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2931 regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_RIGHT_VOLUME,
2932 WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
2933
2934 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_LEFT_VOLUME,
2935 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2936 regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_RIGHT_VOLUME,
2937 WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
2938 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_LEFT_VOLUME,
2939 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2940 regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_RIGHT_VOLUME,
2941 WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
2942
2943 /* No support currently for the underclocked TDM modes and
2944 * pick a default TDM layout with each channel pair working with
2945 * slots 0 and 1. */
2946 regmap_update_bits(wm8996->regmap,
2947 WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
2948 WM8996_AIF1RX_CHAN0_SLOTS_MASK |
2949 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2950 1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
2951 regmap_update_bits(wm8996->regmap,
2952 WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
2953 WM8996_AIF1RX_CHAN1_SLOTS_MASK |
2954 WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
2955 1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
2956 regmap_update_bits(wm8996->regmap,
2957 WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
2958 WM8996_AIF1RX_CHAN2_SLOTS_MASK |
2959 WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
2960 1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
2961 regmap_update_bits(wm8996->regmap,
2962 WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
2963 WM8996_AIF1RX_CHAN3_SLOTS_MASK |
2964 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2965 1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
2966 regmap_update_bits(wm8996->regmap,
2967 WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
2968 WM8996_AIF1RX_CHAN4_SLOTS_MASK |
2969 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2970 1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
2971 regmap_update_bits(wm8996->regmap,
2972 WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
2973 WM8996_AIF1RX_CHAN5_SLOTS_MASK |
2974 WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
2975 1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);
2976
2977 regmap_update_bits(wm8996->regmap,
2978 WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
2979 WM8996_AIF2RX_CHAN0_SLOTS_MASK |
2980 WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
2981 1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
2982 regmap_update_bits(wm8996->regmap,
2983 WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
2984 WM8996_AIF2RX_CHAN1_SLOTS_MASK |
2985 WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
2986 1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);
2987
2988 regmap_update_bits(wm8996->regmap,
2989 WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
2990 WM8996_AIF1TX_CHAN0_SLOTS_MASK |
2991 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2992 1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
2993 regmap_update_bits(wm8996->regmap,
2994 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
2995 WM8996_AIF1TX_CHAN1_SLOTS_MASK |
2996 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
2997 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
2998 regmap_update_bits(wm8996->regmap,
2999 WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
3000 WM8996_AIF1TX_CHAN2_SLOTS_MASK |
3001 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3002 1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
3003 regmap_update_bits(wm8996->regmap,
3004 WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
3005 WM8996_AIF1TX_CHAN3_SLOTS_MASK |
3006 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3007 1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
3008 regmap_update_bits(wm8996->regmap,
3009 WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
3010 WM8996_AIF1TX_CHAN4_SLOTS_MASK |
3011 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3012 1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
3013 regmap_update_bits(wm8996->regmap,
3014 WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
3015 WM8996_AIF1TX_CHAN5_SLOTS_MASK |
3016 WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
3017 1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);
3018
3019 regmap_update_bits(wm8996->regmap,
3020 WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
3021 WM8996_AIF2TX_CHAN0_SLOTS_MASK |
3022 WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
3023 1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
3024 regmap_update_bits(wm8996->regmap,
3025 WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
3026 WM8996_AIF2TX_CHAN1_SLOTS_MASK |
3027 WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
3028 1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
3029
3030 /* If the TX LRCLK pins are not in LRCLK mode configure the
3031 * AIFs to source their clocks from the RX LRCLKs.
3032 */
3033 ret = regmap_read(wm8996->regmap, WM8996_GPIO_1, &reg);
3034 if (ret != 0) {
3035 dev_err(&i2c->dev, "Failed to read GPIO1: %d\n", ret);
3036 goto err_regmap;
3037 }
3038
3039 if (reg & WM8996_GP1_FN_MASK)
3040 regmap_update_bits(wm8996->regmap, WM8996_AIF1_TX_LRCLK_2,
3041 WM8996_AIF1TX_LRCLK_MODE,
3042 WM8996_AIF1TX_LRCLK_MODE);
3043
3044 ret = regmap_read(wm8996->regmap, WM8996_GPIO_2, &reg);
3045 if (ret != 0) {
3046 dev_err(&i2c->dev, "Failed to read GPIO2: %d\n", ret);
3047 goto err_regmap;
3048 }
3049
3050 if (reg & WM8996_GP2_FN_MASK)
3051 regmap_update_bits(wm8996->regmap, WM8996_AIF2_TX_LRCLK_2,
3052 WM8996_AIF2TX_LRCLK_MODE,
3053 WM8996_AIF2TX_LRCLK_MODE);
3054
3215 wm8996_init_gpio(wm8996); 3055 wm8996_init_gpio(wm8996);
3216 3056
3217 ret = snd_soc_register_codec(&i2c->dev, 3057 ret = snd_soc_register_codec(&i2c->dev,
@@ -3225,7 +3065,6 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
3225err_gpiolib: 3065err_gpiolib:
3226 wm8996_free_gpio(wm8996); 3066 wm8996_free_gpio(wm8996);
3227err_regmap: 3067err_regmap:
3228 regmap_exit(wm8996->regmap);
3229err_enable: 3068err_enable:
3230 if (wm8996->pdata.ldo_ena > 0) 3069 if (wm8996->pdata.ldo_ena > 0)
3231 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3070 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
@@ -3241,14 +3080,18 @@ err:
3241static __devexit int wm8996_i2c_remove(struct i2c_client *client) 3080static __devexit int wm8996_i2c_remove(struct i2c_client *client)
3242{ 3081{
3243 struct wm8996_priv *wm8996 = i2c_get_clientdata(client); 3082 struct wm8996_priv *wm8996 = i2c_get_clientdata(client);
3083 int i;
3244 3084
3245 snd_soc_unregister_codec(&client->dev); 3085 snd_soc_unregister_codec(&client->dev);
3246 wm8996_free_gpio(wm8996); 3086 wm8996_free_gpio(wm8996);
3247 regmap_exit(wm8996->regmap);
3248 if (wm8996->pdata.ldo_ena > 0) { 3087 if (wm8996->pdata.ldo_ena > 0) {
3249 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0); 3088 gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
3250 gpio_free(wm8996->pdata.ldo_ena); 3089 gpio_free(wm8996->pdata.ldo_ena);
3251 } 3090 }
3091 for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
3092 regulator_unregister_notifier(wm8996->supplies[i].consumer,
3093 &wm8996->disable_nb[i]);
3094
3252 return 0; 3095 return 0;
3253} 3096}
3254 3097