1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | // |
3 | // rt5682-sdw.c -- RT5682 ALSA SoC audio component driver |
4 | // |
5 | // Copyright 2019 Realtek Semiconductor Corp. |
6 | // Author: Oder Chiou <oder_chiou@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/acpi.h> |
15 | #include <linux/pm_runtime.h> |
16 | #include <linux/regulator/consumer.h> |
17 | #include <linux/mutex.h> |
18 | #include <linux/soundwire/sdw.h> |
19 | #include <linux/soundwire/sdw_type.h> |
20 | #include <linux/soundwire/sdw_registers.h> |
21 | #include <sound/core.h> |
22 | #include <sound/pcm.h> |
23 | #include <sound/pcm_params.h> |
24 | #include <sound/jack.h> |
25 | #include <sound/sdw.h> |
26 | #include <sound/soc.h> |
27 | #include <sound/soc-dapm.h> |
28 | #include <sound/initval.h> |
29 | #include <sound/tlv.h> |
30 | |
31 | #include "rt5682.h" |
32 | |
33 | #define RT5682_SDW_ADDR_L 0x3000 |
34 | #define RT5682_SDW_ADDR_H 0x3001 |
35 | #define RT5682_SDW_DATA_L 0x3004 |
36 | #define RT5682_SDW_DATA_H 0x3005 |
37 | #define RT5682_SDW_CMD 0x3008 |
38 | |
39 | static int rt5682_sdw_read(void *context, unsigned int reg, unsigned int *val) |
40 | { |
41 | struct device *dev = context; |
42 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
43 | unsigned int data_l, data_h; |
44 | |
45 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_CMD, val: 0); |
46 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_ADDR_H, val: (reg >> 8) & 0xff); |
47 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_ADDR_L, val: (reg & 0xff)); |
48 | regmap_read(map: rt5682->sdw_regmap, RT5682_SDW_DATA_H, val: &data_h); |
49 | regmap_read(map: rt5682->sdw_regmap, RT5682_SDW_DATA_L, val: &data_l); |
50 | |
51 | *val = (data_h << 8) | data_l; |
52 | |
53 | dev_vdbg(dev, "[%s] %04x => %04x\n" , __func__, reg, *val); |
54 | |
55 | return 0; |
56 | } |
57 | |
58 | static int rt5682_sdw_write(void *context, unsigned int reg, unsigned int val) |
59 | { |
60 | struct device *dev = context; |
61 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
62 | |
63 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_CMD, val: 1); |
64 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_ADDR_H, val: (reg >> 8) & 0xff); |
65 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_ADDR_L, val: (reg & 0xff)); |
66 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_DATA_H, val: (val >> 8) & 0xff); |
67 | regmap_write(map: rt5682->sdw_regmap, RT5682_SDW_DATA_L, val: (val & 0xff)); |
68 | |
69 | dev_vdbg(dev, "[%s] %04x <= %04x\n" , __func__, reg, val); |
70 | |
71 | return 0; |
72 | } |
73 | |
74 | static const struct regmap_config rt5682_sdw_indirect_regmap = { |
75 | .reg_bits = 16, |
76 | .val_bits = 16, |
77 | .max_register = RT5682_I2C_MODE, |
78 | .volatile_reg = rt5682_volatile_register, |
79 | .readable_reg = rt5682_readable_register, |
80 | .cache_type = REGCACHE_MAPLE, |
81 | .reg_defaults = rt5682_reg, |
82 | .num_reg_defaults = RT5682_REG_NUM, |
83 | .use_single_read = true, |
84 | .use_single_write = true, |
85 | .reg_read = rt5682_sdw_read, |
86 | .reg_write = rt5682_sdw_write, |
87 | }; |
88 | |
89 | static int rt5682_set_sdw_stream(struct snd_soc_dai *dai, void *sdw_stream, |
90 | int direction) |
91 | { |
92 | snd_soc_dai_dma_data_set(dai, stream: direction, data: sdw_stream); |
93 | |
94 | return 0; |
95 | } |
96 | |
97 | static void rt5682_sdw_shutdown(struct snd_pcm_substream *substream, |
98 | struct snd_soc_dai *dai) |
99 | { |
100 | snd_soc_dai_set_dma_data(dai, substream, NULL); |
101 | } |
102 | |
103 | static int rt5682_sdw_hw_params(struct snd_pcm_substream *substream, |
104 | struct snd_pcm_hw_params *params, |
105 | struct snd_soc_dai *dai) |
106 | { |
107 | struct snd_soc_component *component = dai->component; |
108 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(c: component); |
109 | struct sdw_stream_config stream_config = {0}; |
110 | struct sdw_port_config port_config = {0}; |
111 | struct sdw_stream_runtime *sdw_stream; |
112 | int retval; |
113 | unsigned int val_p = 0, val_c = 0, osr_p = 0, osr_c = 0; |
114 | |
115 | dev_dbg(dai->dev, "%s %s" , __func__, dai->name); |
116 | |
117 | sdw_stream = snd_soc_dai_get_dma_data(dai, substream); |
118 | if (!sdw_stream) |
119 | return -ENOMEM; |
120 | |
121 | if (!rt5682->slave) |
122 | return -EINVAL; |
123 | |
124 | /* SoundWire specific configuration */ |
125 | snd_sdw_params_to_config(substream, params, stream_config: &stream_config, port_config: &port_config); |
126 | |
127 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
128 | port_config.num = 1; |
129 | else |
130 | port_config.num = 2; |
131 | |
132 | retval = sdw_stream_add_slave(slave: rt5682->slave, stream_config: &stream_config, |
133 | port_config: &port_config, num_ports: 1, stream: sdw_stream); |
134 | if (retval) { |
135 | dev_err(dai->dev, "%s: Unable to configure port\n" , __func__); |
136 | return retval; |
137 | } |
138 | |
139 | switch (params_rate(p: params)) { |
140 | case 48000: |
141 | val_p = RT5682_SDW_REF_1_48K; |
142 | val_c = RT5682_SDW_REF_2_48K; |
143 | break; |
144 | case 96000: |
145 | val_p = RT5682_SDW_REF_1_96K; |
146 | val_c = RT5682_SDW_REF_2_96K; |
147 | break; |
148 | case 192000: |
149 | val_p = RT5682_SDW_REF_1_192K; |
150 | val_c = RT5682_SDW_REF_2_192K; |
151 | break; |
152 | case 32000: |
153 | val_p = RT5682_SDW_REF_1_32K; |
154 | val_c = RT5682_SDW_REF_2_32K; |
155 | break; |
156 | case 24000: |
157 | val_p = RT5682_SDW_REF_1_24K; |
158 | val_c = RT5682_SDW_REF_2_24K; |
159 | break; |
160 | case 16000: |
161 | val_p = RT5682_SDW_REF_1_16K; |
162 | val_c = RT5682_SDW_REF_2_16K; |
163 | break; |
164 | case 12000: |
165 | val_p = RT5682_SDW_REF_1_12K; |
166 | val_c = RT5682_SDW_REF_2_12K; |
167 | break; |
168 | case 8000: |
169 | val_p = RT5682_SDW_REF_1_8K; |
170 | val_c = RT5682_SDW_REF_2_8K; |
171 | break; |
172 | case 44100: |
173 | val_p = RT5682_SDW_REF_1_44K; |
174 | val_c = RT5682_SDW_REF_2_44K; |
175 | break; |
176 | case 88200: |
177 | val_p = RT5682_SDW_REF_1_88K; |
178 | val_c = RT5682_SDW_REF_2_88K; |
179 | break; |
180 | case 176400: |
181 | val_p = RT5682_SDW_REF_1_176K; |
182 | val_c = RT5682_SDW_REF_2_176K; |
183 | break; |
184 | case 22050: |
185 | val_p = RT5682_SDW_REF_1_22K; |
186 | val_c = RT5682_SDW_REF_2_22K; |
187 | break; |
188 | case 11025: |
189 | val_p = RT5682_SDW_REF_1_11K; |
190 | val_c = RT5682_SDW_REF_2_11K; |
191 | break; |
192 | default: |
193 | return -EINVAL; |
194 | } |
195 | |
196 | if (params_rate(p: params) <= 48000) { |
197 | osr_p = RT5682_DAC_OSR_D_8; |
198 | osr_c = RT5682_ADC_OSR_D_8; |
199 | } else if (params_rate(p: params) <= 96000) { |
200 | osr_p = RT5682_DAC_OSR_D_4; |
201 | osr_c = RT5682_ADC_OSR_D_4; |
202 | } else { |
203 | osr_p = RT5682_DAC_OSR_D_2; |
204 | osr_c = RT5682_ADC_OSR_D_2; |
205 | } |
206 | |
207 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
208 | regmap_update_bits(map: rt5682->regmap, RT5682_SDW_REF_CLK, |
209 | RT5682_SDW_REF_1_MASK, val: val_p); |
210 | regmap_update_bits(map: rt5682->regmap, RT5682_ADDA_CLK_1, |
211 | RT5682_DAC_OSR_MASK, val: osr_p); |
212 | } else { |
213 | regmap_update_bits(map: rt5682->regmap, RT5682_SDW_REF_CLK, |
214 | RT5682_SDW_REF_2_MASK, val: val_c); |
215 | regmap_update_bits(map: rt5682->regmap, RT5682_ADDA_CLK_1, |
216 | RT5682_ADC_OSR_MASK, val: osr_c); |
217 | } |
218 | |
219 | return retval; |
220 | } |
221 | |
222 | static int rt5682_sdw_hw_free(struct snd_pcm_substream *substream, |
223 | struct snd_soc_dai *dai) |
224 | { |
225 | struct snd_soc_component *component = dai->component; |
226 | struct rt5682_priv *rt5682 = snd_soc_component_get_drvdata(c: component); |
227 | struct sdw_stream_runtime *sdw_stream = |
228 | snd_soc_dai_get_dma_data(dai, substream); |
229 | |
230 | if (!rt5682->slave) |
231 | return -EINVAL; |
232 | |
233 | sdw_stream_remove_slave(slave: rt5682->slave, stream: sdw_stream); |
234 | return 0; |
235 | } |
236 | |
237 | static const struct snd_soc_dai_ops rt5682_sdw_ops = { |
238 | .hw_params = rt5682_sdw_hw_params, |
239 | .hw_free = rt5682_sdw_hw_free, |
240 | .set_stream = rt5682_set_sdw_stream, |
241 | .shutdown = rt5682_sdw_shutdown, |
242 | }; |
243 | |
244 | static struct snd_soc_dai_driver rt5682_dai[] = { |
245 | { |
246 | .name = "rt5682-aif1" , |
247 | .id = RT5682_AIF1, |
248 | .playback = { |
249 | .stream_name = "AIF1 Playback" , |
250 | .channels_min = 1, |
251 | .channels_max = 2, |
252 | .rates = RT5682_STEREO_RATES, |
253 | .formats = RT5682_FORMATS, |
254 | }, |
255 | .capture = { |
256 | .stream_name = "AIF1 Capture" , |
257 | .channels_min = 1, |
258 | .channels_max = 2, |
259 | .rates = RT5682_STEREO_RATES, |
260 | .formats = RT5682_FORMATS, |
261 | }, |
262 | .ops = &rt5682_aif1_dai_ops, |
263 | }, |
264 | { |
265 | .name = "rt5682-aif2" , |
266 | .id = RT5682_AIF2, |
267 | .capture = { |
268 | .stream_name = "AIF2 Capture" , |
269 | .channels_min = 1, |
270 | .channels_max = 2, |
271 | .rates = RT5682_STEREO_RATES, |
272 | .formats = RT5682_FORMATS, |
273 | }, |
274 | .ops = &rt5682_aif2_dai_ops, |
275 | }, |
276 | { |
277 | .name = "rt5682-sdw" , |
278 | .id = RT5682_SDW, |
279 | .playback = { |
280 | .stream_name = "SDW Playback" , |
281 | .channels_min = 1, |
282 | .channels_max = 2, |
283 | .rates = RT5682_STEREO_RATES, |
284 | .formats = RT5682_FORMATS, |
285 | }, |
286 | .capture = { |
287 | .stream_name = "SDW Capture" , |
288 | .channels_min = 1, |
289 | .channels_max = 2, |
290 | .rates = RT5682_STEREO_RATES, |
291 | .formats = RT5682_FORMATS, |
292 | }, |
293 | .ops = &rt5682_sdw_ops, |
294 | }, |
295 | }; |
296 | |
297 | static int rt5682_sdw_init(struct device *dev, struct regmap *regmap, |
298 | struct sdw_slave *slave) |
299 | { |
300 | struct rt5682_priv *rt5682; |
301 | int ret; |
302 | |
303 | rt5682 = devm_kzalloc(dev, size: sizeof(*rt5682), GFP_KERNEL); |
304 | if (!rt5682) |
305 | return -ENOMEM; |
306 | |
307 | dev_set_drvdata(dev, data: rt5682); |
308 | rt5682->slave = slave; |
309 | rt5682->sdw_regmap = regmap; |
310 | rt5682->is_sdw = true; |
311 | |
312 | mutex_init(&rt5682->disable_irq_lock); |
313 | |
314 | rt5682->regmap = devm_regmap_init(dev, NULL, dev, |
315 | &rt5682_sdw_indirect_regmap); |
316 | if (IS_ERR(ptr: rt5682->regmap)) { |
317 | ret = PTR_ERR(ptr: rt5682->regmap); |
318 | dev_err(dev, "%s: Failed to allocate register map: %d\n" , |
319 | __func__, ret); |
320 | return ret; |
321 | } |
322 | |
323 | |
324 | ret = rt5682_get_ldo1(rt5682, dev); |
325 | if (ret) |
326 | return ret; |
327 | |
328 | regcache_cache_only(map: rt5682->sdw_regmap, enable: true); |
329 | regcache_cache_only(map: rt5682->regmap, enable: true); |
330 | |
331 | /* |
332 | * Mark hw_init to false |
333 | * HW init will be performed when device reports present |
334 | */ |
335 | rt5682->hw_init = false; |
336 | rt5682->first_hw_init = false; |
337 | |
338 | mutex_init(&rt5682->calibrate_mutex); |
339 | INIT_DELAYED_WORK(&rt5682->jack_detect_work, |
340 | rt5682_jack_detect_handler); |
341 | |
342 | ret = devm_snd_soc_register_component(dev, |
343 | component_driver: &rt5682_soc_component_dev, |
344 | dai_drv: rt5682_dai, ARRAY_SIZE(rt5682_dai)); |
345 | if (ret < 0) |
346 | return ret; |
347 | |
348 | /* set autosuspend parameters */ |
349 | pm_runtime_set_autosuspend_delay(dev, delay: 3000); |
350 | pm_runtime_use_autosuspend(dev); |
351 | |
352 | /* make sure the device does not suspend immediately */ |
353 | pm_runtime_mark_last_busy(dev); |
354 | |
355 | pm_runtime_enable(dev); |
356 | |
357 | /* important note: the device is NOT tagged as 'active' and will remain |
358 | * 'suspended' until the hardware is enumerated/initialized. This is required |
359 | * to make sure the ASoC framework use of pm_runtime_get_sync() does not silently |
360 | * fail with -EACCESS because of race conditions between card creation and enumeration |
361 | */ |
362 | |
363 | dev_dbg(dev, "%s\n" , __func__); |
364 | |
365 | return ret; |
366 | } |
367 | |
368 | static int rt5682_io_init(struct device *dev, struct sdw_slave *slave) |
369 | { |
370 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
371 | int ret = 0, loop = 10; |
372 | unsigned int val; |
373 | |
374 | rt5682->disable_irq = false; |
375 | |
376 | if (rt5682->hw_init) |
377 | return 0; |
378 | |
379 | regcache_cache_only(map: rt5682->sdw_regmap, enable: false); |
380 | regcache_cache_only(map: rt5682->regmap, enable: false); |
381 | if (rt5682->first_hw_init) |
382 | regcache_cache_bypass(map: rt5682->regmap, enable: true); |
383 | |
384 | /* |
385 | * PM runtime status is marked as 'active' only when a Slave reports as Attached |
386 | */ |
387 | if (!rt5682->first_hw_init) |
388 | /* update count of parent 'active' children */ |
389 | pm_runtime_set_active(dev: &slave->dev); |
390 | |
391 | pm_runtime_get_noresume(dev: &slave->dev); |
392 | |
393 | while (loop > 0) { |
394 | regmap_read(map: rt5682->regmap, RT5682_DEVICE_ID, val: &val); |
395 | if (val == DEVICE_ID) |
396 | break; |
397 | dev_warn(dev, "Device with ID register %x is not rt5682\n" , val); |
398 | usleep_range(min: 30000, max: 30005); |
399 | loop--; |
400 | } |
401 | |
402 | if (val != DEVICE_ID) { |
403 | dev_err(dev, "%s: Device with ID register %x is not rt5682\n" , __func__, val); |
404 | ret = -ENODEV; |
405 | goto err_nodev; |
406 | } |
407 | |
408 | rt5682_calibrate(rt5682); |
409 | |
410 | if (rt5682->first_hw_init) { |
411 | regcache_cache_bypass(map: rt5682->regmap, enable: false); |
412 | regcache_mark_dirty(map: rt5682->regmap); |
413 | regcache_sync(map: rt5682->regmap); |
414 | |
415 | /* volatile registers */ |
416 | regmap_update_bits(map: rt5682->regmap, RT5682_CBJ_CTRL_2, |
417 | RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); |
418 | |
419 | goto reinit; |
420 | } |
421 | |
422 | rt5682_apply_patch_list(rt5682, dev); |
423 | |
424 | regmap_write(map: rt5682->regmap, RT5682_DEPOP_1, val: 0x0000); |
425 | |
426 | regmap_update_bits(map: rt5682->regmap, RT5682_PWR_ANLG_1, |
427 | RT5682_LDO1_DVO_MASK | RT5682_HP_DRIVER_MASK, |
428 | RT5682_LDO1_DVO_12 | RT5682_HP_DRIVER_5X); |
429 | regmap_write(map: rt5682->regmap, RT5682_MICBIAS_2, val: 0x0080); |
430 | regmap_write(map: rt5682->regmap, RT5682_TEST_MODE_CTRL_1, val: 0x0000); |
431 | regmap_update_bits(map: rt5682->regmap, RT5682_BIAS_CUR_CTRL_8, |
432 | RT5682_HPA_CP_BIAS_CTRL_MASK, RT5682_HPA_CP_BIAS_3UA); |
433 | regmap_update_bits(map: rt5682->regmap, RT5682_CHARGE_PUMP_1, |
434 | RT5682_CP_CLK_HP_MASK, RT5682_CP_CLK_HP_300KHZ); |
435 | regmap_update_bits(map: rt5682->regmap, RT5682_HP_CHARGE_PUMP_1, |
436 | RT5682_PM_HP_MASK, RT5682_PM_HP_HV); |
437 | |
438 | /* Soundwire */ |
439 | regmap_write(map: rt5682->regmap, RT5682_PLL2_INTERNAL, val: 0xa266); |
440 | regmap_write(map: rt5682->regmap, RT5682_PLL2_CTRL_1, val: 0x1700); |
441 | regmap_write(map: rt5682->regmap, RT5682_PLL2_CTRL_2, val: 0x0006); |
442 | regmap_write(map: rt5682->regmap, RT5682_PLL2_CTRL_3, val: 0x2600); |
443 | regmap_write(map: rt5682->regmap, RT5682_PLL2_CTRL_4, val: 0x0c8f); |
444 | regmap_write(map: rt5682->regmap, RT5682_PLL_TRACK_2, val: 0x3000); |
445 | regmap_write(map: rt5682->regmap, RT5682_PLL_TRACK_3, val: 0x4000); |
446 | regmap_update_bits(map: rt5682->regmap, RT5682_GLB_CLK, |
447 | RT5682_SCLK_SRC_MASK | RT5682_PLL2_SRC_MASK, |
448 | RT5682_SCLK_SRC_PLL2 | RT5682_PLL2_SRC_SDW); |
449 | |
450 | regmap_update_bits(map: rt5682->regmap, RT5682_CBJ_CTRL_2, |
451 | RT5682_EXT_JD_SRC, RT5682_EXT_JD_SRC_MANUAL); |
452 | regmap_write(map: rt5682->regmap, RT5682_CBJ_CTRL_1, val: 0xd142); |
453 | regmap_update_bits(map: rt5682->regmap, RT5682_CBJ_CTRL_5, mask: 0x0700, val: 0x0600); |
454 | regmap_update_bits(map: rt5682->regmap, RT5682_CBJ_CTRL_3, |
455 | RT5682_CBJ_IN_BUF_EN, RT5682_CBJ_IN_BUF_EN); |
456 | regmap_update_bits(map: rt5682->regmap, RT5682_SAR_IL_CMD_1, |
457 | RT5682_SAR_POW_MASK, RT5682_SAR_POW_EN); |
458 | regmap_update_bits(map: rt5682->regmap, RT5682_RC_CLK_CTRL, |
459 | RT5682_POW_IRQ | RT5682_POW_JDH | |
460 | RT5682_POW_ANA, RT5682_POW_IRQ | |
461 | RT5682_POW_JDH | RT5682_POW_ANA); |
462 | regmap_update_bits(map: rt5682->regmap, RT5682_PWR_ANLG_2, |
463 | RT5682_PWR_JDH, RT5682_PWR_JDH); |
464 | regmap_update_bits(map: rt5682->regmap, RT5682_IRQ_CTRL_2, |
465 | RT5682_JD1_EN_MASK | RT5682_JD1_IRQ_MASK, |
466 | RT5682_JD1_EN | RT5682_JD1_IRQ_PUL); |
467 | |
468 | reinit: |
469 | mod_delayed_work(wq: system_power_efficient_wq, |
470 | dwork: &rt5682->jack_detect_work, delay: msecs_to_jiffies(m: 250)); |
471 | |
472 | /* Mark Slave initialization complete */ |
473 | rt5682->hw_init = true; |
474 | rt5682->first_hw_init = true; |
475 | |
476 | err_nodev: |
477 | pm_runtime_mark_last_busy(dev: &slave->dev); |
478 | pm_runtime_put_autosuspend(dev: &slave->dev); |
479 | |
480 | dev_dbg(&slave->dev, "%s hw_init complete: %d\n" , __func__, ret); |
481 | |
482 | return ret; |
483 | } |
484 | |
485 | static bool rt5682_sdw_readable_register(struct device *dev, unsigned int reg) |
486 | { |
487 | switch (reg) { |
488 | case 0x00e0: |
489 | case 0x00f0: |
490 | case 0x3000: |
491 | case 0x3001: |
492 | case 0x3004: |
493 | case 0x3005: |
494 | case 0x3008: |
495 | return true; |
496 | default: |
497 | return false; |
498 | } |
499 | } |
500 | |
501 | static const struct regmap_config rt5682_sdw_regmap = { |
502 | .name = "sdw" , |
503 | .reg_bits = 32, |
504 | .val_bits = 8, |
505 | .max_register = RT5682_I2C_MODE, |
506 | .readable_reg = rt5682_sdw_readable_register, |
507 | .cache_type = REGCACHE_NONE, |
508 | .use_single_read = true, |
509 | .use_single_write = true, |
510 | }; |
511 | |
512 | static int rt5682_update_status(struct sdw_slave *slave, |
513 | enum sdw_slave_status status) |
514 | { |
515 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev: &slave->dev); |
516 | |
517 | if (status == SDW_SLAVE_UNATTACHED) |
518 | rt5682->hw_init = false; |
519 | |
520 | /* |
521 | * Perform initialization only if slave status is present and |
522 | * hw_init flag is false |
523 | */ |
524 | if (rt5682->hw_init || status != SDW_SLAVE_ATTACHED) |
525 | return 0; |
526 | |
527 | /* perform I/O transfers required for Slave initialization */ |
528 | return rt5682_io_init(dev: &slave->dev, slave); |
529 | } |
530 | |
531 | static int rt5682_read_prop(struct sdw_slave *slave) |
532 | { |
533 | struct sdw_slave_prop *prop = &slave->prop; |
534 | int nval, i; |
535 | u32 bit; |
536 | unsigned long addr; |
537 | struct sdw_dpn_prop *dpn; |
538 | |
539 | prop->scp_int1_mask = SDW_SCP_INT1_IMPL_DEF | SDW_SCP_INT1_BUS_CLASH | |
540 | SDW_SCP_INT1_PARITY; |
541 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; |
542 | |
543 | prop->paging_support = false; |
544 | |
545 | /* first we need to allocate memory for set bits in port lists */ |
546 | prop->source_ports = 0x4; /* BITMAP: 00000100 */ |
547 | prop->sink_ports = 0x2; /* BITMAP: 00000010 */ |
548 | |
549 | nval = hweight32(prop->source_ports); |
550 | prop->src_dpn_prop = devm_kcalloc(dev: &slave->dev, n: nval, |
551 | size: sizeof(*prop->src_dpn_prop), |
552 | GFP_KERNEL); |
553 | if (!prop->src_dpn_prop) |
554 | return -ENOMEM; |
555 | |
556 | i = 0; |
557 | dpn = prop->src_dpn_prop; |
558 | addr = prop->source_ports; |
559 | for_each_set_bit(bit, &addr, 32) { |
560 | dpn[i].num = bit; |
561 | dpn[i].type = SDW_DPN_FULL; |
562 | dpn[i].simple_ch_prep_sm = true; |
563 | dpn[i].ch_prep_timeout = 10; |
564 | i++; |
565 | } |
566 | |
567 | /* do this again for sink now */ |
568 | nval = hweight32(prop->sink_ports); |
569 | prop->sink_dpn_prop = devm_kcalloc(dev: &slave->dev, n: nval, |
570 | size: sizeof(*prop->sink_dpn_prop), |
571 | GFP_KERNEL); |
572 | if (!prop->sink_dpn_prop) |
573 | return -ENOMEM; |
574 | |
575 | i = 0; |
576 | dpn = prop->sink_dpn_prop; |
577 | addr = prop->sink_ports; |
578 | for_each_set_bit(bit, &addr, 32) { |
579 | dpn[i].num = bit; |
580 | dpn[i].type = SDW_DPN_FULL; |
581 | dpn[i].simple_ch_prep_sm = true; |
582 | dpn[i].ch_prep_timeout = 10; |
583 | i++; |
584 | } |
585 | |
586 | /* set the timeout values */ |
587 | prop->clk_stop_timeout = 20; |
588 | |
589 | /* wake-up event */ |
590 | prop->wake_capable = 1; |
591 | |
592 | return 0; |
593 | } |
594 | |
595 | /* Bus clock frequency */ |
596 | #define RT5682_CLK_FREQ_9600000HZ 9600000 |
597 | #define RT5682_CLK_FREQ_12000000HZ 12000000 |
598 | #define RT5682_CLK_FREQ_6000000HZ 6000000 |
599 | #define RT5682_CLK_FREQ_4800000HZ 4800000 |
600 | #define RT5682_CLK_FREQ_2400000HZ 2400000 |
601 | #define RT5682_CLK_FREQ_12288000HZ 12288000 |
602 | |
603 | static int rt5682_clock_config(struct device *dev) |
604 | { |
605 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
606 | unsigned int clk_freq, value; |
607 | |
608 | clk_freq = (rt5682->params.curr_dr_freq >> 1); |
609 | |
610 | switch (clk_freq) { |
611 | case RT5682_CLK_FREQ_12000000HZ: |
612 | value = 0x0; |
613 | break; |
614 | case RT5682_CLK_FREQ_6000000HZ: |
615 | value = 0x1; |
616 | break; |
617 | case RT5682_CLK_FREQ_9600000HZ: |
618 | value = 0x2; |
619 | break; |
620 | case RT5682_CLK_FREQ_4800000HZ: |
621 | value = 0x3; |
622 | break; |
623 | case RT5682_CLK_FREQ_2400000HZ: |
624 | value = 0x4; |
625 | break; |
626 | case RT5682_CLK_FREQ_12288000HZ: |
627 | value = 0x5; |
628 | break; |
629 | default: |
630 | return -EINVAL; |
631 | } |
632 | |
633 | regmap_write(map: rt5682->sdw_regmap, reg: 0xe0, val: value); |
634 | regmap_write(map: rt5682->sdw_regmap, reg: 0xf0, val: value); |
635 | |
636 | dev_dbg(dev, "%s complete, clk_freq=%d\n" , __func__, clk_freq); |
637 | |
638 | return 0; |
639 | } |
640 | |
641 | static int rt5682_bus_config(struct sdw_slave *slave, |
642 | struct sdw_bus_params *params) |
643 | { |
644 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev: &slave->dev); |
645 | int ret; |
646 | |
647 | memcpy(&rt5682->params, params, sizeof(*params)); |
648 | |
649 | ret = rt5682_clock_config(dev: &slave->dev); |
650 | if (ret < 0) |
651 | dev_err(&slave->dev, "%s: Invalid clk config" , __func__); |
652 | |
653 | return ret; |
654 | } |
655 | |
656 | static int rt5682_interrupt_callback(struct sdw_slave *slave, |
657 | struct sdw_slave_intr_status *status) |
658 | { |
659 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev: &slave->dev); |
660 | |
661 | dev_dbg(&slave->dev, |
662 | "%s control_port_stat=%x" , __func__, status->control_port); |
663 | |
664 | mutex_lock(&rt5682->disable_irq_lock); |
665 | if (status->control_port & 0x4 && !rt5682->disable_irq) { |
666 | mod_delayed_work(wq: system_power_efficient_wq, |
667 | dwork: &rt5682->jack_detect_work, delay: msecs_to_jiffies(m: rt5682->irq_work_delay_time)); |
668 | } |
669 | mutex_unlock(lock: &rt5682->disable_irq_lock); |
670 | |
671 | return 0; |
672 | } |
673 | |
674 | static const struct sdw_slave_ops rt5682_slave_ops = { |
675 | .read_prop = rt5682_read_prop, |
676 | .interrupt_callback = rt5682_interrupt_callback, |
677 | .update_status = rt5682_update_status, |
678 | .bus_config = rt5682_bus_config, |
679 | }; |
680 | |
681 | static int rt5682_sdw_probe(struct sdw_slave *slave, |
682 | const struct sdw_device_id *id) |
683 | { |
684 | struct regmap *regmap; |
685 | |
686 | /* Regmap Initialization */ |
687 | regmap = devm_regmap_init_sdw(slave, &rt5682_sdw_regmap); |
688 | if (IS_ERR(ptr: regmap)) |
689 | return -EINVAL; |
690 | |
691 | return rt5682_sdw_init(dev: &slave->dev, regmap, slave); |
692 | } |
693 | |
694 | static int rt5682_sdw_remove(struct sdw_slave *slave) |
695 | { |
696 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev: &slave->dev); |
697 | |
698 | if (rt5682->hw_init) |
699 | cancel_delayed_work_sync(dwork: &rt5682->jack_detect_work); |
700 | |
701 | pm_runtime_disable(dev: &slave->dev); |
702 | |
703 | return 0; |
704 | } |
705 | |
706 | static const struct sdw_device_id rt5682_id[] = { |
707 | SDW_SLAVE_ENTRY_EXT(0x025d, 0x5682, 0x2, 0, 0), |
708 | {}, |
709 | }; |
710 | MODULE_DEVICE_TABLE(sdw, rt5682_id); |
711 | |
712 | static int __maybe_unused rt5682_dev_suspend(struct device *dev) |
713 | { |
714 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
715 | |
716 | if (!rt5682->hw_init) |
717 | return 0; |
718 | |
719 | cancel_delayed_work_sync(dwork: &rt5682->jack_detect_work); |
720 | |
721 | regcache_cache_only(map: rt5682->sdw_regmap, enable: true); |
722 | regcache_cache_only(map: rt5682->regmap, enable: true); |
723 | regcache_mark_dirty(map: rt5682->regmap); |
724 | |
725 | return 0; |
726 | } |
727 | |
728 | static int __maybe_unused rt5682_dev_system_suspend(struct device *dev) |
729 | { |
730 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
731 | struct sdw_slave *slave = dev_to_sdw_dev(dev); |
732 | int ret; |
733 | |
734 | if (!rt5682->hw_init) |
735 | return 0; |
736 | |
737 | /* |
738 | * prevent new interrupts from being handled after the |
739 | * deferred work completes and before the parent disables |
740 | * interrupts on the link |
741 | */ |
742 | mutex_lock(&rt5682->disable_irq_lock); |
743 | rt5682->disable_irq = true; |
744 | ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1, |
745 | SDW_SCP_INT1_IMPL_DEF, val: 0); |
746 | mutex_unlock(lock: &rt5682->disable_irq_lock); |
747 | |
748 | if (ret < 0) { |
749 | /* log but don't prevent suspend from happening */ |
750 | dev_dbg(&slave->dev, "%s: could not disable imp-def interrupts\n:" , __func__); |
751 | } |
752 | |
753 | return rt5682_dev_suspend(dev); |
754 | } |
755 | |
756 | static int __maybe_unused rt5682_dev_resume(struct device *dev) |
757 | { |
758 | struct sdw_slave *slave = dev_to_sdw_dev(dev); |
759 | struct rt5682_priv *rt5682 = dev_get_drvdata(dev); |
760 | unsigned long time; |
761 | |
762 | if (!rt5682->first_hw_init) |
763 | return 0; |
764 | |
765 | if (!slave->unattach_request) { |
766 | mutex_lock(&rt5682->disable_irq_lock); |
767 | if (rt5682->disable_irq == true) { |
768 | sdw_write_no_pm(slave, SDW_SCP_INTMASK1, SDW_SCP_INT1_IMPL_DEF); |
769 | rt5682->disable_irq = false; |
770 | } |
771 | mutex_unlock(lock: &rt5682->disable_irq_lock); |
772 | goto regmap_sync; |
773 | } |
774 | |
775 | time = wait_for_completion_timeout(x: &slave->initialization_complete, |
776 | timeout: msecs_to_jiffies(RT5682_PROBE_TIMEOUT)); |
777 | if (!time) { |
778 | dev_err(&slave->dev, "%s: Initialization not complete, timed out\n" , __func__); |
779 | sdw_show_ping_status(bus: slave->bus, sync_delay: true); |
780 | |
781 | return -ETIMEDOUT; |
782 | } |
783 | |
784 | regmap_sync: |
785 | slave->unattach_request = 0; |
786 | regcache_cache_only(map: rt5682->sdw_regmap, enable: false); |
787 | regcache_cache_only(map: rt5682->regmap, enable: false); |
788 | regcache_sync(map: rt5682->regmap); |
789 | |
790 | return 0; |
791 | } |
792 | |
793 | static const struct dev_pm_ops rt5682_pm = { |
794 | SET_SYSTEM_SLEEP_PM_OPS(rt5682_dev_system_suspend, rt5682_dev_resume) |
795 | SET_RUNTIME_PM_OPS(rt5682_dev_suspend, rt5682_dev_resume, NULL) |
796 | }; |
797 | |
798 | static struct sdw_driver rt5682_sdw_driver = { |
799 | .driver = { |
800 | .name = "rt5682" , |
801 | .owner = THIS_MODULE, |
802 | .pm = &rt5682_pm, |
803 | }, |
804 | .probe = rt5682_sdw_probe, |
805 | .remove = rt5682_sdw_remove, |
806 | .ops = &rt5682_slave_ops, |
807 | .id_table = rt5682_id, |
808 | }; |
809 | module_sdw_driver(rt5682_sdw_driver); |
810 | |
811 | MODULE_DESCRIPTION("ASoC RT5682 driver SDW" ); |
812 | MODULE_AUTHOR("Oder Chiou <oder_chiou@realtek.com>" ); |
813 | MODULE_LICENSE("GPL v2" ); |
814 | |