1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * rt298.c -- RT298 ALSA SoC audio codec driver |
4 | * |
5 | * Copyright 2015 Realtek Semiconductor Corp. |
6 | * Author: Bard Liao <bardliao@realtek.com> |
7 | */ |
8 | |
9 | #include <linux/module.h> |
10 | #include <linux/moduleparam.h> |
11 | #include <linux/init.h> |
12 | #include <linux/delay.h> |
13 | #include <linux/pm.h> |
14 | #include <linux/i2c.h> |
15 | #include <linux/platform_device.h> |
16 | #include <linux/spi/spi.h> |
17 | #include <linux/dmi.h> |
18 | #include <linux/acpi.h> |
19 | #include <sound/core.h> |
20 | #include <sound/pcm.h> |
21 | #include <sound/pcm_params.h> |
22 | #include <sound/soc.h> |
23 | #include <sound/soc-dapm.h> |
24 | #include <sound/initval.h> |
25 | #include <sound/tlv.h> |
26 | #include <sound/jack.h> |
27 | #include <linux/workqueue.h> |
28 | #include <sound/rt298.h> |
29 | |
30 | #include "rl6347a.h" |
31 | #include "rt298.h" |
32 | |
33 | #define RT298_VENDOR_ID 0x10ec0298 |
34 | |
35 | struct rt298_priv { |
36 | struct reg_default *index_cache; |
37 | int index_cache_size; |
38 | struct regmap *regmap; |
39 | struct snd_soc_component *component; |
40 | struct rt298_platform_data pdata; |
41 | struct i2c_client *i2c; |
42 | struct snd_soc_jack *jack; |
43 | struct delayed_work jack_detect_work; |
44 | int sys_clk; |
45 | int clk_id; |
46 | int is_hp_in; |
47 | }; |
48 | |
49 | static const struct reg_default rt298_index_def[] = { |
50 | { 0x01, 0xa5a8 }, |
51 | { 0x02, 0x8e95 }, |
52 | { 0x03, 0x0002 }, |
53 | { 0x04, 0xaf67 }, |
54 | { 0x08, 0x200f }, |
55 | { 0x09, 0xd010 }, |
56 | { 0x0a, 0x0100 }, |
57 | { 0x0b, 0x0000 }, |
58 | { 0x0d, 0x2800 }, |
59 | { 0x0f, 0x0022 }, |
60 | { 0x19, 0x0217 }, |
61 | { 0x20, 0x0020 }, |
62 | { 0x33, 0x0208 }, |
63 | { 0x46, 0x0300 }, |
64 | { 0x49, 0x4004 }, |
65 | { 0x4f, 0x50c9 }, |
66 | { 0x50, 0x3000 }, |
67 | { 0x63, 0x1b02 }, |
68 | { 0x67, 0x1111 }, |
69 | { 0x68, 0x1016 }, |
70 | { 0x69, 0x273f }, |
71 | }; |
72 | #define INDEX_CACHE_SIZE ARRAY_SIZE(rt298_index_def) |
73 | |
74 | static const struct reg_default rt298_reg[] = { |
75 | { 0x00170500, 0x00000400 }, |
76 | { 0x00220000, 0x00000031 }, |
77 | { 0x00239000, 0x0000007f }, |
78 | { 0x0023a000, 0x0000007f }, |
79 | { 0x00270500, 0x00000400 }, |
80 | { 0x00370500, 0x00000400 }, |
81 | { 0x00870500, 0x00000400 }, |
82 | { 0x00920000, 0x00000031 }, |
83 | { 0x00935000, 0x000000c3 }, |
84 | { 0x00936000, 0x000000c3 }, |
85 | { 0x00970500, 0x00000400 }, |
86 | { 0x00b37000, 0x00000097 }, |
87 | { 0x00b37200, 0x00000097 }, |
88 | { 0x00b37300, 0x00000097 }, |
89 | { 0x00c37000, 0x00000000 }, |
90 | { 0x00c37100, 0x00000080 }, |
91 | { 0x01270500, 0x00000400 }, |
92 | { 0x01370500, 0x00000400 }, |
93 | { 0x01371f00, 0x411111f0 }, |
94 | { 0x01439000, 0x00000080 }, |
95 | { 0x0143a000, 0x00000080 }, |
96 | { 0x01470700, 0x00000000 }, |
97 | { 0x01470500, 0x00000400 }, |
98 | { 0x01470c00, 0x00000000 }, |
99 | { 0x01470100, 0x00000000 }, |
100 | { 0x01837000, 0x00000000 }, |
101 | { 0x01870500, 0x00000400 }, |
102 | { 0x02050000, 0x00000000 }, |
103 | { 0x02139000, 0x00000080 }, |
104 | { 0x0213a000, 0x00000080 }, |
105 | { 0x02170100, 0x00000000 }, |
106 | { 0x02170500, 0x00000400 }, |
107 | { 0x02170700, 0x00000000 }, |
108 | { 0x02270100, 0x00000000 }, |
109 | { 0x02370100, 0x00000000 }, |
110 | { 0x01870700, 0x00000020 }, |
111 | { 0x00830000, 0x000000c3 }, |
112 | { 0x00930000, 0x000000c3 }, |
113 | { 0x01270700, 0x00000000 }, |
114 | }; |
115 | |
116 | static bool rt298_volatile_register(struct device *dev, unsigned int reg) |
117 | { |
118 | switch (reg) { |
119 | case 0 ... 0xff: |
120 | case RT298_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): |
121 | case RT298_GET_HP_SENSE: |
122 | case RT298_GET_MIC1_SENSE: |
123 | case RT298_PROC_COEF: |
124 | case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_MIC1, 0): |
125 | case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_SPK_OUT, 0): |
126 | case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0): |
127 | return true; |
128 | default: |
129 | return false; |
130 | } |
131 | |
132 | |
133 | } |
134 | |
135 | static bool rt298_readable_register(struct device *dev, unsigned int reg) |
136 | { |
137 | switch (reg) { |
138 | case 0 ... 0xff: |
139 | case RT298_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID): |
140 | case RT298_GET_HP_SENSE: |
141 | case RT298_GET_MIC1_SENSE: |
142 | case RT298_SET_AUDIO_POWER: |
143 | case RT298_SET_HPO_POWER: |
144 | case RT298_SET_SPK_POWER: |
145 | case RT298_SET_DMIC1_POWER: |
146 | case RT298_SPK_MUX: |
147 | case RT298_HPO_MUX: |
148 | case RT298_ADC0_MUX: |
149 | case RT298_ADC1_MUX: |
150 | case RT298_SET_MIC1: |
151 | case RT298_SET_PIN_HPO: |
152 | case RT298_SET_PIN_SPK: |
153 | case RT298_SET_PIN_DMIC1: |
154 | case RT298_SPK_EAPD: |
155 | case RT298_SET_AMP_GAIN_HPO: |
156 | case RT298_SET_DMIC2_DEFAULT: |
157 | case RT298_DACL_GAIN: |
158 | case RT298_DACR_GAIN: |
159 | case RT298_ADCL_GAIN: |
160 | case RT298_ADCR_GAIN: |
161 | case RT298_MIC_GAIN: |
162 | case RT298_SPOL_GAIN: |
163 | case RT298_SPOR_GAIN: |
164 | case RT298_HPOL_GAIN: |
165 | case RT298_HPOR_GAIN: |
166 | case RT298_F_DAC_SWITCH: |
167 | case RT298_F_RECMIX_SWITCH: |
168 | case RT298_REC_MIC_SWITCH: |
169 | case RT298_REC_I2S_SWITCH: |
170 | case RT298_REC_LINE_SWITCH: |
171 | case RT298_REC_BEEP_SWITCH: |
172 | case RT298_DAC_FORMAT: |
173 | case RT298_ADC_FORMAT: |
174 | case RT298_COEF_INDEX: |
175 | case RT298_PROC_COEF: |
176 | case RT298_SET_AMP_GAIN_ADC_IN1: |
177 | case RT298_SET_AMP_GAIN_ADC_IN2: |
178 | case RT298_SET_POWER(RT298_DAC_OUT1): |
179 | case RT298_SET_POWER(RT298_DAC_OUT2): |
180 | case RT298_SET_POWER(RT298_ADC_IN1): |
181 | case RT298_SET_POWER(RT298_ADC_IN2): |
182 | case RT298_SET_POWER(RT298_DMIC2): |
183 | case RT298_SET_POWER(RT298_MIC1): |
184 | case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_MIC1, 0): |
185 | case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_SPK_OUT, 0): |
186 | case VERB_CMD(AC_VERB_GET_EAPD_BTLENABLE, RT298_HP_OUT, 0): |
187 | return true; |
188 | default: |
189 | return false; |
190 | } |
191 | } |
192 | |
193 | #ifdef CONFIG_PM |
194 | static void rt298_index_sync(struct snd_soc_component *component) |
195 | { |
196 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
197 | int i; |
198 | |
199 | for (i = 0; i < INDEX_CACHE_SIZE; i++) { |
200 | snd_soc_component_write(component, reg: rt298->index_cache[i].reg, |
201 | val: rt298->index_cache[i].def); |
202 | } |
203 | } |
204 | #endif |
205 | |
206 | static int rt298_support_power_controls[] = { |
207 | RT298_DAC_OUT1, |
208 | RT298_DAC_OUT2, |
209 | RT298_ADC_IN1, |
210 | RT298_ADC_IN2, |
211 | RT298_MIC1, |
212 | RT298_DMIC1, |
213 | RT298_DMIC2, |
214 | RT298_SPK_OUT, |
215 | RT298_HP_OUT, |
216 | }; |
217 | #define RT298_POWER_REG_LEN ARRAY_SIZE(rt298_support_power_controls) |
218 | |
219 | static int rt298_jack_detect(struct rt298_priv *rt298, bool *hp, bool *mic) |
220 | { |
221 | struct snd_soc_dapm_context *dapm; |
222 | unsigned int val, buf; |
223 | |
224 | *hp = false; |
225 | *mic = false; |
226 | |
227 | if (!rt298->component) |
228 | return -EINVAL; |
229 | |
230 | dapm = snd_soc_component_get_dapm(component: rt298->component); |
231 | |
232 | if (rt298->pdata.cbj_en) { |
233 | regmap_read(map: rt298->regmap, RT298_GET_HP_SENSE, val: &buf); |
234 | *hp = buf & 0x80000000; |
235 | if (*hp == rt298->is_hp_in) |
236 | return -1; |
237 | rt298->is_hp_in = *hp; |
238 | if (*hp) { |
239 | /* power on HV,VERF */ |
240 | regmap_update_bits(map: rt298->regmap, |
241 | RT298_DC_GAIN, mask: 0x200, val: 0x200); |
242 | |
243 | snd_soc_dapm_force_enable_pin(dapm, pin: "HV" ); |
244 | snd_soc_dapm_force_enable_pin(dapm, pin: "VREF" ); |
245 | /* power LDO1 */ |
246 | snd_soc_dapm_force_enable_pin(dapm, pin: "LDO1" ); |
247 | snd_soc_dapm_sync(dapm); |
248 | |
249 | regmap_update_bits(map: rt298->regmap, |
250 | RT298_POWER_CTRL1, mask: 0x1001, val: 0); |
251 | regmap_update_bits(map: rt298->regmap, |
252 | RT298_POWER_CTRL2, mask: 0x4, val: 0x4); |
253 | |
254 | regmap_write(map: rt298->regmap, RT298_SET_MIC1, val: 0x24); |
255 | msleep(msecs: 50); |
256 | |
257 | regmap_update_bits(map: rt298->regmap, |
258 | RT298_CBJ_CTRL1, mask: 0xfcc0, val: 0xd400); |
259 | msleep(msecs: 300); |
260 | regmap_read(map: rt298->regmap, RT298_CBJ_CTRL2, val: &val); |
261 | |
262 | if (0x0070 == (val & 0x0070)) { |
263 | *mic = true; |
264 | } else { |
265 | regmap_update_bits(map: rt298->regmap, |
266 | RT298_CBJ_CTRL1, mask: 0xfcc0, val: 0xe400); |
267 | msleep(msecs: 300); |
268 | regmap_read(map: rt298->regmap, |
269 | RT298_CBJ_CTRL2, val: &val); |
270 | if (0x0070 == (val & 0x0070)) { |
271 | *mic = true; |
272 | } else { |
273 | *mic = false; |
274 | regmap_update_bits(map: rt298->regmap, |
275 | RT298_CBJ_CTRL1, |
276 | mask: 0xfcc0, val: 0xc400); |
277 | } |
278 | } |
279 | |
280 | regmap_update_bits(map: rt298->regmap, |
281 | RT298_DC_GAIN, mask: 0x200, val: 0x0); |
282 | |
283 | } else { |
284 | *mic = false; |
285 | regmap_write(map: rt298->regmap, RT298_SET_MIC1, val: 0x20); |
286 | regmap_update_bits(map: rt298->regmap, |
287 | RT298_CBJ_CTRL1, mask: 0x0400, val: 0x0000); |
288 | } |
289 | } else { |
290 | regmap_read(map: rt298->regmap, RT298_GET_HP_SENSE, val: &buf); |
291 | *hp = buf & 0x80000000; |
292 | regmap_read(map: rt298->regmap, RT298_GET_MIC1_SENSE, val: &buf); |
293 | *mic = buf & 0x80000000; |
294 | } |
295 | if (!*mic) { |
296 | snd_soc_dapm_disable_pin(dapm, pin: "HV" ); |
297 | snd_soc_dapm_disable_pin(dapm, pin: "VREF" ); |
298 | } |
299 | if (!*hp) |
300 | snd_soc_dapm_disable_pin(dapm, pin: "LDO1" ); |
301 | snd_soc_dapm_sync(dapm); |
302 | |
303 | pr_debug("*hp = %d *mic = %d\n" , *hp, *mic); |
304 | |
305 | return 0; |
306 | } |
307 | |
308 | static void rt298_jack_detect_work(struct work_struct *work) |
309 | { |
310 | struct rt298_priv *rt298 = |
311 | container_of(work, struct rt298_priv, jack_detect_work.work); |
312 | int status = 0; |
313 | bool hp = false; |
314 | bool mic = false; |
315 | |
316 | if (rt298_jack_detect(rt298, hp: &hp, mic: &mic) < 0) |
317 | return; |
318 | |
319 | if (hp) |
320 | status |= SND_JACK_HEADPHONE; |
321 | |
322 | if (mic) |
323 | status |= SND_JACK_MICROPHONE; |
324 | |
325 | snd_soc_jack_report(jack: rt298->jack, status, |
326 | mask: SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); |
327 | } |
328 | |
329 | static int rt298_mic_detect(struct snd_soc_component *component, |
330 | struct snd_soc_jack *jack, void *data) |
331 | { |
332 | struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component); |
333 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
334 | |
335 | rt298->jack = jack; |
336 | |
337 | if (jack) { |
338 | /* Enable IRQ */ |
339 | if (rt298->jack->status & SND_JACK_HEADPHONE) |
340 | snd_soc_dapm_force_enable_pin(dapm, pin: "LDO1" ); |
341 | if (rt298->jack->status & SND_JACK_MICROPHONE) { |
342 | snd_soc_dapm_force_enable_pin(dapm, pin: "HV" ); |
343 | snd_soc_dapm_force_enable_pin(dapm, pin: "VREF" ); |
344 | } |
345 | regmap_update_bits(map: rt298->regmap, RT298_IRQ_CTRL, mask: 0x2, val: 0x2); |
346 | /* Send an initial empty report */ |
347 | snd_soc_jack_report(jack: rt298->jack, status: rt298->jack->status, |
348 | mask: SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); |
349 | } else { |
350 | /* Disable IRQ */ |
351 | regmap_update_bits(map: rt298->regmap, RT298_IRQ_CTRL, mask: 0x2, val: 0x0); |
352 | snd_soc_dapm_disable_pin(dapm, pin: "HV" ); |
353 | snd_soc_dapm_disable_pin(dapm, pin: "VREF" ); |
354 | snd_soc_dapm_disable_pin(dapm, pin: "LDO1" ); |
355 | } |
356 | snd_soc_dapm_sync(dapm); |
357 | |
358 | return 0; |
359 | } |
360 | |
361 | static int is_mclk_mode(struct snd_soc_dapm_widget *source, |
362 | struct snd_soc_dapm_widget *sink) |
363 | { |
364 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: source->dapm); |
365 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
366 | |
367 | if (rt298->clk_id == RT298_SCLK_S_MCLK) |
368 | return 1; |
369 | else |
370 | return 0; |
371 | } |
372 | |
373 | static const DECLARE_TLV_DB_SCALE(out_vol_tlv, -6350, 50, 0); |
374 | static const DECLARE_TLV_DB_SCALE(mic_vol_tlv, 0, 1000, 0); |
375 | |
376 | static const struct snd_kcontrol_new rt298_snd_controls[] = { |
377 | SOC_DOUBLE_R_TLV("DAC0 Playback Volume" , RT298_DACL_GAIN, |
378 | RT298_DACR_GAIN, 0, 0x7f, 0, out_vol_tlv), |
379 | SOC_DOUBLE_R_TLV("ADC0 Capture Volume" , RT298_ADCL_GAIN, |
380 | RT298_ADCR_GAIN, 0, 0x7f, 0, out_vol_tlv), |
381 | SOC_SINGLE_TLV("AMIC Volume" , RT298_MIC_GAIN, |
382 | 0, 0x3, 0, mic_vol_tlv), |
383 | SOC_DOUBLE_R("Speaker Playback Switch" , RT298_SPOL_GAIN, |
384 | RT298_SPOR_GAIN, RT298_MUTE_SFT, 1, 1), |
385 | }; |
386 | |
387 | /* Digital Mixer */ |
388 | static const struct snd_kcontrol_new rt298_front_mix[] = { |
389 | SOC_DAPM_SINGLE("DAC Switch" , RT298_F_DAC_SWITCH, |
390 | RT298_MUTE_SFT, 1, 1), |
391 | SOC_DAPM_SINGLE("RECMIX Switch" , RT298_F_RECMIX_SWITCH, |
392 | RT298_MUTE_SFT, 1, 1), |
393 | }; |
394 | |
395 | /* Analog Input Mixer */ |
396 | static const struct snd_kcontrol_new rt298_rec_mix[] = { |
397 | SOC_DAPM_SINGLE("Mic1 Switch" , RT298_REC_MIC_SWITCH, |
398 | RT298_MUTE_SFT, 1, 1), |
399 | SOC_DAPM_SINGLE("I2S Switch" , RT298_REC_I2S_SWITCH, |
400 | RT298_MUTE_SFT, 1, 1), |
401 | SOC_DAPM_SINGLE("Line1 Switch" , RT298_REC_LINE_SWITCH, |
402 | RT298_MUTE_SFT, 1, 1), |
403 | SOC_DAPM_SINGLE("Beep Switch" , RT298_REC_BEEP_SWITCH, |
404 | RT298_MUTE_SFT, 1, 1), |
405 | }; |
406 | |
407 | static const struct snd_kcontrol_new spo_enable_control = |
408 | SOC_DAPM_SINGLE("Switch" , RT298_SET_PIN_SPK, |
409 | RT298_SET_PIN_SFT, 1, 0); |
410 | |
411 | static const struct snd_kcontrol_new hpol_enable_control = |
412 | SOC_DAPM_SINGLE_AUTODISABLE("Switch" , RT298_HPOL_GAIN, |
413 | RT298_MUTE_SFT, 1, 1); |
414 | |
415 | static const struct snd_kcontrol_new hpor_enable_control = |
416 | SOC_DAPM_SINGLE_AUTODISABLE("Switch" , RT298_HPOR_GAIN, |
417 | RT298_MUTE_SFT, 1, 1); |
418 | |
419 | /* ADC0 source */ |
420 | static const char * const rt298_adc_src[] = { |
421 | "Mic" , "RECMIX" , "Dmic" |
422 | }; |
423 | |
424 | static const int rt298_adc_values[] = { |
425 | 0, 4, 5, |
426 | }; |
427 | |
428 | static SOC_VALUE_ENUM_SINGLE_DECL( |
429 | rt298_adc0_enum, RT298_ADC0_MUX, RT298_ADC_SEL_SFT, |
430 | RT298_ADC_SEL_MASK, rt298_adc_src, rt298_adc_values); |
431 | |
432 | static const struct snd_kcontrol_new rt298_adc0_mux = |
433 | SOC_DAPM_ENUM("ADC 0 source" , rt298_adc0_enum); |
434 | |
435 | static SOC_VALUE_ENUM_SINGLE_DECL( |
436 | rt298_adc1_enum, RT298_ADC1_MUX, RT298_ADC_SEL_SFT, |
437 | RT298_ADC_SEL_MASK, rt298_adc_src, rt298_adc_values); |
438 | |
439 | static const struct snd_kcontrol_new rt298_adc1_mux = |
440 | SOC_DAPM_ENUM("ADC 1 source" , rt298_adc1_enum); |
441 | |
442 | static const char * const rt298_dac_src[] = { |
443 | "Front" , "Surround" |
444 | }; |
445 | /* HP-OUT source */ |
446 | static SOC_ENUM_SINGLE_DECL(rt298_hpo_enum, RT298_HPO_MUX, |
447 | 0, rt298_dac_src); |
448 | |
449 | static const struct snd_kcontrol_new rt298_hpo_mux = |
450 | SOC_DAPM_ENUM("HPO source" , rt298_hpo_enum); |
451 | |
452 | /* SPK-OUT source */ |
453 | static SOC_ENUM_SINGLE_DECL(rt298_spo_enum, RT298_SPK_MUX, |
454 | 0, rt298_dac_src); |
455 | |
456 | static const struct snd_kcontrol_new rt298_spo_mux = |
457 | SOC_DAPM_ENUM("SPO source" , rt298_spo_enum); |
458 | |
459 | static int rt298_spk_event(struct snd_soc_dapm_widget *w, |
460 | struct snd_kcontrol *kcontrol, int event) |
461 | { |
462 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm); |
463 | |
464 | switch (event) { |
465 | case SND_SOC_DAPM_POST_PMU: |
466 | snd_soc_component_write(component, |
467 | RT298_SPK_EAPD, RT298_SET_EAPD_HIGH); |
468 | break; |
469 | case SND_SOC_DAPM_PRE_PMD: |
470 | snd_soc_component_write(component, |
471 | RT298_SPK_EAPD, RT298_SET_EAPD_LOW); |
472 | break; |
473 | |
474 | default: |
475 | return 0; |
476 | } |
477 | |
478 | return 0; |
479 | } |
480 | |
481 | static int rt298_set_dmic1_event(struct snd_soc_dapm_widget *w, |
482 | struct snd_kcontrol *kcontrol, int event) |
483 | { |
484 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm); |
485 | |
486 | switch (event) { |
487 | case SND_SOC_DAPM_POST_PMU: |
488 | snd_soc_component_write(component, RT298_SET_PIN_DMIC1, val: 0x20); |
489 | break; |
490 | case SND_SOC_DAPM_PRE_PMD: |
491 | snd_soc_component_write(component, RT298_SET_PIN_DMIC1, val: 0); |
492 | break; |
493 | default: |
494 | return 0; |
495 | } |
496 | |
497 | return 0; |
498 | } |
499 | |
500 | static int rt298_adc_event(struct snd_soc_dapm_widget *w, |
501 | struct snd_kcontrol *kcontrol, int event) |
502 | { |
503 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm); |
504 | unsigned int nid; |
505 | |
506 | nid = (w->reg >> 20) & 0xff; |
507 | |
508 | switch (event) { |
509 | case SND_SOC_DAPM_POST_PMU: |
510 | snd_soc_component_update_bits(component, |
511 | VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0), |
512 | mask: 0x7080, val: 0x7000); |
513 | /* If MCLK doesn't exist, reset AD filter */ |
514 | if (!(snd_soc_component_read(component, RT298_VAD_CTRL) & 0x200)) { |
515 | pr_info("NO MCLK\n" ); |
516 | switch (nid) { |
517 | case RT298_ADC_IN1: |
518 | snd_soc_component_update_bits(component, |
519 | RT298_D_FILTER_CTRL, mask: 0x2, val: 0x2); |
520 | mdelay(10); |
521 | snd_soc_component_update_bits(component, |
522 | RT298_D_FILTER_CTRL, mask: 0x2, val: 0x0); |
523 | break; |
524 | case RT298_ADC_IN2: |
525 | snd_soc_component_update_bits(component, |
526 | RT298_D_FILTER_CTRL, mask: 0x4, val: 0x4); |
527 | mdelay(10); |
528 | snd_soc_component_update_bits(component, |
529 | RT298_D_FILTER_CTRL, mask: 0x4, val: 0x0); |
530 | break; |
531 | } |
532 | } |
533 | break; |
534 | case SND_SOC_DAPM_PRE_PMD: |
535 | snd_soc_component_update_bits(component, |
536 | VERB_CMD(AC_VERB_SET_AMP_GAIN_MUTE, nid, 0), |
537 | mask: 0x7080, val: 0x7080); |
538 | break; |
539 | default: |
540 | return 0; |
541 | } |
542 | |
543 | return 0; |
544 | } |
545 | |
546 | static int rt298_mic1_event(struct snd_soc_dapm_widget *w, |
547 | struct snd_kcontrol *kcontrol, int event) |
548 | { |
549 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm); |
550 | |
551 | switch (event) { |
552 | case SND_SOC_DAPM_PRE_PMU: |
553 | snd_soc_component_update_bits(component, |
554 | RT298_A_BIAS_CTRL3, mask: 0xc000, val: 0x8000); |
555 | snd_soc_component_update_bits(component, |
556 | RT298_A_BIAS_CTRL2, mask: 0xc000, val: 0x8000); |
557 | break; |
558 | case SND_SOC_DAPM_POST_PMD: |
559 | snd_soc_component_update_bits(component, |
560 | RT298_A_BIAS_CTRL3, mask: 0xc000, val: 0x0000); |
561 | snd_soc_component_update_bits(component, |
562 | RT298_A_BIAS_CTRL2, mask: 0xc000, val: 0x0000); |
563 | break; |
564 | default: |
565 | return 0; |
566 | } |
567 | |
568 | return 0; |
569 | } |
570 | |
571 | static const struct snd_soc_dapm_widget rt298_dapm_widgets[] = { |
572 | |
573 | SND_SOC_DAPM_SUPPLY_S("HV" , 1, RT298_POWER_CTRL1, |
574 | 12, 1, NULL, 0), |
575 | SND_SOC_DAPM_SUPPLY("VREF" , RT298_POWER_CTRL1, |
576 | 0, 1, NULL, 0), |
577 | SND_SOC_DAPM_SUPPLY_S("BG_MBIAS" , 1, RT298_POWER_CTRL2, |
578 | 1, 0, NULL, 0), |
579 | SND_SOC_DAPM_SUPPLY_S("LDO1" , 1, RT298_POWER_CTRL2, |
580 | 2, 0, NULL, 0), |
581 | SND_SOC_DAPM_SUPPLY_S("LDO2" , 1, RT298_POWER_CTRL2, |
582 | 3, 0, NULL, 0), |
583 | SND_SOC_DAPM_SUPPLY_S("VREF1" , 1, RT298_POWER_CTRL2, |
584 | 4, 1, NULL, 0), |
585 | SND_SOC_DAPM_SUPPLY_S("LV" , 2, RT298_POWER_CTRL1, |
586 | 13, 1, NULL, 0), |
587 | |
588 | |
589 | SND_SOC_DAPM_SUPPLY("MCLK MODE" , RT298_PLL_CTRL1, |
590 | 5, 0, NULL, 0), |
591 | SND_SOC_DAPM_SUPPLY("MIC1 Input Buffer" , SND_SOC_NOPM, |
592 | 0, 0, rt298_mic1_event, SND_SOC_DAPM_PRE_PMU | |
593 | SND_SOC_DAPM_POST_PMD), |
594 | |
595 | /* Input Lines */ |
596 | SND_SOC_DAPM_INPUT("DMIC1 Pin" ), |
597 | SND_SOC_DAPM_INPUT("DMIC2 Pin" ), |
598 | SND_SOC_DAPM_INPUT("MIC1" ), |
599 | SND_SOC_DAPM_INPUT("LINE1" ), |
600 | SND_SOC_DAPM_INPUT("Beep" ), |
601 | |
602 | /* DMIC */ |
603 | SND_SOC_DAPM_PGA_E("DMIC1" , RT298_SET_POWER(RT298_DMIC1), 0, 1, |
604 | NULL, 0, rt298_set_dmic1_event, |
605 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
606 | SND_SOC_DAPM_PGA("DMIC2" , RT298_SET_POWER(RT298_DMIC2), 0, 1, |
607 | NULL, 0), |
608 | SND_SOC_DAPM_SUPPLY("DMIC Receiver" , SND_SOC_NOPM, |
609 | 0, 0, NULL, 0), |
610 | |
611 | /* REC Mixer */ |
612 | SND_SOC_DAPM_MIXER("RECMIX" , SND_SOC_NOPM, 0, 0, |
613 | rt298_rec_mix, ARRAY_SIZE(rt298_rec_mix)), |
614 | |
615 | /* ADCs */ |
616 | SND_SOC_DAPM_ADC("ADC 0" , NULL, SND_SOC_NOPM, 0, 0), |
617 | SND_SOC_DAPM_ADC("ADC 1" , NULL, SND_SOC_NOPM, 0, 0), |
618 | |
619 | /* ADC Mux */ |
620 | SND_SOC_DAPM_MUX_E("ADC 0 Mux" , RT298_SET_POWER(RT298_ADC_IN1), 0, 1, |
621 | &rt298_adc0_mux, rt298_adc_event, SND_SOC_DAPM_PRE_PMD | |
622 | SND_SOC_DAPM_POST_PMU), |
623 | SND_SOC_DAPM_MUX_E("ADC 1 Mux" , RT298_SET_POWER(RT298_ADC_IN2), 0, 1, |
624 | &rt298_adc1_mux, rt298_adc_event, SND_SOC_DAPM_PRE_PMD | |
625 | SND_SOC_DAPM_POST_PMU), |
626 | |
627 | /* Audio Interface */ |
628 | SND_SOC_DAPM_AIF_IN("AIF1RX" , "AIF1 Playback" , 0, SND_SOC_NOPM, 0, 0), |
629 | SND_SOC_DAPM_AIF_OUT("AIF1TX" , "AIF1 Capture" , 0, SND_SOC_NOPM, 0, 0), |
630 | SND_SOC_DAPM_AIF_IN("AIF2RX" , "AIF2 Playback" , 0, SND_SOC_NOPM, 0, 0), |
631 | SND_SOC_DAPM_AIF_OUT("AIF2TX" , "AIF2 Capture" , 0, SND_SOC_NOPM, 0, 0), |
632 | |
633 | /* Output Side */ |
634 | /* DACs */ |
635 | SND_SOC_DAPM_DAC("DAC 0" , NULL, SND_SOC_NOPM, 0, 0), |
636 | SND_SOC_DAPM_DAC("DAC 1" , NULL, SND_SOC_NOPM, 0, 0), |
637 | |
638 | /* Output Mux */ |
639 | SND_SOC_DAPM_MUX("SPK Mux" , SND_SOC_NOPM, 0, 0, &rt298_spo_mux), |
640 | SND_SOC_DAPM_MUX("HPO Mux" , SND_SOC_NOPM, 0, 0, &rt298_hpo_mux), |
641 | |
642 | SND_SOC_DAPM_SUPPLY("HP Power" , RT298_SET_PIN_HPO, |
643 | RT298_SET_PIN_SFT, 0, NULL, 0), |
644 | |
645 | /* Output Mixer */ |
646 | SND_SOC_DAPM_MIXER("Front" , RT298_SET_POWER(RT298_DAC_OUT1), 0, 1, |
647 | rt298_front_mix, ARRAY_SIZE(rt298_front_mix)), |
648 | SND_SOC_DAPM_PGA("Surround" , RT298_SET_POWER(RT298_DAC_OUT2), 0, 1, |
649 | NULL, 0), |
650 | |
651 | /* Output Pga */ |
652 | SND_SOC_DAPM_SWITCH_E("SPO" , SND_SOC_NOPM, 0, 0, |
653 | &spo_enable_control, rt298_spk_event, |
654 | SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), |
655 | SND_SOC_DAPM_SWITCH("HPO L" , SND_SOC_NOPM, 0, 0, |
656 | &hpol_enable_control), |
657 | SND_SOC_DAPM_SWITCH("HPO R" , SND_SOC_NOPM, 0, 0, |
658 | &hpor_enable_control), |
659 | |
660 | /* Output Lines */ |
661 | SND_SOC_DAPM_OUTPUT("SPOL" ), |
662 | SND_SOC_DAPM_OUTPUT("SPOR" ), |
663 | SND_SOC_DAPM_OUTPUT("HPO Pin" ), |
664 | SND_SOC_DAPM_OUTPUT("SPDIF" ), |
665 | }; |
666 | |
667 | static const struct snd_soc_dapm_route rt298_dapm_routes[] = { |
668 | |
669 | {"ADC 0" , NULL, "MCLK MODE" , is_mclk_mode}, |
670 | {"ADC 1" , NULL, "MCLK MODE" , is_mclk_mode}, |
671 | {"Front" , NULL, "MCLK MODE" , is_mclk_mode}, |
672 | {"Surround" , NULL, "MCLK MODE" , is_mclk_mode}, |
673 | |
674 | {"HP Power" , NULL, "LDO1" }, |
675 | {"HP Power" , NULL, "LDO2" }, |
676 | {"HP Power" , NULL, "LV" }, |
677 | {"HP Power" , NULL, "VREF1" }, |
678 | {"HP Power" , NULL, "BG_MBIAS" }, |
679 | |
680 | {"MIC1" , NULL, "LDO1" }, |
681 | {"MIC1" , NULL, "LDO2" }, |
682 | {"MIC1" , NULL, "HV" }, |
683 | {"MIC1" , NULL, "LV" }, |
684 | {"MIC1" , NULL, "VREF" }, |
685 | {"MIC1" , NULL, "VREF1" }, |
686 | {"MIC1" , NULL, "BG_MBIAS" }, |
687 | {"MIC1" , NULL, "MIC1 Input Buffer" }, |
688 | |
689 | {"SPO" , NULL, "LDO1" }, |
690 | {"SPO" , NULL, "LDO2" }, |
691 | {"SPO" , NULL, "HV" }, |
692 | {"SPO" , NULL, "LV" }, |
693 | {"SPO" , NULL, "VREF" }, |
694 | {"SPO" , NULL, "VREF1" }, |
695 | {"SPO" , NULL, "BG_MBIAS" }, |
696 | |
697 | {"DMIC1" , NULL, "DMIC1 Pin" }, |
698 | {"DMIC2" , NULL, "DMIC2 Pin" }, |
699 | {"DMIC1" , NULL, "DMIC Receiver" }, |
700 | {"DMIC2" , NULL, "DMIC Receiver" }, |
701 | |
702 | {"RECMIX" , "Beep Switch" , "Beep" }, |
703 | {"RECMIX" , "Line1 Switch" , "LINE1" }, |
704 | {"RECMIX" , "Mic1 Switch" , "MIC1" }, |
705 | |
706 | {"ADC 0 Mux" , "Dmic" , "DMIC1" }, |
707 | {"ADC 0 Mux" , "RECMIX" , "RECMIX" }, |
708 | {"ADC 0 Mux" , "Mic" , "MIC1" }, |
709 | {"ADC 1 Mux" , "Dmic" , "DMIC2" }, |
710 | {"ADC 1 Mux" , "RECMIX" , "RECMIX" }, |
711 | {"ADC 1 Mux" , "Mic" , "MIC1" }, |
712 | |
713 | {"ADC 0" , NULL, "ADC 0 Mux" }, |
714 | {"ADC 1" , NULL, "ADC 1 Mux" }, |
715 | |
716 | {"AIF1TX" , NULL, "ADC 0" }, |
717 | {"AIF2TX" , NULL, "ADC 1" }, |
718 | |
719 | {"DAC 0" , NULL, "AIF1RX" }, |
720 | {"DAC 1" , NULL, "AIF2RX" }, |
721 | |
722 | {"Front" , "DAC Switch" , "DAC 0" }, |
723 | {"Front" , "RECMIX Switch" , "RECMIX" }, |
724 | |
725 | {"Surround" , NULL, "DAC 1" }, |
726 | |
727 | {"SPK Mux" , "Front" , "Front" }, |
728 | {"SPK Mux" , "Surround" , "Surround" }, |
729 | |
730 | {"HPO Mux" , "Front" , "Front" }, |
731 | {"HPO Mux" , "Surround" , "Surround" }, |
732 | |
733 | {"SPO" , "Switch" , "SPK Mux" }, |
734 | {"HPO L" , "Switch" , "HPO Mux" }, |
735 | {"HPO R" , "Switch" , "HPO Mux" }, |
736 | {"HPO L" , NULL, "HP Power" }, |
737 | {"HPO R" , NULL, "HP Power" }, |
738 | |
739 | {"SPOL" , NULL, "SPO" }, |
740 | {"SPOR" , NULL, "SPO" }, |
741 | {"HPO Pin" , NULL, "HPO L" }, |
742 | {"HPO Pin" , NULL, "HPO R" }, |
743 | }; |
744 | |
745 | static int rt298_hw_params(struct snd_pcm_substream *substream, |
746 | struct snd_pcm_hw_params *params, |
747 | struct snd_soc_dai *dai) |
748 | { |
749 | struct snd_soc_component *component = dai->component; |
750 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
751 | unsigned int val = 0; |
752 | int d_len_code; |
753 | |
754 | switch (params_rate(p: params)) { |
755 | /* bit 14 0:48K 1:44.1K */ |
756 | case 44100: |
757 | case 48000: |
758 | break; |
759 | default: |
760 | dev_err(component->dev, "Unsupported sample rate %d\n" , |
761 | params_rate(params)); |
762 | return -EINVAL; |
763 | } |
764 | switch (rt298->sys_clk) { |
765 | case 12288000: |
766 | case 24576000: |
767 | if (params_rate(p: params) != 48000) { |
768 | dev_err(component->dev, "Sys_clk is not matched (%d %d)\n" , |
769 | params_rate(params), rt298->sys_clk); |
770 | return -EINVAL; |
771 | } |
772 | break; |
773 | case 11289600: |
774 | case 22579200: |
775 | if (params_rate(p: params) != 44100) { |
776 | dev_err(component->dev, "Sys_clk is not matched (%d %d)\n" , |
777 | params_rate(params), rt298->sys_clk); |
778 | return -EINVAL; |
779 | } |
780 | break; |
781 | } |
782 | |
783 | if (params_channels(p: params) <= 16) { |
784 | /* bit 3:0 Number of Channel */ |
785 | val |= (params_channels(p: params) - 1); |
786 | } else { |
787 | dev_err(component->dev, "Unsupported channels %d\n" , |
788 | params_channels(params)); |
789 | return -EINVAL; |
790 | } |
791 | |
792 | switch (params_width(p: params)) { |
793 | /* bit 6:4 Bits per Sample */ |
794 | case 16: |
795 | d_len_code = 0; |
796 | val |= (0x1 << 4); |
797 | break; |
798 | case 32: |
799 | d_len_code = 2; |
800 | val |= (0x4 << 4); |
801 | break; |
802 | case 20: |
803 | d_len_code = 1; |
804 | val |= (0x2 << 4); |
805 | break; |
806 | case 24: |
807 | d_len_code = 2; |
808 | val |= (0x3 << 4); |
809 | break; |
810 | case 8: |
811 | d_len_code = 3; |
812 | break; |
813 | default: |
814 | return -EINVAL; |
815 | } |
816 | |
817 | snd_soc_component_update_bits(component, |
818 | RT298_I2S_CTRL1, mask: 0x0018, val: d_len_code << 3); |
819 | dev_dbg(component->dev, "format val = 0x%x\n" , val); |
820 | |
821 | snd_soc_component_update_bits(component, RT298_DAC_FORMAT, mask: 0x407f, val); |
822 | snd_soc_component_update_bits(component, RT298_ADC_FORMAT, mask: 0x407f, val); |
823 | |
824 | return 0; |
825 | } |
826 | |
827 | static int rt298_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
828 | { |
829 | struct snd_soc_component *component = dai->component; |
830 | |
831 | switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { |
832 | case SND_SOC_DAIFMT_CBM_CFM: |
833 | snd_soc_component_update_bits(component, |
834 | RT298_I2S_CTRL1, mask: 0x800, val: 0x800); |
835 | break; |
836 | case SND_SOC_DAIFMT_CBS_CFS: |
837 | snd_soc_component_update_bits(component, |
838 | RT298_I2S_CTRL1, mask: 0x800, val: 0x0); |
839 | break; |
840 | default: |
841 | return -EINVAL; |
842 | } |
843 | |
844 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
845 | case SND_SOC_DAIFMT_I2S: |
846 | snd_soc_component_update_bits(component, |
847 | RT298_I2S_CTRL1, mask: 0x300, val: 0x0); |
848 | break; |
849 | case SND_SOC_DAIFMT_LEFT_J: |
850 | snd_soc_component_update_bits(component, |
851 | RT298_I2S_CTRL1, mask: 0x300, val: 0x1 << 8); |
852 | break; |
853 | case SND_SOC_DAIFMT_DSP_A: |
854 | snd_soc_component_update_bits(component, |
855 | RT298_I2S_CTRL1, mask: 0x300, val: 0x2 << 8); |
856 | break; |
857 | case SND_SOC_DAIFMT_DSP_B: |
858 | snd_soc_component_update_bits(component, |
859 | RT298_I2S_CTRL1, mask: 0x300, val: 0x3 << 8); |
860 | break; |
861 | default: |
862 | return -EINVAL; |
863 | } |
864 | /* bit 15 Stream Type 0:PCM 1:Non-PCM */ |
865 | snd_soc_component_update_bits(component, RT298_DAC_FORMAT, mask: 0x8000, val: 0); |
866 | snd_soc_component_update_bits(component, RT298_ADC_FORMAT, mask: 0x8000, val: 0); |
867 | |
868 | return 0; |
869 | } |
870 | |
871 | static int rt298_set_dai_sysclk(struct snd_soc_dai *dai, |
872 | int clk_id, unsigned int freq, int dir) |
873 | { |
874 | struct snd_soc_component *component = dai->component; |
875 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
876 | |
877 | dev_dbg(component->dev, "%s freq=%d\n" , __func__, freq); |
878 | |
879 | if (RT298_SCLK_S_MCLK == clk_id) { |
880 | snd_soc_component_update_bits(component, |
881 | RT298_I2S_CTRL2, mask: 0x0100, val: 0x0); |
882 | snd_soc_component_update_bits(component, |
883 | RT298_PLL_CTRL1, mask: 0x20, val: 0x20); |
884 | } else { |
885 | snd_soc_component_update_bits(component, |
886 | RT298_I2S_CTRL2, mask: 0x0100, val: 0x0100); |
887 | snd_soc_component_update_bits(component, |
888 | RT298_PLL_CTRL1, mask: 0x20, val: 0x0); |
889 | } |
890 | |
891 | switch (freq) { |
892 | case 19200000: |
893 | if (RT298_SCLK_S_MCLK == clk_id) { |
894 | dev_err(component->dev, "Should not use MCLK\n" ); |
895 | return -EINVAL; |
896 | } |
897 | snd_soc_component_update_bits(component, |
898 | RT298_I2S_CTRL2, mask: 0x40, val: 0x40); |
899 | break; |
900 | case 24000000: |
901 | if (RT298_SCLK_S_MCLK == clk_id) { |
902 | dev_err(component->dev, "Should not use MCLK\n" ); |
903 | return -EINVAL; |
904 | } |
905 | snd_soc_component_update_bits(component, |
906 | RT298_I2S_CTRL2, mask: 0x40, val: 0x0); |
907 | break; |
908 | case 12288000: |
909 | case 11289600: |
910 | snd_soc_component_update_bits(component, |
911 | RT298_I2S_CTRL2, mask: 0x8, val: 0x0); |
912 | snd_soc_component_update_bits(component, |
913 | RT298_CLK_DIV, mask: 0xfc1e, val: 0x0004); |
914 | break; |
915 | case 24576000: |
916 | case 22579200: |
917 | snd_soc_component_update_bits(component, |
918 | RT298_I2S_CTRL2, mask: 0x8, val: 0x8); |
919 | snd_soc_component_update_bits(component, |
920 | RT298_CLK_DIV, mask: 0xfc1e, val: 0x5406); |
921 | break; |
922 | default: |
923 | dev_err(component->dev, "Unsupported system clock\n" ); |
924 | return -EINVAL; |
925 | } |
926 | |
927 | rt298->sys_clk = freq; |
928 | rt298->clk_id = clk_id; |
929 | |
930 | return 0; |
931 | } |
932 | |
933 | static int rt298_set_bclk_ratio(struct snd_soc_dai *dai, unsigned int ratio) |
934 | { |
935 | struct snd_soc_component *component = dai->component; |
936 | |
937 | dev_dbg(component->dev, "%s ratio=%d\n" , __func__, ratio); |
938 | if (50 == ratio) |
939 | snd_soc_component_update_bits(component, |
940 | RT298_I2S_CTRL1, mask: 0x1000, val: 0x1000); |
941 | else |
942 | snd_soc_component_update_bits(component, |
943 | RT298_I2S_CTRL1, mask: 0x1000, val: 0x0); |
944 | |
945 | |
946 | return 0; |
947 | } |
948 | |
949 | static int rt298_set_bias_level(struct snd_soc_component *component, |
950 | enum snd_soc_bias_level level) |
951 | { |
952 | switch (level) { |
953 | case SND_SOC_BIAS_PREPARE: |
954 | if (SND_SOC_BIAS_STANDBY == |
955 | snd_soc_component_get_bias_level(component)) { |
956 | snd_soc_component_write(component, |
957 | RT298_SET_AUDIO_POWER, AC_PWRST_D0); |
958 | snd_soc_component_update_bits(component, reg: 0x0d, mask: 0x200, val: 0x200); |
959 | snd_soc_component_update_bits(component, reg: 0x52, mask: 0x80, val: 0x0); |
960 | mdelay(20); |
961 | snd_soc_component_update_bits(component, reg: 0x0d, mask: 0x200, val: 0x0); |
962 | snd_soc_component_update_bits(component, reg: 0x52, mask: 0x80, val: 0x80); |
963 | } |
964 | break; |
965 | |
966 | case SND_SOC_BIAS_STANDBY: |
967 | snd_soc_component_write(component, |
968 | RT298_SET_AUDIO_POWER, AC_PWRST_D3); |
969 | break; |
970 | |
971 | default: |
972 | break; |
973 | } |
974 | |
975 | return 0; |
976 | } |
977 | |
978 | static irqreturn_t rt298_irq(int irq, void *data) |
979 | { |
980 | struct rt298_priv *rt298 = data; |
981 | bool hp = false; |
982 | bool mic = false; |
983 | int ret, status = 0; |
984 | |
985 | ret = rt298_jack_detect(rt298, hp: &hp, mic: &mic); |
986 | |
987 | /* Clear IRQ */ |
988 | regmap_update_bits(map: rt298->regmap, RT298_IRQ_CTRL, mask: 0x1, val: 0x1); |
989 | |
990 | if (ret == 0) { |
991 | if (hp) |
992 | status |= SND_JACK_HEADPHONE; |
993 | |
994 | if (mic) |
995 | status |= SND_JACK_MICROPHONE; |
996 | |
997 | snd_soc_jack_report(jack: rt298->jack, status, |
998 | mask: SND_JACK_MICROPHONE | SND_JACK_HEADPHONE); |
999 | |
1000 | pm_wakeup_event(dev: &rt298->i2c->dev, msec: 300); |
1001 | } |
1002 | |
1003 | return IRQ_HANDLED; |
1004 | } |
1005 | |
1006 | static int rt298_probe(struct snd_soc_component *component) |
1007 | { |
1008 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
1009 | |
1010 | rt298->component = component; |
1011 | INIT_DELAYED_WORK(&rt298->jack_detect_work, rt298_jack_detect_work); |
1012 | |
1013 | if (rt298->i2c->irq) |
1014 | schedule_delayed_work(dwork: &rt298->jack_detect_work, |
1015 | delay: msecs_to_jiffies(m: 1250)); |
1016 | return 0; |
1017 | } |
1018 | |
1019 | static void rt298_remove(struct snd_soc_component *component) |
1020 | { |
1021 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
1022 | |
1023 | cancel_delayed_work_sync(dwork: &rt298->jack_detect_work); |
1024 | rt298->component = NULL; |
1025 | } |
1026 | |
1027 | #ifdef CONFIG_PM |
1028 | static int rt298_suspend(struct snd_soc_component *component) |
1029 | { |
1030 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
1031 | |
1032 | rt298->is_hp_in = -1; |
1033 | regcache_cache_only(map: rt298->regmap, enable: true); |
1034 | regcache_mark_dirty(map: rt298->regmap); |
1035 | |
1036 | return 0; |
1037 | } |
1038 | |
1039 | static int rt298_resume(struct snd_soc_component *component) |
1040 | { |
1041 | struct rt298_priv *rt298 = snd_soc_component_get_drvdata(c: component); |
1042 | |
1043 | regcache_cache_only(map: rt298->regmap, enable: false); |
1044 | rt298_index_sync(component); |
1045 | regcache_sync(map: rt298->regmap); |
1046 | |
1047 | return 0; |
1048 | } |
1049 | #else |
1050 | #define rt298_suspend NULL |
1051 | #define rt298_resume NULL |
1052 | #endif |
1053 | |
1054 | #define RT298_STEREO_RATES (SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000) |
1055 | #define RT298_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1056 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) |
1057 | |
1058 | static const struct snd_soc_dai_ops rt298_aif_dai_ops = { |
1059 | .hw_params = rt298_hw_params, |
1060 | .set_fmt = rt298_set_dai_fmt, |
1061 | .set_sysclk = rt298_set_dai_sysclk, |
1062 | .set_bclk_ratio = rt298_set_bclk_ratio, |
1063 | }; |
1064 | |
1065 | static struct snd_soc_dai_driver rt298_dai[] = { |
1066 | { |
1067 | .name = "rt298-aif1" , |
1068 | .id = RT298_AIF1, |
1069 | .playback = { |
1070 | .stream_name = "AIF1 Playback" , |
1071 | .channels_min = 1, |
1072 | .channels_max = 2, |
1073 | .rates = RT298_STEREO_RATES, |
1074 | .formats = RT298_FORMATS, |
1075 | }, |
1076 | .capture = { |
1077 | .stream_name = "AIF1 Capture" , |
1078 | .channels_min = 1, |
1079 | .channels_max = 2, |
1080 | .rates = RT298_STEREO_RATES, |
1081 | .formats = RT298_FORMATS, |
1082 | }, |
1083 | .ops = &rt298_aif_dai_ops, |
1084 | .symmetric_rate = 1, |
1085 | }, |
1086 | { |
1087 | .name = "rt298-aif2" , |
1088 | .id = RT298_AIF2, |
1089 | .playback = { |
1090 | .stream_name = "AIF2 Playback" , |
1091 | .channels_min = 1, |
1092 | .channels_max = 2, |
1093 | .rates = RT298_STEREO_RATES, |
1094 | .formats = RT298_FORMATS, |
1095 | }, |
1096 | .capture = { |
1097 | .stream_name = "AIF2 Capture" , |
1098 | .channels_min = 1, |
1099 | .channels_max = 2, |
1100 | .rates = RT298_STEREO_RATES, |
1101 | .formats = RT298_FORMATS, |
1102 | }, |
1103 | .ops = &rt298_aif_dai_ops, |
1104 | .symmetric_rate = 1, |
1105 | }, |
1106 | |
1107 | }; |
1108 | |
1109 | static const struct snd_soc_component_driver soc_component_dev_rt298 = { |
1110 | .probe = rt298_probe, |
1111 | .remove = rt298_remove, |
1112 | .suspend = rt298_suspend, |
1113 | .resume = rt298_resume, |
1114 | .set_bias_level = rt298_set_bias_level, |
1115 | .set_jack = rt298_mic_detect, |
1116 | .controls = rt298_snd_controls, |
1117 | .num_controls = ARRAY_SIZE(rt298_snd_controls), |
1118 | .dapm_widgets = rt298_dapm_widgets, |
1119 | .num_dapm_widgets = ARRAY_SIZE(rt298_dapm_widgets), |
1120 | .dapm_routes = rt298_dapm_routes, |
1121 | .num_dapm_routes = ARRAY_SIZE(rt298_dapm_routes), |
1122 | .use_pmdown_time = 1, |
1123 | .endianness = 1, |
1124 | }; |
1125 | |
1126 | static const struct regmap_config rt298_regmap = { |
1127 | .reg_bits = 32, |
1128 | .val_bits = 32, |
1129 | .max_register = 0x02370100, |
1130 | .volatile_reg = rt298_volatile_register, |
1131 | .readable_reg = rt298_readable_register, |
1132 | .reg_write = rl6347a_hw_write, |
1133 | .reg_read = rl6347a_hw_read, |
1134 | .cache_type = REGCACHE_RBTREE, |
1135 | .reg_defaults = rt298_reg, |
1136 | .num_reg_defaults = ARRAY_SIZE(rt298_reg), |
1137 | }; |
1138 | |
1139 | static const struct i2c_device_id rt298_i2c_id[] = { |
1140 | {"rt298" , 0}, |
1141 | {} |
1142 | }; |
1143 | MODULE_DEVICE_TABLE(i2c, rt298_i2c_id); |
1144 | |
1145 | #ifdef CONFIG_ACPI |
1146 | static const struct acpi_device_id rt298_acpi_match[] = { |
1147 | { "INT343A" , 0 }, |
1148 | {}, |
1149 | }; |
1150 | MODULE_DEVICE_TABLE(acpi, rt298_acpi_match); |
1151 | #endif |
1152 | |
1153 | static const struct dmi_system_id force_combo_jack_table[] = { |
1154 | { |
1155 | .ident = "Intel Broxton P" , |
1156 | .matches = { |
1157 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp" ), |
1158 | DMI_MATCH(DMI_PRODUCT_NAME, "Broxton P" ) |
1159 | } |
1160 | }, |
1161 | { |
1162 | .ident = "Intel Gemini Lake" , |
1163 | .matches = { |
1164 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corp" ), |
1165 | DMI_MATCH(DMI_PRODUCT_NAME, "Geminilake" ) |
1166 | } |
1167 | }, |
1168 | { |
1169 | .ident = "Intel Kabylake R RVP" , |
1170 | .matches = { |
1171 | DMI_MATCH(DMI_SYS_VENDOR, "Intel Corporation" ), |
1172 | DMI_MATCH(DMI_PRODUCT_NAME, "Kabylake Client platform" ) |
1173 | } |
1174 | }, |
1175 | { } |
1176 | }; |
1177 | |
1178 | static int rt298_i2c_probe(struct i2c_client *i2c) |
1179 | { |
1180 | struct rt298_platform_data *pdata = dev_get_platdata(dev: &i2c->dev); |
1181 | struct rt298_priv *rt298; |
1182 | struct device *dev = &i2c->dev; |
1183 | const struct acpi_device_id *acpiid; |
1184 | int i, ret; |
1185 | |
1186 | rt298 = devm_kzalloc(dev: &i2c->dev, size: sizeof(*rt298), |
1187 | GFP_KERNEL); |
1188 | if (NULL == rt298) |
1189 | return -ENOMEM; |
1190 | |
1191 | rt298->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt298_regmap); |
1192 | if (IS_ERR(ptr: rt298->regmap)) { |
1193 | ret = PTR_ERR(ptr: rt298->regmap); |
1194 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n" , |
1195 | ret); |
1196 | return ret; |
1197 | } |
1198 | |
1199 | regmap_read(map: rt298->regmap, |
1200 | RT298_GET_PARAM(AC_NODE_ROOT, AC_PAR_VENDOR_ID), val: &ret); |
1201 | if (ret != RT298_VENDOR_ID) { |
1202 | dev_err(&i2c->dev, |
1203 | "Device with ID register %#x is not rt298\n" , ret); |
1204 | return -ENODEV; |
1205 | } |
1206 | |
1207 | rt298->index_cache = devm_kmemdup(dev: &i2c->dev, src: rt298_index_def, |
1208 | len: sizeof(rt298_index_def), GFP_KERNEL); |
1209 | if (!rt298->index_cache) |
1210 | return -ENOMEM; |
1211 | |
1212 | rt298->index_cache_size = INDEX_CACHE_SIZE; |
1213 | rt298->i2c = i2c; |
1214 | i2c_set_clientdata(client: i2c, data: rt298); |
1215 | |
1216 | /* restore codec default */ |
1217 | for (i = 0; i < INDEX_CACHE_SIZE; i++) |
1218 | regmap_write(map: rt298->regmap, reg: rt298->index_cache[i].reg, |
1219 | val: rt298->index_cache[i].def); |
1220 | for (i = 0; i < ARRAY_SIZE(rt298_reg); i++) |
1221 | regmap_write(map: rt298->regmap, reg: rt298_reg[i].reg, |
1222 | val: rt298_reg[i].def); |
1223 | |
1224 | if (pdata) |
1225 | rt298->pdata = *pdata; |
1226 | |
1227 | /* enable jack combo mode on supported devices */ |
1228 | acpiid = acpi_match_device(ids: dev->driver->acpi_match_table, dev); |
1229 | if (acpiid && acpiid->driver_data) { |
1230 | rt298->pdata = *(struct rt298_platform_data *) |
1231 | acpiid->driver_data; |
1232 | } |
1233 | |
1234 | if (dmi_check_system(list: force_combo_jack_table)) { |
1235 | rt298->pdata.cbj_en = true; |
1236 | rt298->pdata.gpio2_en = false; |
1237 | } |
1238 | |
1239 | /* VREF Charging */ |
1240 | regmap_update_bits(map: rt298->regmap, reg: 0x04, mask: 0x80, val: 0x80); |
1241 | regmap_update_bits(map: rt298->regmap, reg: 0x1b, mask: 0x860, val: 0x860); |
1242 | /* Vref2 */ |
1243 | regmap_update_bits(map: rt298->regmap, reg: 0x08, mask: 0x20, val: 0x20); |
1244 | |
1245 | regmap_write(map: rt298->regmap, RT298_SET_AUDIO_POWER, AC_PWRST_D3); |
1246 | |
1247 | for (i = 0; i < RT298_POWER_REG_LEN; i++) |
1248 | regmap_write(map: rt298->regmap, |
1249 | RT298_SET_POWER(rt298_support_power_controls[i]), |
1250 | AC_PWRST_D1); |
1251 | |
1252 | if (!rt298->pdata.cbj_en) { |
1253 | regmap_write(map: rt298->regmap, RT298_CBJ_CTRL2, val: 0x0000); |
1254 | regmap_write(map: rt298->regmap, RT298_MIC1_DET_CTRL, val: 0x0816); |
1255 | regmap_update_bits(map: rt298->regmap, |
1256 | RT298_CBJ_CTRL1, mask: 0xf000, val: 0xb000); |
1257 | } else { |
1258 | regmap_update_bits(map: rt298->regmap, |
1259 | RT298_CBJ_CTRL1, mask: 0xf000, val: 0x5000); |
1260 | } |
1261 | |
1262 | mdelay(10); |
1263 | |
1264 | if (!rt298->pdata.gpio2_en) |
1265 | regmap_write(map: rt298->regmap, RT298_SET_DMIC2_DEFAULT, val: 0x40); |
1266 | else |
1267 | regmap_write(map: rt298->regmap, RT298_SET_DMIC2_DEFAULT, val: 0); |
1268 | |
1269 | mdelay(10); |
1270 | |
1271 | regmap_write(map: rt298->regmap, RT298_MISC_CTRL1, val: 0x0000); |
1272 | regmap_update_bits(map: rt298->regmap, |
1273 | RT298_WIND_FILTER_CTRL, mask: 0x0082, val: 0x0082); |
1274 | |
1275 | regmap_write(map: rt298->regmap, RT298_UNSOLICITED_INLINE_CMD, val: 0x81); |
1276 | regmap_write(map: rt298->regmap, RT298_UNSOLICITED_HP_OUT, val: 0x82); |
1277 | regmap_write(map: rt298->regmap, RT298_UNSOLICITED_MIC1, val: 0x84); |
1278 | regmap_update_bits(map: rt298->regmap, RT298_IRQ_FLAG_CTRL, mask: 0x2, val: 0x2); |
1279 | |
1280 | rt298->is_hp_in = -1; |
1281 | |
1282 | if (rt298->i2c->irq) { |
1283 | ret = request_threaded_irq(irq: rt298->i2c->irq, NULL, thread_fn: rt298_irq, |
1284 | IRQF_TRIGGER_HIGH | IRQF_ONESHOT, name: "rt298" , dev: rt298); |
1285 | if (ret != 0) { |
1286 | dev_err(&i2c->dev, |
1287 | "Failed to request IRQ: %d\n" , ret); |
1288 | return ret; |
1289 | } |
1290 | } |
1291 | |
1292 | ret = devm_snd_soc_register_component(dev: &i2c->dev, |
1293 | component_driver: &soc_component_dev_rt298, |
1294 | dai_drv: rt298_dai, ARRAY_SIZE(rt298_dai)); |
1295 | |
1296 | return ret; |
1297 | } |
1298 | |
1299 | static void rt298_i2c_remove(struct i2c_client *i2c) |
1300 | { |
1301 | struct rt298_priv *rt298 = i2c_get_clientdata(client: i2c); |
1302 | |
1303 | if (i2c->irq) |
1304 | free_irq(i2c->irq, rt298); |
1305 | } |
1306 | |
1307 | |
1308 | static struct i2c_driver rt298_i2c_driver = { |
1309 | .driver = { |
1310 | .name = "rt298" , |
1311 | .acpi_match_table = ACPI_PTR(rt298_acpi_match), |
1312 | }, |
1313 | .probe = rt298_i2c_probe, |
1314 | .remove = rt298_i2c_remove, |
1315 | .id_table = rt298_i2c_id, |
1316 | }; |
1317 | |
1318 | module_i2c_driver(rt298_i2c_driver); |
1319 | |
1320 | MODULE_DESCRIPTION("ASoC RT298 driver" ); |
1321 | MODULE_AUTHOR("Bard Liao <bardliao@realtek.com>" ); |
1322 | MODULE_LICENSE("GPL" ); |
1323 | |