Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ASoC: nau8824: new driver

Add driver for NAU88L24.

Signed-off-by: John Hsu <KCHSU0@nuvoton.com>
Signed-off-by: John Hsu <supercraig0719@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>

authored by

John Hsu and committed by
Mark Brown
dfeabded c1ae3cfa

+2398
+88
Documentation/devicetree/bindings/sound/nau8824.txt
··· 1 + Nuvoton NAU8824 audio codec 2 + 3 + This device supports I2C only. 4 + 5 + Required properties: 6 + - compatible : Must be "nuvoton,nau8824" 7 + 8 + - reg : the I2C address of the device. This is either 0x1a (CSB=0) or 0x1b (CSB=1). 9 + 10 + Optional properties: 11 + - nuvoton,jkdet-polarity: JKDET pin polarity. 0 - active high, 1 - active low. 12 + 13 + - nuvoton,vref-impedance: VREF Impedance selection 14 + 0 - Open 15 + 1 - 25 kOhm 16 + 2 - 125 kOhm 17 + 3 - 2.5 kOhm 18 + 19 + - nuvoton,micbias-voltage: Micbias voltage level. 20 + 0 - VDDA 21 + 1 - VDDA 22 + 2 - VDDA * 1.1 23 + 3 - VDDA * 1.2 24 + 4 - VDDA * 1.3 25 + 5 - VDDA * 1.4 26 + 6 - VDDA * 1.53 27 + 7 - VDDA * 1.53 28 + 29 + - nuvoton,sar-threshold-num: Number of buttons supported 30 + - nuvoton,sar-threshold: Impedance threshold for each button. Array that contains up to 8 buttons configuration. SAR value is calculated as 31 + SAR = 255 * MICBIAS / SAR_VOLTAGE * R / (2000 + R) 32 + where MICBIAS is configured by 'nuvoton,micbias-voltage', SAR_VOLTAGE is configured by 'nuvoton,sar-voltage', R - button impedance. 33 + Refer datasheet section 10.2 for more information about threshold calculation. 34 + 35 + - nuvoton,sar-hysteresis: Button impedance measurement hysteresis. 36 + 37 + - nuvoton,sar-voltage: Reference voltage for button impedance measurement. 38 + 0 - VDDA 39 + 1 - VDDA 40 + 2 - VDDA * 1.1 41 + 3 - VDDA * 1.2 42 + 4 - VDDA * 1.3 43 + 5 - VDDA * 1.4 44 + 6 - VDDA * 1.53 45 + 7 - VDDA * 1.53 46 + 47 + - nuvoton,sar-compare-time: SAR compare time 48 + 0 - 500 ns 49 + 1 - 1 us 50 + 2 - 2 us 51 + 3 - 4 us 52 + 53 + - nuvoton,sar-sampling-time: SAR sampling time 54 + 0 - 2 us 55 + 1 - 4 us 56 + 2 - 8 us 57 + 3 - 16 us 58 + 59 + - nuvoton,short-key-debounce: Button short key press debounce time. 60 + 0 - 30 ms 61 + 1 - 50 ms 62 + 2 - 100 ms 63 + 64 + - nuvoton,jack-eject-debounce: Jack ejection debounce time. 65 + 0 - 0 ms 66 + 1 - 1 ms 67 + 2 - 10 ms 68 + 69 + 70 + Example: 71 + 72 + headset: nau8824@1a { 73 + compatible = "nuvoton,nau8824"; 74 + reg = <0x1a>; 75 + interrupt-parent = <&gpio>; 76 + interrupts = <TEGRA_GPIO(E, 6) IRQ_TYPE_LEVEL_LOW>; 77 + nuvoton,vref-impedance = <2>; 78 + nuvoton,micbias-voltage = <6>; 79 + // Setup 4 buttons impedance according to Android specification 80 + nuvoton,sar-threshold-num = <4>; 81 + nuvoton,sar-threshold = <0xc 0x1e 0x38 0x60>; 82 + nuvoton,sar-hysteresis = <0>; 83 + nuvoton,sar-voltage = <6>; 84 + nuvoton,sar-compare-time = <1>; 85 + nuvoton,sar-sampling-time = <1>; 86 + nuvoton,short-key-debounce = <0>; 87 + nuvoton,jack-eject-debounce = <1>; 88 + };
+5
sound/soc/codecs/Kconfig
··· 97 97 select SND_SOC_ML26124 if I2C 98 98 select SND_SOC_NAU8540 if I2C 99 99 select SND_SOC_NAU8810 if I2C 100 + select SND_SOC_NAU8824 if I2C 100 101 select SND_SOC_NAU8825 if I2C 101 102 select SND_SOC_HDMI_CODEC 102 103 select SND_SOC_PCM1681 if I2C ··· 1115 1114 1116 1115 config SND_SOC_NAU8810 1117 1116 tristate "Nuvoton Technology Corporation NAU88C10 CODEC" 1117 + depends on I2C 1118 + 1119 + config SND_SOC_NAU8824 1120 + tristate "Nuvoton Technology Corporation NAU88L24 CODEC" 1118 1121 depends on I2C 1119 1122 1120 1123 config SND_SOC_NAU8825
+2
sound/soc/codecs/Makefile
··· 92 92 snd-soc-msm8916-digital-objs := msm8916-wcd-digital.o 93 93 snd-soc-nau8540-objs := nau8540.o 94 94 snd-soc-nau8810-objs := nau8810.o 95 + snd-soc-nau8824-objs := nau8824.o 95 96 snd-soc-nau8825-objs := nau8825.o 96 97 snd-soc-hdmi-codec-objs := hdmi-codec.o 97 98 snd-soc-pcm1681-objs := pcm1681.o ··· 322 321 obj-$(CONFIG_SND_SOC_MSM8916_WCD_DIGITAL) +=snd-soc-msm8916-digital.o 323 322 obj-$(CONFIG_SND_SOC_NAU8540) += snd-soc-nau8540.o 324 323 obj-$(CONFIG_SND_SOC_NAU8810) += snd-soc-nau8810.o 324 + obj-$(CONFIG_SND_SOC_NAU8824) += snd-soc-nau8824.o 325 325 obj-$(CONFIG_SND_SOC_NAU8825) += snd-soc-nau8825.o 326 326 obj-$(CONFIG_SND_SOC_HDMI_CODEC) += snd-soc-hdmi-codec.o 327 327 obj-$(CONFIG_SND_SOC_PCM1681) += snd-soc-pcm1681.o
+1837
sound/soc/codecs/nau8824.c
··· 1 + /* 2 + * NAU88L24 ALSA SoC audio driver 3 + * 4 + * Copyright 2016 Nuvoton Technology Corp. 5 + * Author: John Hsu <KCHSU0@nuvoton.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #include <linux/module.h> 13 + #include <linux/delay.h> 14 + #include <linux/init.h> 15 + #include <linux/i2c.h> 16 + #include <linux/regmap.h> 17 + #include <linux/slab.h> 18 + #include <linux/clk.h> 19 + #include <linux/acpi.h> 20 + #include <linux/math64.h> 21 + #include <linux/semaphore.h> 22 + 23 + #include <sound/initval.h> 24 + #include <sound/tlv.h> 25 + #include <sound/core.h> 26 + #include <sound/pcm.h> 27 + #include <sound/pcm_params.h> 28 + #include <sound/soc.h> 29 + #include <sound/jack.h> 30 + 31 + #include "nau8824.h" 32 + 33 + 34 + static int nau8824_config_sysclk(struct nau8824 *nau8824, 35 + int clk_id, unsigned int freq); 36 + static bool nau8824_is_jack_inserted(struct nau8824 *nau8824); 37 + 38 + /* the ADC threshold of headset */ 39 + #define DMIC_CLK 3072000 40 + 41 + /* the ADC threshold of headset */ 42 + #define HEADSET_SARADC_THD 0x80 43 + 44 + /* the parameter threshold of FLL */ 45 + #define NAU_FREF_MAX 13500000 46 + #define NAU_FVCO_MAX 124000000 47 + #define NAU_FVCO_MIN 90000000 48 + 49 + /* scaling for mclk from sysclk_src output */ 50 + static const struct nau8824_fll_attr mclk_src_scaling[] = { 51 + { 1, 0x0 }, 52 + { 2, 0x2 }, 53 + { 4, 0x3 }, 54 + { 8, 0x4 }, 55 + { 16, 0x5 }, 56 + { 32, 0x6 }, 57 + { 3, 0x7 }, 58 + { 6, 0xa }, 59 + { 12, 0xb }, 60 + { 24, 0xc }, 61 + }; 62 + 63 + /* ratio for input clk freq */ 64 + static const struct nau8824_fll_attr fll_ratio[] = { 65 + { 512000, 0x01 }, 66 + { 256000, 0x02 }, 67 + { 128000, 0x04 }, 68 + { 64000, 0x08 }, 69 + { 32000, 0x10 }, 70 + { 8000, 0x20 }, 71 + { 4000, 0x40 }, 72 + }; 73 + 74 + static const struct nau8824_fll_attr fll_pre_scalar[] = { 75 + { 1, 0x0 }, 76 + { 2, 0x1 }, 77 + { 4, 0x2 }, 78 + { 8, 0x3 }, 79 + }; 80 + 81 + /* the maximum frequency of CLK_ADC and CLK_DAC */ 82 + #define CLK_DA_AD_MAX 6144000 83 + 84 + /* over sampling rate */ 85 + static const struct nau8824_osr_attr osr_dac_sel[] = { 86 + { 64, 2 }, /* OSR 64, SRC 1/4 */ 87 + { 256, 0 }, /* OSR 256, SRC 1 */ 88 + { 128, 1 }, /* OSR 128, SRC 1/2 */ 89 + { 0, 0 }, 90 + { 32, 3 }, /* OSR 32, SRC 1/8 */ 91 + }; 92 + 93 + static const struct nau8824_osr_attr osr_adc_sel[] = { 94 + { 32, 3 }, /* OSR 32, SRC 1/8 */ 95 + { 64, 2 }, /* OSR 64, SRC 1/4 */ 96 + { 128, 1 }, /* OSR 128, SRC 1/2 */ 97 + { 256, 0 }, /* OSR 256, SRC 1 */ 98 + }; 99 + 100 + static const struct reg_default nau8824_reg_defaults[] = { 101 + { NAU8824_REG_ENA_CTRL, 0x0000 }, 102 + { NAU8824_REG_CLK_GATING_ENA, 0x0000 }, 103 + { NAU8824_REG_CLK_DIVIDER, 0x0000 }, 104 + { NAU8824_REG_FLL1, 0x0000 }, 105 + { NAU8824_REG_FLL2, 0x3126 }, 106 + { NAU8824_REG_FLL3, 0x0008 }, 107 + { NAU8824_REG_FLL4, 0x0010 }, 108 + { NAU8824_REG_FLL5, 0xC000 }, 109 + { NAU8824_REG_FLL6, 0x6000 }, 110 + { NAU8824_REG_FLL_VCO_RSV, 0xF13C }, 111 + { NAU8824_REG_JACK_DET_CTRL, 0x0000 }, 112 + { NAU8824_REG_INTERRUPT_SETTING_1, 0x0000 }, 113 + { NAU8824_REG_IRQ, 0x0000 }, 114 + { NAU8824_REG_CLEAR_INT_REG, 0x0000 }, 115 + { NAU8824_REG_INTERRUPT_SETTING, 0x1000 }, 116 + { NAU8824_REG_SAR_ADC, 0x0015 }, 117 + { NAU8824_REG_VDET_COEFFICIENT, 0x0110 }, 118 + { NAU8824_REG_VDET_THRESHOLD_1, 0x0000 }, 119 + { NAU8824_REG_VDET_THRESHOLD_2, 0x0000 }, 120 + { NAU8824_REG_VDET_THRESHOLD_3, 0x0000 }, 121 + { NAU8824_REG_VDET_THRESHOLD_4, 0x0000 }, 122 + { NAU8824_REG_GPIO_SEL, 0x0000 }, 123 + { NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 0x000B }, 124 + { NAU8824_REG_PORT0_I2S_PCM_CTRL_2, 0x0010 }, 125 + { NAU8824_REG_PORT0_LEFT_TIME_SLOT, 0x0000 }, 126 + { NAU8824_REG_PORT0_RIGHT_TIME_SLOT, 0x0000 }, 127 + { NAU8824_REG_TDM_CTRL, 0x0000 }, 128 + { NAU8824_REG_ADC_HPF_FILTER, 0x0000 }, 129 + { NAU8824_REG_ADC_FILTER_CTRL, 0x0002 }, 130 + { NAU8824_REG_DAC_FILTER_CTRL_1, 0x0000 }, 131 + { NAU8824_REG_DAC_FILTER_CTRL_2, 0x0000 }, 132 + { NAU8824_REG_NOTCH_FILTER_1, 0x0000 }, 133 + { NAU8824_REG_NOTCH_FILTER_2, 0x0000 }, 134 + { NAU8824_REG_EQ1_LOW, 0x112C }, 135 + { NAU8824_REG_EQ2_EQ3, 0x2C2C }, 136 + { NAU8824_REG_EQ4_EQ5, 0x2C2C }, 137 + { NAU8824_REG_ADC_CH0_DGAIN_CTRL, 0x0100 }, 138 + { NAU8824_REG_ADC_CH1_DGAIN_CTRL, 0x0100 }, 139 + { NAU8824_REG_ADC_CH2_DGAIN_CTRL, 0x0100 }, 140 + { NAU8824_REG_ADC_CH3_DGAIN_CTRL, 0x0100 }, 141 + { NAU8824_REG_DAC_MUTE_CTRL, 0x0000 }, 142 + { NAU8824_REG_DAC_CH0_DGAIN_CTRL, 0x0100 }, 143 + { NAU8824_REG_DAC_CH1_DGAIN_CTRL, 0x0100 }, 144 + { NAU8824_REG_ADC_TO_DAC_ST, 0x0000 }, 145 + { NAU8824_REG_DRC_KNEE_IP12_ADC_CH01, 0x1486 }, 146 + { NAU8824_REG_DRC_KNEE_IP34_ADC_CH01, 0x0F12 }, 147 + { NAU8824_REG_DRC_SLOPE_ADC_CH01, 0x25FF }, 148 + { NAU8824_REG_DRC_ATKDCY_ADC_CH01, 0x3457 }, 149 + { NAU8824_REG_DRC_KNEE_IP12_ADC_CH23, 0x1486 }, 150 + { NAU8824_REG_DRC_KNEE_IP34_ADC_CH23, 0x0F12 }, 151 + { NAU8824_REG_DRC_SLOPE_ADC_CH23, 0x25FF }, 152 + { NAU8824_REG_DRC_ATKDCY_ADC_CH23, 0x3457 }, 153 + { NAU8824_REG_DRC_GAINL_ADC0, 0x0200 }, 154 + { NAU8824_REG_DRC_GAINL_ADC1, 0x0200 }, 155 + { NAU8824_REG_DRC_GAINL_ADC2, 0x0200 }, 156 + { NAU8824_REG_DRC_GAINL_ADC3, 0x0200 }, 157 + { NAU8824_REG_DRC_KNEE_IP12_DAC, 0x1486 }, 158 + { NAU8824_REG_DRC_KNEE_IP34_DAC, 0x0F12 }, 159 + { NAU8824_REG_DRC_SLOPE_DAC, 0x25F9 }, 160 + { NAU8824_REG_DRC_ATKDCY_DAC, 0x3457 }, 161 + { NAU8824_REG_DRC_GAIN_DAC_CH0, 0x0200 }, 162 + { NAU8824_REG_DRC_GAIN_DAC_CH1, 0x0200 }, 163 + { NAU8824_REG_MODE, 0x0000 }, 164 + { NAU8824_REG_MODE1, 0x0000 }, 165 + { NAU8824_REG_MODE2, 0x0000 }, 166 + { NAU8824_REG_CLASSG, 0x0000 }, 167 + { NAU8824_REG_OTP_EFUSE, 0x0000 }, 168 + { NAU8824_REG_OTPDOUT_1, 0x0000 }, 169 + { NAU8824_REG_OTPDOUT_2, 0x0000 }, 170 + { NAU8824_REG_MISC_CTRL, 0x0000 }, 171 + { NAU8824_REG_I2C_TIMEOUT, 0xEFFF }, 172 + { NAU8824_REG_TEST_MODE, 0x0000 }, 173 + { NAU8824_REG_I2C_DEVICE_ID, 0x1AF1 }, 174 + { NAU8824_REG_SAR_ADC_DATA_OUT, 0x00FF }, 175 + { NAU8824_REG_BIAS_ADJ, 0x0000 }, 176 + { NAU8824_REG_PGA_GAIN, 0x0000 }, 177 + { NAU8824_REG_TRIM_SETTINGS, 0x0000 }, 178 + { NAU8824_REG_ANALOG_CONTROL_1, 0x0000 }, 179 + { NAU8824_REG_ANALOG_CONTROL_2, 0x0000 }, 180 + { NAU8824_REG_ENABLE_LO, 0x0000 }, 181 + { NAU8824_REG_GAIN_LO, 0x0000 }, 182 + { NAU8824_REG_CLASSD_GAIN_1, 0x0000 }, 183 + { NAU8824_REG_CLASSD_GAIN_2, 0x0000 }, 184 + { NAU8824_REG_ANALOG_ADC_1, 0x0011 }, 185 + { NAU8824_REG_ANALOG_ADC_2, 0x0020 }, 186 + { NAU8824_REG_RDAC, 0x0008 }, 187 + { NAU8824_REG_MIC_BIAS, 0x0006 }, 188 + { NAU8824_REG_HS_VOLUME_CONTROL, 0x0000 }, 189 + { NAU8824_REG_BOOST, 0x0000 }, 190 + { NAU8824_REG_FEPGA, 0x0000 }, 191 + { NAU8824_REG_FEPGA_II, 0x0000 }, 192 + { NAU8824_REG_FEPGA_SE, 0x0000 }, 193 + { NAU8824_REG_FEPGA_ATTENUATION, 0x0000 }, 194 + { NAU8824_REG_ATT_PORT0, 0x0000 }, 195 + { NAU8824_REG_ATT_PORT1, 0x0000 }, 196 + { NAU8824_REG_POWER_UP_CONTROL, 0x0000 }, 197 + { NAU8824_REG_CHARGE_PUMP_CONTROL, 0x0300 }, 198 + { NAU8824_REG_CHARGE_PUMP_INPUT, 0x0013 }, 199 + }; 200 + 201 + static int nau8824_sema_acquire(struct nau8824 *nau8824, long timeout) 202 + { 203 + int ret; 204 + 205 + if (timeout) { 206 + ret = down_timeout(&nau8824->jd_sem, timeout); 207 + if (ret < 0) 208 + dev_warn(nau8824->dev, "Acquire semaphone timeout\n"); 209 + } else { 210 + ret = down_interruptible(&nau8824->jd_sem); 211 + if (ret < 0) 212 + dev_warn(nau8824->dev, "Acquire semaphone fail\n"); 213 + } 214 + 215 + return ret; 216 + } 217 + 218 + static inline void nau8824_sema_release(struct nau8824 *nau8824) 219 + { 220 + up(&nau8824->jd_sem); 221 + } 222 + 223 + static bool nau8824_readable_reg(struct device *dev, unsigned int reg) 224 + { 225 + switch (reg) { 226 + case NAU8824_REG_ENA_CTRL ... NAU8824_REG_FLL_VCO_RSV: 227 + case NAU8824_REG_JACK_DET_CTRL: 228 + case NAU8824_REG_INTERRUPT_SETTING_1: 229 + case NAU8824_REG_IRQ: 230 + case NAU8824_REG_CLEAR_INT_REG ... NAU8824_REG_VDET_THRESHOLD_4: 231 + case NAU8824_REG_GPIO_SEL: 232 + case NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ... NAU8824_REG_TDM_CTRL: 233 + case NAU8824_REG_ADC_HPF_FILTER ... NAU8824_REG_EQ4_EQ5: 234 + case NAU8824_REG_ADC_CH0_DGAIN_CTRL ... NAU8824_REG_ADC_TO_DAC_ST: 235 + case NAU8824_REG_DRC_KNEE_IP12_ADC_CH01 ... NAU8824_REG_DRC_GAINL_ADC3: 236 + case NAU8824_REG_DRC_KNEE_IP12_DAC ... NAU8824_REG_DRC_GAIN_DAC_CH1: 237 + case NAU8824_REG_CLASSG ... NAU8824_REG_OTP_EFUSE: 238 + case NAU8824_REG_OTPDOUT_1 ... NAU8824_REG_OTPDOUT_2: 239 + case NAU8824_REG_I2C_TIMEOUT: 240 + case NAU8824_REG_I2C_DEVICE_ID ... NAU8824_REG_SAR_ADC_DATA_OUT: 241 + case NAU8824_REG_BIAS_ADJ ... NAU8824_REG_CLASSD_GAIN_2: 242 + case NAU8824_REG_ANALOG_ADC_1 ... NAU8824_REG_ATT_PORT1: 243 + case NAU8824_REG_POWER_UP_CONTROL ... NAU8824_REG_CHARGE_PUMP_INPUT: 244 + return true; 245 + default: 246 + return false; 247 + } 248 + 249 + } 250 + 251 + static bool nau8824_writeable_reg(struct device *dev, unsigned int reg) 252 + { 253 + switch (reg) { 254 + case NAU8824_REG_RESET ... NAU8824_REG_FLL_VCO_RSV: 255 + case NAU8824_REG_JACK_DET_CTRL: 256 + case NAU8824_REG_INTERRUPT_SETTING_1: 257 + case NAU8824_REG_CLEAR_INT_REG ... NAU8824_REG_VDET_THRESHOLD_4: 258 + case NAU8824_REG_GPIO_SEL: 259 + case NAU8824_REG_PORT0_I2S_PCM_CTRL_1 ... NAU8824_REG_TDM_CTRL: 260 + case NAU8824_REG_ADC_HPF_FILTER ... NAU8824_REG_EQ4_EQ5: 261 + case NAU8824_REG_ADC_CH0_DGAIN_CTRL ... NAU8824_REG_ADC_TO_DAC_ST: 262 + case NAU8824_REG_DRC_KNEE_IP12_ADC_CH01: 263 + case NAU8824_REG_DRC_KNEE_IP34_ADC_CH01: 264 + case NAU8824_REG_DRC_SLOPE_ADC_CH01: 265 + case NAU8824_REG_DRC_ATKDCY_ADC_CH01: 266 + case NAU8824_REG_DRC_KNEE_IP12_ADC_CH23: 267 + case NAU8824_REG_DRC_KNEE_IP34_ADC_CH23: 268 + case NAU8824_REG_DRC_SLOPE_ADC_CH23: 269 + case NAU8824_REG_DRC_ATKDCY_ADC_CH23: 270 + case NAU8824_REG_DRC_KNEE_IP12_DAC ... NAU8824_REG_DRC_ATKDCY_DAC: 271 + case NAU8824_REG_CLASSG ... NAU8824_REG_OTP_EFUSE: 272 + case NAU8824_REG_I2C_TIMEOUT: 273 + case NAU8824_REG_BIAS_ADJ ... NAU8824_REG_CLASSD_GAIN_2: 274 + case NAU8824_REG_ANALOG_ADC_1 ... NAU8824_REG_ATT_PORT1: 275 + case NAU8824_REG_POWER_UP_CONTROL ... NAU8824_REG_CHARGE_PUMP_CONTROL: 276 + return true; 277 + default: 278 + return false; 279 + } 280 + } 281 + 282 + static bool nau8824_volatile_reg(struct device *dev, unsigned int reg) 283 + { 284 + switch (reg) { 285 + case NAU8824_REG_RESET: 286 + case NAU8824_REG_IRQ ... NAU8824_REG_CLEAR_INT_REG: 287 + case NAU8824_REG_DRC_GAINL_ADC0 ... NAU8824_REG_DRC_GAINL_ADC3: 288 + case NAU8824_REG_DRC_GAIN_DAC_CH0 ... NAU8824_REG_DRC_GAIN_DAC_CH1: 289 + case NAU8824_REG_OTPDOUT_1 ... NAU8824_REG_OTPDOUT_2: 290 + case NAU8824_REG_I2C_DEVICE_ID ... NAU8824_REG_SAR_ADC_DATA_OUT: 291 + case NAU8824_REG_CHARGE_PUMP_INPUT: 292 + return true; 293 + default: 294 + return false; 295 + } 296 + } 297 + 298 + static const char * const nau8824_companding[] = { 299 + "Off", "NC", "u-law", "A-law" }; 300 + 301 + static const struct soc_enum nau8824_companding_adc_enum = 302 + SOC_ENUM_SINGLE(NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 12, 303 + ARRAY_SIZE(nau8824_companding), nau8824_companding); 304 + 305 + static const struct soc_enum nau8824_companding_dac_enum = 306 + SOC_ENUM_SINGLE(NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 14, 307 + ARRAY_SIZE(nau8824_companding), nau8824_companding); 308 + 309 + static const char * const nau8824_adc_decimation[] = { 310 + "32", "64", "128", "256" }; 311 + 312 + static const struct soc_enum nau8824_adc_decimation_enum = 313 + SOC_ENUM_SINGLE(NAU8824_REG_ADC_FILTER_CTRL, 0, 314 + ARRAY_SIZE(nau8824_adc_decimation), nau8824_adc_decimation); 315 + 316 + static const char * const nau8824_dac_oversampl[] = { 317 + "64", "256", "128", "", "32" }; 318 + 319 + static const struct soc_enum nau8824_dac_oversampl_enum = 320 + SOC_ENUM_SINGLE(NAU8824_REG_DAC_FILTER_CTRL_1, 0, 321 + ARRAY_SIZE(nau8824_dac_oversampl), nau8824_dac_oversampl); 322 + 323 + static const char * const nau8824_input_channel[] = { 324 + "Input CH0", "Input CH1", "Input CH2", "Input CH3" }; 325 + 326 + static const struct soc_enum nau8824_adc_ch0_enum = 327 + SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH0_DGAIN_CTRL, 9, 328 + ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel); 329 + 330 + static const struct soc_enum nau8824_adc_ch1_enum = 331 + SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH1_DGAIN_CTRL, 9, 332 + ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel); 333 + 334 + static const struct soc_enum nau8824_adc_ch2_enum = 335 + SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH2_DGAIN_CTRL, 9, 336 + ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel); 337 + 338 + static const struct soc_enum nau8824_adc_ch3_enum = 339 + SOC_ENUM_SINGLE(NAU8824_REG_ADC_CH3_DGAIN_CTRL, 9, 340 + ARRAY_SIZE(nau8824_input_channel), nau8824_input_channel); 341 + 342 + static const char * const nau8824_tdm_slot[] = { 343 + "Slot 0", "Slot 1", "Slot 2", "Slot 3" }; 344 + 345 + static const struct soc_enum nau8824_dac_left_sel_enum = 346 + SOC_ENUM_SINGLE(NAU8824_REG_TDM_CTRL, 6, 347 + ARRAY_SIZE(nau8824_tdm_slot), nau8824_tdm_slot); 348 + 349 + static const struct soc_enum nau8824_dac_right_sel_enum = 350 + SOC_ENUM_SINGLE(NAU8824_REG_TDM_CTRL, 4, 351 + ARRAY_SIZE(nau8824_tdm_slot), nau8824_tdm_slot); 352 + 353 + static const DECLARE_TLV_DB_MINMAX_MUTE(spk_vol_tlv, 0, 2400); 354 + static const DECLARE_TLV_DB_MINMAX(hp_vol_tlv, -3000, 0); 355 + static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 200, 0); 356 + static const DECLARE_TLV_DB_SCALE(dmic_vol_tlv, -12800, 50, 0); 357 + 358 + static const struct snd_kcontrol_new nau8824_snd_controls[] = { 359 + SOC_ENUM("ADC Companding", nau8824_companding_adc_enum), 360 + SOC_ENUM("DAC Companding", nau8824_companding_dac_enum), 361 + 362 + SOC_ENUM("ADC Decimation Rate", nau8824_adc_decimation_enum), 363 + SOC_ENUM("DAC Oversampling Rate", nau8824_dac_oversampl_enum), 364 + 365 + SOC_SINGLE_TLV("Speaker Right from DACR Volume", 366 + NAU8824_REG_CLASSD_GAIN_1, 8, 0x1f, 0, spk_vol_tlv), 367 + SOC_SINGLE_TLV("Speaker Left from DACL Volume", 368 + NAU8824_REG_CLASSD_GAIN_2, 0, 0x1f, 0, spk_vol_tlv), 369 + SOC_SINGLE_TLV("Speaker Left from DACR Volume", 370 + NAU8824_REG_CLASSD_GAIN_1, 0, 0x1f, 0, spk_vol_tlv), 371 + SOC_SINGLE_TLV("Speaker Right from DACL Volume", 372 + NAU8824_REG_CLASSD_GAIN_2, 8, 0x1f, 0, spk_vol_tlv), 373 + 374 + SOC_SINGLE_TLV("Headphone Right from DACR Volume", 375 + NAU8824_REG_ATT_PORT0, 8, 0x1f, 0, hp_vol_tlv), 376 + SOC_SINGLE_TLV("Headphone Left from DACL Volume", 377 + NAU8824_REG_ATT_PORT0, 0, 0x1f, 0, hp_vol_tlv), 378 + SOC_SINGLE_TLV("Headphone Right from DACL Volume", 379 + NAU8824_REG_ATT_PORT1, 8, 0x1f, 0, hp_vol_tlv), 380 + SOC_SINGLE_TLV("Headphone Left from DACR Volume", 381 + NAU8824_REG_ATT_PORT1, 0, 0x1f, 0, hp_vol_tlv), 382 + 383 + SOC_SINGLE_TLV("Mic1 Volume", NAU8824_REG_FEPGA_II, 384 + NAU8824_FEPGA_GAINL_SFT, 0x12, 0, mic_vol_tlv), 385 + SOC_SINGLE_TLV("Mic2 Volume", NAU8824_REG_FEPGA_II, 386 + NAU8824_FEPGA_GAINR_SFT, 0x12, 0, mic_vol_tlv), 387 + 388 + SOC_SINGLE_TLV("DMIC1 Volume", NAU8824_REG_ADC_CH0_DGAIN_CTRL, 389 + 0, 0x164, 0, dmic_vol_tlv), 390 + SOC_SINGLE_TLV("DMIC2 Volume", NAU8824_REG_ADC_CH1_DGAIN_CTRL, 391 + 0, 0x164, 0, dmic_vol_tlv), 392 + SOC_SINGLE_TLV("DMIC3 Volume", NAU8824_REG_ADC_CH2_DGAIN_CTRL, 393 + 0, 0x164, 0, dmic_vol_tlv), 394 + SOC_SINGLE_TLV("DMIC4 Volume", NAU8824_REG_ADC_CH3_DGAIN_CTRL, 395 + 0, 0x164, 0, dmic_vol_tlv), 396 + 397 + SOC_ENUM("ADC CH0 Select", nau8824_adc_ch0_enum), 398 + SOC_ENUM("ADC CH1 Select", nau8824_adc_ch1_enum), 399 + SOC_ENUM("ADC CH2 Select", nau8824_adc_ch2_enum), 400 + SOC_ENUM("ADC CH3 Select", nau8824_adc_ch3_enum), 401 + 402 + SOC_SINGLE("ADC CH0 TX Switch", NAU8824_REG_TDM_CTRL, 0, 1, 0), 403 + SOC_SINGLE("ADC CH1 TX Switch", NAU8824_REG_TDM_CTRL, 1, 1, 0), 404 + SOC_SINGLE("ADC CH2 TX Switch", NAU8824_REG_TDM_CTRL, 2, 1, 0), 405 + SOC_SINGLE("ADC CH3 TX Switch", NAU8824_REG_TDM_CTRL, 3, 1, 0), 406 + 407 + SOC_ENUM("DACL Channel Source", nau8824_dac_left_sel_enum), 408 + SOC_ENUM("DACR Channel Source", nau8824_dac_right_sel_enum), 409 + 410 + SOC_SINGLE("DACL LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 0, 1, 0), 411 + SOC_SINGLE("DACR LR Mix", NAU8824_REG_DAC_MUTE_CTRL, 1, 1, 0), 412 + }; 413 + 414 + static int nau8824_output_dac_event(struct snd_soc_dapm_widget *w, 415 + struct snd_kcontrol *kcontrol, int event) 416 + { 417 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 418 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 419 + 420 + switch (event) { 421 + case SND_SOC_DAPM_PRE_PMU: 422 + /* Disables the TESTDAC to let DAC signal pass through. */ 423 + regmap_update_bits(nau8824->regmap, NAU8824_REG_ENABLE_LO, 424 + NAU8824_TEST_DAC_EN, 0); 425 + break; 426 + case SND_SOC_DAPM_POST_PMD: 427 + regmap_update_bits(nau8824->regmap, NAU8824_REG_ENABLE_LO, 428 + NAU8824_TEST_DAC_EN, NAU8824_TEST_DAC_EN); 429 + break; 430 + default: 431 + return -EINVAL; 432 + } 433 + 434 + return 0; 435 + } 436 + 437 + static int nau8824_spk_event(struct snd_soc_dapm_widget *w, 438 + struct snd_kcontrol *kcontrol, int event) 439 + { 440 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 441 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 442 + 443 + switch (event) { 444 + case SND_SOC_DAPM_PRE_PMU: 445 + regmap_update_bits(nau8824->regmap, 446 + NAU8824_REG_ANALOG_CONTROL_2, 447 + NAU8824_CLASSD_CLAMP_DIS, NAU8824_CLASSD_CLAMP_DIS); 448 + break; 449 + case SND_SOC_DAPM_POST_PMD: 450 + regmap_update_bits(nau8824->regmap, 451 + NAU8824_REG_ANALOG_CONTROL_2, 452 + NAU8824_CLASSD_CLAMP_DIS, 0); 453 + break; 454 + default: 455 + return -EINVAL; 456 + } 457 + 458 + return 0; 459 + } 460 + 461 + static int nau8824_pump_event(struct snd_soc_dapm_widget *w, 462 + struct snd_kcontrol *kcontrol, int event) 463 + { 464 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 465 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 466 + 467 + switch (event) { 468 + case SND_SOC_DAPM_POST_PMU: 469 + /* Prevent startup click by letting charge pump to ramp up */ 470 + msleep(10); 471 + regmap_update_bits(nau8824->regmap, 472 + NAU8824_REG_CHARGE_PUMP_CONTROL, 473 + NAU8824_JAMNODCLOW, NAU8824_JAMNODCLOW); 474 + break; 475 + case SND_SOC_DAPM_PRE_PMD: 476 + regmap_update_bits(nau8824->regmap, 477 + NAU8824_REG_CHARGE_PUMP_CONTROL, 478 + NAU8824_JAMNODCLOW, 0); 479 + break; 480 + default: 481 + return -EINVAL; 482 + } 483 + 484 + return 0; 485 + } 486 + 487 + static int system_clock_control(struct snd_soc_dapm_widget *w, 488 + struct snd_kcontrol *k, int event) 489 + { 490 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 491 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 492 + 493 + if (SND_SOC_DAPM_EVENT_OFF(event)) { 494 + /* Set clock source to disable or internal clock before the 495 + * playback or capture end. Codec needs clock for Jack 496 + * detection and button press if jack inserted; otherwise, 497 + * the clock should be closed. 498 + */ 499 + if (nau8824_is_jack_inserted(nau8824)) { 500 + nau8824_config_sysclk(nau8824, 501 + NAU8824_CLK_INTERNAL, 0); 502 + } else { 503 + nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0); 504 + } 505 + } 506 + return 0; 507 + } 508 + 509 + static int dmic_clock_control(struct snd_soc_dapm_widget *w, 510 + struct snd_kcontrol *k, int event) 511 + { 512 + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 513 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 514 + int src; 515 + 516 + /* The DMIC clock is gotten from system clock (256fs) divided by 517 + * DMIC_SRC (1, 2, 4, 8, 16, 32). The clock has to be equal or 518 + * less than 3.072 MHz. 519 + */ 520 + for (src = 0; src < 5; src++) { 521 + if ((0x1 << (8 - src)) * nau8824->fs <= DMIC_CLK) 522 + break; 523 + } 524 + dev_dbg(nau8824->dev, "dmic src %d for mclk %d\n", src, nau8824->fs * 256); 525 + regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, 526 + NAU8824_CLK_DMIC_SRC_MASK, (src << NAU8824_CLK_DMIC_SRC_SFT)); 527 + 528 + return 0; 529 + } 530 + 531 + static const struct snd_kcontrol_new nau8824_adc_ch0_dmic = 532 + SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL, 533 + NAU8824_ADC_CH0_DMIC_SFT, 1, 0); 534 + 535 + static const struct snd_kcontrol_new nau8824_adc_ch1_dmic = 536 + SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL, 537 + NAU8824_ADC_CH1_DMIC_SFT, 1, 0); 538 + 539 + static const struct snd_kcontrol_new nau8824_adc_ch2_dmic = 540 + SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL, 541 + NAU8824_ADC_CH2_DMIC_SFT, 1, 0); 542 + 543 + static const struct snd_kcontrol_new nau8824_adc_ch3_dmic = 544 + SOC_DAPM_SINGLE("Switch", NAU8824_REG_ENA_CTRL, 545 + NAU8824_ADC_CH3_DMIC_SFT, 1, 0); 546 + 547 + static const struct snd_kcontrol_new nau8824_adc_left_mixer[] = { 548 + SOC_DAPM_SINGLE("MIC Switch", NAU8824_REG_FEPGA, 549 + NAU8824_FEPGA_MODEL_MIC1_SFT, 1, 0), 550 + SOC_DAPM_SINGLE("HSMIC Switch", NAU8824_REG_FEPGA, 551 + NAU8824_FEPGA_MODEL_HSMIC_SFT, 1, 0), 552 + }; 553 + 554 + static const struct snd_kcontrol_new nau8824_adc_right_mixer[] = { 555 + SOC_DAPM_SINGLE("MIC Switch", NAU8824_REG_FEPGA, 556 + NAU8824_FEPGA_MODER_MIC2_SFT, 1, 0), 557 + SOC_DAPM_SINGLE("HSMIC Switch", NAU8824_REG_FEPGA, 558 + NAU8824_FEPGA_MODER_HSMIC_SFT, 1, 0), 559 + }; 560 + 561 + static const struct snd_kcontrol_new nau8824_hp_left_mixer[] = { 562 + SOC_DAPM_SINGLE("DAC Right Switch", NAU8824_REG_ENABLE_LO, 563 + NAU8824_DACR_HPL_EN_SFT, 1, 0), 564 + SOC_DAPM_SINGLE("DAC Left Switch", NAU8824_REG_ENABLE_LO, 565 + NAU8824_DACL_HPL_EN_SFT, 1, 0), 566 + }; 567 + 568 + static const struct snd_kcontrol_new nau8824_hp_right_mixer[] = { 569 + SOC_DAPM_SINGLE("DAC Left Switch", NAU8824_REG_ENABLE_LO, 570 + NAU8824_DACL_HPR_EN_SFT, 1, 0), 571 + SOC_DAPM_SINGLE("DAC Right Switch", NAU8824_REG_ENABLE_LO, 572 + NAU8824_DACR_HPR_EN_SFT, 1, 0), 573 + }; 574 + 575 + static const char * const nau8824_dac_src[] = { "DACL", "DACR" }; 576 + 577 + static SOC_ENUM_SINGLE_DECL( 578 + nau8824_dacl_enum, NAU8824_REG_DAC_CH0_DGAIN_CTRL, 579 + NAU8824_DAC_CH0_SEL_SFT, nau8824_dac_src); 580 + 581 + static SOC_ENUM_SINGLE_DECL( 582 + nau8824_dacr_enum, NAU8824_REG_DAC_CH1_DGAIN_CTRL, 583 + NAU8824_DAC_CH1_SEL_SFT, nau8824_dac_src); 584 + 585 + static const struct snd_kcontrol_new nau8824_dacl_mux = 586 + SOC_DAPM_ENUM("DACL Source", nau8824_dacl_enum); 587 + 588 + static const struct snd_kcontrol_new nau8824_dacr_mux = 589 + SOC_DAPM_ENUM("DACR Source", nau8824_dacr_enum); 590 + 591 + 592 + static const struct snd_soc_dapm_widget nau8824_dapm_widgets[] = { 593 + SND_SOC_DAPM_SUPPLY("System Clock", SND_SOC_NOPM, 0, 0, 594 + system_clock_control, SND_SOC_DAPM_POST_PMD), 595 + 596 + SND_SOC_DAPM_INPUT("HSMIC1"), 597 + SND_SOC_DAPM_INPUT("HSMIC2"), 598 + SND_SOC_DAPM_INPUT("MIC1"), 599 + SND_SOC_DAPM_INPUT("MIC2"), 600 + SND_SOC_DAPM_INPUT("DMIC1"), 601 + SND_SOC_DAPM_INPUT("DMIC2"), 602 + SND_SOC_DAPM_INPUT("DMIC3"), 603 + SND_SOC_DAPM_INPUT("DMIC4"), 604 + 605 + SND_SOC_DAPM_SUPPLY("SAR", NAU8824_REG_SAR_ADC, 606 + NAU8824_SAR_ADC_EN_SFT, 0, NULL, 0), 607 + SND_SOC_DAPM_SUPPLY("MICBIAS", NAU8824_REG_MIC_BIAS, 608 + NAU8824_MICBIAS_POWERUP_SFT, 0, NULL, 0), 609 + SND_SOC_DAPM_SUPPLY("DMIC12 Power", NAU8824_REG_BIAS_ADJ, 610 + NAU8824_DMIC1_EN_SFT, 0, NULL, 0), 611 + SND_SOC_DAPM_SUPPLY("DMIC34 Power", NAU8824_REG_BIAS_ADJ, 612 + NAU8824_DMIC2_EN_SFT, 0, NULL, 0), 613 + SND_SOC_DAPM_SUPPLY("DMIC Clock", SND_SOC_NOPM, 0, 0, 614 + dmic_clock_control, SND_SOC_DAPM_POST_PMU), 615 + 616 + SND_SOC_DAPM_SWITCH("DMIC1 Enable", SND_SOC_NOPM, 617 + 0, 0, &nau8824_adc_ch0_dmic), 618 + SND_SOC_DAPM_SWITCH("DMIC2 Enable", SND_SOC_NOPM, 619 + 0, 0, &nau8824_adc_ch1_dmic), 620 + SND_SOC_DAPM_SWITCH("DMIC3 Enable", SND_SOC_NOPM, 621 + 0, 0, &nau8824_adc_ch2_dmic), 622 + SND_SOC_DAPM_SWITCH("DMIC4 Enable", SND_SOC_NOPM, 623 + 0, 0, &nau8824_adc_ch3_dmic), 624 + 625 + SND_SOC_DAPM_MIXER("Left ADC", NAU8824_REG_POWER_UP_CONTROL, 626 + 12, 0, nau8824_adc_left_mixer, 627 + ARRAY_SIZE(nau8824_adc_left_mixer)), 628 + SND_SOC_DAPM_MIXER("Right ADC", NAU8824_REG_POWER_UP_CONTROL, 629 + 13, 0, nau8824_adc_right_mixer, 630 + ARRAY_SIZE(nau8824_adc_right_mixer)), 631 + 632 + SND_SOC_DAPM_ADC("ADCL", NULL, NAU8824_REG_ANALOG_ADC_2, 633 + NAU8824_ADCL_EN_SFT, 0), 634 + SND_SOC_DAPM_ADC("ADCR", NULL, NAU8824_REG_ANALOG_ADC_2, 635 + NAU8824_ADCR_EN_SFT, 0), 636 + 637 + SND_SOC_DAPM_AIF_OUT("AIFTX", "HiFi Capture", 0, SND_SOC_NOPM, 0, 0), 638 + SND_SOC_DAPM_AIF_IN("AIFRX", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0), 639 + 640 + SND_SOC_DAPM_DAC("DACL", NULL, NAU8824_REG_RDAC, 641 + NAU8824_DACL_EN_SFT, 0), 642 + SND_SOC_DAPM_SUPPLY("DACL Clock", NAU8824_REG_RDAC, 643 + NAU8824_DACL_CLK_SFT, 0, NULL, 0), 644 + SND_SOC_DAPM_DAC("DACR", NULL, NAU8824_REG_RDAC, 645 + NAU8824_DACR_EN_SFT, 0), 646 + SND_SOC_DAPM_SUPPLY("DACR Clock", NAU8824_REG_RDAC, 647 + NAU8824_DACR_CLK_SFT, 0, NULL, 0), 648 + 649 + SND_SOC_DAPM_MUX("DACL Mux", SND_SOC_NOPM, 0, 0, &nau8824_dacl_mux), 650 + SND_SOC_DAPM_MUX("DACR Mux", SND_SOC_NOPM, 0, 0, &nau8824_dacr_mux), 651 + 652 + SND_SOC_DAPM_PGA_S("Output DACL", 0, NAU8824_REG_CHARGE_PUMP_CONTROL, 653 + 8, 1, nau8824_output_dac_event, 654 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 655 + SND_SOC_DAPM_PGA_S("Output DACR", 0, NAU8824_REG_CHARGE_PUMP_CONTROL, 656 + 9, 1, nau8824_output_dac_event, 657 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 658 + 659 + SND_SOC_DAPM_PGA_S("ClassD", 0, NAU8824_REG_CLASSD_GAIN_1, 660 + NAU8824_CLASSD_EN_SFT, 0, nau8824_spk_event, 661 + SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), 662 + 663 + SND_SOC_DAPM_MIXER("Left Headphone", NAU8824_REG_CLASSG, 664 + NAU8824_CLASSG_LDAC_EN_SFT, 0, nau8824_hp_left_mixer, 665 + ARRAY_SIZE(nau8824_hp_left_mixer)), 666 + SND_SOC_DAPM_MIXER("Right Headphone", NAU8824_REG_CLASSG, 667 + NAU8824_CLASSG_RDAC_EN_SFT, 0, nau8824_hp_right_mixer, 668 + ARRAY_SIZE(nau8824_hp_right_mixer)), 669 + SND_SOC_DAPM_PGA_S("Charge Pump", 1, NAU8824_REG_CHARGE_PUMP_CONTROL, 670 + NAU8824_CHARGE_PUMP_EN_SFT, 0, nau8824_pump_event, 671 + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), 672 + SND_SOC_DAPM_PGA("Output Driver L", 673 + NAU8824_REG_POWER_UP_CONTROL, 3, 0, NULL, 0), 674 + SND_SOC_DAPM_PGA("Output Driver R", 675 + NAU8824_REG_POWER_UP_CONTROL, 2, 0, NULL, 0), 676 + SND_SOC_DAPM_PGA("Main Driver L", 677 + NAU8824_REG_POWER_UP_CONTROL, 1, 0, NULL, 0), 678 + SND_SOC_DAPM_PGA("Main Driver R", 679 + NAU8824_REG_POWER_UP_CONTROL, 0, 0, NULL, 0), 680 + SND_SOC_DAPM_PGA("HP Boost Driver", NAU8824_REG_BOOST, 681 + NAU8824_HP_BOOST_DIS_SFT, 1, NULL, 0), 682 + SND_SOC_DAPM_PGA("Class G", NAU8824_REG_CLASSG, 683 + NAU8824_CLASSG_EN_SFT, 0, NULL, 0), 684 + 685 + SND_SOC_DAPM_OUTPUT("SPKOUTL"), 686 + SND_SOC_DAPM_OUTPUT("SPKOUTR"), 687 + SND_SOC_DAPM_OUTPUT("HPOL"), 688 + SND_SOC_DAPM_OUTPUT("HPOR"), 689 + }; 690 + 691 + static const struct snd_soc_dapm_route nau8824_dapm_routes[] = { 692 + {"DMIC1 Enable", "Switch", "DMIC1"}, 693 + {"DMIC2 Enable", "Switch", "DMIC2"}, 694 + {"DMIC3 Enable", "Switch", "DMIC3"}, 695 + {"DMIC4 Enable", "Switch", "DMIC4"}, 696 + 697 + {"DMIC1", NULL, "DMIC12 Power"}, 698 + {"DMIC2", NULL, "DMIC12 Power"}, 699 + {"DMIC3", NULL, "DMIC34 Power"}, 700 + {"DMIC4", NULL, "DMIC34 Power"}, 701 + {"DMIC12 Power", NULL, "DMIC Clock"}, 702 + {"DMIC34 Power", NULL, "DMIC Clock"}, 703 + 704 + {"Left ADC", "MIC Switch", "MIC1"}, 705 + {"Left ADC", "HSMIC Switch", "HSMIC1"}, 706 + {"Right ADC", "MIC Switch", "MIC2"}, 707 + {"Right ADC", "HSMIC Switch", "HSMIC2"}, 708 + 709 + {"ADCL", NULL, "Left ADC"}, 710 + {"ADCR", NULL, "Right ADC"}, 711 + 712 + {"AIFTX", NULL, "MICBIAS"}, 713 + {"AIFTX", NULL, "ADCL"}, 714 + {"AIFTX", NULL, "ADCR"}, 715 + {"AIFTX", NULL, "DMIC1 Enable"}, 716 + {"AIFTX", NULL, "DMIC2 Enable"}, 717 + {"AIFTX", NULL, "DMIC3 Enable"}, 718 + {"AIFTX", NULL, "DMIC4 Enable"}, 719 + 720 + {"AIFTX", NULL, "System Clock"}, 721 + {"AIFRX", NULL, "System Clock"}, 722 + 723 + {"DACL", NULL, "AIFRX"}, 724 + {"DACL", NULL, "DACL Clock"}, 725 + {"DACR", NULL, "AIFRX"}, 726 + {"DACR", NULL, "DACR Clock"}, 727 + 728 + {"DACL Mux", "DACL", "DACL"}, 729 + {"DACL Mux", "DACR", "DACR"}, 730 + {"DACR Mux", "DACL", "DACL"}, 731 + {"DACR Mux", "DACR", "DACR"}, 732 + 733 + {"Output DACL", NULL, "DACL Mux"}, 734 + {"Output DACR", NULL, "DACR Mux"}, 735 + 736 + {"ClassD", NULL, "Output DACL"}, 737 + {"ClassD", NULL, "Output DACR"}, 738 + 739 + {"Left Headphone", "DAC Left Switch", "Output DACL"}, 740 + {"Left Headphone", "DAC Right Switch", "Output DACR"}, 741 + {"Right Headphone", "DAC Left Switch", "Output DACL"}, 742 + {"Right Headphone", "DAC Right Switch", "Output DACR"}, 743 + 744 + {"Charge Pump", NULL, "Left Headphone"}, 745 + {"Charge Pump", NULL, "Right Headphone"}, 746 + {"Output Driver L", NULL, "Charge Pump"}, 747 + {"Output Driver R", NULL, "Charge Pump"}, 748 + {"Main Driver L", NULL, "Output Driver L"}, 749 + {"Main Driver R", NULL, "Output Driver R"}, 750 + {"Class G", NULL, "Main Driver L"}, 751 + {"Class G", NULL, "Main Driver R"}, 752 + {"HP Boost Driver", NULL, "Class G"}, 753 + 754 + {"SPKOUTL", NULL, "ClassD"}, 755 + {"SPKOUTR", NULL, "ClassD"}, 756 + {"HPOL", NULL, "HP Boost Driver"}, 757 + {"HPOR", NULL, "HP Boost Driver"}, 758 + }; 759 + 760 + static bool nau8824_is_jack_inserted(struct nau8824 *nau8824) 761 + { 762 + struct snd_soc_jack *jack = nau8824->jack; 763 + bool insert = FALSE; 764 + 765 + if (nau8824->irq && jack) 766 + insert = jack->status & SND_JACK_HEADPHONE; 767 + 768 + return insert; 769 + } 770 + 771 + static void nau8824_int_status_clear_all(struct regmap *regmap) 772 + { 773 + int active_irq, clear_irq, i; 774 + 775 + /* Reset the intrruption status from rightmost bit if the corres- 776 + * ponding irq event occurs. 777 + */ 778 + regmap_read(regmap, NAU8824_REG_IRQ, &active_irq); 779 + for (i = 0; i < NAU8824_REG_DATA_LEN; i++) { 780 + clear_irq = (0x1 << i); 781 + if (active_irq & clear_irq) 782 + regmap_write(regmap, 783 + NAU8824_REG_CLEAR_INT_REG, clear_irq); 784 + } 785 + } 786 + 787 + static void nau8824_eject_jack(struct nau8824 *nau8824) 788 + { 789 + struct snd_soc_dapm_context *dapm = nau8824->dapm; 790 + struct regmap *regmap = nau8824->regmap; 791 + 792 + /* Clear all interruption status */ 793 + nau8824_int_status_clear_all(regmap); 794 + 795 + snd_soc_dapm_disable_pin(dapm, "SAR"); 796 + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); 797 + snd_soc_dapm_sync(dapm); 798 + 799 + /* Enable the insertion interruption, disable the ejection 800 + * interruption, and then bypass de-bounce circuit. 801 + */ 802 + regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING, 803 + NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS | 804 + NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_INSERT_DIS, 805 + NAU8824_IRQ_KEY_RELEASE_DIS | NAU8824_IRQ_KEY_SHORT_PRESS_DIS | 806 + NAU8824_IRQ_EJECT_DIS); 807 + regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1, 808 + NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN, 809 + NAU8824_IRQ_INSERT_EN); 810 + regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL, 811 + NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE); 812 + 813 + /* Close clock for jack type detection at manual mode */ 814 + nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0); 815 + } 816 + 817 + static void nau8824_jdet_work(struct work_struct *work) 818 + { 819 + struct nau8824 *nau8824 = container_of( 820 + work, struct nau8824, jdet_work); 821 + struct snd_soc_dapm_context *dapm = nau8824->dapm; 822 + struct regmap *regmap = nau8824->regmap; 823 + int adc_value, event = 0, event_mask = 0; 824 + 825 + snd_soc_dapm_force_enable_pin(dapm, "MICBIAS"); 826 + snd_soc_dapm_force_enable_pin(dapm, "SAR"); 827 + snd_soc_dapm_sync(dapm); 828 + 829 + msleep(100); 830 + 831 + regmap_read(regmap, NAU8824_REG_SAR_ADC_DATA_OUT, &adc_value); 832 + adc_value = adc_value & NAU8824_SAR_ADC_DATA_MASK; 833 + dev_dbg(nau8824->dev, "SAR ADC data 0x%02x\n", adc_value); 834 + if (adc_value < HEADSET_SARADC_THD) { 835 + event |= SND_JACK_HEADPHONE; 836 + 837 + snd_soc_dapm_disable_pin(dapm, "SAR"); 838 + snd_soc_dapm_disable_pin(dapm, "MICBIAS"); 839 + snd_soc_dapm_sync(dapm); 840 + } else { 841 + event |= SND_JACK_HEADSET; 842 + } 843 + event_mask |= SND_JACK_HEADSET; 844 + snd_soc_jack_report(nau8824->jack, event, event_mask); 845 + 846 + nau8824_sema_release(nau8824); 847 + } 848 + 849 + static void nau8824_setup_auto_irq(struct nau8824 *nau8824) 850 + { 851 + struct regmap *regmap = nau8824->regmap; 852 + 853 + /* Enable jack ejection, short key press and release interruption. */ 854 + regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING_1, 855 + NAU8824_IRQ_INSERT_EN | NAU8824_IRQ_EJECT_EN, 856 + NAU8824_IRQ_EJECT_EN); 857 + regmap_update_bits(regmap, NAU8824_REG_INTERRUPT_SETTING, 858 + NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_KEY_RELEASE_DIS | 859 + NAU8824_IRQ_KEY_SHORT_PRESS_DIS, 0); 860 + /* Enable internal VCO needed for interruptions */ 861 + nau8824_config_sysclk(nau8824, NAU8824_CLK_INTERNAL, 0); 862 + regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL, 863 + NAU8824_JD_SLEEP_MODE, 0); 864 + } 865 + 866 + static int nau8824_button_decode(int value) 867 + { 868 + int buttons = 0; 869 + 870 + /* The chip supports up to 8 buttons, but ALSA defines 871 + * only 6 buttons. 872 + */ 873 + if (value & BIT(0)) 874 + buttons |= SND_JACK_BTN_0; 875 + if (value & BIT(1)) 876 + buttons |= SND_JACK_BTN_1; 877 + if (value & BIT(2)) 878 + buttons |= SND_JACK_BTN_2; 879 + if (value & BIT(3)) 880 + buttons |= SND_JACK_BTN_3; 881 + if (value & BIT(4)) 882 + buttons |= SND_JACK_BTN_4; 883 + if (value & BIT(5)) 884 + buttons |= SND_JACK_BTN_5; 885 + 886 + return buttons; 887 + } 888 + 889 + #define NAU8824_BUTTONS (SND_JACK_BTN_0 | SND_JACK_BTN_1 | \ 890 + SND_JACK_BTN_2 | SND_JACK_BTN_3) 891 + 892 + static irqreturn_t nau8824_interrupt(int irq, void *data) 893 + { 894 + struct nau8824 *nau8824 = (struct nau8824 *)data; 895 + struct regmap *regmap = nau8824->regmap; 896 + int active_irq, clear_irq = 0, event = 0, event_mask = 0; 897 + 898 + if (regmap_read(regmap, NAU8824_REG_IRQ, &active_irq)) { 899 + dev_err(nau8824->dev, "failed to read irq status\n"); 900 + return IRQ_NONE; 901 + } 902 + dev_dbg(nau8824->dev, "IRQ %x\n", active_irq); 903 + 904 + if (active_irq & NAU8824_JACK_EJECTION_DETECTED) { 905 + nau8824_eject_jack(nau8824); 906 + event_mask |= SND_JACK_HEADSET; 907 + clear_irq = NAU8824_JACK_EJECTION_DETECTED; 908 + /* release semaphore held after resume, 909 + * and cancel jack detection 910 + */ 911 + nau8824_sema_release(nau8824); 912 + cancel_work_sync(&nau8824->jdet_work); 913 + } else if (active_irq & NAU8824_KEY_SHORT_PRESS_IRQ) { 914 + int key_status, button_pressed; 915 + 916 + regmap_read(regmap, NAU8824_REG_CLEAR_INT_REG, 917 + &key_status); 918 + 919 + /* lower 8 bits of the register are for pressed keys */ 920 + button_pressed = nau8824_button_decode(key_status); 921 + 922 + event |= button_pressed; 923 + dev_dbg(nau8824->dev, "button %x pressed\n", event); 924 + event_mask |= NAU8824_BUTTONS; 925 + clear_irq = NAU8824_KEY_SHORT_PRESS_IRQ; 926 + } else if (active_irq & NAU8824_KEY_RELEASE_IRQ) { 927 + event_mask = NAU8824_BUTTONS; 928 + clear_irq = NAU8824_KEY_RELEASE_IRQ; 929 + } else if (active_irq & NAU8824_JACK_INSERTION_DETECTED) { 930 + /* Turn off insertion interruption at manual mode */ 931 + regmap_update_bits(regmap, 932 + NAU8824_REG_INTERRUPT_SETTING, 933 + NAU8824_IRQ_INSERT_DIS, 934 + NAU8824_IRQ_INSERT_DIS); 935 + regmap_update_bits(regmap, 936 + NAU8824_REG_INTERRUPT_SETTING_1, 937 + NAU8824_IRQ_INSERT_EN, 0); 938 + /* detect microphone and jack type */ 939 + cancel_work_sync(&nau8824->jdet_work); 940 + schedule_work(&nau8824->jdet_work); 941 + 942 + /* Enable interruption for jack type detection at audo 943 + * mode which can detect microphone and jack type. 944 + */ 945 + nau8824_setup_auto_irq(nau8824); 946 + } 947 + 948 + if (!clear_irq) 949 + clear_irq = active_irq; 950 + /* clears the rightmost interruption */ 951 + regmap_write(regmap, NAU8824_REG_CLEAR_INT_REG, clear_irq); 952 + 953 + if (event_mask) 954 + snd_soc_jack_report(nau8824->jack, event, event_mask); 955 + 956 + return IRQ_HANDLED; 957 + } 958 + 959 + static int nau8824_clock_check(struct nau8824 *nau8824, 960 + int stream, int rate, int osr) 961 + { 962 + int osrate; 963 + 964 + if (stream == SNDRV_PCM_STREAM_PLAYBACK) { 965 + if (osr >= ARRAY_SIZE(osr_dac_sel)) 966 + return -EINVAL; 967 + osrate = osr_dac_sel[osr].osr; 968 + } else { 969 + if (osr >= ARRAY_SIZE(osr_adc_sel)) 970 + return -EINVAL; 971 + osrate = osr_adc_sel[osr].osr; 972 + } 973 + 974 + if (!osrate || rate * osr > CLK_DA_AD_MAX) { 975 + dev_err(nau8824->dev, "exceed the maximum frequency of CLK_ADC or CLK_DAC\n"); 976 + return -EINVAL; 977 + } 978 + 979 + return 0; 980 + } 981 + 982 + static int nau8824_hw_params(struct snd_pcm_substream *substream, 983 + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) 984 + { 985 + struct snd_soc_codec *codec = dai->codec; 986 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 987 + unsigned int val_len = 0, osr, ctrl_val, bclk_fs, bclk_div; 988 + 989 + nau8824_sema_acquire(nau8824, HZ); 990 + 991 + /* CLK_DAC or CLK_ADC = OSR * FS 992 + * DAC or ADC clock frequency is defined as Over Sampling Rate (OSR) 993 + * multiplied by the audio sample rate (Fs). Note that the OSR and Fs 994 + * values must be selected such that the maximum frequency is less 995 + * than 6.144 MHz. 996 + */ 997 + nau8824->fs = params_rate(params); 998 + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { 999 + regmap_read(nau8824->regmap, 1000 + NAU8824_REG_DAC_FILTER_CTRL_1, &osr); 1001 + osr &= NAU8824_DAC_OVERSAMPLE_MASK; 1002 + if (nau8824_clock_check(nau8824, substream->stream, 1003 + nau8824->fs, osr)) 1004 + return -EINVAL; 1005 + regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, 1006 + NAU8824_CLK_DAC_SRC_MASK, 1007 + osr_dac_sel[osr].clk_src << NAU8824_CLK_DAC_SRC_SFT); 1008 + } else { 1009 + regmap_read(nau8824->regmap, 1010 + NAU8824_REG_ADC_FILTER_CTRL, &osr); 1011 + osr &= NAU8824_ADC_SYNC_DOWN_MASK; 1012 + if (nau8824_clock_check(nau8824, substream->stream, 1013 + nau8824->fs, osr)) 1014 + return -EINVAL; 1015 + regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, 1016 + NAU8824_CLK_ADC_SRC_MASK, 1017 + osr_adc_sel[osr].clk_src << NAU8824_CLK_ADC_SRC_SFT); 1018 + } 1019 + 1020 + /* make BCLK and LRC divde configuration if the codec as master. */ 1021 + regmap_read(nau8824->regmap, 1022 + NAU8824_REG_PORT0_I2S_PCM_CTRL_2, &ctrl_val); 1023 + if (ctrl_val & NAU8824_I2S_MS_MASTER) { 1024 + /* get the bclk and fs ratio */ 1025 + bclk_fs = snd_soc_params_to_bclk(params) / nau8824->fs; 1026 + if (bclk_fs <= 32) 1027 + bclk_div = 0x3; 1028 + else if (bclk_fs <= 64) 1029 + bclk_div = 0x2; 1030 + else if (bclk_fs <= 128) 1031 + bclk_div = 0x1; 1032 + else if (bclk_fs <= 256) 1033 + bclk_div = 0; 1034 + else 1035 + return -EINVAL; 1036 + regmap_update_bits(nau8824->regmap, 1037 + NAU8824_REG_PORT0_I2S_PCM_CTRL_2, 1038 + NAU8824_I2S_LRC_DIV_MASK | NAU8824_I2S_BLK_DIV_MASK, 1039 + (bclk_div << NAU8824_I2S_LRC_DIV_SFT) | bclk_div); 1040 + } 1041 + 1042 + switch (params_width(params)) { 1043 + case 16: 1044 + val_len |= NAU8824_I2S_DL_16; 1045 + break; 1046 + case 20: 1047 + val_len |= NAU8824_I2S_DL_20; 1048 + break; 1049 + case 24: 1050 + val_len |= NAU8824_I2S_DL_24; 1051 + break; 1052 + case 32: 1053 + val_len |= NAU8824_I2S_DL_32; 1054 + break; 1055 + default: 1056 + return -EINVAL; 1057 + } 1058 + 1059 + regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 1060 + NAU8824_I2S_DL_MASK, val_len); 1061 + 1062 + nau8824_sema_release(nau8824); 1063 + 1064 + return 0; 1065 + } 1066 + 1067 + static int nau8824_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) 1068 + { 1069 + struct snd_soc_codec *codec = dai->codec; 1070 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1071 + unsigned int ctrl1_val = 0, ctrl2_val = 0; 1072 + 1073 + nau8824_sema_acquire(nau8824, HZ); 1074 + 1075 + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { 1076 + case SND_SOC_DAIFMT_CBM_CFM: 1077 + ctrl2_val |= NAU8824_I2S_MS_MASTER; 1078 + break; 1079 + case SND_SOC_DAIFMT_CBS_CFS: 1080 + break; 1081 + default: 1082 + return -EINVAL; 1083 + } 1084 + 1085 + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 1086 + case SND_SOC_DAIFMT_NB_NF: 1087 + break; 1088 + case SND_SOC_DAIFMT_IB_NF: 1089 + ctrl1_val |= NAU8824_I2S_BP_INV; 1090 + break; 1091 + default: 1092 + return -EINVAL; 1093 + } 1094 + 1095 + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 1096 + case SND_SOC_DAIFMT_I2S: 1097 + ctrl1_val |= NAU8824_I2S_DF_I2S; 1098 + break; 1099 + case SND_SOC_DAIFMT_LEFT_J: 1100 + ctrl1_val |= NAU8824_I2S_DF_LEFT; 1101 + break; 1102 + case SND_SOC_DAIFMT_RIGHT_J: 1103 + ctrl1_val |= NAU8824_I2S_DF_RIGTH; 1104 + break; 1105 + case SND_SOC_DAIFMT_DSP_A: 1106 + ctrl1_val |= NAU8824_I2S_DF_PCM_AB; 1107 + break; 1108 + case SND_SOC_DAIFMT_DSP_B: 1109 + ctrl1_val |= NAU8824_I2S_DF_PCM_AB; 1110 + ctrl1_val |= NAU8824_I2S_PCMB_EN; 1111 + break; 1112 + default: 1113 + return -EINVAL; 1114 + } 1115 + 1116 + regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_1, 1117 + NAU8824_I2S_DF_MASK | NAU8824_I2S_BP_MASK | 1118 + NAU8824_I2S_PCMB_EN, ctrl1_val); 1119 + regmap_update_bits(nau8824->regmap, NAU8824_REG_PORT0_I2S_PCM_CTRL_2, 1120 + NAU8824_I2S_MS_MASK, ctrl2_val); 1121 + 1122 + nau8824_sema_release(nau8824); 1123 + 1124 + return 0; 1125 + } 1126 + 1127 + /** 1128 + * nau8824_calc_fll_param - Calculate FLL parameters. 1129 + * @fll_in: external clock provided to codec. 1130 + * @fs: sampling rate. 1131 + * @fll_param: Pointer to structure of FLL parameters. 1132 + * 1133 + * Calculate FLL parameters to configure codec. 1134 + * 1135 + * Returns 0 for success or negative error code. 1136 + */ 1137 + static int nau8824_calc_fll_param(unsigned int fll_in, 1138 + unsigned int fs, struct nau8824_fll *fll_param) 1139 + { 1140 + u64 fvco, fvco_max; 1141 + unsigned int fref, i, fvco_sel; 1142 + 1143 + /* Ensure the reference clock frequency (FREF) is <= 13.5MHz by dividing 1144 + * freq_in by 1, 2, 4, or 8 using FLL pre-scalar. 1145 + * FREF = freq_in / NAU8824_FLL_REF_DIV_MASK 1146 + */ 1147 + for (i = 0; i < ARRAY_SIZE(fll_pre_scalar); i++) { 1148 + fref = fll_in / fll_pre_scalar[i].param; 1149 + if (fref <= NAU_FREF_MAX) 1150 + break; 1151 + } 1152 + if (i == ARRAY_SIZE(fll_pre_scalar)) 1153 + return -EINVAL; 1154 + fll_param->clk_ref_div = fll_pre_scalar[i].val; 1155 + 1156 + /* Choose the FLL ratio based on FREF */ 1157 + for (i = 0; i < ARRAY_SIZE(fll_ratio); i++) { 1158 + if (fref >= fll_ratio[i].param) 1159 + break; 1160 + } 1161 + if (i == ARRAY_SIZE(fll_ratio)) 1162 + return -EINVAL; 1163 + fll_param->ratio = fll_ratio[i].val; 1164 + 1165 + /* Calculate the frequency of DCO (FDCO) given freq_out = 256 * Fs. 1166 + * FDCO must be within the 90MHz - 124MHz or the FFL cannot be 1167 + * guaranteed across the full range of operation. 1168 + * FDCO = freq_out * 2 * mclk_src_scaling 1169 + */ 1170 + fvco_max = 0; 1171 + fvco_sel = ARRAY_SIZE(mclk_src_scaling); 1172 + for (i = 0; i < ARRAY_SIZE(mclk_src_scaling); i++) { 1173 + fvco = 256 * fs * 2 * mclk_src_scaling[i].param; 1174 + if (fvco > NAU_FVCO_MIN && fvco < NAU_FVCO_MAX && 1175 + fvco_max < fvco) { 1176 + fvco_max = fvco; 1177 + fvco_sel = i; 1178 + } 1179 + } 1180 + if (ARRAY_SIZE(mclk_src_scaling) == fvco_sel) 1181 + return -EINVAL; 1182 + fll_param->mclk_src = mclk_src_scaling[fvco_sel].val; 1183 + 1184 + /* Calculate the FLL 10-bit integer input and the FLL 16-bit fractional 1185 + * input based on FDCO, FREF and FLL ratio. 1186 + */ 1187 + fvco = div_u64(fvco_max << 16, fref * fll_param->ratio); 1188 + fll_param->fll_int = (fvco >> 16) & 0x3FF; 1189 + fll_param->fll_frac = fvco & 0xFFFF; 1190 + return 0; 1191 + } 1192 + 1193 + static void nau8824_fll_apply(struct regmap *regmap, 1194 + struct nau8824_fll *fll_param) 1195 + { 1196 + regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER, 1197 + NAU8824_CLK_SRC_MASK | NAU8824_CLK_MCLK_SRC_MASK, 1198 + NAU8824_CLK_SRC_MCLK | fll_param->mclk_src); 1199 + regmap_update_bits(regmap, NAU8824_REG_FLL1, 1200 + NAU8824_FLL_RATIO_MASK, fll_param->ratio); 1201 + /* FLL 16-bit fractional input */ 1202 + regmap_write(regmap, NAU8824_REG_FLL2, fll_param->fll_frac); 1203 + /* FLL 10-bit integer input */ 1204 + regmap_update_bits(regmap, NAU8824_REG_FLL3, 1205 + NAU8824_FLL_INTEGER_MASK, fll_param->fll_int); 1206 + /* FLL pre-scaler */ 1207 + regmap_update_bits(regmap, NAU8824_REG_FLL4, 1208 + NAU8824_FLL_REF_DIV_MASK, 1209 + fll_param->clk_ref_div << NAU8824_FLL_REF_DIV_SFT); 1210 + /* select divided VCO input */ 1211 + regmap_update_bits(regmap, NAU8824_REG_FLL5, 1212 + NAU8824_FLL_CLK_SW_MASK, NAU8824_FLL_CLK_SW_REF); 1213 + /* Disable free-running mode */ 1214 + regmap_update_bits(regmap, 1215 + NAU8824_REG_FLL6, NAU8824_DCO_EN, 0); 1216 + if (fll_param->fll_frac) { 1217 + regmap_update_bits(regmap, NAU8824_REG_FLL5, 1218 + NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN | 1219 + NAU8824_FLL_FTR_SW_MASK, 1220 + NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN | 1221 + NAU8824_FLL_FTR_SW_FILTER); 1222 + regmap_update_bits(regmap, NAU8824_REG_FLL6, 1223 + NAU8824_SDM_EN, NAU8824_SDM_EN); 1224 + } else { 1225 + regmap_update_bits(regmap, NAU8824_REG_FLL5, 1226 + NAU8824_FLL_PDB_DAC_EN | NAU8824_FLL_LOOP_FTR_EN | 1227 + NAU8824_FLL_FTR_SW_MASK, NAU8824_FLL_FTR_SW_ACCU); 1228 + regmap_update_bits(regmap, 1229 + NAU8824_REG_FLL6, NAU8824_SDM_EN, 0); 1230 + } 1231 + } 1232 + 1233 + /* freq_out must be 256*Fs in order to achieve the best performance */ 1234 + static int nau8824_set_pll(struct snd_soc_codec *codec, int pll_id, int source, 1235 + unsigned int freq_in, unsigned int freq_out) 1236 + { 1237 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1238 + struct nau8824_fll fll_param; 1239 + int ret, fs; 1240 + 1241 + fs = freq_out / 256; 1242 + ret = nau8824_calc_fll_param(freq_in, fs, &fll_param); 1243 + if (ret < 0) { 1244 + dev_err(nau8824->dev, "Unsupported input clock %d\n", freq_in); 1245 + return ret; 1246 + } 1247 + dev_dbg(nau8824->dev, "mclk_src=%x ratio=%x fll_frac=%x fll_int=%x clk_ref_div=%x\n", 1248 + fll_param.mclk_src, fll_param.ratio, fll_param.fll_frac, 1249 + fll_param.fll_int, fll_param.clk_ref_div); 1250 + 1251 + nau8824_fll_apply(nau8824->regmap, &fll_param); 1252 + mdelay(2); 1253 + regmap_update_bits(nau8824->regmap, NAU8824_REG_CLK_DIVIDER, 1254 + NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_VCO); 1255 + 1256 + return 0; 1257 + } 1258 + 1259 + static int nau8824_config_sysclk(struct nau8824 *nau8824, 1260 + int clk_id, unsigned int freq) 1261 + { 1262 + struct regmap *regmap = nau8824->regmap; 1263 + 1264 + switch (clk_id) { 1265 + case NAU8824_CLK_DIS: 1266 + regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER, 1267 + NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_MCLK); 1268 + regmap_update_bits(regmap, NAU8824_REG_FLL6, 1269 + NAU8824_DCO_EN, 0); 1270 + break; 1271 + 1272 + case NAU8824_CLK_MCLK: 1273 + nau8824_sema_acquire(nau8824, HZ); 1274 + regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER, 1275 + NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_MCLK); 1276 + regmap_update_bits(regmap, NAU8824_REG_FLL6, 1277 + NAU8824_DCO_EN, 0); 1278 + nau8824_sema_release(nau8824); 1279 + break; 1280 + 1281 + case NAU8824_CLK_INTERNAL: 1282 + regmap_update_bits(regmap, NAU8824_REG_FLL6, 1283 + NAU8824_DCO_EN, NAU8824_DCO_EN); 1284 + regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER, 1285 + NAU8824_CLK_SRC_MASK, NAU8824_CLK_SRC_VCO); 1286 + break; 1287 + 1288 + case NAU8824_CLK_FLL_MCLK: 1289 + nau8824_sema_acquire(nau8824, HZ); 1290 + regmap_update_bits(regmap, NAU8824_REG_FLL3, 1291 + NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_MCLK); 1292 + nau8824_sema_release(nau8824); 1293 + break; 1294 + 1295 + case NAU8824_CLK_FLL_BLK: 1296 + nau8824_sema_acquire(nau8824, HZ); 1297 + regmap_update_bits(regmap, NAU8824_REG_FLL3, 1298 + NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_BLK); 1299 + nau8824_sema_release(nau8824); 1300 + break; 1301 + 1302 + case NAU8824_CLK_FLL_FS: 1303 + nau8824_sema_acquire(nau8824, HZ); 1304 + regmap_update_bits(regmap, NAU8824_REG_FLL3, 1305 + NAU8824_FLL_CLK_SRC_MASK, NAU8824_FLL_CLK_SRC_FS); 1306 + nau8824_sema_release(nau8824); 1307 + break; 1308 + 1309 + default: 1310 + dev_err(nau8824->dev, "Invalid clock id (%d)\n", clk_id); 1311 + return -EINVAL; 1312 + } 1313 + 1314 + dev_dbg(nau8824->dev, "Sysclk is %dHz and clock id is %d\n", freq, 1315 + clk_id); 1316 + 1317 + return 0; 1318 + } 1319 + 1320 + static int nau8824_set_sysclk(struct snd_soc_codec *codec, 1321 + int clk_id, int source, unsigned int freq, int dir) 1322 + { 1323 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1324 + 1325 + return nau8824_config_sysclk(nau8824, clk_id, freq); 1326 + } 1327 + 1328 + static void nau8824_resume_setup(struct nau8824 *nau8824) 1329 + { 1330 + nau8824_config_sysclk(nau8824, NAU8824_CLK_DIS, 0); 1331 + if (nau8824->irq) { 1332 + /* Clear all interruption status */ 1333 + nau8824_int_status_clear_all(nau8824->regmap); 1334 + /* Enable jack detection at sleep mode, insertion detection, 1335 + * and ejection detection. 1336 + */ 1337 + regmap_update_bits(nau8824->regmap, NAU8824_REG_ENA_CTRL, 1338 + NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE); 1339 + regmap_update_bits(nau8824->regmap, 1340 + NAU8824_REG_INTERRUPT_SETTING_1, 1341 + NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 1342 + NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN); 1343 + regmap_update_bits(nau8824->regmap, 1344 + NAU8824_REG_INTERRUPT_SETTING, 1345 + NAU8824_IRQ_EJECT_DIS | NAU8824_IRQ_INSERT_DIS, 0); 1346 + } 1347 + } 1348 + 1349 + static int nau8824_set_bias_level(struct snd_soc_codec *codec, 1350 + enum snd_soc_bias_level level) 1351 + { 1352 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1353 + 1354 + switch (level) { 1355 + case SND_SOC_BIAS_ON: 1356 + break; 1357 + 1358 + case SND_SOC_BIAS_PREPARE: 1359 + break; 1360 + 1361 + case SND_SOC_BIAS_STANDBY: 1362 + if (snd_soc_codec_get_bias_level(codec) == SND_SOC_BIAS_OFF) { 1363 + /* Setup codec configuration after resume */ 1364 + nau8824_resume_setup(nau8824); 1365 + } 1366 + break; 1367 + 1368 + case SND_SOC_BIAS_OFF: 1369 + regmap_update_bits(nau8824->regmap, 1370 + NAU8824_REG_INTERRUPT_SETTING, 0x3ff, 0x3ff); 1371 + regmap_update_bits(nau8824->regmap, 1372 + NAU8824_REG_INTERRUPT_SETTING_1, 1373 + NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 0); 1374 + break; 1375 + } 1376 + 1377 + return 0; 1378 + } 1379 + 1380 + static int nau8824_codec_probe(struct snd_soc_codec *codec) 1381 + { 1382 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1383 + struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 1384 + 1385 + nau8824->dapm = dapm; 1386 + 1387 + return 0; 1388 + } 1389 + 1390 + static int __maybe_unused nau8824_suspend(struct snd_soc_codec *codec) 1391 + { 1392 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1393 + 1394 + if (nau8824->irq) { 1395 + disable_irq(nau8824->irq); 1396 + snd_soc_codec_force_bias_level(codec, SND_SOC_BIAS_OFF); 1397 + } 1398 + regcache_cache_only(nau8824->regmap, true); 1399 + regcache_mark_dirty(nau8824->regmap); 1400 + 1401 + return 0; 1402 + } 1403 + 1404 + static int __maybe_unused nau8824_resume(struct snd_soc_codec *codec) 1405 + { 1406 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1407 + 1408 + regcache_cache_only(nau8824->regmap, false); 1409 + regcache_sync(nau8824->regmap); 1410 + if (nau8824->irq) { 1411 + /* Hold semaphore to postpone playback happening 1412 + * until jack detection done. 1413 + */ 1414 + nau8824_sema_acquire(nau8824, 0); 1415 + enable_irq(nau8824->irq); 1416 + } 1417 + 1418 + return 0; 1419 + } 1420 + 1421 + static struct snd_soc_codec_driver nau8824_codec_driver = { 1422 + .probe = nau8824_codec_probe, 1423 + .set_sysclk = nau8824_set_sysclk, 1424 + .set_pll = nau8824_set_pll, 1425 + .set_bias_level = nau8824_set_bias_level, 1426 + .suspend = nau8824_suspend, 1427 + .resume = nau8824_resume, 1428 + .suspend_bias_off = true, 1429 + 1430 + .component_driver = { 1431 + .controls = nau8824_snd_controls, 1432 + .num_controls = ARRAY_SIZE(nau8824_snd_controls), 1433 + .dapm_widgets = nau8824_dapm_widgets, 1434 + .num_dapm_widgets = ARRAY_SIZE(nau8824_dapm_widgets), 1435 + .dapm_routes = nau8824_dapm_routes, 1436 + .num_dapm_routes = ARRAY_SIZE(nau8824_dapm_routes), 1437 + }, 1438 + }; 1439 + 1440 + static const struct snd_soc_dai_ops nau8824_dai_ops = { 1441 + .hw_params = nau8824_hw_params, 1442 + .set_fmt = nau8824_set_fmt, 1443 + }; 1444 + 1445 + #define NAU8824_RATES SNDRV_PCM_RATE_8000_192000 1446 + #define NAU8824_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE \ 1447 + | SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S32_LE) 1448 + 1449 + static struct snd_soc_dai_driver nau8824_dai = { 1450 + .name = NAU8824_CODEC_DAI, 1451 + .playback = { 1452 + .stream_name = "Playback", 1453 + .channels_min = 1, 1454 + .channels_max = 2, 1455 + .rates = NAU8824_RATES, 1456 + .formats = NAU8824_FORMATS, 1457 + }, 1458 + .capture = { 1459 + .stream_name = "Capture", 1460 + .channels_min = 1, 1461 + .channels_max = 2, 1462 + .rates = NAU8824_RATES, 1463 + .formats = NAU8824_FORMATS, 1464 + }, 1465 + .ops = &nau8824_dai_ops, 1466 + }; 1467 + 1468 + static const struct regmap_config nau8824_regmap_config = { 1469 + .val_bits = NAU8824_REG_ADDR_LEN, 1470 + .reg_bits = NAU8824_REG_DATA_LEN, 1471 + 1472 + .max_register = NAU8824_REG_MAX, 1473 + .readable_reg = nau8824_readable_reg, 1474 + .writeable_reg = nau8824_writeable_reg, 1475 + .volatile_reg = nau8824_volatile_reg, 1476 + 1477 + .cache_type = REGCACHE_RBTREE, 1478 + .reg_defaults = nau8824_reg_defaults, 1479 + .num_reg_defaults = ARRAY_SIZE(nau8824_reg_defaults), 1480 + }; 1481 + 1482 + /** 1483 + * nau8824_enable_jack_detect - Specify a jack for event reporting 1484 + * 1485 + * @component: component to register the jack with 1486 + * @jack: jack to use to report headset and button events on 1487 + * 1488 + * After this function has been called the headset insert/remove and button 1489 + * events will be routed to the given jack. Jack can be null to stop 1490 + * reporting. 1491 + */ 1492 + int nau8824_enable_jack_detect(struct snd_soc_codec *codec, 1493 + struct snd_soc_jack *jack) 1494 + { 1495 + struct nau8824 *nau8824 = snd_soc_codec_get_drvdata(codec); 1496 + int ret; 1497 + 1498 + nau8824->jack = jack; 1499 + /* Initiate jack detection work queue */ 1500 + INIT_WORK(&nau8824->jdet_work, nau8824_jdet_work); 1501 + ret = devm_request_threaded_irq(nau8824->dev, nau8824->irq, NULL, 1502 + nau8824_interrupt, IRQF_TRIGGER_LOW | IRQF_ONESHOT, 1503 + "nau8824", nau8824); 1504 + if (ret) { 1505 + dev_err(nau8824->dev, "Cannot request irq %d (%d)\n", 1506 + nau8824->irq, ret); 1507 + } 1508 + 1509 + return ret; 1510 + } 1511 + EXPORT_SYMBOL_GPL(nau8824_enable_jack_detect); 1512 + 1513 + static void nau8824_reset_chip(struct regmap *regmap) 1514 + { 1515 + regmap_write(regmap, NAU8824_REG_RESET, 0x00); 1516 + regmap_write(regmap, NAU8824_REG_RESET, 0x00); 1517 + } 1518 + 1519 + static void nau8824_setup_buttons(struct nau8824 *nau8824) 1520 + { 1521 + struct regmap *regmap = nau8824->regmap; 1522 + 1523 + regmap_update_bits(regmap, NAU8824_REG_SAR_ADC, 1524 + NAU8824_SAR_TRACKING_GAIN_MASK, 1525 + nau8824->sar_voltage << NAU8824_SAR_TRACKING_GAIN_SFT); 1526 + regmap_update_bits(regmap, NAU8824_REG_SAR_ADC, 1527 + NAU8824_SAR_COMPARE_TIME_MASK, 1528 + nau8824->sar_compare_time << NAU8824_SAR_COMPARE_TIME_SFT); 1529 + regmap_update_bits(regmap, NAU8824_REG_SAR_ADC, 1530 + NAU8824_SAR_SAMPLING_TIME_MASK, 1531 + nau8824->sar_sampling_time << NAU8824_SAR_SAMPLING_TIME_SFT); 1532 + 1533 + regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT, 1534 + NAU8824_LEVELS_NR_MASK, 1535 + (nau8824->sar_threshold_num - 1) << NAU8824_LEVELS_NR_SFT); 1536 + regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT, 1537 + NAU8824_HYSTERESIS_MASK, 1538 + nau8824->sar_hysteresis << NAU8824_HYSTERESIS_SFT); 1539 + regmap_update_bits(regmap, NAU8824_REG_VDET_COEFFICIENT, 1540 + NAU8824_SHORTKEY_DEBOUNCE_MASK, 1541 + nau8824->key_debounce << NAU8824_SHORTKEY_DEBOUNCE_SFT); 1542 + 1543 + regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_1, 1544 + (nau8824->sar_threshold[0] << 8) | nau8824->sar_threshold[1]); 1545 + regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_2, 1546 + (nau8824->sar_threshold[2] << 8) | nau8824->sar_threshold[3]); 1547 + regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_3, 1548 + (nau8824->sar_threshold[4] << 8) | nau8824->sar_threshold[5]); 1549 + regmap_write(regmap, NAU8824_REG_VDET_THRESHOLD_4, 1550 + (nau8824->sar_threshold[6] << 8) | nau8824->sar_threshold[7]); 1551 + } 1552 + 1553 + static void nau8824_init_regs(struct nau8824 *nau8824) 1554 + { 1555 + struct regmap *regmap = nau8824->regmap; 1556 + 1557 + /* Enable Bias/VMID/VMID Tieoff */ 1558 + regmap_update_bits(regmap, NAU8824_REG_BIAS_ADJ, 1559 + NAU8824_VMID | NAU8824_VMID_SEL_MASK, NAU8824_VMID | 1560 + (nau8824->vref_impedance << NAU8824_VMID_SEL_SFT)); 1561 + regmap_update_bits(regmap, NAU8824_REG_BOOST, 1562 + NAU8824_GLOBAL_BIAS_EN, NAU8824_GLOBAL_BIAS_EN); 1563 + mdelay(2); 1564 + regmap_update_bits(regmap, NAU8824_REG_MIC_BIAS, 1565 + NAU8824_MICBIAS_VOLTAGE_MASK, nau8824->micbias_voltage); 1566 + /* Disable Boost Driver, Automatic Short circuit protection enable */ 1567 + regmap_update_bits(regmap, NAU8824_REG_BOOST, 1568 + NAU8824_PRECHARGE_DIS | NAU8824_HP_BOOST_DIS | 1569 + NAU8824_HP_BOOST_G_DIS | NAU8824_SHORT_SHUTDOWN_EN, 1570 + NAU8824_PRECHARGE_DIS | NAU8824_HP_BOOST_DIS | 1571 + NAU8824_HP_BOOST_G_DIS | NAU8824_SHORT_SHUTDOWN_EN); 1572 + /* Scaling for ADC and DAC clock */ 1573 + regmap_update_bits(regmap, NAU8824_REG_CLK_DIVIDER, 1574 + NAU8824_CLK_ADC_SRC_MASK | NAU8824_CLK_DAC_SRC_MASK, 1575 + (0x1 << NAU8824_CLK_ADC_SRC_SFT) | 1576 + (0x1 << NAU8824_CLK_DAC_SRC_SFT)); 1577 + regmap_update_bits(regmap, NAU8824_REG_DAC_MUTE_CTRL, 1578 + NAU8824_DAC_ZC_EN, NAU8824_DAC_ZC_EN); 1579 + regmap_update_bits(regmap, NAU8824_REG_ENA_CTRL, 1580 + NAU8824_DAC_CH1_EN | NAU8824_DAC_CH0_EN | 1581 + NAU8824_ADC_CH0_EN | NAU8824_ADC_CH1_EN | 1582 + NAU8824_ADC_CH2_EN | NAU8824_ADC_CH3_EN, 1583 + NAU8824_DAC_CH1_EN | NAU8824_DAC_CH0_EN | 1584 + NAU8824_ADC_CH0_EN | NAU8824_ADC_CH1_EN | 1585 + NAU8824_ADC_CH2_EN | NAU8824_ADC_CH3_EN); 1586 + regmap_update_bits(regmap, NAU8824_REG_CLK_GATING_ENA, 1587 + NAU8824_CLK_ADC_CH23_EN | NAU8824_CLK_ADC_CH01_EN | 1588 + NAU8824_CLK_DAC_CH1_EN | NAU8824_CLK_DAC_CH0_EN | 1589 + NAU8824_CLK_I2S_EN | NAU8824_CLK_GAIN_EN | 1590 + NAU8824_CLK_SAR_EN | NAU8824_CLK_DMIC_CH23_EN, 1591 + NAU8824_CLK_ADC_CH23_EN | NAU8824_CLK_ADC_CH01_EN | 1592 + NAU8824_CLK_DAC_CH1_EN | NAU8824_CLK_DAC_CH0_EN | 1593 + NAU8824_CLK_I2S_EN | NAU8824_CLK_GAIN_EN | 1594 + NAU8824_CLK_SAR_EN | NAU8824_CLK_DMIC_CH23_EN); 1595 + /* Class G timer 64ms */ 1596 + regmap_update_bits(regmap, NAU8824_REG_CLASSG, 1597 + NAU8824_CLASSG_TIMER_MASK, 1598 + 0x20 << NAU8824_CLASSG_TIMER_SFT); 1599 + regmap_update_bits(regmap, NAU8824_REG_TRIM_SETTINGS, 1600 + NAU8824_DRV_CURR_INC, NAU8824_DRV_CURR_INC); 1601 + /* Disable DACR/L power */ 1602 + regmap_update_bits(regmap, NAU8824_REG_CHARGE_PUMP_CONTROL, 1603 + NAU8824_SPKR_PULL_DOWN | NAU8824_SPKL_PULL_DOWN | 1604 + NAU8824_POWER_DOWN_DACR | NAU8824_POWER_DOWN_DACL, 1605 + NAU8824_SPKR_PULL_DOWN | NAU8824_SPKL_PULL_DOWN | 1606 + NAU8824_POWER_DOWN_DACR | NAU8824_POWER_DOWN_DACL); 1607 + /* Enable TESTDAC. This sets the analog DAC inputs to a '0' input 1608 + * signal to avoid any glitches due to power up transients in both 1609 + * the analog and digital DAC circuit. 1610 + */ 1611 + regmap_update_bits(regmap, NAU8824_REG_ENABLE_LO, 1612 + NAU8824_TEST_DAC_EN, NAU8824_TEST_DAC_EN); 1613 + /* Config L/R channel */ 1614 + regmap_update_bits(regmap, NAU8824_REG_DAC_CH0_DGAIN_CTRL, 1615 + NAU8824_DAC_CH0_SEL_MASK, NAU8824_DAC_CH0_SEL_I2S0); 1616 + regmap_update_bits(regmap, NAU8824_REG_DAC_CH1_DGAIN_CTRL, 1617 + NAU8824_DAC_CH1_SEL_MASK, NAU8824_DAC_CH1_SEL_I2S1); 1618 + regmap_update_bits(regmap, NAU8824_REG_ENABLE_LO, 1619 + NAU8824_DACR_HPR_EN | NAU8824_DACL_HPL_EN, 1620 + NAU8824_DACR_HPR_EN | NAU8824_DACL_HPL_EN); 1621 + /* Default oversampling/decimations settings are unusable 1622 + * (audible hiss). Set it to something better. 1623 + */ 1624 + regmap_update_bits(regmap, NAU8824_REG_ADC_FILTER_CTRL, 1625 + NAU8824_ADC_SYNC_DOWN_MASK, NAU8824_ADC_SYNC_DOWN_64); 1626 + regmap_update_bits(regmap, NAU8824_REG_DAC_FILTER_CTRL_1, 1627 + NAU8824_DAC_CICCLP_OFF | NAU8824_DAC_OVERSAMPLE_MASK, 1628 + NAU8824_DAC_CICCLP_OFF | NAU8824_DAC_OVERSAMPLE_64); 1629 + /* Class D gain 9db for 1R and 2L */ 1630 + regmap_update_bits(regmap, NAU8824_REG_CLASSD_GAIN_1, 1631 + NAU8824_CLASSD_GAIN_1R_MASK, 1632 + (0xa << NAU8824_CLASSD_GAIN_1R_SFT)); 1633 + regmap_update_bits(regmap, NAU8824_REG_CLASSD_GAIN_2, 1634 + NAU8824_CLASSD_GAIN_2L_MASK, 0xa); 1635 + /* DAC clock delay 2ns, VREF */ 1636 + regmap_update_bits(regmap, NAU8824_REG_RDAC, 1637 + NAU8824_RDAC_CLK_DELAY_MASK | NAU8824_RDAC_VREF_MASK, 1638 + (0x2 << NAU8824_RDAC_CLK_DELAY_SFT) | 1639 + (0x3 << NAU8824_RDAC_VREF_SFT)); 1640 + /* PGA input mode selection */ 1641 + regmap_update_bits(regmap, NAU8824_REG_FEPGA, 1642 + NAU8824_FEPGA_MODEL_SHORT_EN | NAU8824_FEPGA_MODER_SHORT_EN, 1643 + NAU8824_FEPGA_MODEL_SHORT_EN | NAU8824_FEPGA_MODER_SHORT_EN); 1644 + /* Digital microphone control */ 1645 + regmap_update_bits(regmap, NAU8824_REG_ANALOG_CONTROL_1, 1646 + NAU8824_DMIC_CLK_DRV_STRG | NAU8824_DMIC_CLK_SLEW_FAST, 1647 + NAU8824_DMIC_CLK_DRV_STRG | NAU8824_DMIC_CLK_SLEW_FAST); 1648 + regmap_update_bits(regmap, NAU8824_REG_JACK_DET_CTRL, 1649 + NAU8824_JACK_LOGIC, 1650 + /* jkdet_polarity - 1 is for active-low */ 1651 + nau8824->jkdet_polarity ? 0 : NAU8824_JACK_LOGIC); 1652 + regmap_update_bits(regmap, 1653 + NAU8824_REG_JACK_DET_CTRL, NAU8824_JACK_EJECT_DT_MASK, 1654 + (nau8824->jack_eject_debounce << NAU8824_JACK_EJECT_DT_SFT)); 1655 + if (nau8824->sar_threshold_num) 1656 + nau8824_setup_buttons(nau8824); 1657 + } 1658 + 1659 + static int nau8824_setup_irq(struct nau8824 *nau8824) 1660 + { 1661 + /* Disable interruption before codec initiation done */ 1662 + regmap_update_bits(nau8824->regmap, NAU8824_REG_ENA_CTRL, 1663 + NAU8824_JD_SLEEP_MODE, NAU8824_JD_SLEEP_MODE); 1664 + regmap_update_bits(nau8824->regmap, 1665 + NAU8824_REG_INTERRUPT_SETTING, 0x3ff, 0x3ff); 1666 + regmap_update_bits(nau8824->regmap, NAU8824_REG_INTERRUPT_SETTING_1, 1667 + NAU8824_IRQ_EJECT_EN | NAU8824_IRQ_INSERT_EN, 0); 1668 + 1669 + return 0; 1670 + } 1671 + 1672 + static void nau8824_print_device_properties(struct nau8824 *nau8824) 1673 + { 1674 + struct device *dev = nau8824->dev; 1675 + int i; 1676 + 1677 + dev_dbg(dev, "jkdet-polarity: %d\n", nau8824->jkdet_polarity); 1678 + dev_dbg(dev, "micbias-voltage: %d\n", nau8824->micbias_voltage); 1679 + dev_dbg(dev, "vref-impedance: %d\n", nau8824->vref_impedance); 1680 + 1681 + dev_dbg(dev, "sar-threshold-num: %d\n", nau8824->sar_threshold_num); 1682 + for (i = 0; i < nau8824->sar_threshold_num; i++) 1683 + dev_dbg(dev, "sar-threshold[%d]=%x\n", i, 1684 + nau8824->sar_threshold[i]); 1685 + 1686 + dev_dbg(dev, "sar-hysteresis: %d\n", nau8824->sar_hysteresis); 1687 + dev_dbg(dev, "sar-voltage: %d\n", nau8824->sar_voltage); 1688 + dev_dbg(dev, "sar-compare-time: %d\n", nau8824->sar_compare_time); 1689 + dev_dbg(dev, "sar-sampling-time: %d\n", nau8824->sar_sampling_time); 1690 + dev_dbg(dev, "short-key-debounce: %d\n", nau8824->key_debounce); 1691 + dev_dbg(dev, "jack-eject-debounce: %d\n", 1692 + nau8824->jack_eject_debounce); 1693 + } 1694 + 1695 + static int nau8824_read_device_properties(struct device *dev, 1696 + struct nau8824 *nau8824) { 1697 + int ret; 1698 + 1699 + ret = device_property_read_u32(dev, "nuvoton,jkdet-polarity", 1700 + &nau8824->jkdet_polarity); 1701 + if (ret) 1702 + nau8824->jkdet_polarity = 1; 1703 + ret = device_property_read_u32(dev, "nuvoton,micbias-voltage", 1704 + &nau8824->micbias_voltage); 1705 + if (ret) 1706 + nau8824->micbias_voltage = 6; 1707 + ret = device_property_read_u32(dev, "nuvoton,vref-impedance", 1708 + &nau8824->vref_impedance); 1709 + if (ret) 1710 + nau8824->vref_impedance = 2; 1711 + ret = device_property_read_u32(dev, "nuvoton,sar-threshold-num", 1712 + &nau8824->sar_threshold_num); 1713 + if (ret) 1714 + nau8824->sar_threshold_num = 4; 1715 + ret = device_property_read_u32_array(dev, "nuvoton,sar-threshold", 1716 + nau8824->sar_threshold, nau8824->sar_threshold_num); 1717 + if (ret) { 1718 + nau8824->sar_threshold[0] = 0x0a; 1719 + nau8824->sar_threshold[1] = 0x14; 1720 + nau8824->sar_threshold[2] = 0x26; 1721 + nau8824->sar_threshold[3] = 0x73; 1722 + } 1723 + ret = device_property_read_u32(dev, "nuvoton,sar-hysteresis", 1724 + &nau8824->sar_hysteresis); 1725 + if (ret) 1726 + nau8824->sar_hysteresis = 0; 1727 + ret = device_property_read_u32(dev, "nuvoton,sar-voltage", 1728 + &nau8824->sar_voltage); 1729 + if (ret) 1730 + nau8824->sar_voltage = 6; 1731 + ret = device_property_read_u32(dev, "nuvoton,sar-compare-time", 1732 + &nau8824->sar_compare_time); 1733 + if (ret) 1734 + nau8824->sar_compare_time = 1; 1735 + ret = device_property_read_u32(dev, "nuvoton,sar-sampling-time", 1736 + &nau8824->sar_sampling_time); 1737 + if (ret) 1738 + nau8824->sar_sampling_time = 1; 1739 + ret = device_property_read_u32(dev, "nuvoton,short-key-debounce", 1740 + &nau8824->key_debounce); 1741 + if (ret) 1742 + nau8824->key_debounce = 0; 1743 + ret = device_property_read_u32(dev, "nuvoton,jack-eject-debounce", 1744 + &nau8824->jack_eject_debounce); 1745 + if (ret) 1746 + nau8824->jack_eject_debounce = 1; 1747 + 1748 + return 0; 1749 + } 1750 + 1751 + static int nau8824_i2c_probe(struct i2c_client *i2c, 1752 + const struct i2c_device_id *id) 1753 + { 1754 + struct device *dev = &i2c->dev; 1755 + struct nau8824 *nau8824 = dev_get_platdata(dev); 1756 + int ret, value; 1757 + 1758 + if (!nau8824) { 1759 + nau8824 = devm_kzalloc(dev, sizeof(*nau8824), GFP_KERNEL); 1760 + if (!nau8824) 1761 + return -ENOMEM; 1762 + ret = nau8824_read_device_properties(dev, nau8824); 1763 + if (ret) 1764 + return ret; 1765 + } 1766 + i2c_set_clientdata(i2c, nau8824); 1767 + 1768 + nau8824->regmap = devm_regmap_init_i2c(i2c, &nau8824_regmap_config); 1769 + if (IS_ERR(nau8824->regmap)) 1770 + return PTR_ERR(nau8824->regmap); 1771 + nau8824->dev = dev; 1772 + nau8824->irq = i2c->irq; 1773 + sema_init(&nau8824->jd_sem, 1); 1774 + 1775 + nau8824_print_device_properties(nau8824); 1776 + 1777 + ret = regmap_read(nau8824->regmap, NAU8824_REG_I2C_DEVICE_ID, &value); 1778 + if (ret < 0) { 1779 + dev_err(dev, "Failed to read device id from the NAU8824: %d\n", 1780 + ret); 1781 + return ret; 1782 + } 1783 + nau8824_reset_chip(nau8824->regmap); 1784 + nau8824_init_regs(nau8824); 1785 + 1786 + if (i2c->irq) 1787 + nau8824_setup_irq(nau8824); 1788 + 1789 + return snd_soc_register_codec(dev, 1790 + &nau8824_codec_driver, &nau8824_dai, 1); 1791 + } 1792 + 1793 + 1794 + static int nau8824_i2c_remove(struct i2c_client *client) 1795 + { 1796 + snd_soc_unregister_codec(&client->dev); 1797 + return 0; 1798 + } 1799 + 1800 + static const struct i2c_device_id nau8824_i2c_ids[] = { 1801 + { "nau8824", 0 }, 1802 + { } 1803 + }; 1804 + MODULE_DEVICE_TABLE(i2c, nau8824_i2c_ids); 1805 + 1806 + #ifdef CONFIG_OF 1807 + static const struct of_device_id nau8824_of_ids[] = { 1808 + { .compatible = "nuvoton,nau8824", }, 1809 + {} 1810 + }; 1811 + MODULE_DEVICE_TABLE(of, nau8824_of_ids); 1812 + #endif 1813 + 1814 + #ifdef CONFIG_ACPI 1815 + static const struct acpi_device_id nau8824_acpi_match[] = { 1816 + { "10508824", 0 }, 1817 + {}, 1818 + }; 1819 + MODULE_DEVICE_TABLE(acpi, nau8824_acpi_match); 1820 + #endif 1821 + 1822 + static struct i2c_driver nau8824_i2c_driver = { 1823 + .driver = { 1824 + .name = "nau8824", 1825 + .of_match_table = of_match_ptr(nau8824_of_ids), 1826 + .acpi_match_table = ACPI_PTR(nau8824_acpi_match), 1827 + }, 1828 + .probe = nau8824_i2c_probe, 1829 + .remove = nau8824_i2c_remove, 1830 + .id_table = nau8824_i2c_ids, 1831 + }; 1832 + module_i2c_driver(nau8824_i2c_driver); 1833 + 1834 + 1835 + MODULE_DESCRIPTION("ASoC NAU88L24 driver"); 1836 + MODULE_AUTHOR("John Hsu <KCHSU0@nuvoton.com>"); 1837 + MODULE_LICENSE("GPL v2");
+466
sound/soc/codecs/nau8824.h
··· 1 + /* 2 + * NAU88L24 ALSA SoC audio driver 3 + * 4 + * Copyright 2016 Nuvoton Technology Corp. 5 + * Author: John Hsu <KCHSU0@nuvoton.com> 6 + * 7 + * This program is free software; you can redistribute it and/or modify 8 + * it under the terms of the GNU General Public License version 2 as 9 + * published by the Free Software Foundation. 10 + */ 11 + 12 + #ifndef __NAU8824_H__ 13 + #define __NAU8824_H__ 14 + 15 + #define NAU8824_REG_RESET 0x00 16 + #define NAU8824_REG_ENA_CTRL 0x01 17 + #define NAU8824_REG_CLK_GATING_ENA 0x02 18 + #define NAU8824_REG_CLK_DIVIDER 0x03 19 + #define NAU8824_REG_FLL1 0x04 20 + #define NAU8824_REG_FLL2 0x05 21 + #define NAU8824_REG_FLL3 0x06 22 + #define NAU8824_REG_FLL4 0x07 23 + #define NAU8824_REG_FLL5 0x08 24 + #define NAU8824_REG_FLL6 0x09 25 + #define NAU8824_REG_FLL_VCO_RSV 0x0A 26 + #define NAU8824_REG_JACK_DET_CTRL 0x0D 27 + #define NAU8824_REG_INTERRUPT_SETTING_1 0x0F 28 + #define NAU8824_REG_IRQ 0x10 29 + #define NAU8824_REG_CLEAR_INT_REG 0x11 30 + #define NAU8824_REG_INTERRUPT_SETTING 0x12 31 + #define NAU8824_REG_SAR_ADC 0x13 32 + #define NAU8824_REG_VDET_COEFFICIENT 0x14 33 + #define NAU8824_REG_VDET_THRESHOLD_1 0x15 34 + #define NAU8824_REG_VDET_THRESHOLD_2 0x16 35 + #define NAU8824_REG_VDET_THRESHOLD_3 0x17 36 + #define NAU8824_REG_VDET_THRESHOLD_4 0x18 37 + #define NAU8824_REG_GPIO_SEL 0x1A 38 + #define NAU8824_REG_PORT0_I2S_PCM_CTRL_1 0x1C 39 + #define NAU8824_REG_PORT0_I2S_PCM_CTRL_2 0x1D 40 + #define NAU8824_REG_PORT0_LEFT_TIME_SLOT 0x1E 41 + #define NAU8824_REG_PORT0_RIGHT_TIME_SLOT 0x1F 42 + #define NAU8824_REG_TDM_CTRL 0x20 43 + #define NAU8824_REG_ADC_HPF_FILTER 0x23 44 + #define NAU8824_REG_ADC_FILTER_CTRL 0x24 45 + #define NAU8824_REG_DAC_FILTER_CTRL_1 0x25 46 + #define NAU8824_REG_DAC_FILTER_CTRL_2 0x26 47 + #define NAU8824_REG_NOTCH_FILTER_1 0x27 48 + #define NAU8824_REG_NOTCH_FILTER_2 0x28 49 + #define NAU8824_REG_EQ1_LOW 0x29 50 + #define NAU8824_REG_EQ2_EQ3 0x2A 51 + #define NAU8824_REG_EQ4_EQ5 0x2B 52 + #define NAU8824_REG_ADC_CH0_DGAIN_CTRL 0x2D 53 + #define NAU8824_REG_ADC_CH1_DGAIN_CTRL 0x2E 54 + #define NAU8824_REG_ADC_CH2_DGAIN_CTRL 0x2F 55 + #define NAU8824_REG_ADC_CH3_DGAIN_CTRL 0x30 56 + #define NAU8824_REG_DAC_MUTE_CTRL 0x31 57 + #define NAU8824_REG_DAC_CH0_DGAIN_CTRL 0x32 58 + #define NAU8824_REG_DAC_CH1_DGAIN_CTRL 0x33 59 + #define NAU8824_REG_ADC_TO_DAC_ST 0x34 60 + #define NAU8824_REG_DRC_KNEE_IP12_ADC_CH01 0x38 61 + #define NAU8824_REG_DRC_KNEE_IP34_ADC_CH01 0x39 62 + #define NAU8824_REG_DRC_SLOPE_ADC_CH01 0x3A 63 + #define NAU8824_REG_DRC_ATKDCY_ADC_CH01 0x3B 64 + #define NAU8824_REG_DRC_KNEE_IP12_ADC_CH23 0x3C 65 + #define NAU8824_REG_DRC_KNEE_IP34_ADC_CH23 0x3D 66 + #define NAU8824_REG_DRC_SLOPE_ADC_CH23 0x3E 67 + #define NAU8824_REG_DRC_ATKDCY_ADC_CH23 0x3F 68 + #define NAU8824_REG_DRC_GAINL_ADC0 0x40 69 + #define NAU8824_REG_DRC_GAINL_ADC1 0x41 70 + #define NAU8824_REG_DRC_GAINL_ADC2 0x42 71 + #define NAU8824_REG_DRC_GAINL_ADC3 0x43 72 + #define NAU8824_REG_DRC_KNEE_IP12_DAC 0x45 73 + #define NAU8824_REG_DRC_KNEE_IP34_DAC 0x46 74 + #define NAU8824_REG_DRC_SLOPE_DAC 0x47 75 + #define NAU8824_REG_DRC_ATKDCY_DAC 0x48 76 + #define NAU8824_REG_DRC_GAIN_DAC_CH0 0x49 77 + #define NAU8824_REG_DRC_GAIN_DAC_CH1 0x4A 78 + #define NAU8824_REG_MODE 0x4C 79 + #define NAU8824_REG_MODE1 0x4D 80 + #define NAU8824_REG_MODE2 0x4E 81 + #define NAU8824_REG_CLASSG 0x50 82 + #define NAU8824_REG_OTP_EFUSE 0x51 83 + #define NAU8824_REG_OTPDOUT_1 0x53 84 + #define NAU8824_REG_OTPDOUT_2 0x54 85 + #define NAU8824_REG_MISC_CTRL 0x55 86 + #define NAU8824_REG_I2C_TIMEOUT 0x56 87 + #define NAU8824_REG_TEST_MODE 0x57 88 + #define NAU8824_REG_I2C_DEVICE_ID 0x58 89 + #define NAU8824_REG_SAR_ADC_DATA_OUT 0x59 90 + #define NAU8824_REG_BIAS_ADJ 0x66 91 + #define NAU8824_REG_PGA_GAIN 0x67 92 + #define NAU8824_REG_TRIM_SETTINGS 0x68 93 + #define NAU8824_REG_ANALOG_CONTROL_1 0x69 94 + #define NAU8824_REG_ANALOG_CONTROL_2 0x6A 95 + #define NAU8824_REG_ENABLE_LO 0x6B 96 + #define NAU8824_REG_GAIN_LO 0x6C 97 + #define NAU8824_REG_CLASSD_GAIN_1 0x6D 98 + #define NAU8824_REG_CLASSD_GAIN_2 0x6E 99 + #define NAU8824_REG_ANALOG_ADC_1 0x71 100 + #define NAU8824_REG_ANALOG_ADC_2 0x72 101 + #define NAU8824_REG_RDAC 0x73 102 + #define NAU8824_REG_MIC_BIAS 0x74 103 + #define NAU8824_REG_HS_VOLUME_CONTROL 0x75 104 + #define NAU8824_REG_BOOST 0x76 105 + #define NAU8824_REG_FEPGA 0x77 106 + #define NAU8824_REG_FEPGA_II 0x78 107 + #define NAU8824_REG_FEPGA_SE 0x79 108 + #define NAU8824_REG_FEPGA_ATTENUATION 0x7A 109 + #define NAU8824_REG_ATT_PORT0 0x7B 110 + #define NAU8824_REG_ATT_PORT1 0x7C 111 + #define NAU8824_REG_POWER_UP_CONTROL 0x7F 112 + #define NAU8824_REG_CHARGE_PUMP_CONTROL 0x80 113 + #define NAU8824_REG_CHARGE_PUMP_INPUT 0x81 114 + #define NAU8824_REG_MAX NAU8824_REG_CHARGE_PUMP_INPUT 115 + /* 16-bit control register address, and 16-bits control register data */ 116 + #define NAU8824_REG_ADDR_LEN 16 117 + #define NAU8824_REG_DATA_LEN 16 118 + 119 + 120 + /* ENA_CTRL (0x1) */ 121 + #define NAU8824_DMIC_LCH_EDGE_CH23 (0x1 << 12) 122 + #define NAU8824_DMIC_LCH_EDGE_CH01 (0x1 << 11) 123 + #define NAU8824_JD_SLEEP_MODE (0x1 << 10) 124 + #define NAU8824_ADC_CH3_DMIC_SFT 9 125 + #define NAU8824_ADC_CH3_DMIC_EN (0x1 << NAU8824_ADC_CH3_DMIC_SFT) 126 + #define NAU8824_ADC_CH2_DMIC_SFT 8 127 + #define NAU8824_ADC_CH2_DMIC_EN (0x1 << NAU8824_ADC_CH2_DMIC_SFT) 128 + #define NAU8824_ADC_CH1_DMIC_SFT 7 129 + #define NAU8824_ADC_CH1_DMIC_EN (0x1 << NAU8824_ADC_CH1_DMIC_SFT) 130 + #define NAU8824_ADC_CH0_DMIC_SFT 6 131 + #define NAU8824_ADC_CH0_DMIC_EN (0x1 << NAU8824_ADC_CH0_DMIC_SFT) 132 + #define NAU8824_DAC_CH1_EN (0x1 << 5) 133 + #define NAU8824_DAC_CH0_EN (0x1 << 4) 134 + #define NAU8824_ADC_CH3_EN (0x1 << 3) 135 + #define NAU8824_ADC_CH2_EN (0x1 << 2) 136 + #define NAU8824_ADC_CH1_EN (0x1 << 1) 137 + #define NAU8824_ADC_CH0_EN 0x1 138 + 139 + /* CLK_GATING_ENA (0x02) */ 140 + #define NAU8824_CLK_ADC_CH23_EN (0x1 << 15) 141 + #define NAU8824_CLK_ADC_CH01_EN (0x1 << 14) 142 + #define NAU8824_CLK_DAC_CH1_EN (0x1 << 13) 143 + #define NAU8824_CLK_DAC_CH0_EN (0x1 << 12) 144 + #define NAU8824_CLK_I2S_EN (0x1 << 7) 145 + #define NAU8824_CLK_GAIN_EN (0x1 << 5) 146 + #define NAU8824_CLK_SAR_EN (0x1 << 3) 147 + #define NAU8824_CLK_DMIC_CH23_EN (0x1 << 1) 148 + 149 + /* CLK_DIVIDER (0x3) */ 150 + #define NAU8824_CLK_SRC_SFT 15 151 + #define NAU8824_CLK_SRC_MASK (1 << NAU8824_CLK_SRC_SFT) 152 + #define NAU8824_CLK_SRC_VCO (1 << NAU8824_CLK_SRC_SFT) 153 + #define NAU8824_CLK_SRC_MCLK (0 << NAU8824_CLK_SRC_SFT) 154 + #define NAU8824_CLK_MCLK_SRC_MASK (0xf << 0) 155 + #define NAU8824_CLK_DMIC_SRC_SFT 10 156 + #define NAU8824_CLK_DMIC_SRC_MASK (0x7 << NAU8824_CLK_DMIC_SRC_SFT) 157 + #define NAU8824_CLK_ADC_SRC_SFT 6 158 + #define NAU8824_CLK_ADC_SRC_MASK (0x3 << NAU8824_CLK_ADC_SRC_SFT) 159 + #define NAU8824_CLK_DAC_SRC_SFT 4 160 + #define NAU8824_CLK_DAC_SRC_MASK (0x3 << NAU8824_CLK_DAC_SRC_SFT) 161 + 162 + /* FLL1 (0x04) */ 163 + #define NAU8824_FLL_RATIO_MASK (0x7f << 0) 164 + 165 + /* FLL3 (0x06) */ 166 + #define NAU8824_FLL_INTEGER_MASK (0x3ff << 0) 167 + #define NAU8824_FLL_CLK_SRC_SFT 10 168 + #define NAU8824_FLL_CLK_SRC_MASK (0x3 << NAU8824_FLL_CLK_SRC_SFT) 169 + #define NAU8824_FLL_CLK_SRC_MCLK (0 << NAU8824_FLL_CLK_SRC_SFT) 170 + #define NAU8824_FLL_CLK_SRC_BLK (0x2 << NAU8824_FLL_CLK_SRC_SFT) 171 + #define NAU8824_FLL_CLK_SRC_FS (0x3 << NAU8824_FLL_CLK_SRC_SFT) 172 + 173 + /* FLL4 (0x07) */ 174 + #define NAU8824_FLL_REF_DIV_SFT 10 175 + #define NAU8824_FLL_REF_DIV_MASK (0x3 << NAU8824_FLL_REF_DIV_SFT) 176 + 177 + /* FLL5 (0x08) */ 178 + #define NAU8824_FLL_PDB_DAC_EN (0x1 << 15) 179 + #define NAU8824_FLL_LOOP_FTR_EN (0x1 << 14) 180 + #define NAU8824_FLL_CLK_SW_MASK (0x1 << 13) 181 + #define NAU8824_FLL_CLK_SW_N2 (0x1 << 13) 182 + #define NAU8824_FLL_CLK_SW_REF (0x0 << 13) 183 + #define NAU8824_FLL_FTR_SW_MASK (0x1 << 12) 184 + #define NAU8824_FLL_FTR_SW_ACCU (0x1 << 12) 185 + #define NAU8824_FLL_FTR_SW_FILTER (0x0 << 12) 186 + 187 + /* FLL6 (0x9) */ 188 + #define NAU8824_DCO_EN (0x1 << 15) 189 + #define NAU8824_SDM_EN (0x1 << 14) 190 + 191 + /* IRQ (0x10) */ 192 + #define NAU8824_SHORT_CIRCUIT_IRQ (0x1 << 7) 193 + #define NAU8824_IMPEDANCE_MEAS_IRQ (0x1 << 6) 194 + #define NAU8824_KEY_RELEASE_IRQ (0x1 << 5) 195 + #define NAU8824_KEY_LONG_PRESS_IRQ (0x1 << 4) 196 + #define NAU8824_KEY_SHORT_PRESS_IRQ (0x1 << 3) 197 + #define NAU8824_JACK_EJECTION_DETECTED (0x1 << 1) 198 + #define NAU8824_JACK_INSERTION_DETECTED 0x1 199 + 200 + /* JACK_DET_CTRL (0x0D) */ 201 + #define NAU8824_JACK_EJECT_DT_SFT 2 202 + #define NAU8824_JACK_EJECT_DT_MASK (0x3 << NAU8824_JACK_EJECT_DT_SFT) 203 + #define NAU8824_JACK_LOGIC 0x1 204 + 205 + 206 + /* INTERRUPT_SETTING_1 (0x0F) */ 207 + #define NAU8824_IRQ_EJECT_EN (0x1 << 9) 208 + #define NAU8824_IRQ_INSERT_EN (0x1 << 8) 209 + 210 + /* INTERRUPT_SETTING (0x12) */ 211 + #define NAU8824_IRQ_KEY_RELEASE_DIS (0x1 << 5) 212 + #define NAU8824_IRQ_KEY_SHORT_PRESS_DIS (0x1 << 3) 213 + #define NAU8824_IRQ_EJECT_DIS (0x1 << 1) 214 + #define NAU8824_IRQ_INSERT_DIS 0x1 215 + 216 + /* SAR_ADC (0x13) */ 217 + #define NAU8824_SAR_ADC_EN_SFT 12 218 + #define NAU8824_SAR_TRACKING_GAIN_SFT 8 219 + #define NAU8824_SAR_TRACKING_GAIN_MASK (0x7 << NAU8824_SAR_TRACKING_GAIN_SFT) 220 + #define NAU8824_SAR_COMPARE_TIME_SFT 2 221 + #define NAU8824_SAR_COMPARE_TIME_MASK (3 << 2) 222 + #define NAU8824_SAR_SAMPLING_TIME_SFT 0 223 + #define NAU8824_SAR_SAMPLING_TIME_MASK (3 << 0) 224 + 225 + /* VDET_COEFFICIENT (0x14) */ 226 + #define NAU8824_SHORTKEY_DEBOUNCE_SFT 12 227 + #define NAU8824_SHORTKEY_DEBOUNCE_MASK (0x3 << NAU8824_SHORTKEY_DEBOUNCE_SFT) 228 + #define NAU8824_LEVELS_NR_SFT 8 229 + #define NAU8824_LEVELS_NR_MASK (0x7 << 8) 230 + #define NAU8824_HYSTERESIS_SFT 0 231 + #define NAU8824_HYSTERESIS_MASK 0xf 232 + 233 + /* PORT0_I2S_PCM_CTRL_1 (0x1C) */ 234 + #define NAU8824_I2S_BP_SFT 7 235 + #define NAU8824_I2S_BP_MASK (1 << NAU8824_I2S_BP_SFT) 236 + #define NAU8824_I2S_BP_INV (1 << NAU8824_I2S_BP_SFT) 237 + #define NAU8824_I2S_PCMB_SFT 6 238 + #define NAU8824_I2S_PCMB_EN (1 << NAU8824_I2S_PCMB_SFT) 239 + #define NAU8824_I2S_DL_SFT 2 240 + #define NAU8824_I2S_DL_MASK (0x3 << NAU8824_I2S_DL_SFT) 241 + #define NAU8824_I2S_DL_16 (0 << NAU8824_I2S_DL_SFT) 242 + #define NAU8824_I2S_DL_20 (1 << NAU8824_I2S_DL_SFT) 243 + #define NAU8824_I2S_DL_24 (2 << NAU8824_I2S_DL_SFT) 244 + #define NAU8824_I2S_DL_32 (3 << NAU8824_I2S_DL_SFT) 245 + #define NAU8824_I2S_DF_MASK 0x3 246 + #define NAU8824_I2S_DF_RIGTH 0 247 + #define NAU8824_I2S_DF_LEFT 1 248 + #define NAU8824_I2S_DF_I2S 2 249 + #define NAU8824_I2S_DF_PCM_AB 3 250 + 251 + 252 + /* PORT0_I2S_PCM_CTRL_2 (0x1D) */ 253 + #define NAU8824_I2S_LRC_DIV_SFT 12 254 + #define NAU8824_I2S_LRC_DIV_MASK (0x3 << NAU8824_I2S_LRC_DIV_SFT) 255 + #define NAU8824_I2S_MS_SFT 3 256 + #define NAU8824_I2S_MS_MASK (1 << NAU8824_I2S_MS_SFT) 257 + #define NAU8824_I2S_MS_MASTER (1 << NAU8824_I2S_MS_SFT) 258 + #define NAU8824_I2S_MS_SLAVE (0 << NAU8824_I2S_MS_SFT) 259 + #define NAU8824_I2S_BLK_DIV_MASK 0x7 260 + 261 + /* ADC_FILTER_CTRL (0x24) */ 262 + #define NAU8824_ADC_SYNC_DOWN_MASK 0x3 263 + #define NAU8824_ADC_SYNC_DOWN_32 0 264 + #define NAU8824_ADC_SYNC_DOWN_64 1 265 + #define NAU8824_ADC_SYNC_DOWN_128 2 266 + #define NAU8824_ADC_SYNC_DOWN_256 3 267 + 268 + /* DAC_FILTER_CTRL_1 (0x25) */ 269 + #define NAU8824_DAC_CICCLP_OFF (0x1 << 7) 270 + #define NAU8824_DAC_OVERSAMPLE_MASK 0x7 271 + #define NAU8824_DAC_OVERSAMPLE_64 0 272 + #define NAU8824_DAC_OVERSAMPLE_256 1 273 + #define NAU8824_DAC_OVERSAMPLE_128 2 274 + #define NAU8824_DAC_OVERSAMPLE_32 4 275 + 276 + /* DAC_MUTE_CTRL (0x31) */ 277 + #define NAU8824_DAC_CH01_MIX 0x3 278 + #define NAU8824_DAC_ZC_EN (0x1 << 11) 279 + 280 + /* DAC_CH0_DGAIN_CTRL (0x32) */ 281 + #define NAU8824_DAC_CH0_SEL_SFT 9 282 + #define NAU8824_DAC_CH0_SEL_MASK (0x1 << NAU8824_DAC_CH0_SEL_SFT) 283 + #define NAU8824_DAC_CH0_SEL_I2S0 (0x0 << NAU8824_DAC_CH0_SEL_SFT) 284 + #define NAU8824_DAC_CH0_SEL_I2S1 (0x1 << NAU8824_DAC_CH0_SEL_SFT) 285 + #define NAU8824_DAC_CH0_VOL_MASK 0x1ff 286 + 287 + /* DAC_CH1_DGAIN_CTRL (0x33) */ 288 + #define NAU8824_DAC_CH1_SEL_SFT 9 289 + #define NAU8824_DAC_CH1_SEL_MASK (0x1 << NAU8824_DAC_CH1_SEL_SFT) 290 + #define NAU8824_DAC_CH1_SEL_I2S0 (0x0 << NAU8824_DAC_CH1_SEL_SFT) 291 + #define NAU8824_DAC_CH1_SEL_I2S1 (0x1 << NAU8824_DAC_CH1_SEL_SFT) 292 + #define NAU8824_DAC_CH1_VOL_MASK 0x1ff 293 + 294 + /* CLASSG (0x50) */ 295 + #define NAU8824_CLASSG_TIMER_SFT 8 296 + #define NAU8824_CLASSG_TIMER_MASK (0x3f << NAU8824_CLASSG_TIMER_SFT) 297 + #define NAU8824_CLASSG_LDAC_EN_SFT 2 298 + #define NAU8824_CLASSG_RDAC_EN_SFT 1 299 + #define NAU8824_CLASSG_EN_SFT 0 300 + 301 + /* SAR_ADC_DATA_OUT (0x59) */ 302 + #define NAU8824_SAR_ADC_DATA_MASK 0xff 303 + 304 + /* BIAS_ADJ (0x66) */ 305 + #define NAU8824_VMID (1 << 6) 306 + #define NAU8824_VMID_SEL_SFT 4 307 + #define NAU8824_VMID_SEL_MASK (3 << NAU8824_VMID_SEL_SFT) 308 + #define NAU8824_DMIC2_EN_SFT 3 309 + #define NAU8824_DMIC1_EN_SFT 2 310 + 311 + /* TRIM_SETTINGS (0x68) */ 312 + #define NAU8824_DRV_CURR_INC (1 << 15) 313 + 314 + /* ANALOG_CONTROL_1 (0x69) */ 315 + #define NAU8824_DMIC_CLK_DRV_STRG (1 << 3) 316 + #define NAU8824_DMIC_CLK_SLEW_FAST (0x7) 317 + 318 + /* ANALOG_CONTROL_2 (0x6A) */ 319 + #define NAU8824_CLASSD_CLAMP_DIS_SFT 3 320 + #define NAU8824_CLASSD_CLAMP_DIS (0x1 << NAU8824_CLASSD_CLAMP_DIS_SFT) 321 + 322 + /* ENABLE_LO (0x6B) */ 323 + #define NAU8824_TEST_DAC_SFT 14 324 + #define NAU8824_TEST_DAC_EN (0x3 << NAU8824_TEST_DAC_SFT) 325 + #define NAU8824_DACL_HPR_EN_SFT 3 326 + #define NAU8824_DACL_HPR_EN (0x1 << NAU8824_DACL_HPR_EN_SFT) 327 + #define NAU8824_DACR_HPR_EN_SFT 2 328 + #define NAU8824_DACR_HPR_EN (0x1 << NAU8824_DACR_HPR_EN_SFT) 329 + #define NAU8824_DACR_HPL_EN_SFT 1 330 + #define NAU8824_DACR_HPL_EN (0x1 << NAU8824_DACR_HPL_EN_SFT) 331 + #define NAU8824_DACL_HPL_EN_SFT 0 332 + #define NAU8824_DACL_HPL_EN 0x1 333 + 334 + /* CLASSD_GAIN_1 (0x6D) */ 335 + #define NAU8824_CLASSD_GAIN_1R_SFT 8 336 + #define NAU8824_CLASSD_GAIN_1R_MASK (0x1f << NAU8824_CLASSD_GAIN_1R_SFT) 337 + #define NAU8824_CLASSD_EN_SFT 7 338 + #define NAU8824_CLASSD_EN (0x1 << NAU8824_CLASSD_EN_SFT) 339 + #define NAU8824_CLASSD_GAIN_1L_MASK 0x1f 340 + 341 + /* CLASSD_GAIN_2 (0x6E) */ 342 + #define NAU8824_CLASSD_GAIN_2R_SFT 8 343 + #define NAU8824_CLASSD_GAIN_2R_MASK (0x1f << NAU8824_CLASSD_GAIN_1R_SFT) 344 + #define NAU8824_CLASSD_EN_SFT 7 345 + #define NAU8824_CLASSD_EN (0x1 << NAU8824_CLASSD_EN_SFT) 346 + #define NAU8824_CLASSD_GAIN_2L_MASK 0x1f 347 + 348 + /* ANALOG_ADC_2 (0x72) */ 349 + #define NAU8824_ADCR_EN_SFT 7 350 + #define NAU8824_ADCL_EN_SFT 6 351 + 352 + /* RDAC (0x73) */ 353 + #define NAU8824_DACR_EN_SFT 13 354 + #define NAU8824_DACL_EN_SFT 12 355 + #define NAU8824_DACR_CLK_SFT 9 356 + #define NAU8824_DACL_CLK_SFT 8 357 + #define NAU8824_RDAC_CLK_DELAY_SFT 4 358 + #define NAU8824_RDAC_CLK_DELAY_MASK (0x7 << NAU8824_RDAC_CLK_DELAY_SFT) 359 + #define NAU8824_RDAC_VREF_SFT 2 360 + #define NAU8824_RDAC_VREF_MASK (0x3 << NAU8824_RDAC_VREF_SFT) 361 + 362 + /* MIC_BIAS (0x74) */ 363 + #define NAU8824_MICBIAS_JKSLV (1 << 14) 364 + #define NAU8824_MICBIAS_JKR2 (1 << 12) 365 + #define NAU8824_MICBIAS_POWERUP_SFT 8 366 + #define NAU8824_MICBIAS_VOLTAGE_SFT 0 367 + #define NAU8824_MICBIAS_VOLTAGE_MASK 0x7 368 + 369 + /* BOOST (0x76) */ 370 + #define NAU8824_PRECHARGE_DIS (0x1 << 13) 371 + #define NAU8824_GLOBAL_BIAS_EN (0x1 << 12) 372 + #define NAU8824_HP_BOOST_DIS_SFT 9 373 + #define NAU8824_HP_BOOST_DIS (0x1 << NAU8824_HP_BOOST_DIS_SFT) 374 + #define NAU8824_HP_BOOST_G_DIS_SFT 8 375 + #define NAU8824_HP_BOOST_G_DIS (0x1 << NAU8824_HP_BOOST_G_DIS_SFT) 376 + #define NAU8824_SHORT_SHUTDOWN_DIG_EN (1 << 7) 377 + #define NAU8824_SHORT_SHUTDOWN_EN (1 << 6) 378 + 379 + /* FEPGA (0x77) */ 380 + #define NAU8824_FEPGA_MODER_SHORT_SFT 7 381 + #define NAU8824_FEPGA_MODER_SHORT_EN (0x1 << NAU8824_FEPGA_MODER_SHORT_SFT) 382 + #define NAU8824_FEPGA_MODER_MIC2_SFT 5 383 + #define NAU8824_FEPGA_MODER_MIC2_EN (0x1 << NAU8824_FEPGA_MODER_MIC2_SFT) 384 + #define NAU8824_FEPGA_MODER_HSMIC_SFT 4 385 + #define NAU8824_FEPGA_MODER_HSMIC_EN (0x1 << NAU8824_FEPGA_MODER_HSMIC_SFT) 386 + #define NAU8824_FEPGA_MODEL_SHORT_SFT 3 387 + #define NAU8824_FEPGA_MODEL_SHORT_EN (0x1 << NAU8824_FEPGA_MODEL_SHORT_SFT) 388 + #define NAU8824_FEPGA_MODEL_MIC1_SFT 1 389 + #define NAU8824_FEPGA_MODEL_MIC1_EN (0x1 << NAU8824_FEPGA_MODEL_MIC1_SFT) 390 + #define NAU8824_FEPGA_MODEL_HSMIC_SFT 0 391 + #define NAU8824_FEPGA_MODEL_HSMIC_EN (0x1 << NAU8824_FEPGA_MODEL_HSMIC_SFT) 392 + 393 + /* FEPGA_II (0x78) */ 394 + #define NAU8824_FEPGA_GAINR_SFT 5 395 + #define NAU8824_FEPGA_GAINR_MASK (0x1f << NAU8824_FEPGA_GAINR_SFT) 396 + #define NAU8824_FEPGA_GAINL_SFT 0 397 + #define NAU8824_FEPGA_GAINL_MASK 0x1f 398 + 399 + /* CHARGE_PUMP_CONTROL (0x80) */ 400 + #define NAU8824_JAMNODCLOW (0x1 << 15) 401 + #define NAU8824_SPKR_PULL_DOWN (0x1 << 13) 402 + #define NAU8824_SPKL_PULL_DOWN (0x1 << 12) 403 + #define NAU8824_POWER_DOWN_DACR (0x1 << 9) 404 + #define NAU8824_POWER_DOWN_DACL (0x1 << 8) 405 + #define NAU8824_CHARGE_PUMP_EN_SFT 5 406 + #define NAU8824_CHARGE_PUMP_EN (0x1 << NAU8824_CHARGE_PUMP_EN_SFT) 407 + 408 + 409 + #define NAU8824_CODEC_DAI "nau8824-hifi" 410 + 411 + /* System Clock Source */ 412 + enum { 413 + NAU8824_CLK_DIS, 414 + NAU8824_CLK_MCLK, 415 + NAU8824_CLK_INTERNAL, 416 + NAU8824_CLK_FLL_MCLK, 417 + NAU8824_CLK_FLL_BLK, 418 + NAU8824_CLK_FLL_FS, 419 + }; 420 + 421 + struct nau8824 { 422 + struct device *dev; 423 + struct regmap *regmap; 424 + struct snd_soc_dapm_context *dapm; 425 + struct snd_soc_jack *jack; 426 + struct work_struct jdet_work; 427 + struct semaphore jd_sem; 428 + int fs; 429 + int irq; 430 + int micbias_voltage; 431 + int vref_impedance; 432 + int jkdet_polarity; 433 + int sar_threshold_num; 434 + int sar_threshold[8]; 435 + int sar_hysteresis; 436 + int sar_voltage; 437 + int sar_compare_time; 438 + int sar_sampling_time; 439 + int key_debounce; 440 + int jack_eject_debounce; 441 + }; 442 + 443 + struct nau8824_fll { 444 + int mclk_src; 445 + int ratio; 446 + int fll_frac; 447 + int fll_int; 448 + int clk_ref_div; 449 + }; 450 + 451 + struct nau8824_fll_attr { 452 + unsigned int param; 453 + unsigned int val; 454 + }; 455 + 456 + struct nau8824_osr_attr { 457 + unsigned int osr; 458 + unsigned int clk_src; 459 + }; 460 + 461 + 462 + int nau8824_enable_jack_detect(struct snd_soc_codec *codec, 463 + struct snd_soc_jack *jack); 464 + 465 + #endif /* _NAU8824_H */ 466 +