| OLD | NEW |
| 1 /* | 1 /* |
| 2 * wm8962.c -- WM8962 ALSA SoC Audio driver | 2 * wm8962.c -- WM8962 ALSA SoC Audio driver |
| 3 * | 3 * |
| 4 * Copyright 2010 Wolfson Microelectronics plc | 4 * Copyright 2010 Wolfson Microelectronics plc |
| 5 * | 5 * |
| 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
| 7 * | 7 * |
| 8 * | 8 * |
| 9 * This program is free software; you can redistribute it and/or modify | 9 * This program is free software; you can redistribute it and/or modify |
| 10 * it under the terms of the GNU General Public License version 2 as | 10 * it under the terms of the GNU General Public License version 2 as |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 #include <linux/input.h> | 22 #include <linux/input.h> |
| 23 #include <linux/platform_device.h> | 23 #include <linux/platform_device.h> |
| 24 #include <linux/regulator/consumer.h> | 24 #include <linux/regulator/consumer.h> |
| 25 #include <linux/slab.h> | 25 #include <linux/slab.h> |
| 26 #include <linux/workqueue.h> | 26 #include <linux/workqueue.h> |
| 27 #include <sound/core.h> | 27 #include <sound/core.h> |
| 28 #include <sound/jack.h> | 28 #include <sound/jack.h> |
| 29 #include <sound/pcm.h> | 29 #include <sound/pcm.h> |
| 30 #include <sound/pcm_params.h> | 30 #include <sound/pcm_params.h> |
| 31 #include <sound/soc.h> | 31 #include <sound/soc.h> |
| 32 #include <sound/soc-dapm.h> | |
| 33 #include <sound/initval.h> | 32 #include <sound/initval.h> |
| 34 #include <sound/tlv.h> | 33 #include <sound/tlv.h> |
| 35 #include <sound/wm8962.h> | 34 #include <sound/wm8962.h> |
| 35 #include <trace/events/asoc.h> |
| 36 | 36 |
| 37 #include "wm8962.h" | 37 #include "wm8962.h" |
| 38 | 38 |
| 39 #define WM8962_NUM_SUPPLIES 8 | 39 #define WM8962_NUM_SUPPLIES 8 |
| 40 static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { | 40 static const char *wm8962_supply_names[WM8962_NUM_SUPPLIES] = { |
| 41 "DCVDD", | 41 "DCVDD", |
| 42 "DBVDD", | 42 "DBVDD", |
| 43 "AVDD", | 43 "AVDD", |
| 44 "CPVDD", | 44 "CPVDD", |
| 45 "MICVDD", | 45 "MICVDD", |
| (...skipping 1885 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1931 [21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */ | 1931 [21132] = { 0x00FF, 0x00FF, 0x0000 }, /* R21132 - VSS_XTS29_1 */ |
| 1932 [21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */ | 1932 [21133] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21133 - VSS_XTS29_0 */ |
| 1933 [21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */ | 1933 [21134] = { 0x00FF, 0x00FF, 0x0000 }, /* R21134 - VSS_XTS30_1 */ |
| 1934 [21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */ | 1934 [21135] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21135 - VSS_XTS30_0 */ |
| 1935 [21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */ | 1935 [21136] = { 0x00FF, 0x00FF, 0x0000 }, /* R21136 - VSS_XTS31_1 */ |
| 1936 [21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */ | 1936 [21137] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21137 - VSS_XTS31_0 */ |
| 1937 [21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */ | 1937 [21138] = { 0x00FF, 0x00FF, 0x0000 }, /* R21138 - VSS_XTS32_1 */ |
| 1938 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ | 1938 [21139] = { 0xFFFF, 0xFFFF, 0x0000 }, /* R21139 - VSS_XTS32_0 */ |
| 1939 }; | 1939 }; |
| 1940 | 1940 |
| 1941 static int wm8962_volatile_register(unsigned int reg) | 1941 static int wm8962_volatile_register(struct snd_soc_codec *codec, unsigned int re
g) |
| 1942 { | 1942 { |
| 1943 if (wm8962_reg_access[reg].vol) | 1943 if (wm8962_reg_access[reg].vol) |
| 1944 return 1; | 1944 return 1; |
| 1945 else | 1945 else |
| 1946 return 0; | 1946 return 0; |
| 1947 } | 1947 } |
| 1948 | 1948 |
| 1949 static int wm8962_readable_register(unsigned int reg) | 1949 static int wm8962_readable_register(struct snd_soc_codec *codec, unsigned int re
g) |
| 1950 { | 1950 { |
| 1951 if (wm8962_reg_access[reg].read) | 1951 if (wm8962_reg_access[reg].read) |
| 1952 return 1; | 1952 return 1; |
| 1953 else | 1953 else |
| 1954 return 0; | 1954 return 0; |
| 1955 } | 1955 } |
| 1956 | 1956 |
| 1957 static int wm8962_reset(struct snd_soc_codec *codec) | 1957 static int wm8962_reset(struct snd_soc_codec *codec) |
| 1958 { | 1958 { |
| 1959 » return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0); | 1959 » return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); |
| 1960 } | 1960 } |
| 1961 | 1961 |
| 1962 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); | 1962 static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); |
| 1963 static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0); | 1963 static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0); |
| 1964 static const unsigned int mixinpga_tlv[] = { | 1964 static const unsigned int mixinpga_tlv[] = { |
| 1965 TLV_DB_RANGE_HEAD(7), | 1965 TLV_DB_RANGE_HEAD(7), |
| 1966 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0), | 1966 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0), |
| 1967 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0), | 1967 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0), |
| 1968 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0), | 1968 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0), |
| 1969 5, 5, TLV_DB_SCALE_ITEM(2400, 0, 0), | 1969 5, 5, TLV_DB_SCALE_ITEM(2400, 0, 0), |
| (...skipping 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2670 { "SPKOUTR Output", NULL, "SYSCLK" }, | 2670 { "SPKOUTR Output", NULL, "SYSCLK" }, |
| 2671 { "SPKOUTR Output", NULL, "TOCLK" }, | 2671 { "SPKOUTR Output", NULL, "TOCLK" }, |
| 2672 | 2672 |
| 2673 { "SPKOUTL", NULL, "SPKOUTL Output" }, | 2673 { "SPKOUTL", NULL, "SPKOUTL Output" }, |
| 2674 { "SPKOUTR", NULL, "SPKOUTR Output" }, | 2674 { "SPKOUTR", NULL, "SPKOUTR Output" }, |
| 2675 }; | 2675 }; |
| 2676 | 2676 |
| 2677 static int wm8962_add_widgets(struct snd_soc_codec *codec) | 2677 static int wm8962_add_widgets(struct snd_soc_codec *codec) |
| 2678 { | 2678 { |
| 2679 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | 2679 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); |
| 2680 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 2680 | 2681 |
| 2681 snd_soc_add_controls(codec, wm8962_snd_controls, | 2682 snd_soc_add_controls(codec, wm8962_snd_controls, |
| 2682 ARRAY_SIZE(wm8962_snd_controls)); | 2683 ARRAY_SIZE(wm8962_snd_controls)); |
| 2683 if (pdata && pdata->spk_mono) | 2684 if (pdata && pdata->spk_mono) |
| 2684 snd_soc_add_controls(codec, wm8962_spk_mono_controls, | 2685 snd_soc_add_controls(codec, wm8962_spk_mono_controls, |
| 2685 ARRAY_SIZE(wm8962_spk_mono_controls)); | 2686 ARRAY_SIZE(wm8962_spk_mono_controls)); |
| 2686 else | 2687 else |
| 2687 snd_soc_add_controls(codec, wm8962_spk_stereo_controls, | 2688 snd_soc_add_controls(codec, wm8962_spk_stereo_controls, |
| 2688 ARRAY_SIZE(wm8962_spk_stereo_controls)); | 2689 ARRAY_SIZE(wm8962_spk_stereo_controls)); |
| 2689 | 2690 |
| 2690 | 2691 |
| 2691 » snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets, | 2692 » snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets, |
| 2692 ARRAY_SIZE(wm8962_dapm_widgets)); | 2693 ARRAY_SIZE(wm8962_dapm_widgets)); |
| 2693 if (pdata && pdata->spk_mono) | 2694 if (pdata && pdata->spk_mono) |
| 2694 » » snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets, | 2695 » » snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets, |
| 2695 ARRAY_SIZE(wm8962_dapm_spk_mono_widget
s)); | 2696 ARRAY_SIZE(wm8962_dapm_spk_mono_widget
s)); |
| 2696 else | 2697 else |
| 2697 » » snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets, | 2698 » » snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets, |
| 2698 ARRAY_SIZE(wm8962_dapm_spk_stereo_widg
ets)); | 2699 ARRAY_SIZE(wm8962_dapm_spk_stereo_widg
ets)); |
| 2699 | 2700 |
| 2700 » snd_soc_dapm_add_routes(codec, wm8962_intercon, | 2701 » snd_soc_dapm_add_routes(dapm, wm8962_intercon, |
| 2701 ARRAY_SIZE(wm8962_intercon)); | 2702 ARRAY_SIZE(wm8962_intercon)); |
| 2702 if (pdata && pdata->spk_mono) | 2703 if (pdata && pdata->spk_mono) |
| 2703 » » snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon, | 2704 » » snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon, |
| 2704 ARRAY_SIZE(wm8962_spk_mono_intercon)); | 2705 ARRAY_SIZE(wm8962_spk_mono_intercon)); |
| 2705 else | 2706 else |
| 2706 » » snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon, | 2707 » » snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon, |
| 2707 ARRAY_SIZE(wm8962_spk_stereo_intercon)); | 2708 ARRAY_SIZE(wm8962_spk_stereo_intercon)); |
| 2708 | 2709 |
| 2709 | 2710 |
| 2710 » snd_soc_dapm_disable_pin(codec, "Beep"); | 2711 » snd_soc_dapm_disable_pin(dapm, "Beep"); |
| 2711 | 2712 |
| 2712 return 0; | 2713 return 0; |
| 2713 } | 2714 } |
| 2714 | 2715 |
| 2715 static void wm8962_sync_cache(struct snd_soc_codec *codec) | 2716 static void wm8962_sync_cache(struct snd_soc_codec *codec) |
| 2716 { | 2717 { |
| 2717 u16 *reg_cache = codec->reg_cache; | 2718 u16 *reg_cache = codec->reg_cache; |
| 2718 int i; | 2719 int i; |
| 2719 | 2720 |
| 2720 if (!codec->cache_sync) | 2721 if (!codec->cache_sync) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2807 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_2, | 2808 snd_soc_update_bits(codec, WM8962_AUDIO_INTERFACE_2, |
| 2808 WM8962_AIF_RATE_MASK, aif2); | 2809 WM8962_AIF_RATE_MASK, aif2); |
| 2809 } | 2810 } |
| 2810 | 2811 |
| 2811 static int wm8962_set_bias_level(struct snd_soc_codec *codec, | 2812 static int wm8962_set_bias_level(struct snd_soc_codec *codec, |
| 2812 enum snd_soc_bias_level level) | 2813 enum snd_soc_bias_level level) |
| 2813 { | 2814 { |
| 2814 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 2815 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
| 2815 int ret; | 2816 int ret; |
| 2816 | 2817 |
| 2817 » if (level == codec->bias_level) | 2818 » if (level == codec->dapm.bias_level) |
| 2818 return 0; | 2819 return 0; |
| 2819 | 2820 |
| 2820 switch (level) { | 2821 switch (level) { |
| 2821 case SND_SOC_BIAS_ON: | 2822 case SND_SOC_BIAS_ON: |
| 2822 break; | 2823 break; |
| 2823 | 2824 |
| 2824 case SND_SOC_BIAS_PREPARE: | 2825 case SND_SOC_BIAS_PREPARE: |
| 2825 /* VMID 2*50k */ | 2826 /* VMID 2*50k */ |
| 2826 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, | 2827 snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, |
| 2827 WM8962_VMID_SEL_MASK, 0x80); | 2828 WM8962_VMID_SEL_MASK, 0x80); |
| 2828 break; | 2829 break; |
| 2829 | 2830 |
| 2830 case SND_SOC_BIAS_STANDBY: | 2831 case SND_SOC_BIAS_STANDBY: |
| 2831 » » if (codec->bias_level == SND_SOC_BIAS_OFF) { | 2832 » » if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { |
| 2832 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies)
, | 2833 ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies)
, |
| 2833 wm8962->supplies); | 2834 wm8962->supplies); |
| 2834 if (ret != 0) { | 2835 if (ret != 0) { |
| 2835 dev_err(codec->dev, | 2836 dev_err(codec->dev, |
| 2836 "Failed to enable supplies: %d\n", | 2837 "Failed to enable supplies: %d\n", |
| 2837 ret); | 2838 ret); |
| 2838 return ret; | 2839 return ret; |
| 2839 } | 2840 } |
| 2840 | 2841 |
| 2841 wm8962_sync_cache(codec); | 2842 wm8962_sync_cache(codec); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2871 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0); | 2872 WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, 0); |
| 2872 | 2873 |
| 2873 snd_soc_update_bits(codec, WM8962_ANTI_POP, | 2874 snd_soc_update_bits(codec, WM8962_ANTI_POP, |
| 2874 WM8962_STARTUP_BIAS_ENA | | 2875 WM8962_STARTUP_BIAS_ENA | |
| 2875 WM8962_VMID_BUF_ENA, 0); | 2876 WM8962_VMID_BUF_ENA, 0); |
| 2876 | 2877 |
| 2877 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), | 2878 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), |
| 2878 wm8962->supplies); | 2879 wm8962->supplies); |
| 2879 break; | 2880 break; |
| 2880 } | 2881 } |
| 2881 » codec->bias_level = level; | 2882 » codec->dapm.bias_level = level; |
| 2882 return 0; | 2883 return 0; |
| 2883 } | 2884 } |
| 2884 | 2885 |
| 2885 static const struct { | 2886 static const struct { |
| 2886 int rate; | 2887 int rate; |
| 2887 int reg; | 2888 int reg; |
| 2888 } sr_vals[] = { | 2889 } sr_vals[] = { |
| 2889 { 48000, 0 }, | 2890 { 48000, 0 }, |
| 2890 { 44100, 0 }, | 2891 { 44100, 0 }, |
| 2891 { 32000, 1 }, | 2892 { 32000, 1 }, |
| (...skipping 449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3341 | 3342 |
| 3342 if (active & WM8962_FIFOS_ERR_EINT) | 3343 if (active & WM8962_FIFOS_ERR_EINT) |
| 3343 dev_err(codec->dev, "FIFO error\n"); | 3344 dev_err(codec->dev, "FIFO error\n"); |
| 3344 | 3345 |
| 3345 if (active & WM8962_TEMP_SHUT_EINT) | 3346 if (active & WM8962_TEMP_SHUT_EINT) |
| 3346 dev_crit(codec->dev, "Thermal shutdown\n"); | 3347 dev_crit(codec->dev, "Thermal shutdown\n"); |
| 3347 | 3348 |
| 3348 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { | 3349 if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { |
| 3349 dev_dbg(codec->dev, "Microphone event detected\n"); | 3350 dev_dbg(codec->dev, "Microphone event detected\n"); |
| 3350 | 3351 |
| 3352 #ifndef CONFIG_SND_SOC_WM8962_MODULE |
| 3353 trace_snd_soc_jack_irq(dev_name(codec->dev)); |
| 3354 #endif |
| 3355 |
| 3356 pm_wakeup_event(codec->dev, 300); |
| 3357 |
| 3351 schedule_delayed_work(&wm8962->mic_work, | 3358 schedule_delayed_work(&wm8962->mic_work, |
| 3352 msecs_to_jiffies(250)); | 3359 msecs_to_jiffies(250)); |
| 3353 } | 3360 } |
| 3354 | 3361 |
| 3355 /* Acknowledge the interrupts */ | 3362 /* Acknowledge the interrupts */ |
| 3356 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); | 3363 snd_soc_write(codec, WM8962_INTERRUPT_STATUS_2, active); |
| 3357 | 3364 |
| 3358 return IRQ_HANDLED; | 3365 return IRQ_HANDLED; |
| 3359 } | 3366 } |
| 3360 | 3367 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3426 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) | 3433 #if defined(CONFIG_INPUT) || defined(CONFIG_INPUT_MODULE) |
| 3427 static int beep_rates[] = { | 3434 static int beep_rates[] = { |
| 3428 500, 1000, 2000, 4000, | 3435 500, 1000, 2000, 4000, |
| 3429 }; | 3436 }; |
| 3430 | 3437 |
| 3431 static void wm8962_beep_work(struct work_struct *work) | 3438 static void wm8962_beep_work(struct work_struct *work) |
| 3432 { | 3439 { |
| 3433 struct wm8962_priv *wm8962 = | 3440 struct wm8962_priv *wm8962 = |
| 3434 container_of(work, struct wm8962_priv, beep_work); | 3441 container_of(work, struct wm8962_priv, beep_work); |
| 3435 struct snd_soc_codec *codec = wm8962->codec; | 3442 struct snd_soc_codec *codec = wm8962->codec; |
| 3443 struct snd_soc_dapm_context *dapm = &codec->dapm; |
| 3436 int i; | 3444 int i; |
| 3437 int reg = 0; | 3445 int reg = 0; |
| 3438 int best = 0; | 3446 int best = 0; |
| 3439 | 3447 |
| 3440 if (wm8962->beep_rate) { | 3448 if (wm8962->beep_rate) { |
| 3441 for (i = 0; i < ARRAY_SIZE(beep_rates); i++) { | 3449 for (i = 0; i < ARRAY_SIZE(beep_rates); i++) { |
| 3442 if (abs(wm8962->beep_rate - beep_rates[i]) < | 3450 if (abs(wm8962->beep_rate - beep_rates[i]) < |
| 3443 abs(wm8962->beep_rate - beep_rates[best])) | 3451 abs(wm8962->beep_rate - beep_rates[best])) |
| 3444 best = i; | 3452 best = i; |
| 3445 } | 3453 } |
| 3446 | 3454 |
| 3447 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n", | 3455 dev_dbg(codec->dev, "Set beep rate %dHz for requested %dHz\n", |
| 3448 beep_rates[best], wm8962->beep_rate); | 3456 beep_rates[best], wm8962->beep_rate); |
| 3449 | 3457 |
| 3450 reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT); | 3458 reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT); |
| 3451 | 3459 |
| 3452 » » snd_soc_dapm_enable_pin(codec, "Beep"); | 3460 » » snd_soc_dapm_enable_pin(dapm, "Beep"); |
| 3453 } else { | 3461 } else { |
| 3454 dev_dbg(codec->dev, "Disabling beep\n"); | 3462 dev_dbg(codec->dev, "Disabling beep\n"); |
| 3455 » » snd_soc_dapm_disable_pin(codec, "Beep"); | 3463 » » snd_soc_dapm_disable_pin(dapm, "Beep"); |
| 3456 } | 3464 } |
| 3457 | 3465 |
| 3458 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, | 3466 snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, |
| 3459 WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg); | 3467 WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg); |
| 3460 | 3468 |
| 3461 » snd_soc_dapm_sync(codec); | 3469 » snd_soc_dapm_sync(dapm); |
| 3462 } | 3470 } |
| 3463 | 3471 |
| 3464 /* For usability define a way of injecting beep events for the device - | 3472 /* For usability define a way of injecting beep events for the device - |
| 3465 * many systems will not have a keyboard. | 3473 * many systems will not have a keyboard. |
| 3466 */ | 3474 */ |
| 3467 static int wm8962_beep_event(struct input_dev *dev, unsigned int type, | 3475 static int wm8962_beep_event(struct input_dev *dev, unsigned int type, |
| 3468 unsigned int code, int hz) | 3476 unsigned int code, int hz) |
| 3469 { | 3477 { |
| 3470 struct snd_soc_codec *codec = input_get_drvdata(dev); | 3478 struct snd_soc_codec *codec = input_get_drvdata(dev); |
| 3471 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3479 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3620 | 3628 |
| 3621 return 0; | 3629 return 0; |
| 3622 } | 3630 } |
| 3623 | 3631 |
| 3624 static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | 3632 static void wm8962_gpio_set(struct gpio_chip *chip, unsigned offset, int value) |
| 3625 { | 3633 { |
| 3626 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); | 3634 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); |
| 3627 struct snd_soc_codec *codec = wm8962->codec; | 3635 struct snd_soc_codec *codec = wm8962->codec; |
| 3628 | 3636 |
| 3629 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, | 3637 snd_soc_update_bits(codec, WM8962_GPIO_BASE + offset, |
| 3630 » » » WM8962_GP2_LVL, value << WM8962_GP2_LVL_SHIFT); | 3638 » » » WM8962_GP2_LVL, !!value << WM8962_GP2_LVL_SHIFT); |
| 3631 } | 3639 } |
| 3632 | 3640 |
| 3633 static int wm8962_gpio_direction_out(struct gpio_chip *chip, | 3641 static int wm8962_gpio_direction_out(struct gpio_chip *chip, |
| 3634 unsigned offset, int value) | 3642 unsigned offset, int value) |
| 3635 { | 3643 { |
| 3636 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); | 3644 struct wm8962_priv *wm8962 = gpio_to_wm8962(chip); |
| 3637 struct snd_soc_codec *codec = wm8962->codec; | 3645 struct snd_soc_codec *codec = wm8962->codec; |
| 3638 int val; | 3646 int val; |
| 3639 | 3647 |
| 3640 /* Force function 1 (logic output) */ | 3648 /* Force function 1 (logic output) */ |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3699 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); | 3707 struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); |
| 3700 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, | 3708 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, |
| 3701 dev); | 3709 dev); |
| 3702 u16 *reg_cache = codec->reg_cache; | 3710 u16 *reg_cache = codec->reg_cache; |
| 3703 int i, trigger, irq_pol; | 3711 int i, trigger, irq_pol; |
| 3704 | 3712 |
| 3705 wm8962->codec = codec; | 3713 wm8962->codec = codec; |
| 3706 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); | 3714 INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); |
| 3707 | 3715 |
| 3708 codec->cache_sync = 1; | 3716 codec->cache_sync = 1; |
| 3709 » codec->idle_bias_off = 1; | 3717 » codec->dapm.idle_bias_off = 1; |
| 3710 | 3718 |
| 3711 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); | 3719 ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); |
| 3712 if (ret != 0) { | 3720 if (ret != 0) { |
| 3713 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); | 3721 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); |
| 3714 goto err; | 3722 goto err; |
| 3715 } | 3723 } |
| 3716 | 3724 |
| 3717 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) | 3725 for (i = 0; i < ARRAY_SIZE(wm8962->supplies); i++) |
| 3718 wm8962->supplies[i].supply = wm8962_supply_names[i]; | 3726 wm8962->supplies[i].supply = wm8962_supply_names[i]; |
| 3719 | 3727 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3807 if (pdata->mic_cfg) | 3815 if (pdata->mic_cfg) |
| 3808 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, | 3816 snd_soc_update_bits(codec, WM8962_ADDITIONAL_CONTROL_4, |
| 3809 WM8962_MICDET_ENA | | 3817 WM8962_MICDET_ENA | |
| 3810 WM8962_MICDET_THR_MASK | | 3818 WM8962_MICDET_THR_MASK | |
| 3811 WM8962_MICSHORT_THR_MASK | | 3819 WM8962_MICSHORT_THR_MASK | |
| 3812 WM8962_MICBIAS_LVL, | 3820 WM8962_MICBIAS_LVL, |
| 3813 pdata->mic_cfg); | 3821 pdata->mic_cfg); |
| 3814 } | 3822 } |
| 3815 | 3823 |
| 3816 /* Latch volume update bits */ | 3824 /* Latch volume update bits */ |
| 3817 » reg_cache[WM8962_LEFT_INPUT_VOLUME] |= WM8962_IN_VU; | 3825 » snd_soc_update_bits(codec, WM8962_LEFT_INPUT_VOLUME, |
| 3818 » reg_cache[WM8962_RIGHT_INPUT_VOLUME] |= WM8962_IN_VU; | 3826 » » » WM8962_IN_VU, WM8962_IN_VU); |
| 3819 » reg_cache[WM8962_LEFT_ADC_VOLUME] |= WM8962_ADC_VU; | 3827 » snd_soc_update_bits(codec, WM8962_RIGHT_INPUT_VOLUME, |
| 3820 » reg_cache[WM8962_RIGHT_ADC_VOLUME] |= WM8962_ADC_VU; | 3828 » » » WM8962_IN_VU, WM8962_IN_VU); |
| 3821 » reg_cache[WM8962_LEFT_DAC_VOLUME] |= WM8962_DAC_VU; | 3829 » snd_soc_update_bits(codec, WM8962_LEFT_ADC_VOLUME, |
| 3822 » reg_cache[WM8962_RIGHT_DAC_VOLUME] |= WM8962_DAC_VU; | 3830 » » » WM8962_ADC_VU, WM8962_ADC_VU); |
| 3823 » reg_cache[WM8962_SPKOUTL_VOLUME] |= WM8962_SPKOUT_VU; | 3831 » snd_soc_update_bits(codec, WM8962_RIGHT_ADC_VOLUME, |
| 3824 » reg_cache[WM8962_SPKOUTR_VOLUME] |= WM8962_SPKOUT_VU; | 3832 » » » WM8962_ADC_VU, WM8962_ADC_VU); |
| 3825 » reg_cache[WM8962_HPOUTL_VOLUME] |= WM8962_HPOUT_VU; | 3833 » snd_soc_update_bits(codec, WM8962_LEFT_DAC_VOLUME, |
| 3826 » reg_cache[WM8962_HPOUTR_VOLUME] |= WM8962_HPOUT_VU; | 3834 » » » WM8962_DAC_VU, WM8962_DAC_VU); |
| 3835 » snd_soc_update_bits(codec, WM8962_RIGHT_DAC_VOLUME, |
| 3836 » » » WM8962_DAC_VU, WM8962_DAC_VU); |
| 3837 » snd_soc_update_bits(codec, WM8962_SPKOUTL_VOLUME, |
| 3838 » » » WM8962_SPKOUT_VU, WM8962_SPKOUT_VU); |
| 3839 » snd_soc_update_bits(codec, WM8962_SPKOUTR_VOLUME, |
| 3840 » » » WM8962_SPKOUT_VU, WM8962_SPKOUT_VU); |
| 3841 » snd_soc_update_bits(codec, WM8962_HPOUTL_VOLUME, |
| 3842 » » » WM8962_HPOUT_VU, WM8962_HPOUT_VU); |
| 3843 » snd_soc_update_bits(codec, WM8962_HPOUTR_VOLUME, |
| 3844 » » » WM8962_HPOUT_VU, WM8962_HPOUT_VU); |
| 3827 | 3845 |
| 3828 wm8962_add_widgets(codec); | 3846 wm8962_add_widgets(codec); |
| 3829 | 3847 |
| 3830 wm8962_init_beep(codec); | 3848 wm8962_init_beep(codec); |
| 3831 wm8962_init_gpio(codec); | 3849 wm8962_init_gpio(codec); |
| 3832 | 3850 |
| 3833 if (i2c->irq) { | 3851 if (i2c->irq) { |
| 3834 if (pdata && pdata->irq_active_low) { | 3852 if (pdata && pdata->irq_active_low) { |
| 3835 trigger = IRQF_TRIGGER_LOW; | 3853 trigger = IRQF_TRIGGER_LOW; |
| 3836 irq_pol = WM8962_IRQ_POL; | 3854 irq_pol = WM8962_IRQ_POL; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 3858 } | 3876 } |
| 3859 } | 3877 } |
| 3860 | 3878 |
| 3861 return 0; | 3879 return 0; |
| 3862 | 3880 |
| 3863 err_enable: | 3881 err_enable: |
| 3864 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | 3882 regulator_bulk_disable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); |
| 3865 err_get: | 3883 err_get: |
| 3866 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); | 3884 regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); |
| 3867 err: | 3885 err: |
| 3868 kfree(wm8962); | |
| 3869 return ret; | 3886 return ret; |
| 3870 } | 3887 } |
| 3871 | 3888 |
| 3872 static int wm8962_remove(struct snd_soc_codec *codec) | 3889 static int wm8962_remove(struct snd_soc_codec *codec) |
| 3873 { | 3890 { |
| 3874 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); | 3891 struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); |
| 3875 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, | 3892 struct i2c_client *i2c = container_of(codec->dev, struct i2c_client, |
| 3876 dev); | 3893 dev); |
| 3877 int i; | 3894 int i; |
| 3878 | 3895 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3966 { | 3983 { |
| 3967 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 3984 #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
| 3968 i2c_del_driver(&wm8962_i2c_driver); | 3985 i2c_del_driver(&wm8962_i2c_driver); |
| 3969 #endif | 3986 #endif |
| 3970 } | 3987 } |
| 3971 module_exit(wm8962_exit); | 3988 module_exit(wm8962_exit); |
| 3972 | 3989 |
| 3973 MODULE_DESCRIPTION("ASoC WM8962 driver"); | 3990 MODULE_DESCRIPTION("ASoC WM8962 driver"); |
| 3974 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); | 3991 MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>"); |
| 3975 MODULE_LICENSE("GPL"); | 3992 MODULE_LICENSE("GPL"); |
| OLD | NEW |