1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * rt5514.c -- RT5514 ALSA SoC audio codec driver |
4 | * |
5 | * Copyright 2015 Realtek Semiconductor Corp. |
6 | * Author: Oder Chiou <oder_chiou@realtek.com> |
7 | */ |
8 | |
9 | #include <linux/acpi.h> |
10 | #include <linux/fs.h> |
11 | #include <linux/module.h> |
12 | #include <linux/moduleparam.h> |
13 | #include <linux/init.h> |
14 | #include <linux/delay.h> |
15 | #include <linux/pm.h> |
16 | #include <linux/regmap.h> |
17 | #include <linux/i2c.h> |
18 | #include <linux/platform_device.h> |
19 | #include <linux/firmware.h> |
20 | #include <sound/core.h> |
21 | #include <sound/pcm.h> |
22 | #include <sound/pcm_params.h> |
23 | #include <sound/soc.h> |
24 | #include <sound/soc-dapm.h> |
25 | #include <sound/initval.h> |
26 | #include <sound/tlv.h> |
27 | |
28 | #include "rl6231.h" |
29 | #include "rt5514.h" |
30 | #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) |
31 | #include "rt5514-spi.h" |
32 | #endif |
33 | |
34 | static const struct reg_sequence rt5514_i2c_patch[] = { |
35 | {0x1800101c, 0x00000000}, |
36 | {0x18001100, 0x0000031f}, |
37 | {0x18001104, 0x00000007}, |
38 | {0x18001108, 0x00000000}, |
39 | {0x1800110c, 0x00000000}, |
40 | {0x18001110, 0x00000000}, |
41 | {0x18001114, 0x00000001}, |
42 | {0x18001118, 0x00000000}, |
43 | {0x18002f08, 0x00000006}, |
44 | {0x18002f00, 0x00055149}, |
45 | {0x18002f00, 0x0005514b}, |
46 | {0x18002f00, 0x00055149}, |
47 | {0xfafafafa, 0x00000001}, |
48 | {0x18002f10, 0x00000001}, |
49 | {0x18002f10, 0x00000000}, |
50 | {0x18002f10, 0x00000001}, |
51 | {0xfafafafa, 0x00000001}, |
52 | {0x18002000, 0x000010ec}, |
53 | {0xfafafafa, 0x00000000}, |
54 | }; |
55 | |
56 | static const struct reg_sequence rt5514_patch[] = { |
57 | {RT5514_DIG_IO_CTRL, 0x00000040}, |
58 | {RT5514_CLK_CTRL1, 0x38020041}, |
59 | {RT5514_SRC_CTRL, 0x44000eee}, |
60 | {RT5514_ANA_CTRL_LDO10, 0x00028604}, |
61 | {RT5514_ANA_CTRL_ADCFED, 0x00000800}, |
62 | {RT5514_ASRC_IN_CTRL1, 0x00000003}, |
63 | {RT5514_DOWNFILTER0_CTRL3, 0x10000342}, |
64 | {RT5514_DOWNFILTER1_CTRL3, 0x10000342}, |
65 | }; |
66 | |
67 | static const struct reg_default rt5514_reg[] = { |
68 | {RT5514_RESET, 0x00000000}, |
69 | {RT5514_PWR_ANA1, 0x00808880}, |
70 | {RT5514_PWR_ANA2, 0x00220000}, |
71 | {RT5514_I2S_CTRL1, 0x00000330}, |
72 | {RT5514_I2S_CTRL2, 0x20000000}, |
73 | {RT5514_VAD_CTRL6, 0xc00007d2}, |
74 | {RT5514_EXT_VAD_CTRL, 0x80000080}, |
75 | {RT5514_DIG_IO_CTRL, 0x00000040}, |
76 | {RT5514_PAD_CTRL1, 0x00804000}, |
77 | {RT5514_DMIC_DATA_CTRL, 0x00000005}, |
78 | {RT5514_DIG_SOURCE_CTRL, 0x00000002}, |
79 | {RT5514_SRC_CTRL, 0x44000eee}, |
80 | {RT5514_DOWNFILTER2_CTRL1, 0x0000882f}, |
81 | {RT5514_PLL_SOURCE_CTRL, 0x00000004}, |
82 | {RT5514_CLK_CTRL1, 0x38020041}, |
83 | {RT5514_CLK_CTRL2, 0x00000000}, |
84 | {RT5514_PLL3_CALIB_CTRL1, 0x00400200}, |
85 | {RT5514_PLL3_CALIB_CTRL5, 0x40220012}, |
86 | {RT5514_DELAY_BUF_CTRL1, 0x7fff006a}, |
87 | {RT5514_DELAY_BUF_CTRL3, 0x00000000}, |
88 | {RT5514_ASRC_IN_CTRL1, 0x00000003}, |
89 | {RT5514_DOWNFILTER0_CTRL1, 0x00020c2f}, |
90 | {RT5514_DOWNFILTER0_CTRL2, 0x00020c2f}, |
91 | {RT5514_DOWNFILTER0_CTRL3, 0x10000342}, |
92 | {RT5514_DOWNFILTER1_CTRL1, 0x00020c2f}, |
93 | {RT5514_DOWNFILTER1_CTRL2, 0x00020c2f}, |
94 | {RT5514_DOWNFILTER1_CTRL3, 0x10000342}, |
95 | {RT5514_ANA_CTRL_LDO10, 0x00028604}, |
96 | {RT5514_ANA_CTRL_LDO18_16, 0x02000345}, |
97 | {RT5514_ANA_CTRL_ADC12, 0x0000a2a8}, |
98 | {RT5514_ANA_CTRL_ADC21, 0x00001180}, |
99 | {RT5514_ANA_CTRL_ADC22, 0x0000aaa8}, |
100 | {RT5514_ANA_CTRL_ADC23, 0x00151427}, |
101 | {RT5514_ANA_CTRL_MICBST, 0x00002000}, |
102 | {RT5514_ANA_CTRL_ADCFED, 0x00000800}, |
103 | {RT5514_ANA_CTRL_INBUF, 0x00000143}, |
104 | {RT5514_ANA_CTRL_VREF, 0x00008d50}, |
105 | {RT5514_ANA_CTRL_PLL3, 0x0000000e}, |
106 | {RT5514_ANA_CTRL_PLL1_1, 0x00000000}, |
107 | {RT5514_ANA_CTRL_PLL1_2, 0x00030220}, |
108 | {RT5514_DMIC_LP_CTRL, 0x00000000}, |
109 | {RT5514_MISC_CTRL_DSP, 0x00000000}, |
110 | {RT5514_DSP_CTRL1, 0x00055149}, |
111 | {RT5514_DSP_CTRL3, 0x00000006}, |
112 | {RT5514_DSP_CTRL4, 0x00000001}, |
113 | {RT5514_VENDOR_ID1, 0x00000001}, |
114 | {RT5514_VENDOR_ID2, 0x10ec5514}, |
115 | }; |
116 | |
117 | static void rt5514_enable_dsp_prepare(struct rt5514_priv *rt5514) |
118 | { |
119 | /* Reset */ |
120 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002000, val: 0x000010ec); |
121 | /* LDO_I_limit */ |
122 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002200, val: 0x00028604); |
123 | /* I2C bypass enable */ |
124 | regmap_write(map: rt5514->i2c_regmap, reg: 0xfafafafa, val: 0x00000001); |
125 | /* mini-core reset */ |
126 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002f00, val: 0x0005514b); |
127 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002f00, val: 0x00055149); |
128 | /* I2C bypass disable */ |
129 | regmap_write(map: rt5514->i2c_regmap, reg: 0xfafafafa, val: 0x00000000); |
130 | /* PIN config */ |
131 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002070, val: 0x00000040); |
132 | /* PLL3(QN)=RCOSC*(10+2) */ |
133 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002240, val: 0x0000000a); |
134 | /* PLL3 source=RCOSC, fsi=rt_clk */ |
135 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002100, val: 0x0000000b); |
136 | /* Power on RCOSC, pll3 */ |
137 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002004, val: 0x00808b81); |
138 | /* DSP clk source = pll3, ENABLE DSP clk */ |
139 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002f08, val: 0x00000005); |
140 | /* Enable DSP clk auto switch */ |
141 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18001114, val: 0x00000001); |
142 | /* Reduce DSP power */ |
143 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18001118, val: 0x00000001); |
144 | } |
145 | |
146 | static bool rt5514_volatile_register(struct device *dev, unsigned int reg) |
147 | { |
148 | switch (reg) { |
149 | case RT5514_VENDOR_ID1: |
150 | case RT5514_VENDOR_ID2: |
151 | return true; |
152 | |
153 | default: |
154 | return false; |
155 | } |
156 | } |
157 | |
158 | static bool rt5514_readable_register(struct device *dev, unsigned int reg) |
159 | { |
160 | switch (reg) { |
161 | case RT5514_RESET: |
162 | case RT5514_PWR_ANA1: |
163 | case RT5514_PWR_ANA2: |
164 | case RT5514_I2S_CTRL1: |
165 | case RT5514_I2S_CTRL2: |
166 | case RT5514_VAD_CTRL6: |
167 | case RT5514_EXT_VAD_CTRL: |
168 | case RT5514_DIG_IO_CTRL: |
169 | case RT5514_PAD_CTRL1: |
170 | case RT5514_DMIC_DATA_CTRL: |
171 | case RT5514_DIG_SOURCE_CTRL: |
172 | case RT5514_SRC_CTRL: |
173 | case RT5514_DOWNFILTER2_CTRL1: |
174 | case RT5514_PLL_SOURCE_CTRL: |
175 | case RT5514_CLK_CTRL1: |
176 | case RT5514_CLK_CTRL2: |
177 | case RT5514_PLL3_CALIB_CTRL1: |
178 | case RT5514_PLL3_CALIB_CTRL5: |
179 | case RT5514_DELAY_BUF_CTRL1: |
180 | case RT5514_DELAY_BUF_CTRL3: |
181 | case RT5514_ASRC_IN_CTRL1: |
182 | case RT5514_DOWNFILTER0_CTRL1: |
183 | case RT5514_DOWNFILTER0_CTRL2: |
184 | case RT5514_DOWNFILTER0_CTRL3: |
185 | case RT5514_DOWNFILTER1_CTRL1: |
186 | case RT5514_DOWNFILTER1_CTRL2: |
187 | case RT5514_DOWNFILTER1_CTRL3: |
188 | case RT5514_ANA_CTRL_LDO10: |
189 | case RT5514_ANA_CTRL_LDO18_16: |
190 | case RT5514_ANA_CTRL_ADC12: |
191 | case RT5514_ANA_CTRL_ADC21: |
192 | case RT5514_ANA_CTRL_ADC22: |
193 | case RT5514_ANA_CTRL_ADC23: |
194 | case RT5514_ANA_CTRL_MICBST: |
195 | case RT5514_ANA_CTRL_ADCFED: |
196 | case RT5514_ANA_CTRL_INBUF: |
197 | case RT5514_ANA_CTRL_VREF: |
198 | case RT5514_ANA_CTRL_PLL3: |
199 | case RT5514_ANA_CTRL_PLL1_1: |
200 | case RT5514_ANA_CTRL_PLL1_2: |
201 | case RT5514_DMIC_LP_CTRL: |
202 | case RT5514_MISC_CTRL_DSP: |
203 | case RT5514_DSP_CTRL1: |
204 | case RT5514_DSP_CTRL3: |
205 | case RT5514_DSP_CTRL4: |
206 | case RT5514_VENDOR_ID1: |
207 | case RT5514_VENDOR_ID2: |
208 | return true; |
209 | |
210 | default: |
211 | return false; |
212 | } |
213 | } |
214 | |
215 | static bool rt5514_i2c_readable_register(struct device *dev, |
216 | unsigned int reg) |
217 | { |
218 | switch (reg) { |
219 | case RT5514_DSP_MAPPING | RT5514_RESET: |
220 | case RT5514_DSP_MAPPING | RT5514_PWR_ANA1: |
221 | case RT5514_DSP_MAPPING | RT5514_PWR_ANA2: |
222 | case RT5514_DSP_MAPPING | RT5514_I2S_CTRL1: |
223 | case RT5514_DSP_MAPPING | RT5514_I2S_CTRL2: |
224 | case RT5514_DSP_MAPPING | RT5514_VAD_CTRL6: |
225 | case RT5514_DSP_MAPPING | RT5514_EXT_VAD_CTRL: |
226 | case RT5514_DSP_MAPPING | RT5514_DIG_IO_CTRL: |
227 | case RT5514_DSP_MAPPING | RT5514_PAD_CTRL1: |
228 | case RT5514_DSP_MAPPING | RT5514_DMIC_DATA_CTRL: |
229 | case RT5514_DSP_MAPPING | RT5514_DIG_SOURCE_CTRL: |
230 | case RT5514_DSP_MAPPING | RT5514_SRC_CTRL: |
231 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER2_CTRL1: |
232 | case RT5514_DSP_MAPPING | RT5514_PLL_SOURCE_CTRL: |
233 | case RT5514_DSP_MAPPING | RT5514_CLK_CTRL1: |
234 | case RT5514_DSP_MAPPING | RT5514_CLK_CTRL2: |
235 | case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL1: |
236 | case RT5514_DSP_MAPPING | RT5514_PLL3_CALIB_CTRL5: |
237 | case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL1: |
238 | case RT5514_DSP_MAPPING | RT5514_DELAY_BUF_CTRL3: |
239 | case RT5514_DSP_MAPPING | RT5514_ASRC_IN_CTRL1: |
240 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL1: |
241 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL2: |
242 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER0_CTRL3: |
243 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL1: |
244 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL2: |
245 | case RT5514_DSP_MAPPING | RT5514_DOWNFILTER1_CTRL3: |
246 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_LDO10: |
247 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_LDO18_16: |
248 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC12: |
249 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC21: |
250 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC22: |
251 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADC23: |
252 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_MICBST: |
253 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_ADCFED: |
254 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_INBUF: |
255 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_VREF: |
256 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL3: |
257 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL1_1: |
258 | case RT5514_DSP_MAPPING | RT5514_ANA_CTRL_PLL1_2: |
259 | case RT5514_DSP_MAPPING | RT5514_DMIC_LP_CTRL: |
260 | case RT5514_DSP_MAPPING | RT5514_MISC_CTRL_DSP: |
261 | case RT5514_DSP_MAPPING | RT5514_DSP_CTRL1: |
262 | case RT5514_DSP_MAPPING | RT5514_DSP_CTRL3: |
263 | case RT5514_DSP_MAPPING | RT5514_DSP_CTRL4: |
264 | case RT5514_DSP_MAPPING | RT5514_VENDOR_ID1: |
265 | case RT5514_DSP_MAPPING | RT5514_VENDOR_ID2: |
266 | return true; |
267 | |
268 | default: |
269 | return false; |
270 | } |
271 | } |
272 | |
273 | /* {-3, 0, +3, +4.5, +7.5, +9.5, +12, +14, +17} dB */ |
274 | static const DECLARE_TLV_DB_RANGE(bst_tlv, |
275 | 0, 2, TLV_DB_SCALE_ITEM(-300, 300, 0), |
276 | 3, 3, TLV_DB_SCALE_ITEM(450, 0, 0), |
277 | 4, 4, TLV_DB_SCALE_ITEM(750, 0, 0), |
278 | 5, 5, TLV_DB_SCALE_ITEM(950, 0, 0), |
279 | 6, 6, TLV_DB_SCALE_ITEM(1200, 0, 0), |
280 | 7, 7, TLV_DB_SCALE_ITEM(1400, 0, 0), |
281 | 8, 8, TLV_DB_SCALE_ITEM(1700, 0, 0) |
282 | ); |
283 | |
284 | static const DECLARE_TLV_DB_SCALE(adc_vol_tlv, -1725, 75, 0); |
285 | |
286 | static int rt5514_dsp_voice_wake_up_get(struct snd_kcontrol *kcontrol, |
287 | struct snd_ctl_elem_value *ucontrol) |
288 | { |
289 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
290 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
291 | |
292 | ucontrol->value.integer.value[0] = rt5514->dsp_enabled; |
293 | |
294 | return 0; |
295 | } |
296 | |
297 | static int rt5514_calibration(struct rt5514_priv *rt5514, bool on) |
298 | { |
299 | if (on) { |
300 | regmap_write(map: rt5514->regmap, RT5514_ANA_CTRL_PLL3, val: 0x0000000a); |
301 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL_SOURCE_CTRL, mask: 0xf, |
302 | val: 0xa); |
303 | regmap_update_bits(map: rt5514->regmap, RT5514_PWR_ANA1, mask: 0x301, |
304 | val: 0x301); |
305 | regmap_write(map: rt5514->regmap, RT5514_PLL3_CALIB_CTRL4, |
306 | val: 0x80000000 | rt5514->pll3_cal_value); |
307 | regmap_write(map: rt5514->regmap, RT5514_PLL3_CALIB_CTRL1, |
308 | val: 0x8bb80800); |
309 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL3_CALIB_CTRL5, |
310 | mask: 0xc0000000, val: 0x80000000); |
311 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL3_CALIB_CTRL5, |
312 | mask: 0xc0000000, val: 0xc0000000); |
313 | } else { |
314 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL3_CALIB_CTRL5, |
315 | mask: 0xc0000000, val: 0x40000000); |
316 | regmap_update_bits(map: rt5514->regmap, RT5514_PWR_ANA1, mask: 0x301, val: 0); |
317 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL_SOURCE_CTRL, mask: 0xf, |
318 | val: 0x4); |
319 | } |
320 | |
321 | return 0; |
322 | } |
323 | |
324 | static int rt5514_dsp_voice_wake_up_put(struct snd_kcontrol *kcontrol, |
325 | struct snd_ctl_elem_value *ucontrol) |
326 | { |
327 | struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); |
328 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
329 | const struct firmware *fw = NULL; |
330 | u8 buf[8]; |
331 | |
332 | if (ucontrol->value.integer.value[0] == rt5514->dsp_enabled) |
333 | return 0; |
334 | |
335 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { |
336 | rt5514->dsp_enabled = ucontrol->value.integer.value[0]; |
337 | |
338 | if (rt5514->dsp_enabled) { |
339 | if (rt5514->pdata.dsp_calib_clk_name && |
340 | !IS_ERR(ptr: rt5514->dsp_calib_clk)) { |
341 | if (clk_set_rate(clk: rt5514->dsp_calib_clk, |
342 | rate: rt5514->pdata.dsp_calib_clk_rate)) |
343 | dev_err(component->dev, |
344 | "Can't set rate for mclk" ); |
345 | |
346 | if (clk_prepare_enable(clk: rt5514->dsp_calib_clk)) |
347 | dev_err(component->dev, |
348 | "Can't enable dsp_calib_clk" ); |
349 | |
350 | rt5514_calibration(rt5514, on: true); |
351 | |
352 | msleep(msecs: 20); |
353 | #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) |
354 | rt5514_spi_burst_read(RT5514_PLL3_CALIB_CTRL6 | |
355 | RT5514_DSP_MAPPING, rxbuf: buf, len: sizeof(buf)); |
356 | #else |
357 | dev_err(component->dev, "There is no SPI driver for" |
358 | " loading the firmware\n" ); |
359 | memset(buf, 0, sizeof(buf)); |
360 | #endif |
361 | rt5514->pll3_cal_value = buf[0] | buf[1] << 8 | |
362 | buf[2] << 16 | buf[3] << 24; |
363 | |
364 | rt5514_calibration(rt5514, on: false); |
365 | clk_disable_unprepare(clk: rt5514->dsp_calib_clk); |
366 | } |
367 | |
368 | rt5514_enable_dsp_prepare(rt5514); |
369 | |
370 | request_firmware(fw: &fw, RT5514_FIRMWARE1, device: component->dev); |
371 | if (fw) { |
372 | #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) |
373 | rt5514_spi_burst_write(addr: 0x4ff60000, txbuf: fw->data, |
374 | len: ((fw->size/8)+1)*8); |
375 | #else |
376 | dev_err(component->dev, "There is no SPI driver for" |
377 | " loading the firmware\n" ); |
378 | #endif |
379 | release_firmware(fw); |
380 | fw = NULL; |
381 | } |
382 | |
383 | request_firmware(fw: &fw, RT5514_FIRMWARE2, device: component->dev); |
384 | if (fw) { |
385 | #if IS_ENABLED(CONFIG_SND_SOC_RT5514_SPI) |
386 | rt5514_spi_burst_write(addr: 0x4ffc0000, txbuf: fw->data, |
387 | len: ((fw->size/8)+1)*8); |
388 | #else |
389 | dev_err(component->dev, "There is no SPI driver for" |
390 | " loading the firmware\n" ); |
391 | #endif |
392 | release_firmware(fw); |
393 | fw = NULL; |
394 | } |
395 | |
396 | /* DSP run */ |
397 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002f00, |
398 | val: 0x00055148); |
399 | |
400 | if (rt5514->pdata.dsp_calib_clk_name && |
401 | !IS_ERR(ptr: rt5514->dsp_calib_clk)) { |
402 | msleep(msecs: 20); |
403 | |
404 | regmap_write(map: rt5514->i2c_regmap, reg: 0x1800211c, |
405 | val: rt5514->pll3_cal_value); |
406 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002124, |
407 | val: 0x00220012); |
408 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002124, |
409 | val: 0x80220042); |
410 | regmap_write(map: rt5514->i2c_regmap, reg: 0x18002124, |
411 | val: 0xe0220042); |
412 | } |
413 | } else { |
414 | regmap_multi_reg_write(map: rt5514->i2c_regmap, |
415 | regs: rt5514_i2c_patch, ARRAY_SIZE(rt5514_i2c_patch)); |
416 | regcache_mark_dirty(map: rt5514->regmap); |
417 | regcache_sync(map: rt5514->regmap); |
418 | } |
419 | } |
420 | |
421 | return 1; |
422 | } |
423 | |
424 | static const struct snd_kcontrol_new rt5514_snd_controls[] = { |
425 | SOC_DOUBLE_TLV("MIC Boost Volume" , RT5514_ANA_CTRL_MICBST, |
426 | RT5514_SEL_BSTL_SFT, RT5514_SEL_BSTR_SFT, 8, 0, bst_tlv), |
427 | SOC_DOUBLE_R_TLV("ADC1 Capture Volume" , RT5514_DOWNFILTER0_CTRL1, |
428 | RT5514_DOWNFILTER0_CTRL2, RT5514_AD_GAIN_SFT, 63, 0, |
429 | adc_vol_tlv), |
430 | SOC_DOUBLE_R_TLV("ADC2 Capture Volume" , RT5514_DOWNFILTER1_CTRL1, |
431 | RT5514_DOWNFILTER1_CTRL2, RT5514_AD_GAIN_SFT, 63, 0, |
432 | adc_vol_tlv), |
433 | SOC_SINGLE_EXT("DSP Voice Wake Up" , SND_SOC_NOPM, 0, 1, 0, |
434 | rt5514_dsp_voice_wake_up_get, rt5514_dsp_voice_wake_up_put), |
435 | }; |
436 | |
437 | /* ADC Mixer*/ |
438 | static const struct snd_kcontrol_new rt5514_sto1_adc_l_mix[] = { |
439 | SOC_DAPM_SINGLE("DMIC Switch" , RT5514_DOWNFILTER0_CTRL1, |
440 | RT5514_AD_DMIC_MIX_BIT, 1, 1), |
441 | SOC_DAPM_SINGLE("ADC Switch" , RT5514_DOWNFILTER0_CTRL1, |
442 | RT5514_AD_AD_MIX_BIT, 1, 1), |
443 | }; |
444 | |
445 | static const struct snd_kcontrol_new rt5514_sto1_adc_r_mix[] = { |
446 | SOC_DAPM_SINGLE("DMIC Switch" , RT5514_DOWNFILTER0_CTRL2, |
447 | RT5514_AD_DMIC_MIX_BIT, 1, 1), |
448 | SOC_DAPM_SINGLE("ADC Switch" , RT5514_DOWNFILTER0_CTRL2, |
449 | RT5514_AD_AD_MIX_BIT, 1, 1), |
450 | }; |
451 | |
452 | static const struct snd_kcontrol_new rt5514_sto2_adc_l_mix[] = { |
453 | SOC_DAPM_SINGLE("DMIC Switch" , RT5514_DOWNFILTER1_CTRL1, |
454 | RT5514_AD_DMIC_MIX_BIT, 1, 1), |
455 | SOC_DAPM_SINGLE("ADC Switch" , RT5514_DOWNFILTER1_CTRL1, |
456 | RT5514_AD_AD_MIX_BIT, 1, 1), |
457 | }; |
458 | |
459 | static const struct snd_kcontrol_new rt5514_sto2_adc_r_mix[] = { |
460 | SOC_DAPM_SINGLE("DMIC Switch" , RT5514_DOWNFILTER1_CTRL2, |
461 | RT5514_AD_DMIC_MIX_BIT, 1, 1), |
462 | SOC_DAPM_SINGLE("ADC Switch" , RT5514_DOWNFILTER1_CTRL2, |
463 | RT5514_AD_AD_MIX_BIT, 1, 1), |
464 | }; |
465 | |
466 | /* DMIC Source */ |
467 | static const char * const rt5514_dmic_src[] = { |
468 | "DMIC1" , "DMIC2" |
469 | }; |
470 | |
471 | static SOC_ENUM_SINGLE_DECL( |
472 | rt5514_stereo1_dmic_enum, RT5514_DIG_SOURCE_CTRL, |
473 | RT5514_AD0_DMIC_INPUT_SEL_SFT, rt5514_dmic_src); |
474 | |
475 | static const struct snd_kcontrol_new rt5514_sto1_dmic_mux = |
476 | SOC_DAPM_ENUM("Stereo1 DMIC Source" , rt5514_stereo1_dmic_enum); |
477 | |
478 | static SOC_ENUM_SINGLE_DECL( |
479 | rt5514_stereo2_dmic_enum, RT5514_DIG_SOURCE_CTRL, |
480 | RT5514_AD1_DMIC_INPUT_SEL_SFT, rt5514_dmic_src); |
481 | |
482 | static const struct snd_kcontrol_new rt5514_sto2_dmic_mux = |
483 | SOC_DAPM_ENUM("Stereo2 DMIC Source" , rt5514_stereo2_dmic_enum); |
484 | |
485 | /** |
486 | * rt5514_calc_dmic_clk - Calculate the frequency divider parameter of dmic. |
487 | * |
488 | * @component: only used for dev_warn |
489 | * @rate: base clock rate. |
490 | * |
491 | * Choose divider parameter that gives the highest possible DMIC frequency in |
492 | * 1MHz - 3MHz range. |
493 | */ |
494 | static int rt5514_calc_dmic_clk(struct snd_soc_component *component, int rate) |
495 | { |
496 | static const int div[] = {2, 3, 4, 8, 12, 16, 24, 32}; |
497 | int i; |
498 | |
499 | if (rate < 1000000 * div[0]) { |
500 | pr_warn("Base clock rate %d is too low\n" , rate); |
501 | return -EINVAL; |
502 | } |
503 | |
504 | for (i = 0; i < ARRAY_SIZE(div); i++) { |
505 | /* find divider that gives DMIC frequency below 3.072MHz */ |
506 | if (3072000 * div[i] >= rate) |
507 | return i; |
508 | } |
509 | |
510 | dev_warn(component->dev, "Base clock rate %d is too high\n" , rate); |
511 | return -EINVAL; |
512 | } |
513 | |
514 | static int rt5514_set_dmic_clk(struct snd_soc_dapm_widget *w, |
515 | struct snd_kcontrol *kcontrol, int event) |
516 | { |
517 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: w->dapm); |
518 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
519 | int idx; |
520 | |
521 | idx = rt5514_calc_dmic_clk(component, rate: rt5514->sysclk); |
522 | if (idx < 0) |
523 | dev_err(component->dev, "Failed to set DMIC clock\n" ); |
524 | else |
525 | regmap_update_bits(map: rt5514->regmap, RT5514_CLK_CTRL1, |
526 | RT5514_CLK_DMIC_OUT_SEL_MASK, |
527 | val: idx << RT5514_CLK_DMIC_OUT_SEL_SFT); |
528 | |
529 | if (rt5514->pdata.dmic_init_delay) |
530 | msleep(msecs: rt5514->pdata.dmic_init_delay); |
531 | |
532 | return idx; |
533 | } |
534 | |
535 | static int rt5514_is_sys_clk_from_pll(struct snd_soc_dapm_widget *source, |
536 | struct snd_soc_dapm_widget *sink) |
537 | { |
538 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: source->dapm); |
539 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
540 | |
541 | if (rt5514->sysclk_src == RT5514_SCLK_S_PLL1) |
542 | return 1; |
543 | else |
544 | return 0; |
545 | } |
546 | |
547 | static int rt5514_i2s_use_asrc(struct snd_soc_dapm_widget *source, |
548 | struct snd_soc_dapm_widget *sink) |
549 | { |
550 | struct snd_soc_component *component = snd_soc_dapm_to_component(dapm: source->dapm); |
551 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
552 | |
553 | return (rt5514->sysclk > rt5514->lrck * 384); |
554 | } |
555 | |
556 | static const struct snd_soc_dapm_widget rt5514_dapm_widgets[] = { |
557 | /* Input Lines */ |
558 | SND_SOC_DAPM_INPUT("DMIC1L" ), |
559 | SND_SOC_DAPM_INPUT("DMIC1R" ), |
560 | SND_SOC_DAPM_INPUT("DMIC2L" ), |
561 | SND_SOC_DAPM_INPUT("DMIC2R" ), |
562 | |
563 | SND_SOC_DAPM_INPUT("AMICL" ), |
564 | SND_SOC_DAPM_INPUT("AMICR" ), |
565 | |
566 | SND_SOC_DAPM_PGA("DMIC1" , SND_SOC_NOPM, 0, 0, NULL, 0), |
567 | SND_SOC_DAPM_PGA("DMIC2" , SND_SOC_NOPM, 0, 0, NULL, 0), |
568 | |
569 | SND_SOC_DAPM_SUPPLY_S("DMIC CLK" , 1, SND_SOC_NOPM, 0, 0, |
570 | rt5514_set_dmic_clk, SND_SOC_DAPM_PRE_PMU), |
571 | |
572 | SND_SOC_DAPM_SUPPLY("ADC CLK" , RT5514_CLK_CTRL1, |
573 | RT5514_CLK_AD_ANA1_EN_BIT, 0, NULL, 0), |
574 | |
575 | SND_SOC_DAPM_SUPPLY("LDO18 IN" , RT5514_PWR_ANA1, |
576 | RT5514_POW_LDO18_IN_BIT, 0, NULL, 0), |
577 | SND_SOC_DAPM_SUPPLY("LDO18 ADC" , RT5514_PWR_ANA1, |
578 | RT5514_POW_LDO18_ADC_BIT, 0, NULL, 0), |
579 | SND_SOC_DAPM_SUPPLY("LDO21" , RT5514_PWR_ANA1, RT5514_POW_LDO21_BIT, 0, |
580 | NULL, 0), |
581 | SND_SOC_DAPM_SUPPLY("BG LDO18 IN" , RT5514_PWR_ANA1, |
582 | RT5514_POW_BG_LDO18_IN_BIT, 0, NULL, 0), |
583 | SND_SOC_DAPM_SUPPLY("BG LDO21" , RT5514_PWR_ANA1, |
584 | RT5514_POW_BG_LDO21_BIT, 0, NULL, 0), |
585 | SND_SOC_DAPM_SUPPLY("BG MBIAS" , RT5514_PWR_ANA2, |
586 | RT5514_POW_BG_MBIAS_BIT, 0, NULL, 0), |
587 | SND_SOC_DAPM_SUPPLY("MBIAS" , RT5514_PWR_ANA2, RT5514_POW_MBIAS_BIT, 0, |
588 | NULL, 0), |
589 | SND_SOC_DAPM_SUPPLY("VREF2" , RT5514_PWR_ANA2, RT5514_POW_VREF2_BIT, 0, |
590 | NULL, 0), |
591 | SND_SOC_DAPM_SUPPLY("VREF1" , RT5514_PWR_ANA2, RT5514_POW_VREF1_BIT, 0, |
592 | NULL, 0), |
593 | SND_SOC_DAPM_SUPPLY("ADC Power" , SND_SOC_NOPM, 0, 0, NULL, 0), |
594 | |
595 | |
596 | SND_SOC_DAPM_SUPPLY("LDO16L" , RT5514_PWR_ANA2, RT5514_POWL_LDO16_BIT, 0, |
597 | NULL, 0), |
598 | SND_SOC_DAPM_SUPPLY("ADC1L" , RT5514_PWR_ANA2, RT5514_POW_ADC1_L_BIT, 0, |
599 | NULL, 0), |
600 | SND_SOC_DAPM_SUPPLY("BSTL2" , RT5514_PWR_ANA2, RT5514_POW2_BSTL_BIT, 0, |
601 | NULL, 0), |
602 | SND_SOC_DAPM_SUPPLY("BSTL" , RT5514_PWR_ANA2, RT5514_POW_BSTL_BIT, 0, |
603 | NULL, 0), |
604 | SND_SOC_DAPM_SUPPLY("ADCFEDL" , RT5514_PWR_ANA2, RT5514_POW_ADCFEDL_BIT, |
605 | 0, NULL, 0), |
606 | SND_SOC_DAPM_SUPPLY("ADCL Power" , SND_SOC_NOPM, 0, 0, NULL, 0), |
607 | |
608 | SND_SOC_DAPM_SUPPLY("LDO16R" , RT5514_PWR_ANA2, RT5514_POWR_LDO16_BIT, 0, |
609 | NULL, 0), |
610 | SND_SOC_DAPM_SUPPLY("ADC1R" , RT5514_PWR_ANA2, RT5514_POW_ADC1_R_BIT, 0, |
611 | NULL, 0), |
612 | SND_SOC_DAPM_SUPPLY("BSTR2" , RT5514_PWR_ANA2, RT5514_POW2_BSTR_BIT, 0, |
613 | NULL, 0), |
614 | SND_SOC_DAPM_SUPPLY("BSTR" , RT5514_PWR_ANA2, RT5514_POW_BSTR_BIT, 0, |
615 | NULL, 0), |
616 | SND_SOC_DAPM_SUPPLY("ADCFEDR" , RT5514_PWR_ANA2, RT5514_POW_ADCFEDR_BIT, |
617 | 0, NULL, 0), |
618 | SND_SOC_DAPM_SUPPLY("ADCR Power" , SND_SOC_NOPM, 0, 0, NULL, 0), |
619 | |
620 | SND_SOC_DAPM_SUPPLY("PLL1 LDO ENABLE" , RT5514_ANA_CTRL_PLL1_2, |
621 | RT5514_EN_LDO_PLL1_BIT, 0, NULL, 0), |
622 | SND_SOC_DAPM_SUPPLY("PLL1 LDO" , RT5514_PWR_ANA2, |
623 | RT5514_POW_PLL1_LDO_BIT, 0, NULL, 0), |
624 | SND_SOC_DAPM_SUPPLY("PLL1" , RT5514_PWR_ANA2, RT5514_POW_PLL1_BIT, 0, |
625 | NULL, 0), |
626 | SND_SOC_DAPM_SUPPLY_S("ASRC AD1" , 1, RT5514_CLK_CTRL2, |
627 | RT5514_CLK_AD0_ASRC_EN_BIT, 0, NULL, 0), |
628 | SND_SOC_DAPM_SUPPLY_S("ASRC AD2" , 1, RT5514_CLK_CTRL2, |
629 | RT5514_CLK_AD1_ASRC_EN_BIT, 0, NULL, 0), |
630 | |
631 | /* ADC Mux */ |
632 | SND_SOC_DAPM_MUX("Stereo1 DMIC Mux" , SND_SOC_NOPM, 0, 0, |
633 | &rt5514_sto1_dmic_mux), |
634 | SND_SOC_DAPM_MUX("Stereo2 DMIC Mux" , SND_SOC_NOPM, 0, 0, |
635 | &rt5514_sto2_dmic_mux), |
636 | |
637 | /* ADC Mixer */ |
638 | SND_SOC_DAPM_SUPPLY("adc stereo1 filter" , RT5514_CLK_CTRL1, |
639 | RT5514_CLK_AD0_EN_BIT, 0, NULL, 0), |
640 | SND_SOC_DAPM_SUPPLY("adc stereo2 filter" , RT5514_CLK_CTRL1, |
641 | RT5514_CLK_AD1_EN_BIT, 0, NULL, 0), |
642 | |
643 | SND_SOC_DAPM_MIXER("Sto1 ADC MIXL" , SND_SOC_NOPM, 0, 0, |
644 | rt5514_sto1_adc_l_mix, ARRAY_SIZE(rt5514_sto1_adc_l_mix)), |
645 | SND_SOC_DAPM_MIXER("Sto1 ADC MIXR" , SND_SOC_NOPM, 0, 0, |
646 | rt5514_sto1_adc_r_mix, ARRAY_SIZE(rt5514_sto1_adc_r_mix)), |
647 | SND_SOC_DAPM_MIXER("Sto2 ADC MIXL" , SND_SOC_NOPM, 0, 0, |
648 | rt5514_sto2_adc_l_mix, ARRAY_SIZE(rt5514_sto2_adc_l_mix)), |
649 | SND_SOC_DAPM_MIXER("Sto2 ADC MIXR" , SND_SOC_NOPM, 0, 0, |
650 | rt5514_sto2_adc_r_mix, ARRAY_SIZE(rt5514_sto2_adc_r_mix)), |
651 | |
652 | SND_SOC_DAPM_ADC("Stereo1 ADC MIXL" , NULL, RT5514_DOWNFILTER0_CTRL1, |
653 | RT5514_AD_AD_MUTE_BIT, 1), |
654 | SND_SOC_DAPM_ADC("Stereo1 ADC MIXR" , NULL, RT5514_DOWNFILTER0_CTRL2, |
655 | RT5514_AD_AD_MUTE_BIT, 1), |
656 | SND_SOC_DAPM_ADC("Stereo2 ADC MIXL" , NULL, RT5514_DOWNFILTER1_CTRL1, |
657 | RT5514_AD_AD_MUTE_BIT, 1), |
658 | SND_SOC_DAPM_ADC("Stereo2 ADC MIXR" , NULL, RT5514_DOWNFILTER1_CTRL2, |
659 | RT5514_AD_AD_MUTE_BIT, 1), |
660 | |
661 | /* ADC PGA */ |
662 | SND_SOC_DAPM_PGA("Stereo1 ADC MIX" , SND_SOC_NOPM, 0, 0, NULL, 0), |
663 | SND_SOC_DAPM_PGA("Stereo2 ADC MIX" , SND_SOC_NOPM, 0, 0, NULL, 0), |
664 | |
665 | /* Audio Interface */ |
666 | SND_SOC_DAPM_AIF_OUT("AIF1TX" , "AIF1 Capture" , 0, SND_SOC_NOPM, 0, 0), |
667 | }; |
668 | |
669 | static const struct snd_soc_dapm_route rt5514_dapm_routes[] = { |
670 | { "DMIC1" , NULL, "DMIC1L" }, |
671 | { "DMIC1" , NULL, "DMIC1R" }, |
672 | { "DMIC2" , NULL, "DMIC2L" }, |
673 | { "DMIC2" , NULL, "DMIC2R" }, |
674 | |
675 | { "DMIC1L" , NULL, "DMIC CLK" }, |
676 | { "DMIC1R" , NULL, "DMIC CLK" }, |
677 | { "DMIC2L" , NULL, "DMIC CLK" }, |
678 | { "DMIC2R" , NULL, "DMIC CLK" }, |
679 | |
680 | { "Stereo1 DMIC Mux" , "DMIC1" , "DMIC1" }, |
681 | { "Stereo1 DMIC Mux" , "DMIC2" , "DMIC2" }, |
682 | |
683 | { "Sto1 ADC MIXL" , "DMIC Switch" , "Stereo1 DMIC Mux" }, |
684 | { "Sto1 ADC MIXL" , "ADC Switch" , "AMICL" }, |
685 | { "Sto1 ADC MIXR" , "DMIC Switch" , "Stereo1 DMIC Mux" }, |
686 | { "Sto1 ADC MIXR" , "ADC Switch" , "AMICR" }, |
687 | |
688 | { "ADC Power" , NULL, "LDO18 IN" }, |
689 | { "ADC Power" , NULL, "LDO18 ADC" }, |
690 | { "ADC Power" , NULL, "LDO21" }, |
691 | { "ADC Power" , NULL, "BG LDO18 IN" }, |
692 | { "ADC Power" , NULL, "BG LDO21" }, |
693 | { "ADC Power" , NULL, "BG MBIAS" }, |
694 | { "ADC Power" , NULL, "MBIAS" }, |
695 | { "ADC Power" , NULL, "VREF2" }, |
696 | { "ADC Power" , NULL, "VREF1" }, |
697 | |
698 | { "ADCL Power" , NULL, "LDO16L" }, |
699 | { "ADCL Power" , NULL, "ADC1L" }, |
700 | { "ADCL Power" , NULL, "BSTL2" }, |
701 | { "ADCL Power" , NULL, "BSTL" }, |
702 | { "ADCL Power" , NULL, "ADCFEDL" }, |
703 | |
704 | { "ADCR Power" , NULL, "LDO16R" }, |
705 | { "ADCR Power" , NULL, "ADC1R" }, |
706 | { "ADCR Power" , NULL, "BSTR2" }, |
707 | { "ADCR Power" , NULL, "BSTR" }, |
708 | { "ADCR Power" , NULL, "ADCFEDR" }, |
709 | |
710 | { "AMICL" , NULL, "ADC CLK" }, |
711 | { "AMICL" , NULL, "ADC Power" }, |
712 | { "AMICL" , NULL, "ADCL Power" }, |
713 | { "AMICR" , NULL, "ADC CLK" }, |
714 | { "AMICR" , NULL, "ADC Power" }, |
715 | { "AMICR" , NULL, "ADCR Power" }, |
716 | |
717 | { "PLL1 LDO" , NULL, "PLL1 LDO ENABLE" }, |
718 | { "PLL1" , NULL, "PLL1 LDO" }, |
719 | |
720 | { "Stereo1 ADC MIXL" , NULL, "Sto1 ADC MIXL" }, |
721 | { "Stereo1 ADC MIXR" , NULL, "Sto1 ADC MIXR" }, |
722 | |
723 | { "Stereo1 ADC MIX" , NULL, "Stereo1 ADC MIXL" }, |
724 | { "Stereo1 ADC MIX" , NULL, "Stereo1 ADC MIXR" }, |
725 | { "Stereo1 ADC MIX" , NULL, "adc stereo1 filter" }, |
726 | { "adc stereo1 filter" , NULL, "PLL1" , rt5514_is_sys_clk_from_pll }, |
727 | { "adc stereo1 filter" , NULL, "ASRC AD1" , rt5514_i2s_use_asrc }, |
728 | |
729 | { "Stereo2 DMIC Mux" , "DMIC1" , "DMIC1" }, |
730 | { "Stereo2 DMIC Mux" , "DMIC2" , "DMIC2" }, |
731 | |
732 | { "Sto2 ADC MIXL" , "DMIC Switch" , "Stereo2 DMIC Mux" }, |
733 | { "Sto2 ADC MIXL" , "ADC Switch" , "AMICL" }, |
734 | { "Sto2 ADC MIXR" , "DMIC Switch" , "Stereo2 DMIC Mux" }, |
735 | { "Sto2 ADC MIXR" , "ADC Switch" , "AMICR" }, |
736 | |
737 | { "Stereo2 ADC MIXL" , NULL, "Sto2 ADC MIXL" }, |
738 | { "Stereo2 ADC MIXR" , NULL, "Sto2 ADC MIXR" }, |
739 | |
740 | { "Stereo2 ADC MIX" , NULL, "Stereo2 ADC MIXL" }, |
741 | { "Stereo2 ADC MIX" , NULL, "Stereo2 ADC MIXR" }, |
742 | { "Stereo2 ADC MIX" , NULL, "adc stereo2 filter" }, |
743 | { "adc stereo2 filter" , NULL, "PLL1" , rt5514_is_sys_clk_from_pll }, |
744 | { "adc stereo2 filter" , NULL, "ASRC AD2" , rt5514_i2s_use_asrc }, |
745 | |
746 | { "AIF1TX" , NULL, "Stereo1 ADC MIX" }, |
747 | { "AIF1TX" , NULL, "Stereo2 ADC MIX" }, |
748 | }; |
749 | |
750 | static int rt5514_hw_params(struct snd_pcm_substream *substream, |
751 | struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) |
752 | { |
753 | struct snd_soc_component *component = dai->component; |
754 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
755 | int pre_div, bclk_ms, frame_size; |
756 | unsigned int val_len = 0; |
757 | |
758 | rt5514->lrck = params_rate(p: params); |
759 | pre_div = rl6231_get_clk_info(sclk: rt5514->sysclk, rate: rt5514->lrck); |
760 | if (pre_div < 0) { |
761 | dev_err(component->dev, "Unsupported clock setting\n" ); |
762 | return -EINVAL; |
763 | } |
764 | |
765 | frame_size = snd_soc_params_to_frame_size(params); |
766 | if (frame_size < 0) { |
767 | dev_err(component->dev, "Unsupported frame size: %d\n" , frame_size); |
768 | return -EINVAL; |
769 | } |
770 | |
771 | bclk_ms = frame_size > 32; |
772 | rt5514->bclk = rt5514->lrck * (32 << bclk_ms); |
773 | |
774 | dev_dbg(dai->dev, "bclk is %dHz and lrck is %dHz\n" , |
775 | rt5514->bclk, rt5514->lrck); |
776 | dev_dbg(dai->dev, "bclk_ms is %d and pre_div is %d for iis %d\n" , |
777 | bclk_ms, pre_div, dai->id); |
778 | |
779 | switch (params_format(p: params)) { |
780 | case SNDRV_PCM_FORMAT_S16_LE: |
781 | break; |
782 | case SNDRV_PCM_FORMAT_S20_3LE: |
783 | val_len = RT5514_I2S_DL_20; |
784 | break; |
785 | case SNDRV_PCM_FORMAT_S24_LE: |
786 | val_len = RT5514_I2S_DL_24; |
787 | break; |
788 | case SNDRV_PCM_FORMAT_S8: |
789 | val_len = RT5514_I2S_DL_8; |
790 | break; |
791 | default: |
792 | return -EINVAL; |
793 | } |
794 | |
795 | regmap_update_bits(map: rt5514->regmap, RT5514_I2S_CTRL1, RT5514_I2S_DL_MASK, |
796 | val: val_len); |
797 | regmap_update_bits(map: rt5514->regmap, RT5514_CLK_CTRL1, |
798 | RT5514_CLK_AD_ANA1_SEL_MASK, |
799 | val: (pre_div + 1) << RT5514_CLK_AD_ANA1_SEL_SFT); |
800 | regmap_update_bits(map: rt5514->regmap, RT5514_CLK_CTRL2, |
801 | RT5514_CLK_SYS_DIV_OUT_MASK | RT5514_SEL_ADC_OSR_MASK, |
802 | val: pre_div << RT5514_CLK_SYS_DIV_OUT_SFT | |
803 | pre_div << RT5514_SEL_ADC_OSR_SFT); |
804 | |
805 | return 0; |
806 | } |
807 | |
808 | static int rt5514_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
809 | { |
810 | struct snd_soc_component *component = dai->component; |
811 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
812 | unsigned int reg_val = 0; |
813 | |
814 | switch (fmt & SND_SOC_DAIFMT_INV_MASK) { |
815 | case SND_SOC_DAIFMT_NB_NF: |
816 | break; |
817 | |
818 | case SND_SOC_DAIFMT_NB_IF: |
819 | reg_val |= RT5514_I2S_LR_INV; |
820 | break; |
821 | |
822 | case SND_SOC_DAIFMT_IB_NF: |
823 | reg_val |= RT5514_I2S_BP_INV; |
824 | break; |
825 | |
826 | case SND_SOC_DAIFMT_IB_IF: |
827 | reg_val |= RT5514_I2S_BP_INV | RT5514_I2S_LR_INV; |
828 | break; |
829 | |
830 | default: |
831 | return -EINVAL; |
832 | } |
833 | |
834 | switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { |
835 | case SND_SOC_DAIFMT_I2S: |
836 | break; |
837 | |
838 | case SND_SOC_DAIFMT_LEFT_J: |
839 | reg_val |= RT5514_I2S_DF_LEFT; |
840 | break; |
841 | |
842 | case SND_SOC_DAIFMT_DSP_A: |
843 | reg_val |= RT5514_I2S_DF_PCM_A; |
844 | break; |
845 | |
846 | case SND_SOC_DAIFMT_DSP_B: |
847 | reg_val |= RT5514_I2S_DF_PCM_B; |
848 | break; |
849 | |
850 | default: |
851 | return -EINVAL; |
852 | } |
853 | |
854 | regmap_update_bits(map: rt5514->regmap, RT5514_I2S_CTRL1, |
855 | RT5514_I2S_DF_MASK | RT5514_I2S_BP_MASK | RT5514_I2S_LR_MASK, |
856 | val: reg_val); |
857 | |
858 | return 0; |
859 | } |
860 | |
861 | static int rt5514_set_dai_sysclk(struct snd_soc_dai *dai, |
862 | int clk_id, unsigned int freq, int dir) |
863 | { |
864 | struct snd_soc_component *component = dai->component; |
865 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
866 | unsigned int reg_val = 0; |
867 | |
868 | if (freq == rt5514->sysclk && clk_id == rt5514->sysclk_src) |
869 | return 0; |
870 | |
871 | switch (clk_id) { |
872 | case RT5514_SCLK_S_MCLK: |
873 | reg_val |= RT5514_CLK_SYS_PRE_SEL_MCLK; |
874 | break; |
875 | |
876 | case RT5514_SCLK_S_PLL1: |
877 | reg_val |= RT5514_CLK_SYS_PRE_SEL_PLL; |
878 | break; |
879 | |
880 | default: |
881 | dev_err(component->dev, "Invalid clock id (%d)\n" , clk_id); |
882 | return -EINVAL; |
883 | } |
884 | |
885 | regmap_update_bits(map: rt5514->regmap, RT5514_CLK_CTRL2, |
886 | RT5514_CLK_SYS_PRE_SEL_MASK, val: reg_val); |
887 | |
888 | rt5514->sysclk = freq; |
889 | rt5514->sysclk_src = clk_id; |
890 | |
891 | dev_dbg(dai->dev, "Sysclk is %dHz and clock id is %d\n" , freq, clk_id); |
892 | |
893 | return 0; |
894 | } |
895 | |
896 | static int rt5514_set_dai_pll(struct snd_soc_dai *dai, int pll_id, int source, |
897 | unsigned int freq_in, unsigned int freq_out) |
898 | { |
899 | struct snd_soc_component *component = dai->component; |
900 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
901 | struct rl6231_pll_code pll_code; |
902 | int ret; |
903 | |
904 | if (!freq_in || !freq_out) { |
905 | dev_dbg(component->dev, "PLL disabled\n" ); |
906 | |
907 | rt5514->pll_in = 0; |
908 | rt5514->pll_out = 0; |
909 | regmap_update_bits(map: rt5514->regmap, RT5514_CLK_CTRL2, |
910 | RT5514_CLK_SYS_PRE_SEL_MASK, |
911 | RT5514_CLK_SYS_PRE_SEL_MCLK); |
912 | |
913 | return 0; |
914 | } |
915 | |
916 | if (source == rt5514->pll_src && freq_in == rt5514->pll_in && |
917 | freq_out == rt5514->pll_out) |
918 | return 0; |
919 | |
920 | switch (source) { |
921 | case RT5514_PLL1_S_MCLK: |
922 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL_SOURCE_CTRL, |
923 | RT5514_PLL_1_SEL_MASK, RT5514_PLL_1_SEL_MCLK); |
924 | break; |
925 | |
926 | case RT5514_PLL1_S_BCLK: |
927 | regmap_update_bits(map: rt5514->regmap, RT5514_PLL_SOURCE_CTRL, |
928 | RT5514_PLL_1_SEL_MASK, RT5514_PLL_1_SEL_SCLK); |
929 | break; |
930 | |
931 | default: |
932 | dev_err(component->dev, "Unknown PLL source %d\n" , source); |
933 | return -EINVAL; |
934 | } |
935 | |
936 | ret = rl6231_pll_calc(freq_in, freq_out, pll_code: &pll_code); |
937 | if (ret < 0) { |
938 | dev_err(component->dev, "Unsupported input clock %d\n" , freq_in); |
939 | return ret; |
940 | } |
941 | |
942 | dev_dbg(component->dev, "bypass=%d m=%d n=%d k=%d\n" , |
943 | pll_code.m_bp, (pll_code.m_bp ? 0 : pll_code.m_code), |
944 | pll_code.n_code, pll_code.k_code); |
945 | |
946 | regmap_write(map: rt5514->regmap, RT5514_ANA_CTRL_PLL1_1, |
947 | val: pll_code.k_code << RT5514_PLL_K_SFT | |
948 | pll_code.n_code << RT5514_PLL_N_SFT | |
949 | (pll_code.m_bp ? 0 : pll_code.m_code) << RT5514_PLL_M_SFT); |
950 | regmap_update_bits(map: rt5514->regmap, RT5514_ANA_CTRL_PLL1_2, |
951 | RT5514_PLL_M_BP, val: pll_code.m_bp << RT5514_PLL_M_BP_SFT); |
952 | |
953 | rt5514->pll_in = freq_in; |
954 | rt5514->pll_out = freq_out; |
955 | rt5514->pll_src = source; |
956 | |
957 | return 0; |
958 | } |
959 | |
960 | static int rt5514_set_tdm_slot(struct snd_soc_dai *dai, unsigned int tx_mask, |
961 | unsigned int rx_mask, int slots, int slot_width) |
962 | { |
963 | struct snd_soc_component *component = dai->component; |
964 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
965 | unsigned int val = 0, val2 = 0; |
966 | |
967 | if (rx_mask || tx_mask) |
968 | val |= RT5514_TDM_MODE; |
969 | |
970 | switch (tx_mask) { |
971 | case 0x3: |
972 | val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH2 | |
973 | RT5514_TDM_DOCKING_START_SLOT0; |
974 | break; |
975 | |
976 | case 0x30: |
977 | val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH2 | |
978 | RT5514_TDM_DOCKING_START_SLOT4; |
979 | break; |
980 | |
981 | case 0xf: |
982 | val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH4 | |
983 | RT5514_TDM_DOCKING_START_SLOT0; |
984 | break; |
985 | |
986 | case 0xf0: |
987 | val2 |= RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH4 | |
988 | RT5514_TDM_DOCKING_START_SLOT4; |
989 | break; |
990 | |
991 | default: |
992 | break; |
993 | } |
994 | |
995 | |
996 | |
997 | switch (slots) { |
998 | case 4: |
999 | val |= RT5514_TDMSLOT_SEL_RX_4CH | RT5514_TDMSLOT_SEL_TX_4CH; |
1000 | break; |
1001 | |
1002 | case 6: |
1003 | val |= RT5514_TDMSLOT_SEL_RX_6CH | RT5514_TDMSLOT_SEL_TX_6CH; |
1004 | break; |
1005 | |
1006 | case 8: |
1007 | val |= RT5514_TDMSLOT_SEL_RX_8CH | RT5514_TDMSLOT_SEL_TX_8CH; |
1008 | break; |
1009 | |
1010 | case 2: |
1011 | default: |
1012 | break; |
1013 | } |
1014 | |
1015 | switch (slot_width) { |
1016 | case 20: |
1017 | val |= RT5514_CH_LEN_RX_20 | RT5514_CH_LEN_TX_20; |
1018 | break; |
1019 | |
1020 | case 24: |
1021 | val |= RT5514_CH_LEN_RX_24 | RT5514_CH_LEN_TX_24; |
1022 | break; |
1023 | |
1024 | case 25: |
1025 | val |= RT5514_TDM_MODE2; |
1026 | break; |
1027 | |
1028 | case 32: |
1029 | val |= RT5514_CH_LEN_RX_32 | RT5514_CH_LEN_TX_32; |
1030 | break; |
1031 | |
1032 | case 16: |
1033 | default: |
1034 | break; |
1035 | } |
1036 | |
1037 | regmap_update_bits(map: rt5514->regmap, RT5514_I2S_CTRL1, RT5514_TDM_MODE | |
1038 | RT5514_TDMSLOT_SEL_RX_MASK | RT5514_TDMSLOT_SEL_TX_MASK | |
1039 | RT5514_CH_LEN_RX_MASK | RT5514_CH_LEN_TX_MASK | |
1040 | RT5514_TDM_MODE2, val); |
1041 | |
1042 | regmap_update_bits(map: rt5514->regmap, RT5514_I2S_CTRL2, |
1043 | RT5514_TDM_DOCKING_MODE | RT5514_TDM_DOCKING_VALID_CH_MASK | |
1044 | RT5514_TDM_DOCKING_START_MASK, val: val2); |
1045 | |
1046 | return 0; |
1047 | } |
1048 | |
1049 | static int rt5514_set_bias_level(struct snd_soc_component *component, |
1050 | enum snd_soc_bias_level level) |
1051 | { |
1052 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
1053 | int ret; |
1054 | |
1055 | switch (level) { |
1056 | case SND_SOC_BIAS_PREPARE: |
1057 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_ON) { |
1058 | clk_disable_unprepare(clk: rt5514->mclk); |
1059 | } else { |
1060 | ret = clk_prepare_enable(clk: rt5514->mclk); |
1061 | if (ret) |
1062 | return ret; |
1063 | } |
1064 | break; |
1065 | |
1066 | case SND_SOC_BIAS_STANDBY: |
1067 | if (snd_soc_component_get_bias_level(component) == SND_SOC_BIAS_OFF) { |
1068 | /* |
1069 | * If the DSP is enabled in start of recording, the DSP |
1070 | * should be disabled, and sync back to normal recording |
1071 | * settings to make sure recording properly. |
1072 | */ |
1073 | if (rt5514->dsp_enabled) { |
1074 | rt5514->dsp_enabled = 0; |
1075 | regmap_multi_reg_write(map: rt5514->i2c_regmap, |
1076 | regs: rt5514_i2c_patch, |
1077 | ARRAY_SIZE(rt5514_i2c_patch)); |
1078 | regcache_mark_dirty(map: rt5514->regmap); |
1079 | regcache_sync(map: rt5514->regmap); |
1080 | } |
1081 | } |
1082 | break; |
1083 | |
1084 | default: |
1085 | break; |
1086 | } |
1087 | |
1088 | return 0; |
1089 | } |
1090 | |
1091 | static int rt5514_probe(struct snd_soc_component *component) |
1092 | { |
1093 | struct rt5514_priv *rt5514 = snd_soc_component_get_drvdata(c: component); |
1094 | struct platform_device *pdev = container_of(component->dev, |
1095 | struct platform_device, dev); |
1096 | |
1097 | rt5514->mclk = devm_clk_get_optional(dev: component->dev, id: "mclk" ); |
1098 | if (IS_ERR(ptr: rt5514->mclk)) |
1099 | return PTR_ERR(ptr: rt5514->mclk); |
1100 | |
1101 | if (rt5514->pdata.dsp_calib_clk_name) { |
1102 | rt5514->dsp_calib_clk = devm_clk_get(dev: &pdev->dev, |
1103 | id: rt5514->pdata.dsp_calib_clk_name); |
1104 | if (PTR_ERR(ptr: rt5514->dsp_calib_clk) == -EPROBE_DEFER) |
1105 | return -EPROBE_DEFER; |
1106 | } |
1107 | |
1108 | rt5514->component = component; |
1109 | rt5514->pll3_cal_value = 0x0078b000; |
1110 | |
1111 | return 0; |
1112 | } |
1113 | |
1114 | static int rt5514_i2c_read(void *context, unsigned int reg, unsigned int *val) |
1115 | { |
1116 | struct i2c_client *client = context; |
1117 | struct rt5514_priv *rt5514 = i2c_get_clientdata(client); |
1118 | |
1119 | regmap_read(map: rt5514->i2c_regmap, reg: reg | RT5514_DSP_MAPPING, val); |
1120 | |
1121 | return 0; |
1122 | } |
1123 | |
1124 | static int rt5514_i2c_write(void *context, unsigned int reg, unsigned int val) |
1125 | { |
1126 | struct i2c_client *client = context; |
1127 | struct rt5514_priv *rt5514 = i2c_get_clientdata(client); |
1128 | |
1129 | regmap_write(map: rt5514->i2c_regmap, reg: reg | RT5514_DSP_MAPPING, val); |
1130 | |
1131 | return 0; |
1132 | } |
1133 | |
1134 | #define RT5514_STEREO_RATES SNDRV_PCM_RATE_8000_192000 |
1135 | #define RT5514_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ |
1136 | SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S8) |
1137 | |
1138 | static const struct snd_soc_dai_ops rt5514_aif_dai_ops = { |
1139 | .hw_params = rt5514_hw_params, |
1140 | .set_fmt = rt5514_set_dai_fmt, |
1141 | .set_sysclk = rt5514_set_dai_sysclk, |
1142 | .set_pll = rt5514_set_dai_pll, |
1143 | .set_tdm_slot = rt5514_set_tdm_slot, |
1144 | }; |
1145 | |
1146 | static struct snd_soc_dai_driver rt5514_dai[] = { |
1147 | { |
1148 | .name = "rt5514-aif1" , |
1149 | .id = 0, |
1150 | .capture = { |
1151 | .stream_name = "AIF1 Capture" , |
1152 | .channels_min = 1, |
1153 | .channels_max = 4, |
1154 | .rates = RT5514_STEREO_RATES, |
1155 | .formats = RT5514_FORMATS, |
1156 | }, |
1157 | .ops = &rt5514_aif_dai_ops, |
1158 | } |
1159 | }; |
1160 | |
1161 | static const struct snd_soc_component_driver soc_component_dev_rt5514 = { |
1162 | .probe = rt5514_probe, |
1163 | .set_bias_level = rt5514_set_bias_level, |
1164 | .controls = rt5514_snd_controls, |
1165 | .num_controls = ARRAY_SIZE(rt5514_snd_controls), |
1166 | .dapm_widgets = rt5514_dapm_widgets, |
1167 | .num_dapm_widgets = ARRAY_SIZE(rt5514_dapm_widgets), |
1168 | .dapm_routes = rt5514_dapm_routes, |
1169 | .num_dapm_routes = ARRAY_SIZE(rt5514_dapm_routes), |
1170 | .use_pmdown_time = 1, |
1171 | .endianness = 1, |
1172 | }; |
1173 | |
1174 | static const struct regmap_config rt5514_i2c_regmap = { |
1175 | .name = "i2c" , |
1176 | .reg_bits = 32, |
1177 | .val_bits = 32, |
1178 | |
1179 | .readable_reg = rt5514_i2c_readable_register, |
1180 | |
1181 | .cache_type = REGCACHE_NONE, |
1182 | }; |
1183 | |
1184 | static const struct regmap_config rt5514_regmap = { |
1185 | .reg_bits = 16, |
1186 | .val_bits = 32, |
1187 | |
1188 | .max_register = RT5514_VENDOR_ID2, |
1189 | .volatile_reg = rt5514_volatile_register, |
1190 | .readable_reg = rt5514_readable_register, |
1191 | .reg_read = rt5514_i2c_read, |
1192 | .reg_write = rt5514_i2c_write, |
1193 | |
1194 | .cache_type = REGCACHE_MAPLE, |
1195 | .reg_defaults = rt5514_reg, |
1196 | .num_reg_defaults = ARRAY_SIZE(rt5514_reg), |
1197 | .use_single_read = true, |
1198 | .use_single_write = true, |
1199 | }; |
1200 | |
1201 | static const struct i2c_device_id rt5514_i2c_id[] = { |
1202 | { "rt5514" , 0 }, |
1203 | { } |
1204 | }; |
1205 | MODULE_DEVICE_TABLE(i2c, rt5514_i2c_id); |
1206 | |
1207 | #if defined(CONFIG_OF) |
1208 | static const struct of_device_id rt5514_of_match[] = { |
1209 | { .compatible = "realtek,rt5514" , }, |
1210 | {}, |
1211 | }; |
1212 | MODULE_DEVICE_TABLE(of, rt5514_of_match); |
1213 | #endif |
1214 | |
1215 | #ifdef CONFIG_ACPI |
1216 | static const struct acpi_device_id rt5514_acpi_match[] = { |
1217 | { "10EC5514" , 0}, |
1218 | {}, |
1219 | }; |
1220 | MODULE_DEVICE_TABLE(acpi, rt5514_acpi_match); |
1221 | #endif |
1222 | |
1223 | static int rt5514_parse_dp(struct rt5514_priv *rt5514, struct device *dev) |
1224 | { |
1225 | device_property_read_u32(dev, propname: "realtek,dmic-init-delay-ms" , |
1226 | val: &rt5514->pdata.dmic_init_delay); |
1227 | device_property_read_string(dev, propname: "realtek,dsp-calib-clk-name" , |
1228 | val: &rt5514->pdata.dsp_calib_clk_name); |
1229 | device_property_read_u32(dev, propname: "realtek,dsp-calib-clk-rate" , |
1230 | val: &rt5514->pdata.dsp_calib_clk_rate); |
1231 | |
1232 | return 0; |
1233 | } |
1234 | |
1235 | static __maybe_unused int rt5514_i2c_resume(struct device *dev) |
1236 | { |
1237 | struct rt5514_priv *rt5514 = dev_get_drvdata(dev); |
1238 | unsigned int val; |
1239 | |
1240 | /* |
1241 | * Add a bogus read to avoid rt5514's confusion after s2r in case it |
1242 | * saw glitches on the i2c lines and thought the other side sent a |
1243 | * start bit. |
1244 | */ |
1245 | regmap_read(map: rt5514->regmap, RT5514_VENDOR_ID2, val: &val); |
1246 | |
1247 | return 0; |
1248 | } |
1249 | |
1250 | static int rt5514_i2c_probe(struct i2c_client *i2c) |
1251 | { |
1252 | struct rt5514_platform_data *pdata = dev_get_platdata(dev: &i2c->dev); |
1253 | struct rt5514_priv *rt5514; |
1254 | int ret; |
1255 | unsigned int val = ~0; |
1256 | |
1257 | rt5514 = devm_kzalloc(dev: &i2c->dev, size: sizeof(struct rt5514_priv), |
1258 | GFP_KERNEL); |
1259 | if (rt5514 == NULL) |
1260 | return -ENOMEM; |
1261 | |
1262 | i2c_set_clientdata(client: i2c, data: rt5514); |
1263 | |
1264 | if (pdata) |
1265 | rt5514->pdata = *pdata; |
1266 | else |
1267 | rt5514_parse_dp(rt5514, dev: &i2c->dev); |
1268 | |
1269 | rt5514->i2c_regmap = devm_regmap_init_i2c(i2c, &rt5514_i2c_regmap); |
1270 | if (IS_ERR(ptr: rt5514->i2c_regmap)) { |
1271 | ret = PTR_ERR(ptr: rt5514->i2c_regmap); |
1272 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n" , |
1273 | ret); |
1274 | return ret; |
1275 | } |
1276 | |
1277 | rt5514->regmap = devm_regmap_init(&i2c->dev, NULL, i2c, &rt5514_regmap); |
1278 | if (IS_ERR(ptr: rt5514->regmap)) { |
1279 | ret = PTR_ERR(ptr: rt5514->regmap); |
1280 | dev_err(&i2c->dev, "Failed to allocate register map: %d\n" , |
1281 | ret); |
1282 | return ret; |
1283 | } |
1284 | |
1285 | /* |
1286 | * The rt5514 can get confused if the i2c lines glitch together, as |
1287 | * can happen at bootup as regulators are turned off and on. If it's |
1288 | * in this glitched state the first i2c read will fail, so we'll give |
1289 | * it one change to retry. |
1290 | */ |
1291 | ret = regmap_read(map: rt5514->regmap, RT5514_VENDOR_ID2, val: &val); |
1292 | if (ret || val != RT5514_DEVICE_ID) |
1293 | ret = regmap_read(map: rt5514->regmap, RT5514_VENDOR_ID2, val: &val); |
1294 | if (ret || val != RT5514_DEVICE_ID) { |
1295 | dev_err(&i2c->dev, |
1296 | "Device with ID register %x is not rt5514\n" , val); |
1297 | return -ENODEV; |
1298 | } |
1299 | |
1300 | ret = regmap_multi_reg_write(map: rt5514->i2c_regmap, regs: rt5514_i2c_patch, |
1301 | ARRAY_SIZE(rt5514_i2c_patch)); |
1302 | if (ret != 0) |
1303 | dev_warn(&i2c->dev, "Failed to apply i2c_regmap patch: %d\n" , |
1304 | ret); |
1305 | |
1306 | ret = regmap_register_patch(map: rt5514->regmap, regs: rt5514_patch, |
1307 | ARRAY_SIZE(rt5514_patch)); |
1308 | if (ret != 0) |
1309 | dev_warn(&i2c->dev, "Failed to apply regmap patch: %d\n" , ret); |
1310 | |
1311 | return devm_snd_soc_register_component(dev: &i2c->dev, |
1312 | component_driver: &soc_component_dev_rt5514, |
1313 | dai_drv: rt5514_dai, ARRAY_SIZE(rt5514_dai)); |
1314 | } |
1315 | |
1316 | static const struct dev_pm_ops rt5514_i2_pm_ops = { |
1317 | SET_SYSTEM_SLEEP_PM_OPS(NULL, rt5514_i2c_resume) |
1318 | }; |
1319 | |
1320 | static struct i2c_driver rt5514_i2c_driver = { |
1321 | .driver = { |
1322 | .name = "rt5514" , |
1323 | .acpi_match_table = ACPI_PTR(rt5514_acpi_match), |
1324 | .of_match_table = of_match_ptr(rt5514_of_match), |
1325 | .pm = &rt5514_i2_pm_ops, |
1326 | }, |
1327 | .probe = rt5514_i2c_probe, |
1328 | .id_table = rt5514_i2c_id, |
1329 | }; |
1330 | module_i2c_driver(rt5514_i2c_driver); |
1331 | |
1332 | MODULE_DESCRIPTION("ASoC RT5514 driver" ); |
1333 | MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>" ); |
1334 | MODULE_LICENSE("GPL v2" ); |
1335 | |