1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | // |
3 | // es8326.c -- es8326 ALSA SoC audio driver |
4 | // Copyright Everest Semiconductor Co., Ltd |
5 | // |
6 | // Authors: David Yang <yangxiaohua@everest-semi.com> |
7 | // |
8 | |
9 | #include <linux/clk.h> |
10 | #include <linux/i2c.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/irq.h> |
13 | #include <linux/module.h> |
14 | #include <sound/jack.h> |
15 | #include <sound/pcm_params.h> |
16 | #include <sound/soc.h> |
17 | #include <sound/soc-dapm.h> |
18 | #include <sound/tlv.h> |
19 | #include "es8326.h" |
20 | |
21 | struct es8326_priv { |
22 | struct clk *mclk; |
23 | struct i2c_client *i2c; |
24 | struct regmap *regmap; |
25 | struct snd_soc_component *component; |
26 | struct delayed_work jack_detect_work; |
27 | struct delayed_work button_press_work; |
28 | struct snd_soc_jack *jack; |
29 | int irq; |
30 | /* The lock protects the situation that an irq is generated |
31 | * while enabling or disabling or during an irq. |
32 | */ |
33 | struct mutex lock; |
34 | u8 jack_pol; |
35 | u8 interrupt_src; |
36 | u8 interrupt_clk; |
37 | u8 hpl_vol; |
38 | u8 hpr_vol; |
39 | bool jd_inverted; |
40 | unsigned int sysclk; |
41 | |
42 | bool calibrated; |
43 | int version; |
44 | int hp; |
45 | int jack_remove_retry; |
46 | }; |
47 | |
48 | static int es8326_crosstalk1_get(struct snd_kcontrol *kcontrol, |
49 | struct snd_ctl_elem_value *ucontrol) |
50 | { |
51 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
52 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
53 | unsigned int crosstalk_h, crosstalk_l; |
54 | unsigned int crosstalk; |
55 | |
56 | regmap_read(map: es8326->regmap, ES8326_DAC_RAMPRATE, val: &crosstalk_h); |
57 | regmap_read(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: &crosstalk_l); |
58 | crosstalk_h &= 0x20; |
59 | crosstalk_l &= 0xf0; |
60 | crosstalk = crosstalk_h >> 1 | crosstalk_l >> 4; |
61 | ucontrol->value.integer.value[0] = crosstalk; |
62 | |
63 | return 0; |
64 | } |
65 | |
66 | static int es8326_crosstalk1_set(struct snd_kcontrol *kcontrol, |
67 | struct snd_ctl_elem_value *ucontrol) |
68 | { |
69 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
70 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
71 | unsigned int crosstalk_h, crosstalk_l; |
72 | unsigned int crosstalk; |
73 | |
74 | crosstalk = ucontrol->value.integer.value[0]; |
75 | regmap_read(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: &crosstalk_l); |
76 | crosstalk_h = (crosstalk & 0x10) << 1; |
77 | crosstalk_l &= 0x0f; |
78 | crosstalk_l |= (crosstalk & 0x0f) << 4; |
79 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_RAMPRATE, |
80 | mask: 0x20, val: crosstalk_h); |
81 | regmap_write(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: crosstalk_l); |
82 | |
83 | return 0; |
84 | } |
85 | |
86 | static int es8326_crosstalk2_get(struct snd_kcontrol *kcontrol, |
87 | struct snd_ctl_elem_value *ucontrol) |
88 | { |
89 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
90 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
91 | unsigned int crosstalk_h, crosstalk_l; |
92 | unsigned int crosstalk; |
93 | |
94 | regmap_read(map: es8326->regmap, ES8326_DAC_RAMPRATE, val: &crosstalk_h); |
95 | regmap_read(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: &crosstalk_l); |
96 | crosstalk_h &= 0x10; |
97 | crosstalk_l &= 0x0f; |
98 | crosstalk = crosstalk_h | crosstalk_l; |
99 | ucontrol->value.integer.value[0] = crosstalk; |
100 | |
101 | return 0; |
102 | } |
103 | |
104 | static int es8326_crosstalk2_set(struct snd_kcontrol *kcontrol, |
105 | struct snd_ctl_elem_value *ucontrol) |
106 | { |
107 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
108 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
109 | unsigned int crosstalk_h, crosstalk_l; |
110 | unsigned int crosstalk; |
111 | |
112 | crosstalk = ucontrol->value.integer.value[0]; |
113 | regmap_read(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: &crosstalk_l); |
114 | crosstalk_h = crosstalk & 0x10; |
115 | crosstalk_l &= 0xf0; |
116 | crosstalk_l |= crosstalk & 0x0f; |
117 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_RAMPRATE, |
118 | mask: 0x10, val: crosstalk_h); |
119 | regmap_write(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: crosstalk_l); |
120 | |
121 | return 0; |
122 | } |
123 | |
124 | static int es8326_hplvol_get(struct snd_kcontrol *kcontrol, |
125 | struct snd_ctl_elem_value *ucontrol) |
126 | { |
127 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
128 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
129 | |
130 | ucontrol->value.integer.value[0] = es8326->hpl_vol; |
131 | |
132 | return 0; |
133 | } |
134 | |
135 | static int es8326_hplvol_set(struct snd_kcontrol *kcontrol, |
136 | struct snd_ctl_elem_value *ucontrol) |
137 | { |
138 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
139 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
140 | unsigned int hp_vol; |
141 | |
142 | hp_vol = ucontrol->value.integer.value[0]; |
143 | if (hp_vol > 5) |
144 | return -EINVAL; |
145 | if (es8326->hpl_vol != hp_vol) { |
146 | es8326->hpl_vol = hp_vol; |
147 | if (hp_vol >= 3) |
148 | hp_vol++; |
149 | regmap_update_bits(map: es8326->regmap, ES8326_HP_VOL, |
150 | mask: 0x70, val: (hp_vol << 4)); |
151 | return 1; |
152 | } |
153 | |
154 | return 0; |
155 | } |
156 | |
157 | static int es8326_hprvol_get(struct snd_kcontrol *kcontrol, |
158 | struct snd_ctl_elem_value *ucontrol) |
159 | { |
160 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
161 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
162 | |
163 | ucontrol->value.integer.value[0] = es8326->hpr_vol; |
164 | |
165 | return 0; |
166 | } |
167 | |
168 | static int es8326_hprvol_set(struct snd_kcontrol *kcontrol, |
169 | struct snd_ctl_elem_value *ucontrol) |
170 | { |
171 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
172 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
173 | unsigned int hp_vol; |
174 | |
175 | hp_vol = ucontrol->value.integer.value[0]; |
176 | if (hp_vol > 5) |
177 | return -EINVAL; |
178 | if (es8326->hpr_vol != hp_vol) { |
179 | es8326->hpr_vol = hp_vol; |
180 | if (hp_vol >= 3) |
181 | hp_vol++; |
182 | regmap_update_bits(map: es8326->regmap, ES8326_HP_VOL, |
183 | mask: 0x07, val: hp_vol); |
184 | return 1; |
185 | } |
186 | |
187 | return 0; |
188 | } |
189 | |
190 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(dac_vol_tlv, -9550, 50, 0); |
191 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_vol_tlv, -9550, 50, 0); |
192 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_analog_pga_tlv, 0, 300, 0); |
193 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(adc_pga_tlv, 0, 600, 0); |
194 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(softramp_rate, 0, 100, 0); |
195 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(drc_target_tlv, -3200, 200, 0); |
196 | static const SNDRV_CTL_TLVD_DECLARE_DB_SCALE(drc_recovery_tlv, -125, 250, 0); |
197 | |
198 | static const char *const winsize[] = { |
199 | "0.25db/2 LRCK" , |
200 | "0.25db/4 LRCK" , |
201 | "0.25db/8 LRCK" , |
202 | "0.25db/16 LRCK" , |
203 | "0.25db/32 LRCK" , |
204 | "0.25db/64 LRCK" , |
205 | "0.25db/128 LRCK" , |
206 | "0.25db/256 LRCK" , |
207 | "0.25db/512 LRCK" , |
208 | "0.25db/1024 LRCK" , |
209 | "0.25db/2048 LRCK" , |
210 | "0.25db/4096 LRCK" , |
211 | "0.25db/8192 LRCK" , |
212 | "0.25db/16384 LRCK" , |
213 | "0.25db/32768 LRCK" , |
214 | "0.25db/65536 LRCK" , |
215 | }; |
216 | |
217 | static const char *const dacpol_txt[] = { |
218 | "Normal" , "R Invert" , "L Invert" , "L + R Invert" }; |
219 | |
220 | static const char *const hp_spkvol_switch[] = { |
221 | "HPVOL: HPL+HPL, SPKVOL: HPL+HPL" , |
222 | "HPVOL: HPL+HPR, SPKVOL: HPL+HPR" , |
223 | "HPVOL: HPL+HPL, SPKVOL: SPKL+SPKR" , |
224 | "HPVOL: HPL+HPR, SPKVOL: SPKL+SPKR" , |
225 | }; |
226 | |
227 | static const struct soc_enum dacpol = |
228 | SOC_ENUM_SINGLE(ES8326_DAC_DSM, 4, 4, dacpol_txt); |
229 | static const struct soc_enum alc_winsize = |
230 | SOC_ENUM_SINGLE(ES8326_ADC_RAMPRATE, 4, 16, winsize); |
231 | static const struct soc_enum drc_winsize = |
232 | SOC_ENUM_SINGLE(ES8326_DRC_WINSIZE, 4, 16, winsize); |
233 | static const struct soc_enum hpvol_spkvol_switch = |
234 | SOC_ENUM_SINGLE(ES8326_HP_MISC, 6, 4, hp_spkvol_switch); |
235 | |
236 | static const struct snd_kcontrol_new es8326_snd_controls[] = { |
237 | SOC_SINGLE_TLV("DAC Playback Volume" , ES8326_DACL_VOL, 0, 0xbf, 0, dac_vol_tlv), |
238 | SOC_ENUM("Playback Polarity" , dacpol), |
239 | SOC_SINGLE_TLV("DAC Ramp Rate" , ES8326_DAC_RAMPRATE, 0, 0x0f, 0, softramp_rate), |
240 | SOC_SINGLE_TLV("DRC Recovery Level" , ES8326_DRC_RECOVERY, 0, 4, 0, drc_recovery_tlv), |
241 | SOC_ENUM("DRC Winsize" , drc_winsize), |
242 | SOC_SINGLE_TLV("DRC Target Level" , ES8326_DRC_WINSIZE, 0, 0x0f, 0, drc_target_tlv), |
243 | |
244 | SOC_DOUBLE_R_TLV("ADC Capture Volume" , ES8326_ADC1_VOL, ES8326_ADC2_VOL, 0, 0xff, 0, |
245 | adc_vol_tlv), |
246 | SOC_DOUBLE_TLV("ADC PGA Volume" , ES8326_ADC_SCALE, 4, 0, 5, 0, adc_pga_tlv), |
247 | SOC_SINGLE_TLV("ADC PGA Gain Volume" , ES8326_PGAGAIN, 0, 10, 0, adc_analog_pga_tlv), |
248 | SOC_SINGLE_TLV("ADC Ramp Rate" , ES8326_ADC_RAMPRATE, 0, 0x0f, 0, softramp_rate), |
249 | SOC_SINGLE("ALC Capture Switch" , ES8326_ALC_RECOVERY, 3, 1, 0), |
250 | SOC_SINGLE_TLV("ALC Capture Recovery Level" , ES8326_ALC_LEVEL, |
251 | 0, 4, 0, drc_recovery_tlv), |
252 | SOC_ENUM("ALC Capture Winsize" , alc_winsize), |
253 | SOC_SINGLE_TLV("ALC Capture Target Level" , ES8326_ALC_LEVEL, |
254 | 0, 0x0f, 0, drc_target_tlv), |
255 | |
256 | SOC_SINGLE_EXT("CROSSTALK1" , SND_SOC_NOPM, 0, 31, 0, |
257 | es8326_crosstalk1_get, es8326_crosstalk1_set), |
258 | SOC_SINGLE_EXT("CROSSTALK2" , SND_SOC_NOPM, 0, 31, 0, |
259 | es8326_crosstalk2_get, es8326_crosstalk2_set), |
260 | SOC_SINGLE_EXT("HPL Volume" , SND_SOC_NOPM, 0, 5, 0, |
261 | es8326_hplvol_get, es8326_hplvol_set), |
262 | SOC_SINGLE_EXT("HPR Volume" , SND_SOC_NOPM, 0, 5, 0, |
263 | es8326_hprvol_get, es8326_hprvol_set), |
264 | |
265 | SOC_SINGLE_TLV("HPL Playback Volume" , ES8326_DACL_VOL, 0, 0xbf, 0, dac_vol_tlv), |
266 | SOC_SINGLE_TLV("HPR Playback Volume" , ES8326_DACR_VOL, 0, 0xbf, 0, dac_vol_tlv), |
267 | SOC_SINGLE_TLV("SPKL Playback Volume" , ES8326_SPKL_VOL, 0, 0xbf, 0, dac_vol_tlv), |
268 | SOC_SINGLE_TLV("SPKR Playback Volume" , ES8326_SPKR_VOL, 0, 0xbf, 0, dac_vol_tlv), |
269 | |
270 | SOC_ENUM("HPVol SPKVol Switch" , hpvol_spkvol_switch), |
271 | }; |
272 | |
273 | static const struct snd_soc_dapm_widget es8326_dapm_widgets[] = { |
274 | SND_SOC_DAPM_INPUT("MIC1" ), |
275 | SND_SOC_DAPM_INPUT("MIC2" ), |
276 | SND_SOC_DAPM_INPUT("MIC3" ), |
277 | SND_SOC_DAPM_INPUT("MIC4" ), |
278 | |
279 | SND_SOC_DAPM_ADC("ADC L" , NULL, SND_SOC_NOPM, 0, 0), |
280 | SND_SOC_DAPM_ADC("ADC R" , NULL, SND_SOC_NOPM, 0, 0), |
281 | |
282 | /* Digital Interface */ |
283 | SND_SOC_DAPM_AIF_OUT("I2S OUT" , "I2S1 Capture" , 0, SND_SOC_NOPM, 0, 0), |
284 | SND_SOC_DAPM_AIF_IN("I2S IN" , "I2S1 Playback" , 0, SND_SOC_NOPM, 0, 0), |
285 | |
286 | /* Analog Power Supply*/ |
287 | SND_SOC_DAPM_DAC("Right DAC" , NULL, ES8326_ANA_PDN, 0, 1), |
288 | SND_SOC_DAPM_DAC("Left DAC" , NULL, ES8326_ANA_PDN, 1, 1), |
289 | SND_SOC_DAPM_SUPPLY("MICBIAS1" , ES8326_ANA_MICBIAS, 2, 0, NULL, 0), |
290 | SND_SOC_DAPM_SUPPLY("MICBIAS2" , ES8326_ANA_MICBIAS, 3, 0, NULL, 0), |
291 | |
292 | SND_SOC_DAPM_PGA("LHPMIX" , ES8326_DAC2HPMIX, 7, 0, NULL, 0), |
293 | SND_SOC_DAPM_PGA("RHPMIX" , ES8326_DAC2HPMIX, 3, 0, NULL, 0), |
294 | |
295 | SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOR Supply" , ES8326_HP_CAL, |
296 | 4, 7, 0, 0), |
297 | SND_SOC_DAPM_REG(snd_soc_dapm_supply, "HPOL Supply" , ES8326_HP_CAL, |
298 | 0, 7, 0, 0), |
299 | |
300 | SND_SOC_DAPM_OUTPUT("HPOL" ), |
301 | SND_SOC_DAPM_OUTPUT("HPOR" ), |
302 | }; |
303 | |
304 | static const struct snd_soc_dapm_route es8326_dapm_routes[] = { |
305 | {"ADC L" , NULL, "MIC1" }, |
306 | {"ADC R" , NULL, "MIC2" }, |
307 | {"ADC L" , NULL, "MIC3" }, |
308 | {"ADC R" , NULL, "MIC4" }, |
309 | |
310 | {"I2S OUT" , NULL, "ADC L" }, |
311 | {"I2S OUT" , NULL, "ADC R" }, |
312 | |
313 | {"Right DAC" , NULL, "I2S IN" }, |
314 | {"Left DAC" , NULL, "I2S IN" }, |
315 | |
316 | {"LHPMIX" , NULL, "Left DAC" }, |
317 | {"RHPMIX" , NULL, "Right DAC" }, |
318 | |
319 | {"HPOR" , NULL, "HPOR Supply" }, |
320 | {"HPOL" , NULL, "HPOL Supply" }, |
321 | |
322 | {"HPOL" , NULL, "LHPMIX" }, |
323 | {"HPOR" , NULL, "RHPMIX" }, |
324 | }; |
325 | |
326 | static bool es8326_volatile_register(struct device *dev, unsigned int reg) |
327 | { |
328 | switch (reg) { |
329 | case ES8326_HPL_OFFSET_INI: |
330 | case ES8326_HPR_OFFSET_INI: |
331 | case ES8326_HPDET_STA: |
332 | case ES8326_CTIA_OMTP_STA: |
333 | case ES8326_CSM_MUTE_STA: |
334 | return true; |
335 | default: |
336 | return false; |
337 | } |
338 | } |
339 | |
340 | static const struct regmap_config es8326_regmap_config = { |
341 | .reg_bits = 8, |
342 | .val_bits = 8, |
343 | .max_register = 0xff, |
344 | .volatile_reg = es8326_volatile_register, |
345 | .cache_type = REGCACHE_RBTREE, |
346 | }; |
347 | |
348 | struct _coeff_div { |
349 | u16 fs; |
350 | u32 rate; |
351 | u32 mclk; |
352 | u8 reg4; |
353 | u8 reg5; |
354 | u8 reg6; |
355 | u8 reg7; |
356 | u8 reg8; |
357 | u8 reg9; |
358 | u8 rega; |
359 | u8 regb; |
360 | }; |
361 | |
362 | /* codec hifi mclk clock divider coefficients */ |
363 | /* {ratio, LRCK, MCLK, REG04, REG05, REG06, REG07, REG08, REG09, REG10, REG11} */ |
364 | static const struct _coeff_div coeff_div_v0[] = { |
365 | {64, 8000, 512000, 0x60, 0x01, 0x0F, 0x75, 0x0A, 0x1B, 0x1F, 0x7F}, |
366 | {64, 16000, 1024000, 0x20, 0x00, 0x33, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, |
367 | {64, 44100, 2822400, 0xE0, 0x00, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
368 | {64, 48000, 3072000, 0xE0, 0x00, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
369 | {128, 8000, 1024000, 0x60, 0x00, 0x33, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, |
370 | {128, 16000, 2048000, 0x20, 0x00, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, |
371 | {128, 44100, 5644800, 0xE0, 0x01, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
372 | {128, 48000, 6144000, 0xE0, 0x01, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
373 | |
374 | {192, 32000, 6144000, 0xE0, 0x02, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
375 | {256, 8000, 2048000, 0x60, 0x00, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, |
376 | {256, 16000, 4096000, 0x20, 0x01, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, |
377 | {256, 44100, 11289600, 0xE0, 0x00, 0x30, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
378 | {256, 48000, 12288000, 0xE0, 0x00, 0x30, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
379 | {384, 32000, 12288000, 0xE0, 0x05, 0x03, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
380 | {400, 48000, 19200000, 0xE9, 0x04, 0x0F, 0x6d, 0x4A, 0x0A, 0x1F, 0x1F}, |
381 | |
382 | {500, 48000, 24000000, 0xF8, 0x04, 0x3F, 0x6D, 0x4A, 0x0A, 0x1F, 0x1F}, |
383 | {512, 8000, 4096000, 0x60, 0x01, 0x03, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, |
384 | {512, 16000, 8192000, 0x20, 0x00, 0x30, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, |
385 | {512, 44100, 22579200, 0xE0, 0x00, 0x00, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
386 | {512, 48000, 24576000, 0xE0, 0x00, 0x00, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
387 | {768, 32000, 24576000, 0xE0, 0x02, 0x30, 0x2D, 0x4A, 0x0A, 0x1F, 0x1F}, |
388 | {1024, 8000, 8192000, 0x60, 0x00, 0x30, 0x35, 0x0A, 0x1B, 0x1F, 0x7F}, |
389 | {1024, 16000, 16384000, 0x20, 0x00, 0x00, 0x35, 0x0A, 0x1B, 0x1F, 0x3F}, |
390 | }; |
391 | |
392 | static const struct _coeff_div coeff_div_v3[] = { |
393 | {32, 8000, 256000, 0x60, 0x00, 0x0F, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
394 | {32, 16000, 512000, 0x20, 0x00, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, |
395 | {32, 44100, 1411200, 0x00, 0x00, 0x13, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, |
396 | {32, 48000, 1536000, 0x00, 0x00, 0x13, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, |
397 | {36, 8000, 288000, 0x20, 0x00, 0x0D, 0x75, 0x8A, 0x1B, 0x23, 0x47}, |
398 | {36, 16000, 576000, 0x20, 0x00, 0x0D, 0x75, 0x8A, 0x1B, 0x23, 0x47}, |
399 | {48, 8000, 384000, 0x60, 0x02, 0x1F, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
400 | {48, 16000, 768000, 0x20, 0x02, 0x0F, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, |
401 | {48, 48000, 2304000, 0x00, 0x02, 0x0D, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, |
402 | |
403 | {64, 8000, 512000, 0x60, 0x00, 0x35, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
404 | {64, 16000, 1024000, 0x20, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, |
405 | {64, 44100, 2822400, 0xE0, 0x00, 0x31, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, |
406 | {64, 48000, 3072000, 0xE0, 0x00, 0x31, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, |
407 | {72, 8000, 576000, 0x20, 0x00, 0x13, 0x35, 0x8A, 0x1B, 0x23, 0x47}, |
408 | {72, 16000, 1152000, 0x20, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x23, 0x47}, |
409 | {96, 8000, 768000, 0x60, 0x02, 0x1D, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
410 | {96, 16000, 1536000, 0x20, 0x02, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x3F}, |
411 | {100, 48000, 4800000, 0x04, 0x04, 0x3F, 0x6D, 0xB8, 0x08, 0x4f, 0x1f}, |
412 | {125, 48000, 6000000, 0x04, 0x04, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, |
413 | |
414 | {128, 8000, 1024000, 0x60, 0x00, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
415 | {128, 16000, 2048000, 0x20, 0x00, 0x31, 0x35, 0x08, 0x19, 0x1F, 0x3F}, |
416 | {128, 44100, 5644800, 0xE0, 0x00, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, |
417 | {128, 48000, 6144000, 0xE0, 0x00, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, |
418 | {144, 8000, 1152000, 0x20, 0x00, 0x03, 0x35, 0x8A, 0x1B, 0x23, 0x47}, |
419 | {144, 16000, 2304000, 0x20, 0x00, 0x11, 0x35, 0x8A, 0x1B, 0x23, 0x47}, |
420 | {192, 8000, 1536000, 0x60, 0x02, 0x0D, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
421 | {192, 32000, 6144000, 0xE0, 0x02, 0x31, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, |
422 | {192, 16000, 3072000, 0x20, 0x02, 0x05, 0x75, 0xCA, 0x1B, 0x1F, 0x3F}, |
423 | |
424 | {200, 48000, 9600000, 0x04, 0x04, 0x0F, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, |
425 | {250, 48000, 12000000, 0x04, 0x04, 0x0F, 0x2D, 0xCA, 0x0A, 0x27, 0x27}, |
426 | {256, 8000, 2048000, 0x60, 0x00, 0x31, 0x35, 0x08, 0x19, 0x1F, 0x7F}, |
427 | {256, 16000, 4096000, 0x20, 0x00, 0x01, 0x35, 0x08, 0x19, 0x1F, 0x3F}, |
428 | {256, 44100, 11289600, 0xE0, 0x01, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, |
429 | {256, 48000, 12288000, 0xE0, 0x01, 0x01, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, |
430 | {288, 8000, 2304000, 0x20, 0x00, 0x01, 0x35, 0x8A, 0x1B, 0x23, 0x47}, |
431 | {384, 8000, 3072000, 0x60, 0x02, 0x05, 0x75, 0x8A, 0x1B, 0x1F, 0x7F}, |
432 | {384, 16000, 6144000, 0x20, 0x02, 0x03, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, |
433 | {384, 32000, 12288000, 0xE0, 0x02, 0x01, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, |
434 | {384, 48000, 18432000, 0x00, 0x02, 0x01, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, |
435 | |
436 | {400, 48000, 19200000, 0xE4, 0x04, 0x35, 0x6d, 0xCA, 0x0A, 0x1F, 0x1F}, |
437 | {500, 48000, 24000000, 0xF8, 0x04, 0x3F, 0x6D, 0xCA, 0x0A, 0x1F, 0x1F}, |
438 | {512, 8000, 4096000, 0x60, 0x00, 0x01, 0x08, 0x19, 0x1B, 0x1F, 0x7F}, |
439 | {512, 16000, 8192000, 0x20, 0x00, 0x30, 0x35, 0x08, 0x19, 0x1F, 0x3F}, |
440 | {512, 44100, 22579200, 0xE0, 0x00, 0x00, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, |
441 | {512, 48000, 24576000, 0xE0, 0x00, 0x00, 0x2D, 0x48, 0x08, 0x1F, 0x1F}, |
442 | {768, 8000, 6144000, 0x60, 0x02, 0x11, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, |
443 | {768, 16000, 12288000, 0x20, 0x02, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, |
444 | {768, 32000, 24576000, 0xE0, 0x02, 0x30, 0x2D, 0xCA, 0x0A, 0x1F, 0x1F}, |
445 | {800, 48000, 38400000, 0x00, 0x18, 0x13, 0x2D, 0x8A, 0x0A, 0x1F, 0x1F}, |
446 | |
447 | {1024, 8000, 8192000, 0x60, 0x00, 0x30, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, |
448 | {1024, 16000, 16384000, 0x20, 0x00, 0x00, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, |
449 | {1152, 16000, 18432000, 0x20, 0x08, 0x11, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, |
450 | {1536, 8000, 12288000, 0x60, 0x02, 0x01, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, |
451 | {1536, 16000, 24576000, 0x20, 0x02, 0x10, 0x35, 0x8A, 0x1B, 0x1F, 0x3F}, |
452 | {1625, 8000, 13000000, 0x0C, 0x18, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, |
453 | {1625, 16000, 26000000, 0x0C, 0x18, 0x1F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, |
454 | {2048, 8000, 16384000, 0x60, 0x00, 0x00, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, |
455 | {2304, 8000, 18432000, 0x40, 0x02, 0x10, 0x35, 0x8A, 0x1B, 0x1F, 0x5F}, |
456 | {3072, 8000, 24576000, 0x60, 0x02, 0x10, 0x35, 0x8A, 0x1B, 0x1F, 0x7F}, |
457 | {3250, 8000, 26000000, 0x0C, 0x18, 0x0F, 0x2D, 0x8A, 0x0A, 0x27, 0x27}, |
458 | }; |
459 | |
460 | static inline int get_coeff(int mclk, int rate, int array, |
461 | const struct _coeff_div *coeff_div) |
462 | { |
463 | int i; |
464 | |
465 | for (i = 0; i < array; i++) { |
466 | if (coeff_div[i].rate == rate && coeff_div[i].mclk == mclk) |
467 | return i; |
468 | } |
469 | |
470 | return -EINVAL; |
471 | } |
472 | |
473 | static int es8326_set_dai_sysclk(struct snd_soc_dai *codec_dai, |
474 | int clk_id, unsigned int freq, int dir) |
475 | { |
476 | struct snd_soc_component *codec = codec_dai->component; |
477 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: codec); |
478 | |
479 | es8326->sysclk = freq; |
480 | |
481 | return 0; |
482 | } |
483 | |
484 | static int es8326_set_dai_fmt(struct snd_soc_dai *codec_dai, unsigned int fmt) |
485 | { |
486 | struct snd_soc_component *component = codec_dai->component; |
487 | u8 iface = 0; |
488 | |
489 | switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { |
490 | case SND_SOC_DAIFMT_CBC_CFP: |
491 | snd_soc_component_update_bits(component, ES8326_RESET, |
492 | ES8326_MASTER_MODE_EN, ES8326_MASTER_MODE_EN); |
493 | break; |
494 | case SND_SOC_DAIFMT_CBC_CFC: |
495 | break; |
496 | default: |
497 | return -EINVAL; |
498 | } |
499 | |
500 | /* interface format */ |
501 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
502 | case SND_SOC_DAIFMT_I2S: |
503 | break; |
504 | case SND_SOC_DAIFMT_RIGHT_J: |
505 | dev_err(component->dev, "Codec driver does not support right justified\n" ); |
506 | return -EINVAL; |
507 | case SND_SOC_DAIFMT_LEFT_J: |
508 | iface |= ES8326_DAIFMT_LEFT_J; |
509 | break; |
510 | case SND_SOC_DAIFMT_DSP_A: |
511 | iface |= ES8326_DAIFMT_DSP_A; |
512 | break; |
513 | case SND_SOC_DAIFMT_DSP_B: |
514 | iface |= ES8326_DAIFMT_DSP_B; |
515 | break; |
516 | default: |
517 | return -EINVAL; |
518 | } |
519 | |
520 | snd_soc_component_update_bits(component, ES8326_FMT, ES8326_DAIFMT_MASK, val: iface); |
521 | |
522 | return 0; |
523 | } |
524 | |
525 | static int es8326_pcm_hw_params(struct snd_pcm_substream *substream, |
526 | struct snd_pcm_hw_params *params, |
527 | struct snd_soc_dai *dai) |
528 | { |
529 | struct snd_soc_component *component = dai->component; |
530 | const struct _coeff_div *coeff_div; |
531 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
532 | u8 srate = 0; |
533 | int coeff, array; |
534 | |
535 | if (es8326->version == 0) { |
536 | coeff_div = coeff_div_v0; |
537 | array = ARRAY_SIZE(coeff_div_v0); |
538 | } else { |
539 | coeff_div = coeff_div_v3; |
540 | array = ARRAY_SIZE(coeff_div_v3); |
541 | } |
542 | coeff = get_coeff(mclk: es8326->sysclk, rate: params_rate(p: params), array, coeff_div); |
543 | /* bit size */ |
544 | switch (params_format(p: params)) { |
545 | case SNDRV_PCM_FORMAT_S16_LE: |
546 | srate |= ES8326_S16_LE; |
547 | break; |
548 | case SNDRV_PCM_FORMAT_S20_3LE: |
549 | srate |= ES8326_S20_3_LE; |
550 | break; |
551 | case SNDRV_PCM_FORMAT_S18_3LE: |
552 | srate |= ES8326_S18_LE; |
553 | break; |
554 | case SNDRV_PCM_FORMAT_S24_LE: |
555 | srate |= ES8326_S24_LE; |
556 | break; |
557 | case SNDRV_PCM_FORMAT_S32_LE: |
558 | srate |= ES8326_S32_LE; |
559 | break; |
560 | default: |
561 | return -EINVAL; |
562 | } |
563 | |
564 | /* set iface & srate */ |
565 | snd_soc_component_update_bits(component, ES8326_FMT, ES8326_DATA_LEN_MASK, val: srate); |
566 | |
567 | if (coeff >= 0) { |
568 | regmap_write(map: es8326->regmap, ES8326_CLK_DIV1, |
569 | val: coeff_div[coeff].reg4); |
570 | regmap_write(map: es8326->regmap, ES8326_CLK_DIV2, |
571 | val: coeff_div[coeff].reg5); |
572 | regmap_write(map: es8326->regmap, ES8326_CLK_DLL, |
573 | val: coeff_div[coeff].reg6); |
574 | regmap_write(map: es8326->regmap, ES8326_CLK_MUX, |
575 | val: coeff_div[coeff].reg7); |
576 | regmap_write(map: es8326->regmap, ES8326_CLK_ADC_SEL, |
577 | val: coeff_div[coeff].reg8); |
578 | regmap_write(map: es8326->regmap, ES8326_CLK_DAC_SEL, |
579 | val: coeff_div[coeff].reg9); |
580 | regmap_write(map: es8326->regmap, ES8326_CLK_ADC_OSR, |
581 | val: coeff_div[coeff].rega); |
582 | regmap_write(map: es8326->regmap, ES8326_CLK_DAC_OSR, |
583 | val: coeff_div[coeff].regb); |
584 | } else { |
585 | dev_warn(component->dev, "Clock coefficients do not match" ); |
586 | } |
587 | |
588 | return 0; |
589 | } |
590 | |
591 | static int es8326_mute(struct snd_soc_dai *dai, int mute, int direction) |
592 | { |
593 | struct snd_soc_component *component = dai->component; |
594 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
595 | unsigned int offset_l, offset_r; |
596 | |
597 | if (mute) { |
598 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { |
599 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF); |
600 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_MUTE, |
601 | ES8326_MUTE_MASK, ES8326_MUTE); |
602 | regmap_update_bits(map: es8326->regmap, ES8326_HP_DRIVER_REF, |
603 | mask: 0x30, val: 0x00); |
604 | } else { |
605 | regmap_update_bits(map: es8326->regmap, ES8326_ADC_MUTE, |
606 | mask: 0x0F, val: 0x0F); |
607 | } |
608 | } else { |
609 | if (!es8326->calibrated) { |
610 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, ES8326_HP_FORCE_CAL); |
611 | msleep(msecs: 30); |
612 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF); |
613 | regmap_read(map: es8326->regmap, ES8326_HPL_OFFSET_INI, val: &offset_l); |
614 | regmap_read(map: es8326->regmap, ES8326_HPR_OFFSET_INI, val: &offset_r); |
615 | regmap_write(map: es8326->regmap, ES8326_HP_OFFSET_CAL, val: 0x8c); |
616 | regmap_write(map: es8326->regmap, ES8326_HPL_OFFSET_INI, val: offset_l); |
617 | regmap_write(map: es8326->regmap, ES8326_HPR_OFFSET_INI, val: offset_r); |
618 | es8326->calibrated = true; |
619 | } |
620 | if (direction == SNDRV_PCM_STREAM_PLAYBACK) { |
621 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_DSM, mask: 0x01, val: 0x01); |
622 | usleep_range(min: 1000, max: 5000); |
623 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_DSM, mask: 0x01, val: 0x00); |
624 | usleep_range(min: 1000, max: 5000); |
625 | regmap_update_bits(map: es8326->regmap, ES8326_HP_DRIVER_REF, mask: 0x30, val: 0x20); |
626 | regmap_update_bits(map: es8326->regmap, ES8326_HP_DRIVER_REF, mask: 0x30, val: 0x30); |
627 | regmap_write(map: es8326->regmap, ES8326_HP_DRIVER, val: 0xa1); |
628 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, ES8326_HP_ON); |
629 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_MUTE, |
630 | ES8326_MUTE_MASK, val: ~(ES8326_MUTE)); |
631 | } else { |
632 | msleep(msecs: 300); |
633 | regmap_update_bits(map: es8326->regmap, ES8326_ADC_MUTE, |
634 | mask: 0x0F, val: 0x00); |
635 | } |
636 | } |
637 | return 0; |
638 | } |
639 | |
640 | static int es8326_set_bias_level(struct snd_soc_component *codec, |
641 | enum snd_soc_bias_level level) |
642 | { |
643 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: codec); |
644 | int ret; |
645 | |
646 | switch (level) { |
647 | case SND_SOC_BIAS_ON: |
648 | ret = clk_prepare_enable(clk: es8326->mclk); |
649 | if (ret) |
650 | return ret; |
651 | |
652 | regmap_update_bits(map: es8326->regmap, ES8326_RESET, mask: 0x02, val: 0x02); |
653 | usleep_range(min: 5000, max: 10000); |
654 | regmap_write(map: es8326->regmap, ES8326_INTOUT_IO, val: es8326->interrupt_clk); |
655 | regmap_write(map: es8326->regmap, ES8326_SDINOUT1_IO, |
656 | val: (ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT)); |
657 | regmap_write(map: es8326->regmap, ES8326_PGA_PDN, val: 0x40); |
658 | regmap_write(map: es8326->regmap, ES8326_ANA_PDN, val: 0x00); |
659 | regmap_update_bits(map: es8326->regmap, ES8326_CLK_CTL, mask: 0x20, val: 0x20); |
660 | regmap_update_bits(map: es8326->regmap, ES8326_RESET, mask: 0x02, val: 0x00); |
661 | break; |
662 | case SND_SOC_BIAS_PREPARE: |
663 | break; |
664 | case SND_SOC_BIAS_STANDBY: |
665 | regmap_write(map: es8326->regmap, ES8326_ANA_PDN, val: 0x3b); |
666 | regmap_update_bits(map: es8326->regmap, ES8326_CLK_CTL, mask: 0x20, val: 0x00); |
667 | regmap_write(map: es8326->regmap, ES8326_SDINOUT1_IO, ES8326_IO_INPUT); |
668 | break; |
669 | case SND_SOC_BIAS_OFF: |
670 | clk_disable_unprepare(clk: es8326->mclk); |
671 | break; |
672 | } |
673 | |
674 | return 0; |
675 | } |
676 | |
677 | #define es8326_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ |
678 | SNDRV_PCM_FMTBIT_S24_LE) |
679 | |
680 | static const struct snd_soc_dai_ops es8326_ops = { |
681 | .hw_params = es8326_pcm_hw_params, |
682 | .set_fmt = es8326_set_dai_fmt, |
683 | .set_sysclk = es8326_set_dai_sysclk, |
684 | .mute_stream = es8326_mute, |
685 | .no_capture_mute = 0, |
686 | }; |
687 | |
688 | static struct snd_soc_dai_driver es8326_dai = { |
689 | .name = "ES8326 HiFi" , |
690 | .playback = { |
691 | .stream_name = "Playback" , |
692 | .channels_min = 1, |
693 | .channels_max = 2, |
694 | .rates = SNDRV_PCM_RATE_8000_48000, |
695 | .formats = es8326_FORMATS, |
696 | }, |
697 | .capture = { |
698 | .stream_name = "Capture" , |
699 | .channels_min = 1, |
700 | .channels_max = 2, |
701 | .rates = SNDRV_PCM_RATE_8000_48000, |
702 | .formats = es8326_FORMATS, |
703 | }, |
704 | .ops = &es8326_ops, |
705 | .symmetric_rate = 1, |
706 | }; |
707 | |
708 | static void es8326_enable_micbias(struct snd_soc_component *component) |
709 | { |
710 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); |
711 | |
712 | snd_soc_dapm_mutex_lock(dapm); |
713 | snd_soc_dapm_force_enable_pin_unlocked(dapm, pin: "MICBIAS1" ); |
714 | snd_soc_dapm_force_enable_pin_unlocked(dapm, pin: "MICBIAS2" ); |
715 | snd_soc_dapm_sync_unlocked(dapm); |
716 | snd_soc_dapm_mutex_unlock(dapm); |
717 | } |
718 | |
719 | static void es8326_disable_micbias(struct snd_soc_component *component) |
720 | { |
721 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); |
722 | |
723 | snd_soc_dapm_mutex_lock(dapm); |
724 | snd_soc_dapm_disable_pin_unlocked(dapm, pin: "MICBIAS1" ); |
725 | snd_soc_dapm_disable_pin_unlocked(dapm, pin: "MICBIAS2" ); |
726 | snd_soc_dapm_sync_unlocked(dapm); |
727 | snd_soc_dapm_mutex_unlock(dapm); |
728 | } |
729 | |
730 | /* |
731 | * For button detection, set the following in soundcard |
732 | * snd_jack_set_key(jack->jack, SND_JACK_BTN_0, KEY_PLAYPAUSE); |
733 | * snd_jack_set_key(jack->jack, SND_JACK_BTN_1, KEY_VOLUMEUP); |
734 | * snd_jack_set_key(jack->jack, SND_JACK_BTN_2, KEY_VOLUMEDOWN); |
735 | */ |
736 | static void es8326_jack_button_handler(struct work_struct *work) |
737 | { |
738 | struct es8326_priv *es8326 = |
739 | container_of(work, struct es8326_priv, button_press_work.work); |
740 | struct snd_soc_component *comp = es8326->component; |
741 | unsigned int iface; |
742 | static int button_to_report, press_count; |
743 | static int prev_button, cur_button; |
744 | |
745 | if (!(es8326->jack->status & SND_JACK_HEADSET)) /* Jack unplugged */ |
746 | return; |
747 | |
748 | mutex_lock(&es8326->lock); |
749 | iface = snd_soc_component_read(component: comp, ES8326_HPDET_STA); |
750 | switch (iface) { |
751 | case 0x93: |
752 | /* pause button detected */ |
753 | cur_button = SND_JACK_BTN_0; |
754 | break; |
755 | case 0x6f: |
756 | case 0x4b: |
757 | /* button volume up */ |
758 | cur_button = SND_JACK_BTN_1; |
759 | break; |
760 | case 0x27: |
761 | /* button volume down */ |
762 | cur_button = SND_JACK_BTN_2; |
763 | break; |
764 | case 0x1e: |
765 | case 0xe2: |
766 | /* button released or not pressed */ |
767 | cur_button = 0; |
768 | break; |
769 | default: |
770 | break; |
771 | } |
772 | |
773 | if ((prev_button == cur_button) && (cur_button != 0)) { |
774 | press_count++; |
775 | if (press_count > 3) { |
776 | /* report a press every 120ms */ |
777 | snd_soc_jack_report(jack: es8326->jack, status: cur_button, |
778 | mask: SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); |
779 | press_count = 0; |
780 | } |
781 | button_to_report = cur_button; |
782 | queue_delayed_work(wq: system_wq, dwork: &es8326->button_press_work, |
783 | delay: msecs_to_jiffies(m: 35)); |
784 | } else if (prev_button != cur_button) { |
785 | /* mismatch, detect again */ |
786 | prev_button = cur_button; |
787 | queue_delayed_work(wq: system_wq, dwork: &es8326->button_press_work, |
788 | delay: msecs_to_jiffies(m: 35)); |
789 | } else { |
790 | /* released or no pressed */ |
791 | if (button_to_report != 0) { |
792 | snd_soc_jack_report(jack: es8326->jack, status: button_to_report, |
793 | mask: SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); |
794 | snd_soc_jack_report(jack: es8326->jack, status: 0, |
795 | mask: SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2); |
796 | button_to_report = 0; |
797 | } |
798 | } |
799 | mutex_unlock(lock: &es8326->lock); |
800 | } |
801 | |
802 | static void es8326_jack_detect_handler(struct work_struct *work) |
803 | { |
804 | struct es8326_priv *es8326 = |
805 | container_of(work, struct es8326_priv, jack_detect_work.work); |
806 | struct snd_soc_component *comp = es8326->component; |
807 | unsigned int iface; |
808 | |
809 | mutex_lock(&es8326->lock); |
810 | iface = snd_soc_component_read(component: comp, ES8326_HPDET_STA); |
811 | dev_dbg(comp->dev, "gpio flag %#04x" , iface); |
812 | |
813 | if ((es8326->jack_remove_retry == 1) && (es8326->version != ES8326_VERSION_B)) { |
814 | if (iface & ES8326_HPINSERT_FLAG) |
815 | es8326->jack_remove_retry = 2; |
816 | else |
817 | es8326->jack_remove_retry = 0; |
818 | |
819 | dev_dbg(comp->dev, "remove event check, set HPJACK_POL normal, cnt = %d\n" , |
820 | es8326->jack_remove_retry); |
821 | /* |
822 | * Inverted HPJACK_POL bit to trigger one IRQ to double check HP Removal event |
823 | */ |
824 | regmap_update_bits(map: es8326->regmap, ES8326_HPDET_TYPE, |
825 | ES8326_HP_DET_JACK_POL, val: (es8326->jd_inverted ? |
826 | ~es8326->jack_pol : es8326->jack_pol)); |
827 | goto exit; |
828 | } |
829 | |
830 | if ((iface & ES8326_HPINSERT_FLAG) == 0) { |
831 | /* Jack unplugged or spurious IRQ */ |
832 | dev_dbg(comp->dev, "No headset detected\n" ); |
833 | es8326_disable_micbias(component: es8326->component); |
834 | if (es8326->jack->status & SND_JACK_HEADPHONE) { |
835 | dev_dbg(comp->dev, "Report hp remove event\n" ); |
836 | snd_soc_jack_report(jack: es8326->jack, status: 0, mask: SND_JACK_HEADSET); |
837 | /* mute adc when mic path switch */ |
838 | regmap_write(map: es8326->regmap, ES8326_ADC1_SRC, val: 0x44); |
839 | regmap_write(map: es8326->regmap, ES8326_ADC2_SRC, val: 0x66); |
840 | es8326->hp = 0; |
841 | } |
842 | regmap_update_bits(map: es8326->regmap, ES8326_HPDET_TYPE, mask: 0x03, val: 0x01); |
843 | regmap_write(map: es8326->regmap, ES8326_SYS_BIAS, val: 0x0a); |
844 | regmap_update_bits(map: es8326->regmap, ES8326_HP_DRIVER_REF, mask: 0x0f, val: 0x03); |
845 | regmap_write(map: es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); |
846 | /* |
847 | * Inverted HPJACK_POL bit to trigger one IRQ to double check HP Removal event |
848 | */ |
849 | if ((es8326->jack_remove_retry == 0) && (es8326->version != ES8326_VERSION_B)) { |
850 | es8326->jack_remove_retry = 1; |
851 | dev_dbg(comp->dev, "remove event check, invert HPJACK_POL, cnt = %d\n" , |
852 | es8326->jack_remove_retry); |
853 | regmap_update_bits(map: es8326->regmap, ES8326_HPDET_TYPE, |
854 | ES8326_HP_DET_JACK_POL, val: (es8326->jd_inverted ? |
855 | es8326->jack_pol : ~es8326->jack_pol)); |
856 | |
857 | } else { |
858 | es8326->jack_remove_retry = 0; |
859 | } |
860 | } else if ((iface & ES8326_HPINSERT_FLAG) == ES8326_HPINSERT_FLAG) { |
861 | es8326->jack_remove_retry = 0; |
862 | if (es8326->hp == 0) { |
863 | dev_dbg(comp->dev, "First insert, start OMTP/CTIA type check\n" ); |
864 | /* |
865 | * set auto-check mode, then restart jack_detect_work after 400ms. |
866 | * Don't report jack status. |
867 | */ |
868 | regmap_write(map: es8326->regmap, ES8326_INT_SOURCE, |
869 | val: (ES8326_INT_SRC_PIN9 | ES8326_INT_SRC_BUTTON)); |
870 | regmap_update_bits(map: es8326->regmap, ES8326_HPDET_TYPE, mask: 0x03, val: 0x01); |
871 | es8326_enable_micbias(component: es8326->component); |
872 | usleep_range(min: 50000, max: 70000); |
873 | regmap_update_bits(map: es8326->regmap, ES8326_HPDET_TYPE, mask: 0x03, val: 0x00); |
874 | regmap_write(map: es8326->regmap, ES8326_SYS_BIAS, val: 0x1f); |
875 | regmap_update_bits(map: es8326->regmap, ES8326_HP_DRIVER_REF, mask: 0x0f, val: 0x08); |
876 | queue_delayed_work(wq: system_wq, dwork: &es8326->jack_detect_work, |
877 | delay: msecs_to_jiffies(m: 400)); |
878 | es8326->hp = 1; |
879 | goto exit; |
880 | } |
881 | if (es8326->jack->status & SND_JACK_HEADSET) { |
882 | /* detect button */ |
883 | dev_dbg(comp->dev, "button pressed\n" ); |
884 | queue_delayed_work(wq: system_wq, dwork: &es8326->button_press_work, delay: 10); |
885 | goto exit; |
886 | } |
887 | if ((iface & ES8326_HPBUTTON_FLAG) == 0x01) { |
888 | dev_dbg(comp->dev, "Headphone detected\n" ); |
889 | snd_soc_jack_report(jack: es8326->jack, |
890 | status: SND_JACK_HEADPHONE, mask: SND_JACK_HEADSET); |
891 | } else { |
892 | dev_dbg(comp->dev, "Headset detected\n" ); |
893 | snd_soc_jack_report(jack: es8326->jack, |
894 | status: SND_JACK_HEADSET, mask: SND_JACK_HEADSET); |
895 | |
896 | regmap_update_bits(map: es8326->regmap, ES8326_PGA_PDN, |
897 | mask: 0x08, val: 0x08); |
898 | regmap_update_bits(map: es8326->regmap, ES8326_PGAGAIN, |
899 | mask: 0x80, val: 0x80); |
900 | regmap_write(map: es8326->regmap, ES8326_ADC1_SRC, val: 0x00); |
901 | regmap_write(map: es8326->regmap, ES8326_ADC2_SRC, val: 0x00); |
902 | regmap_update_bits(map: es8326->regmap, ES8326_PGA_PDN, |
903 | mask: 0x08, val: 0x00); |
904 | usleep_range(min: 10000, max: 15000); |
905 | } |
906 | } |
907 | exit: |
908 | mutex_unlock(lock: &es8326->lock); |
909 | } |
910 | |
911 | static irqreturn_t es8326_irq(int irq, void *dev_id) |
912 | { |
913 | struct es8326_priv *es8326 = dev_id; |
914 | |
915 | if (!es8326->jack) |
916 | goto out; |
917 | |
918 | if (es8326->jack->status & SND_JACK_HEADSET) |
919 | queue_delayed_work(wq: system_wq, dwork: &es8326->jack_detect_work, |
920 | delay: msecs_to_jiffies(m: 10)); |
921 | else |
922 | queue_delayed_work(wq: system_wq, dwork: &es8326->jack_detect_work, |
923 | delay: msecs_to_jiffies(m: 300)); |
924 | |
925 | out: |
926 | return IRQ_HANDLED; |
927 | } |
928 | |
929 | static int es8326_calibrate(struct snd_soc_component *component) |
930 | { |
931 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
932 | unsigned int reg; |
933 | unsigned int offset_l, offset_r; |
934 | |
935 | regmap_read(map: es8326->regmap, ES8326_CHIP_VERSION, val: ®); |
936 | es8326->version = reg; |
937 | |
938 | if ((es8326->version == ES8326_VERSION_B) && (es8326->calibrated == false)) { |
939 | dev_dbg(component->dev, "ES8326_VERSION_B, calibrating\n" ); |
940 | regmap_write(map: es8326->regmap, ES8326_CLK_INV, val: 0xc0); |
941 | regmap_write(map: es8326->regmap, ES8326_CLK_DIV1, val: 0x03); |
942 | regmap_write(map: es8326->regmap, ES8326_CLK_DLL, val: 0x30); |
943 | regmap_write(map: es8326->regmap, ES8326_CLK_MUX, val: 0xed); |
944 | regmap_write(map: es8326->regmap, ES8326_CLK_DAC_SEL, val: 0x08); |
945 | regmap_write(map: es8326->regmap, ES8326_CLK_TRI, val: 0xc1); |
946 | regmap_write(map: es8326->regmap, ES8326_DAC_MUTE, val: 0x03); |
947 | regmap_write(map: es8326->regmap, ES8326_ANA_VSEL, val: 0x7f); |
948 | regmap_write(map: es8326->regmap, ES8326_VMIDLOW, val: 0x23); |
949 | regmap_write(map: es8326->regmap, ES8326_DAC2HPMIX, val: 0x88); |
950 | usleep_range(min: 15000, max: 20000); |
951 | regmap_write(map: es8326->regmap, ES8326_HP_OFFSET_CAL, val: 0x8c); |
952 | usleep_range(min: 15000, max: 20000); |
953 | regmap_write(map: es8326->regmap, ES8326_RESET, val: 0xc0); |
954 | usleep_range(min: 15000, max: 20000); |
955 | |
956 | regmap_write(map: es8326->regmap, ES8326_HP_OFFSET_CAL, ES8326_HP_OFF); |
957 | regmap_read(map: es8326->regmap, ES8326_CSM_MUTE_STA, val: ®); |
958 | if ((reg & 0xf0) != 0x40) |
959 | msleep(msecs: 50); |
960 | |
961 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, val: 0xd4); |
962 | msleep(msecs: 200); |
963 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, val: 0x4d); |
964 | msleep(msecs: 200); |
965 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, ES8326_HP_OFF); |
966 | regmap_read(map: es8326->regmap, ES8326_HPL_OFFSET_INI, val: &offset_l); |
967 | regmap_read(map: es8326->regmap, ES8326_HPR_OFFSET_INI, val: &offset_r); |
968 | regmap_write(map: es8326->regmap, ES8326_HP_OFFSET_CAL, val: 0x8c); |
969 | regmap_write(map: es8326->regmap, ES8326_HPL_OFFSET_INI, val: offset_l); |
970 | regmap_write(map: es8326->regmap, ES8326_HPR_OFFSET_INI, val: offset_r); |
971 | regmap_write(map: es8326->regmap, ES8326_CLK_INV, val: 0x00); |
972 | |
973 | es8326->calibrated = true; |
974 | } |
975 | |
976 | return 0; |
977 | } |
978 | |
979 | static int es8326_resume(struct snd_soc_component *component) |
980 | { |
981 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
982 | |
983 | regcache_cache_only(map: es8326->regmap, enable: false); |
984 | regcache_sync(map: es8326->regmap); |
985 | |
986 | /* reset internal clock state */ |
987 | regmap_write(map: es8326->regmap, ES8326_RESET, val: 0x1f); |
988 | regmap_write(map: es8326->regmap, ES8326_VMIDSEL, val: 0x0E); |
989 | regmap_write(map: es8326->regmap, ES8326_ANA_LP, val: 0xf0); |
990 | usleep_range(min: 10000, max: 15000); |
991 | regmap_write(map: es8326->regmap, ES8326_HPJACK_TIMER, val: 0xd9); |
992 | regmap_write(map: es8326->regmap, ES8326_ANA_MICBIAS, val: 0xcb); |
993 | /* set headphone default type and detect pin */ |
994 | regmap_write(map: es8326->regmap, ES8326_HPDET_TYPE, val: 0x83); |
995 | regmap_write(map: es8326->regmap, ES8326_CLK_RESAMPLE, val: 0x05); |
996 | |
997 | /* set internal oscillator as clock source of headpone cp */ |
998 | regmap_write(map: es8326->regmap, ES8326_CLK_DIV_CPC, val: 0x89); |
999 | regmap_write(map: es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_ON); |
1000 | /* clock manager reset release */ |
1001 | regmap_write(map: es8326->regmap, ES8326_RESET, val: 0x17); |
1002 | /* set headphone detection as half scan mode */ |
1003 | regmap_write(map: es8326->regmap, ES8326_HP_MISC, val: 0x3d); |
1004 | regmap_write(map: es8326->regmap, ES8326_PULLUP_CTL, val: 0x00); |
1005 | |
1006 | /* enable headphone driver */ |
1007 | regmap_write(map: es8326->regmap, ES8326_HP_VOL, val: 0xc4); |
1008 | regmap_write(map: es8326->regmap, ES8326_HP_DRIVER, val: 0xa7); |
1009 | usleep_range(min: 2000, max: 5000); |
1010 | regmap_write(map: es8326->regmap, ES8326_HP_DRIVER_REF, val: 0x23); |
1011 | regmap_write(map: es8326->regmap, ES8326_HP_DRIVER_REF, val: 0x33); |
1012 | regmap_write(map: es8326->regmap, ES8326_HP_DRIVER, val: 0xa1); |
1013 | |
1014 | regmap_write(map: es8326->regmap, ES8326_CLK_INV, val: 0x00); |
1015 | regmap_write(map: es8326->regmap, ES8326_CLK_VMIDS1, val: 0xc4); |
1016 | regmap_write(map: es8326->regmap, ES8326_CLK_VMIDS2, val: 0x81); |
1017 | regmap_write(map: es8326->regmap, ES8326_CLK_CAL_TIME, val: 0x00); |
1018 | /* calibrate for B version */ |
1019 | es8326_calibrate(component); |
1020 | regmap_write(map: es8326->regmap, ES8326_DAC_CROSSTALK, val: 0xaa); |
1021 | regmap_write(map: es8326->regmap, ES8326_DAC_RAMPRATE, val: 0x00); |
1022 | /* turn off headphone out */ |
1023 | regmap_write(map: es8326->regmap, ES8326_HP_CAL, val: 0x00); |
1024 | /* set ADC and DAC in low power mode */ |
1025 | regmap_write(map: es8326->regmap, ES8326_ANA_LP, val: 0xf0); |
1026 | |
1027 | regmap_write(map: es8326->regmap, ES8326_ANA_VSEL, val: 0x7F); |
1028 | /* select vdda as micbias source */ |
1029 | regmap_write(map: es8326->regmap, ES8326_VMIDLOW, val: 0x23); |
1030 | /* set dac dsmclip = 1 */ |
1031 | regmap_write(map: es8326->regmap, ES8326_DAC_DSM, val: 0x08); |
1032 | regmap_write(map: es8326->regmap, ES8326_DAC_VPPSCALE, val: 0x15); |
1033 | |
1034 | regmap_write(map: es8326->regmap, ES8326_HPDET_TYPE, val: 0x80 | |
1035 | ((es8326->version == ES8326_VERSION_B) ? |
1036 | (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol) : |
1037 | (ES8326_HP_DET_SRC_PIN9 | es8326->jack_pol | 0x04))); |
1038 | usleep_range(min: 5000, max: 10000); |
1039 | es8326_enable_micbias(component: es8326->component); |
1040 | usleep_range(min: 50000, max: 70000); |
1041 | regmap_update_bits(map: es8326->regmap, ES8326_HPDET_TYPE, mask: 0x03, val: 0x00); |
1042 | regmap_write(map: es8326->regmap, ES8326_INT_SOURCE, ES8326_INT_SRC_PIN9); |
1043 | regmap_write(map: es8326->regmap, ES8326_INTOUT_IO, |
1044 | val: es8326->interrupt_clk); |
1045 | regmap_write(map: es8326->regmap, ES8326_SDINOUT1_IO, |
1046 | val: (ES8326_IO_DMIC_CLK << ES8326_SDINOUT1_SHIFT)); |
1047 | regmap_write(map: es8326->regmap, ES8326_SDINOUT23_IO, ES8326_IO_INPUT); |
1048 | |
1049 | regmap_write(map: es8326->regmap, ES8326_ANA_PDN, val: 0x00); |
1050 | regmap_write(map: es8326->regmap, ES8326_RESET, ES8326_CSM_ON); |
1051 | regmap_update_bits(map: es8326->regmap, ES8326_PGAGAIN, ES8326_MIC_SEL_MASK, |
1052 | ES8326_MIC1_SEL); |
1053 | |
1054 | regmap_update_bits(map: es8326->regmap, ES8326_DAC_MUTE, ES8326_MUTE_MASK, |
1055 | ES8326_MUTE); |
1056 | |
1057 | regmap_write(map: es8326->regmap, ES8326_ADC_MUTE, val: 0x0f); |
1058 | |
1059 | es8326->jack_remove_retry = 0; |
1060 | es8326->hp = 0; |
1061 | es8326->hpl_vol = 0x03; |
1062 | es8326->hpr_vol = 0x03; |
1063 | |
1064 | es8326_irq(irq: es8326->irq, dev_id: es8326); |
1065 | return 0; |
1066 | } |
1067 | |
1068 | static int es8326_suspend(struct snd_soc_component *component) |
1069 | { |
1070 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
1071 | |
1072 | cancel_delayed_work_sync(dwork: &es8326->jack_detect_work); |
1073 | es8326_disable_micbias(component); |
1074 | es8326->calibrated = false; |
1075 | regmap_write(map: es8326->regmap, ES8326_CLK_MUX, val: 0x2d); |
1076 | regmap_write(map: es8326->regmap, ES8326_DAC2HPMIX, val: 0x00); |
1077 | regmap_write(map: es8326->regmap, ES8326_ANA_PDN, val: 0x3b); |
1078 | regmap_write(map: es8326->regmap, ES8326_CLK_CTL, ES8326_CLK_OFF); |
1079 | regcache_cache_only(map: es8326->regmap, enable: true); |
1080 | regcache_mark_dirty(map: es8326->regmap); |
1081 | |
1082 | /* reset register value to default */ |
1083 | regmap_write(map: es8326->regmap, ES8326_CSM_I2C_STA, val: 0x01); |
1084 | usleep_range(min: 1000, max: 3000); |
1085 | regmap_write(map: es8326->regmap, ES8326_CSM_I2C_STA, val: 0x00); |
1086 | return 0; |
1087 | } |
1088 | |
1089 | static int es8326_probe(struct snd_soc_component *component) |
1090 | { |
1091 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
1092 | int ret; |
1093 | |
1094 | es8326->component = component; |
1095 | es8326->jd_inverted = device_property_read_bool(dev: component->dev, |
1096 | propname: "everest,jack-detect-inverted" ); |
1097 | |
1098 | ret = device_property_read_u8(dev: component->dev, propname: "everest,jack-pol" , val: &es8326->jack_pol); |
1099 | if (ret != 0) { |
1100 | dev_dbg(component->dev, "jack-pol return %d" , ret); |
1101 | es8326->jack_pol = ES8326_HP_TYPE_AUTO; |
1102 | } |
1103 | dev_dbg(component->dev, "jack-pol %x" , es8326->jack_pol); |
1104 | |
1105 | ret = device_property_read_u8(dev: component->dev, propname: "everest,interrupt-src" , |
1106 | val: &es8326->interrupt_src); |
1107 | if (ret != 0) { |
1108 | dev_dbg(component->dev, "interrupt-src return %d" , ret); |
1109 | es8326->interrupt_src = ES8326_HP_DET_SRC_PIN9; |
1110 | } |
1111 | dev_dbg(component->dev, "interrupt-src %x" , es8326->interrupt_src); |
1112 | |
1113 | ret = device_property_read_u8(dev: component->dev, propname: "everest,interrupt-clk" , |
1114 | val: &es8326->interrupt_clk); |
1115 | if (ret != 0) { |
1116 | dev_dbg(component->dev, "interrupt-clk return %d" , ret); |
1117 | es8326->interrupt_clk = 0x00; |
1118 | } |
1119 | dev_dbg(component->dev, "interrupt-clk %x" , es8326->interrupt_clk); |
1120 | |
1121 | es8326_resume(component); |
1122 | return 0; |
1123 | } |
1124 | |
1125 | static void es8326_enable_jack_detect(struct snd_soc_component *component, |
1126 | struct snd_soc_jack *jack) |
1127 | { |
1128 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
1129 | |
1130 | mutex_lock(&es8326->lock); |
1131 | if (es8326->jd_inverted) |
1132 | snd_soc_component_update_bits(component, ES8326_HPDET_TYPE, |
1133 | ES8326_HP_DET_JACK_POL, val: ~es8326->jack_pol); |
1134 | es8326->jack = jack; |
1135 | |
1136 | mutex_unlock(lock: &es8326->lock); |
1137 | es8326_irq(irq: es8326->irq, dev_id: es8326); |
1138 | } |
1139 | |
1140 | static void es8326_disable_jack_detect(struct snd_soc_component *component) |
1141 | { |
1142 | struct es8326_priv *es8326 = snd_soc_component_get_drvdata(c: component); |
1143 | |
1144 | dev_dbg(component->dev, "Enter into %s\n" , __func__); |
1145 | if (!es8326->jack) |
1146 | return; /* Already disabled (or never enabled) */ |
1147 | cancel_delayed_work_sync(dwork: &es8326->jack_detect_work); |
1148 | |
1149 | mutex_lock(&es8326->lock); |
1150 | if (es8326->jack->status & SND_JACK_MICROPHONE) { |
1151 | es8326_disable_micbias(component); |
1152 | snd_soc_jack_report(jack: es8326->jack, status: 0, mask: SND_JACK_HEADSET); |
1153 | } |
1154 | es8326->jack = NULL; |
1155 | mutex_unlock(lock: &es8326->lock); |
1156 | } |
1157 | |
1158 | static int es8326_set_jack(struct snd_soc_component *component, |
1159 | struct snd_soc_jack *jack, void *data) |
1160 | { |
1161 | if (jack) |
1162 | es8326_enable_jack_detect(component, jack); |
1163 | else |
1164 | es8326_disable_jack_detect(component); |
1165 | |
1166 | return 0; |
1167 | } |
1168 | |
1169 | static void es8326_remove(struct snd_soc_component *component) |
1170 | { |
1171 | es8326_disable_jack_detect(component); |
1172 | es8326_set_bias_level(codec: component, level: SND_SOC_BIAS_OFF); |
1173 | } |
1174 | |
1175 | static const struct snd_soc_component_driver soc_component_dev_es8326 = { |
1176 | .probe = es8326_probe, |
1177 | .remove = es8326_remove, |
1178 | .resume = es8326_resume, |
1179 | .suspend = es8326_suspend, |
1180 | .set_bias_level = es8326_set_bias_level, |
1181 | .set_jack = es8326_set_jack, |
1182 | .dapm_widgets = es8326_dapm_widgets, |
1183 | .num_dapm_widgets = ARRAY_SIZE(es8326_dapm_widgets), |
1184 | .dapm_routes = es8326_dapm_routes, |
1185 | .num_dapm_routes = ARRAY_SIZE(es8326_dapm_routes), |
1186 | .controls = es8326_snd_controls, |
1187 | .num_controls = ARRAY_SIZE(es8326_snd_controls), |
1188 | .use_pmdown_time = 1, |
1189 | .endianness = 1, |
1190 | }; |
1191 | |
1192 | static int es8326_i2c_probe(struct i2c_client *i2c) |
1193 | { |
1194 | struct es8326_priv *es8326; |
1195 | int ret; |
1196 | |
1197 | es8326 = devm_kzalloc(dev: &i2c->dev, size: sizeof(struct es8326_priv), GFP_KERNEL); |
1198 | if (!es8326) |
1199 | return -ENOMEM; |
1200 | |
1201 | i2c_set_clientdata(client: i2c, data: es8326); |
1202 | es8326->i2c = i2c; |
1203 | mutex_init(&es8326->lock); |
1204 | es8326->regmap = devm_regmap_init_i2c(i2c, &es8326_regmap_config); |
1205 | if (IS_ERR(ptr: es8326->regmap)) { |
1206 | ret = PTR_ERR(ptr: es8326->regmap); |
1207 | dev_err(&i2c->dev, "Failed to init regmap: %d\n" , ret); |
1208 | return ret; |
1209 | } |
1210 | |
1211 | es8326->irq = i2c->irq; |
1212 | INIT_DELAYED_WORK(&es8326->jack_detect_work, |
1213 | es8326_jack_detect_handler); |
1214 | INIT_DELAYED_WORK(&es8326->button_press_work, |
1215 | es8326_jack_button_handler); |
1216 | /* ES8316 is level-based while ES8326 is edge-based */ |
1217 | ret = devm_request_threaded_irq(dev: &i2c->dev, irq: es8326->irq, NULL, thread_fn: es8326_irq, |
1218 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
1219 | devname: "es8326" , dev_id: es8326); |
1220 | if (ret) { |
1221 | dev_warn(&i2c->dev, "Failed to request IRQ: %d: %d\n" , |
1222 | es8326->irq, ret); |
1223 | es8326->irq = -ENXIO; |
1224 | } |
1225 | |
1226 | es8326->mclk = devm_clk_get_optional(dev: &i2c->dev, id: "mclk" ); |
1227 | if (IS_ERR(ptr: es8326->mclk)) { |
1228 | dev_err(&i2c->dev, "unable to get mclk\n" ); |
1229 | return PTR_ERR(ptr: es8326->mclk); |
1230 | } |
1231 | if (!es8326->mclk) |
1232 | dev_warn(&i2c->dev, "assuming static mclk\n" ); |
1233 | |
1234 | ret = clk_prepare_enable(clk: es8326->mclk); |
1235 | if (ret) { |
1236 | dev_err(&i2c->dev, "unable to enable mclk\n" ); |
1237 | return ret; |
1238 | } |
1239 | return devm_snd_soc_register_component(dev: &i2c->dev, |
1240 | component_driver: &soc_component_dev_es8326, |
1241 | dai_drv: &es8326_dai, num_dai: 1); |
1242 | } |
1243 | |
1244 | static const struct i2c_device_id es8326_i2c_id[] = { |
1245 | {"es8326" , 0 }, |
1246 | {} |
1247 | }; |
1248 | MODULE_DEVICE_TABLE(i2c, es8326_i2c_id); |
1249 | |
1250 | #ifdef CONFIG_OF |
1251 | static const struct of_device_id es8326_of_match[] = { |
1252 | { .compatible = "everest,es8326" , }, |
1253 | {} |
1254 | }; |
1255 | MODULE_DEVICE_TABLE(of, es8326_of_match); |
1256 | #endif |
1257 | |
1258 | #ifdef CONFIG_ACPI |
1259 | static const struct acpi_device_id es8326_acpi_match[] = { |
1260 | {"ESSX8326" , 0}, |
1261 | {}, |
1262 | }; |
1263 | MODULE_DEVICE_TABLE(acpi, es8326_acpi_match); |
1264 | #endif |
1265 | |
1266 | static struct i2c_driver es8326_i2c_driver = { |
1267 | .driver = { |
1268 | .name = "es8326" , |
1269 | .acpi_match_table = ACPI_PTR(es8326_acpi_match), |
1270 | .of_match_table = of_match_ptr(es8326_of_match), |
1271 | }, |
1272 | .probe = es8326_i2c_probe, |
1273 | .id_table = es8326_i2c_id, |
1274 | }; |
1275 | module_i2c_driver(es8326_i2c_driver); |
1276 | |
1277 | MODULE_DESCRIPTION("ASoC es8326 driver" ); |
1278 | MODULE_AUTHOR("David Yang <yangxiaohua@everest-semi.com>" ); |
1279 | MODULE_LICENSE("GPL" ); |
1280 | |