Lines Matching +full:gpio +full:- +full:mux +full:- +full:clock

2  * wm8903.c  --  WM8903 ALSA SoC Audio driver
14 * - TDM mode configuration.
15 * - Digital microphone support.
23 #include <linux/gpio.h>
43 { 4, 0x0018 }, /* R4 - Bias Control 0 */
44 { 5, 0x0000 }, /* R5 - VMID Control 0 */
45 { 6, 0x0000 }, /* R6 - Mic Bias Control 0 */
46 { 8, 0x0001 }, /* R8 - Analogue DAC 0 */
47 { 10, 0x0001 }, /* R10 - Analogue ADC 0 */
48 { 12, 0x0000 }, /* R12 - Power Management 0 */
49 { 13, 0x0000 }, /* R13 - Power Management 1 */
50 { 14, 0x0000 }, /* R14 - Power Management 2 */
51 { 15, 0x0000 }, /* R15 - Power Management 3 */
52 { 16, 0x0000 }, /* R16 - Power Management 4 */
53 { 17, 0x0000 }, /* R17 - Power Management 5 */
54 { 18, 0x0000 }, /* R18 - Power Management 6 */
55 { 20, 0x0400 }, /* R20 - Clock Rates 0 */
56 { 21, 0x0D07 }, /* R21 - Clock Rates 1 */
57 { 22, 0x0000 }, /* R22 - Clock Rates 2 */
58 { 24, 0x0050 }, /* R24 - Audio Interface 0 */
59 { 25, 0x0242 }, /* R25 - Audio Interface 1 */
60 { 26, 0x0008 }, /* R26 - Audio Interface 2 */
61 { 27, 0x0022 }, /* R27 - Audio Interface 3 */
62 { 30, 0x00C0 }, /* R30 - DAC Digital Volume Left */
63 { 31, 0x00C0 }, /* R31 - DAC Digital Volume Right */
64 { 32, 0x0000 }, /* R32 - DAC Digital 0 */
65 { 33, 0x0000 }, /* R33 - DAC Digital 1 */
66 { 36, 0x00C0 }, /* R36 - ADC Digital Volume Left */
67 { 37, 0x00C0 }, /* R37 - ADC Digital Volume Right */
68 { 38, 0x0000 }, /* R38 - ADC Digital 0 */
69 { 39, 0x0073 }, /* R39 - Digital Microphone 0 */
70 { 40, 0x09BF }, /* R40 - DRC 0 */
71 { 41, 0x3241 }, /* R41 - DRC 1 */
72 { 42, 0x0020 }, /* R42 - DRC 2 */
73 { 43, 0x0000 }, /* R43 - DRC 3 */
74 { 44, 0x0085 }, /* R44 - Analogue Left Input 0 */
75 { 45, 0x0085 }, /* R45 - Analogue Right Input 0 */
76 { 46, 0x0044 }, /* R46 - Analogue Left Input 1 */
77 { 47, 0x0044 }, /* R47 - Analogue Right Input 1 */
78 { 50, 0x0008 }, /* R50 - Analogue Left Mix 0 */
79 { 51, 0x0004 }, /* R51 - Analogue Right Mix 0 */
80 { 52, 0x0000 }, /* R52 - Analogue Spk Mix Left 0 */
81 { 53, 0x0000 }, /* R53 - Analogue Spk Mix Left 1 */
82 { 54, 0x0000 }, /* R54 - Analogue Spk Mix Right 0 */
83 { 55, 0x0000 }, /* R55 - Analogue Spk Mix Right 1 */
84 { 57, 0x002D }, /* R57 - Analogue OUT1 Left */
85 { 58, 0x002D }, /* R58 - Analogue OUT1 Right */
86 { 59, 0x0039 }, /* R59 - Analogue OUT2 Left */
87 { 60, 0x0039 }, /* R60 - Analogue OUT2 Right */
88 { 62, 0x0139 }, /* R62 - Analogue OUT3 Left */
89 { 63, 0x0139 }, /* R63 - Analogue OUT3 Right */
90 { 64, 0x0000 }, /* R65 - Analogue SPK Output Control 0 */
91 { 67, 0x0010 }, /* R67 - DC Servo 0 */
92 { 69, 0x00A4 }, /* R69 - DC Servo 2 */
93 { 90, 0x0000 }, /* R90 - Analogue HP 0 */
94 { 94, 0x0000 }, /* R94 - Analogue Lineout 0 */
95 { 98, 0x0000 }, /* R98 - Charge Pump 0 */
96 { 104, 0x0000 }, /* R104 - Class W 0 */
97 { 108, 0x0000 }, /* R108 - Write Sequencer 0 */
98 { 109, 0x0000 }, /* R109 - Write Sequencer 1 */
99 { 110, 0x0000 }, /* R110 - Write Sequencer 2 */
100 { 111, 0x0000 }, /* R111 - Write Sequencer 3 */
101 { 112, 0x0000 }, /* R112 - Write Sequencer 4 */
102 { 114, 0x0000 }, /* R114 - Control Interface */
103 { 116, 0x00A8 }, /* R116 - GPIO Control 1 */
104 { 117, 0x00A8 }, /* R117 - GPIO Control 2 */
105 { 118, 0x00A8 }, /* R118 - GPIO Control 3 */
106 { 119, 0x0220 }, /* R119 - GPIO Control 4 */
107 { 120, 0x01A0 }, /* R120 - GPIO Control 5 */
108 { 122, 0xFFFF }, /* R122 - Interrupt Status 1 Mask */
109 { 123, 0x0000 }, /* R123 - Interrupt Polarity 1 */
110 { 126, 0x0000 }, /* R126 - Interrupt Control */
111 { 129, 0x0000 }, /* R129 - Control Interface Test 1 */
112 { 149, 0x6810 }, /* R149 - Charge Pump Test 1 */
113 { 164, 0x0028 }, /* R164 - Clock Rate Test 4 */
114 { 172, 0x0000 }, /* R172 - Analogue Output Bias 0 */
261 struct snd_soc_codec *codec = w->codec; in wm8903_dcs_event()
266 wm8903->dcs_pending |= 1 << w->shift; in wm8903_dcs_event()
270 1 << w->shift, 0); in wm8903_dcs_event()
290 if (wm8903->dcs_pending) { in wm8903_seq_notifier()
291 dev_dbg(codec->dev, "Starting DC servo for %x\n", in wm8903_seq_notifier()
292 wm8903->dcs_pending); in wm8903_seq_notifier()
295 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) { in wm8903_seq_notifier()
296 if (!(wm8903->dcs_pending & (1 << i))) in wm8903_seq_notifier()
299 if (wm8903->dcs_cache[i]) { in wm8903_seq_notifier()
300 dev_dbg(codec->dev, in wm8903_seq_notifier()
302 3 - i, wm8903->dcs_cache[i]); in wm8903_seq_notifier()
305 wm8903->dcs_cache[i] & 0xff); in wm8903_seq_notifier()
307 dev_dbg(codec->dev, in wm8903_seq_notifier()
308 "Calibrate DC servo %d\n", 3 - i); in wm8903_seq_notifier()
314 if (wm8903->class_w_users) in wm8903_seq_notifier()
321 WM8903_DCS_ENA_MASK, wm8903->dcs_pending); in wm8903_seq_notifier()
331 if (wm8903->class_w_users) in wm8903_seq_notifier()
334 for (i = 0; i < ARRAY_SIZE(wm8903->dcs_cache); i++) { in wm8903_seq_notifier()
335 if (!(wm8903->dcs_pending & (1 << i))) in wm8903_seq_notifier()
340 dev_dbg(codec->dev, "DC servo %d: %x\n", in wm8903_seq_notifier()
341 3 - i, val); in wm8903_seq_notifier()
342 wm8903->dcs_cache[i] = val; in wm8903_seq_notifier()
351 wm8903->dcs_pending = 0; in wm8903_seq_notifier()
367 struct snd_soc_dapm_widget *widget = wlist->widgets[0]; in wm8903_class_w_put()
368 struct snd_soc_codec *codec = widget->codec; in wm8903_class_w_put()
376 if (ucontrol->value.integer.value[0]) { in wm8903_class_w_put()
377 if (wm8903->class_w_users == 0) { in wm8903_class_w_put()
378 dev_dbg(codec->dev, "Disabling Class W\n"); in wm8903_class_w_put()
382 wm8903->class_w_users++; in wm8903_class_w_put()
389 if (!ucontrol->value.integer.value[0]) { in wm8903_class_w_put()
390 if (wm8903->class_w_users == 1) { in wm8903_class_w_put()
391 dev_dbg(codec->dev, "Enabling Class W\n"); in wm8903_class_w_put()
395 wm8903->class_w_users--; in wm8903_class_w_put()
398 dev_dbg(codec->dev, "Bypass use count now %d\n", in wm8903_class_w_put()
399 wm8903->class_w_users); in wm8903_class_w_put()
421 if (wm8903->deemph) { in wm8903_set_deemph()
424 if (abs(wm8903_deemph[i] - wm8903->fs) < in wm8903_set_deemph()
425 abs(wm8903_deemph[best] - wm8903->fs)) in wm8903_set_deemph()
435 dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", in wm8903_set_deemph()
448 ucontrol->value.enumerated.item[0] = wm8903->deemph; in wm8903_get_deemph()
458 int deemph = ucontrol->value.enumerated.item[0]; in wm8903_put_deemph()
462 return -EINVAL; in wm8903_put_deemph()
464 mutex_lock(&codec->mutex); in wm8903_put_deemph()
465 if (wm8903->deemph != deemph) { in wm8903_put_deemph()
466 wm8903->deemph = deemph; in wm8903_put_deemph()
472 mutex_unlock(&codec->mutex); in wm8903_put_deemph()
478 static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1);
480 static const DECLARE_TLV_DB_SCALE(digital_sidetone_tlv, -3600, 300, 0);
481 static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0);
484 static const DECLARE_TLV_DB_SCALE(drc_tlv_amp, -2250, 75, 0);
487 static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0);
490 "Hi-fi", "Voice 1", "Voice 2", "Voice 3"
579 "Single-Ended", "Differential Line", "Differential Mic"
644 /* Input PGAs - No TLV since the scale depends on PGA mode */
736 SOC_DAPM_ENUM("Left Input Mode Mux", linput_mode_enum);
739 SOC_DAPM_ENUM("Right Input Mode Mux", rinput_mode_enum);
742 SOC_DAPM_ENUM("Left Input Mux", linput_enum);
745 SOC_DAPM_ENUM("Left Inverting Input Mux", linput_inv_enum);
748 SOC_DAPM_ENUM("Right Input Mux", rinput_enum);
751 SOC_DAPM_ENUM("Right Inverting Input Mux", rinput_inv_enum);
754 SOC_DAPM_ENUM("DACL Sidetone Mux", lsidetone_enum);
757 SOC_DAPM_ENUM("DACR Sidetone Mux", rsidetone_enum);
763 SOC_DAPM_ENUM("Left Capture Mux", lcapture_enum);
766 SOC_DAPM_ENUM("Right Capture Mux", rcapture_enum);
769 SOC_DAPM_ENUM("Left Playback Mux", lplay_enum);
772 SOC_DAPM_ENUM("Right Playback Mux", rplay_enum);
825 SND_SOC_DAPM_MUX("Left Input Mux", SND_SOC_NOPM, 0, 0, &linput_mux),
826 SND_SOC_DAPM_MUX("Left Input Inverting Mux", SND_SOC_NOPM, 0, 0,
828 SND_SOC_DAPM_MUX("Left Input Mode Mux", SND_SOC_NOPM, 0, 0, &linput_mode_mux),
830 SND_SOC_DAPM_MUX("Right Input Mux", SND_SOC_NOPM, 0, 0, &rinput_mux),
831 SND_SOC_DAPM_MUX("Right Input Inverting Mux", SND_SOC_NOPM, 0, 0,
833 SND_SOC_DAPM_MUX("Right Input Mode Mux", SND_SOC_NOPM, 0, 0, &rinput_mode_mux),
844 SND_SOC_DAPM_MUX("Left Capture Mux", SND_SOC_NOPM, 0, 0, &lcapture_mux),
845 SND_SOC_DAPM_MUX("Right Capture Mux", SND_SOC_NOPM, 0, 0, &rcapture_mux),
856 SND_SOC_DAPM_MUX("Left Playback Mux", SND_SOC_NOPM, 0, 0, &lplay_mux),
857 SND_SOC_DAPM_MUX("Right Playback Mux", SND_SOC_NOPM, 0, 0, &rplay_mux),
938 { "Left Input Mux", "IN1L", "IN1L" },
939 { "Left Input Mux", "IN2L", "IN2L" },
940 { "Left Input Mux", "IN3L", "IN3L" },
942 { "Left Input Inverting Mux", "IN1L", "IN1L" },
943 { "Left Input Inverting Mux", "IN2L", "IN2L" },
944 { "Left Input Inverting Mux", "IN3L", "IN3L" },
946 { "Right Input Mux", "IN1R", "IN1R" },
947 { "Right Input Mux", "IN2R", "IN2R" },
948 { "Right Input Mux", "IN3R", "IN3R" },
950 { "Right Input Inverting Mux", "IN1R", "IN1R" },
951 { "Right Input Inverting Mux", "IN2R", "IN2R" },
952 { "Right Input Inverting Mux", "IN3R", "IN3R" },
954 { "Left Input Mode Mux", "Single-Ended", "Left Input Inverting Mux" },
955 { "Left Input Mode Mux", "Differential Line",
956 "Left Input Mux" },
957 { "Left Input Mode Mux", "Differential Line",
958 "Left Input Inverting Mux" },
959 { "Left Input Mode Mux", "Differential Mic",
960 "Left Input Mux" },
961 { "Left Input Mode Mux", "Differential Mic",
962 "Left Input Inverting Mux" },
964 { "Right Input Mode Mux", "Single-Ended",
965 "Right Input Inverting Mux" },
966 { "Right Input Mode Mux", "Differential Line",
967 "Right Input Mux" },
968 { "Right Input Mode Mux", "Differential Line",
969 "Right Input Inverting Mux" },
970 { "Right Input Mode Mux", "Differential Mic",
971 "Right Input Mux" },
972 { "Right Input Mode Mux", "Differential Mic",
973 "Right Input Inverting Mux" },
975 { "Left Input PGA", NULL, "Left Input Mode Mux" },
976 { "Right Input PGA", NULL, "Right Input Mode Mux" },
983 { "Left Capture Mux", "Left", "ADCL" },
984 { "Left Capture Mux", "Right", "ADCR" },
986 { "Right Capture Mux", "Left", "ADCL" },
987 { "Right Capture Mux", "Right", "ADCR" },
989 { "AIFTXL", NULL, "Left Capture Mux" },
990 { "AIFTXR", NULL, "Right Capture Mux" },
997 { "Left Playback Mux", "Left", "AIFRXL" },
998 { "Left Playback Mux", "Right", "AIFRXR" },
1000 { "Right Playback Mux", "Left", "AIFRXL" },
1001 { "Right Playback Mux", "Right", "AIFRXR" },
1008 { "DACL", NULL, "Left Playback Mux" },
1012 { "DACR", NULL, "Right Playback Mux" },
1105 if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { in wm8903_set_bias_level()
1163 dev_dbg(codec->dev, "Enabling Class W\n"); in wm8903_set_bias_level()
1200 codec->dapm.bias_level = level; in wm8903_set_bias_level()
1208 struct snd_soc_codec *codec = codec_dai->codec; in wm8903_set_dai_sysclk()
1211 wm8903->sysclk = freq; in wm8903_set_dai_sysclk()
1219 struct snd_soc_codec *codec = codec_dai->codec; in wm8903_set_dai_fmt()
1238 return -EINVAL; in wm8903_set_dai_fmt()
1257 return -EINVAL; in wm8903_set_dai_fmt()
1260 /* Clock inversion */ in wm8903_set_dai_fmt()
1272 return -EINVAL; in wm8903_set_dai_fmt()
1291 return -EINVAL; in wm8903_set_dai_fmt()
1295 return -EINVAL; in wm8903_set_dai_fmt()
1305 struct snd_soc_codec *codec = codec_dai->codec; in wm8903_digital_mute()
1388 /* CLK_SYS/BCLK ratios - multiplied by 10 due to .5s */
1435 struct snd_soc_pcm_runtime *rtd = substream->private_data; in wm8903_hw_params()
1436 struct snd_soc_codec *codec =rtd->codec; in wm8903_hw_params()
1461 /* Configure sample rate logic for DSP - choose nearest rate */ in wm8903_hw_params()
1463 best_val = abs(sample_rates[dsp_config].rate - fs); in wm8903_hw_params()
1465 cur_val = abs(sample_rates[i].rate - fs); in wm8903_hw_params()
1472 dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); in wm8903_hw_params()
1495 return -EINVAL; in wm8903_hw_params()
1498 dev_dbg(codec->dev, "MCLK = %dHz, target sample rate = %dHz\n", in wm8903_hw_params()
1499 wm8903->sysclk, fs); in wm8903_hw_params()
1502 * the clock we want, particularly with USB derived inputs, so in wm8903_hw_params()
1506 best_val = abs((wm8903->sysclk / in wm8903_hw_params()
1508 clk_sys_ratios[0].div)) - fs); in wm8903_hw_params()
1510 cur_val = abs((wm8903->sysclk / in wm8903_hw_params()
1512 clk_sys_ratios[i].div)) - fs); in wm8903_hw_params()
1522 clk_sys = wm8903->sysclk / 2; in wm8903_hw_params()
1525 clk_sys = wm8903->sysclk; in wm8903_hw_params()
1533 dev_dbg(codec->dev, "CLK_SYS_RATE=%x, CLK_SYS_MODE=%x div=%d\n", in wm8903_hw_params()
1538 dev_dbg(codec->dev, "Actual CLK_SYS = %dHz\n", clk_sys); in wm8903_hw_params()
1543 * BCLKs to clock out the samples). in wm8903_hw_params()
1546 best_val = ((clk_sys * 10) / bclk_divs[0].ratio) - bclk; in wm8903_hw_params()
1549 cur_val = ((clk_sys * 10) / bclk_divs[i].ratio) - bclk; in wm8903_hw_params()
1560 dev_dbg(codec->dev, "BCLK ratio %d for %dHz - actual BCLK = %dHz\n", in wm8903_hw_params()
1567 wm8903->fs = params_rate(params); in wm8903_hw_params()
1581 * wm8903_mic_detect - Enable microphone detection via the WM8903 IRQ
1603 dev_dbg(codec->dev, "Enabling microphone detection: %x %x\n", in wm8903_mic_detect()
1607 wm8903->mic_jack = jack; in wm8903_mic_detect()
1608 wm8903->mic_det = det; in wm8903_mic_detect()
1609 wm8903->mic_short = shrt; in wm8903_mic_detect()
1649 dev_warn(codec->dev, "Write sequencer done\n"); in wm8903_irq()
1654 * invert the polarity of the interrupt after each event - to in wm8903_irq()
1659 mic_report = wm8903->mic_last_report; in wm8903_irq()
1664 trace_snd_soc_jack_irq(dev_name(codec->dev)); in wm8903_irq()
1668 dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); in wm8903_irq()
1670 mic_report ^= wm8903->mic_short; in wm8903_irq()
1675 dev_dbg(codec->dev, "Microphone detect (pol=%x)\n", int_pol); in wm8903_irq()
1677 mic_report ^= wm8903->mic_det; in wm8903_irq()
1680 msleep(wm8903->mic_delay); in wm8903_irq()
1686 snd_soc_jack_report(wm8903->mic_jack, mic_report, in wm8903_irq()
1687 wm8903->mic_short | wm8903->mic_det); in wm8903_irq()
1689 wm8903->mic_last_report = mic_report; in wm8903_irq()
1724 .name = "wm8903-hifi",
1754 regcache_sync(wm8903->regmap); in wm8903_resume()
1770 return -EINVAL; in wm8903_gpio_request()
1778 struct snd_soc_codec *codec = wm8903->codec; in wm8903_gpio_direction_in()
1797 struct snd_soc_codec *codec = wm8903->codec; in wm8903_gpio_get()
1809 struct snd_soc_codec *codec = wm8903->codec; in wm8903_gpio_direction_out()
1828 struct snd_soc_codec *codec = wm8903->codec; in wm8903_gpio_set()
1849 struct wm8903_platform_data *pdata = wm8903->pdata; in wm8903_init_gpio()
1852 wm8903->gpio_chip = wm8903_template_chip; in wm8903_init_gpio()
1853 wm8903->gpio_chip.ngpio = WM8903_NUM_GPIO; in wm8903_init_gpio()
1854 wm8903->gpio_chip.dev = codec->dev; in wm8903_init_gpio()
1856 if (pdata->gpio_base) in wm8903_init_gpio()
1857 wm8903->gpio_chip.base = pdata->gpio_base; in wm8903_init_gpio()
1859 wm8903->gpio_chip.base = -1; in wm8903_init_gpio()
1861 ret = gpiochip_add(&wm8903->gpio_chip); in wm8903_init_gpio()
1863 dev_err(codec->dev, "Failed to add GPIOs: %d\n", ret); in wm8903_init_gpio()
1871 ret = gpiochip_remove(&wm8903->gpio_chip); in wm8903_free_gpio()
1873 dev_err(codec->dev, "Failed to remove GPIOs: %d\n", ret); in wm8903_free_gpio()
1888 struct wm8903_platform_data *pdata = wm8903->pdata; in wm8903_probe()
1894 wm8903->codec = codec; in wm8903_probe()
1895 codec->control_data = wm8903->regmap; in wm8903_probe()
1899 dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); in wm8903_probe()
1904 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { in wm8903_probe()
1905 if ((!pdata->gpio_cfg[i]) || in wm8903_probe()
1906 (pdata->gpio_cfg[i] > WM8903_GPIO_CONFIG_ZERO)) in wm8903_probe()
1910 pdata->gpio_cfg[i] & 0x7fff); in wm8903_probe()
1912 val = (pdata->gpio_cfg[i] & WM8903_GP1_FN_MASK) in wm8903_probe()
1927 pdata->micdet_cfg); in wm8903_probe()
1929 /* Microphone detection needs the WSEQ clock */ in wm8903_probe()
1930 if (pdata->micdet_cfg) in wm8903_probe()
1940 WARN_ON(!mic_gpio && (pdata->micdet_cfg & WM8903_MICDET_ENA)); in wm8903_probe()
1942 wm8903->mic_delay = pdata->micdet_delay; in wm8903_probe()
1944 if (wm8903->irq) { in wm8903_probe()
1945 if (pdata->irq_active_low) { in wm8903_probe()
1956 ret = request_threaded_irq(wm8903->irq, NULL, wm8903_irq, in wm8903_probe()
1960 dev_err(codec->dev, "Failed to request IRQ: %d\n", in wm8903_probe()
2016 if (wm8903->irq) in wm8903_remove()
2017 free_irq(wm8903->irq, codec); in wm8903_remove()
2053 struct irq_data *irq_data = irq_get_irq_data(i2c->irq); in wm8903_set_pdata_irq_trigger()
2055 dev_err(&i2c->dev, "Invalid IRQ: %d\n", in wm8903_set_pdata_irq_trigger()
2056 i2c->irq); in wm8903_set_pdata_irq_trigger()
2057 return -EINVAL; in wm8903_set_pdata_irq_trigger()
2065 * so we are able to select active-high in wm8903_set_pdata_irq_trigger()
2067 /* Fall-through */ in wm8903_set_pdata_irq_trigger()
2069 pdata->irq_active_low = false; in wm8903_set_pdata_irq_trigger()
2072 pdata->irq_active_low = true; in wm8903_set_pdata_irq_trigger()
2082 const struct device_node *np = i2c->dev.of_node; in wm8903_set_pdata_from_of()
2086 if (of_property_read_u32(np, "micdet-cfg", &val32) >= 0) in wm8903_set_pdata_from_of()
2087 pdata->micdet_cfg = val32; in wm8903_set_pdata_from_of()
2089 if (of_property_read_u32(np, "micdet-delay", &val32) >= 0) in wm8903_set_pdata_from_of()
2090 pdata->micdet_delay = val32; in wm8903_set_pdata_from_of()
2092 if (of_property_read_u32_array(np, "gpio-cfg", pdata->gpio_cfg, in wm8903_set_pdata_from_of()
2093 ARRAY_SIZE(pdata->gpio_cfg)) >= 0) { in wm8903_set_pdata_from_of()
2106 for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) { in wm8903_set_pdata_from_of()
2107 if (pdata->gpio_cfg[i] == 0) { in wm8903_set_pdata_from_of()
2108 pdata->gpio_cfg[i] = WM8903_GPIO_CONFIG_ZERO; in wm8903_set_pdata_from_of()
2109 } else if (pdata->gpio_cfg[i] == 0xffffffff) { in wm8903_set_pdata_from_of()
2110 pdata->gpio_cfg[i] = 0; in wm8903_set_pdata_from_of()
2111 } else if (pdata->gpio_cfg[i] > 0x7fff) { in wm8903_set_pdata_from_of()
2112 dev_err(&i2c->dev, "Invalid gpio-cfg[%d] %x\n", in wm8903_set_pdata_from_of()
2113 i, pdata->gpio_cfg[i]); in wm8903_set_pdata_from_of()
2114 return -EINVAL; in wm8903_set_pdata_from_of()
2125 struct wm8903_platform_data *pdata = dev_get_platdata(&i2c->dev); in wm8903_i2c_probe()
2130 wm8903 = devm_kzalloc(&i2c->dev, sizeof(struct wm8903_priv), in wm8903_i2c_probe()
2133 return -ENOMEM; in wm8903_i2c_probe()
2135 wm8903->regmap = regmap_init_i2c(i2c, &wm8903_regmap); in wm8903_i2c_probe()
2136 if (IS_ERR(wm8903->regmap)) { in wm8903_i2c_probe()
2137 ret = PTR_ERR(wm8903->regmap); in wm8903_i2c_probe()
2138 dev_err(&i2c->dev, "Failed to allocate register map: %d\n", in wm8903_i2c_probe()
2144 wm8903->irq = i2c->irq; in wm8903_i2c_probe()
2148 wm8903->pdata = pdata; in wm8903_i2c_probe()
2150 wm8903->pdata = devm_kzalloc(&i2c->dev, in wm8903_i2c_probe()
2153 if (wm8903->pdata == NULL) { in wm8903_i2c_probe()
2154 dev_err(&i2c->dev, "Failed to allocate pdata\n"); in wm8903_i2c_probe()
2155 return -ENOMEM; in wm8903_i2c_probe()
2158 if (i2c->irq) { in wm8903_i2c_probe()
2159 ret = wm8903_set_pdata_irq_trigger(i2c, wm8903->pdata); in wm8903_i2c_probe()
2164 if (i2c->dev.of_node) { in wm8903_i2c_probe()
2165 ret = wm8903_set_pdata_from_of(i2c, wm8903->pdata); in wm8903_i2c_probe()
2171 ret = regmap_read(wm8903->regmap, WM8903_SW_RESET_AND_ID, &val); in wm8903_i2c_probe()
2173 dev_err(&i2c->dev, "Failed to read chip ID: %d\n", ret); in wm8903_i2c_probe()
2177 dev_err(&i2c->dev, "Device with ID %x is not a WM8903\n", val); in wm8903_i2c_probe()
2178 ret = -ENODEV; in wm8903_i2c_probe()
2182 ret = regmap_read(wm8903->regmap, WM8903_REVISION_NUMBER, &val); in wm8903_i2c_probe()
2184 dev_err(&i2c->dev, "Failed to read chip revision: %d\n", ret); in wm8903_i2c_probe()
2187 dev_info(&i2c->dev, "WM8903 revision %c\n", in wm8903_i2c_probe()
2191 regmap_write(wm8903->regmap, WM8903_SW_RESET_AND_ID, 0x8903); in wm8903_i2c_probe()
2193 ret = snd_soc_register_codec(&i2c->dev, in wm8903_i2c_probe()
2200 regmap_exit(wm8903->regmap); in wm8903_i2c_probe()
2208 regmap_exit(wm8903->regmap); in wm8903_i2c_remove()
2209 snd_soc_unregister_codec(&client->dev); in wm8903_i2c_remove()