1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // Components shared between ASoC and HDA CS35L56 drivers
4 //
5 // Copyright (C) 2023 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
7
8 #include <linux/gpio/consumer.h>
9 #include <linux/regmap.h>
10 #include <linux/regulator/consumer.h>
11 #include <linux/types.h>
12
13 #include "cs35l56.h"
14
15 static const struct reg_sequence cs35l56_patch[] = {
16 /*
17 * Firmware can change these to non-defaults to satisfy SDCA.
18 * Ensure that they are at known defaults.
19 */
20 { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 },
21 { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
22 { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
23 { CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 },
24
25 /* These are not reset by a soft-reset, so patch to defaults. */
26 { CS35L56_MAIN_RENDER_USER_MUTE, 0x00000000 },
27 { CS35L56_MAIN_RENDER_USER_VOLUME, 0x00000000 },
28 { CS35L56_MAIN_POSTURE_NUMBER, 0x00000000 },
29 };
30
cs35l56_set_patch(struct cs35l56_base * cs35l56_base)31 int cs35l56_set_patch(struct cs35l56_base *cs35l56_base)
32 {
33 return regmap_register_patch(cs35l56_base->regmap, cs35l56_patch,
34 ARRAY_SIZE(cs35l56_patch));
35 }
36 EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED);
37
38 static const struct reg_default cs35l56_reg_defaults[] = {
39 { CS35L56_ASP1_ENABLES1, 0x00000000 },
40 { CS35L56_ASP1_CONTROL1, 0x00000028 },
41 { CS35L56_ASP1_CONTROL2, 0x18180200 },
42 { CS35L56_ASP1_CONTROL3, 0x00000002 },
43 { CS35L56_ASP1_FRAME_CONTROL1, 0x03020100 },
44 { CS35L56_ASP1_FRAME_CONTROL5, 0x00020100 },
45 { CS35L56_ASP1_DATA_CONTROL1, 0x00000018 },
46 { CS35L56_ASP1_DATA_CONTROL5, 0x00000018 },
47
48 /* no defaults for ASP1TX mixer */
49
50 { CS35L56_SWIRE_DP3_CH1_INPUT, 0x00000018 },
51 { CS35L56_SWIRE_DP3_CH2_INPUT, 0x00000019 },
52 { CS35L56_SWIRE_DP3_CH3_INPUT, 0x00000029 },
53 { CS35L56_SWIRE_DP3_CH4_INPUT, 0x00000028 },
54 { CS35L56_IRQ1_MASK_1, 0x83ffffff },
55 { CS35L56_IRQ1_MASK_2, 0xffff7fff },
56 { CS35L56_IRQ1_MASK_4, 0xe0ffffff },
57 { CS35L56_IRQ1_MASK_8, 0xfc000fff },
58 { CS35L56_IRQ1_MASK_18, 0x1f7df0ff },
59 { CS35L56_IRQ1_MASK_20, 0x15c00000 },
60 { CS35L56_MAIN_RENDER_USER_MUTE, 0x00000000 },
61 { CS35L56_MAIN_RENDER_USER_VOLUME, 0x00000000 },
62 { CS35L56_MAIN_POSTURE_NUMBER, 0x00000000 },
63 };
64
cs35l56_is_dsp_memory(unsigned int reg)65 static bool cs35l56_is_dsp_memory(unsigned int reg)
66 {
67 switch (reg) {
68 case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
69 case CS35L56_DSP1_XMEM_UNPACKED32_0 ... CS35L56_DSP1_XMEM_UNPACKED32_4095:
70 case CS35L56_DSP1_XMEM_UNPACKED24_0 ... CS35L56_DSP1_XMEM_UNPACKED24_8191:
71 case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
72 case CS35L56_DSP1_YMEM_UNPACKED32_0 ... CS35L56_DSP1_YMEM_UNPACKED32_3070:
73 case CS35L56_DSP1_YMEM_UNPACKED24_0 ... CS35L56_DSP1_YMEM_UNPACKED24_6141:
74 case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
75 return true;
76 default:
77 return false;
78 }
79 }
80
cs35l56_readable_reg(struct device * dev,unsigned int reg)81 static bool cs35l56_readable_reg(struct device *dev, unsigned int reg)
82 {
83 switch (reg) {
84 case CS35L56_DEVID:
85 case CS35L56_REVID:
86 case CS35L56_RELID:
87 case CS35L56_OTPID:
88 case CS35L56_SFT_RESET:
89 case CS35L56_GLOBAL_ENABLES:
90 case CS35L56_BLOCK_ENABLES:
91 case CS35L56_BLOCK_ENABLES2:
92 case CS35L56_REFCLK_INPUT:
93 case CS35L56_GLOBAL_SAMPLE_RATE:
94 case CS35L56_ASP1_ENABLES1:
95 case CS35L56_ASP1_CONTROL1:
96 case CS35L56_ASP1_CONTROL2:
97 case CS35L56_ASP1_CONTROL3:
98 case CS35L56_ASP1_FRAME_CONTROL1:
99 case CS35L56_ASP1_FRAME_CONTROL5:
100 case CS35L56_ASP1_DATA_CONTROL1:
101 case CS35L56_ASP1_DATA_CONTROL5:
102 case CS35L56_DACPCM1_INPUT:
103 case CS35L56_DACPCM2_INPUT:
104 case CS35L56_ASP1TX1_INPUT:
105 case CS35L56_ASP1TX2_INPUT:
106 case CS35L56_ASP1TX3_INPUT:
107 case CS35L56_ASP1TX4_INPUT:
108 case CS35L56_DSP1RX1_INPUT:
109 case CS35L56_DSP1RX2_INPUT:
110 case CS35L56_SWIRE_DP3_CH1_INPUT:
111 case CS35L56_SWIRE_DP3_CH2_INPUT:
112 case CS35L56_SWIRE_DP3_CH3_INPUT:
113 case CS35L56_SWIRE_DP3_CH4_INPUT:
114 case CS35L56_IRQ1_CFG:
115 case CS35L56_IRQ1_STATUS:
116 case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
117 case CS35L56_IRQ1_EINT_18:
118 case CS35L56_IRQ1_EINT_20:
119 case CS35L56_IRQ1_MASK_1:
120 case CS35L56_IRQ1_MASK_2:
121 case CS35L56_IRQ1_MASK_4:
122 case CS35L56_IRQ1_MASK_8:
123 case CS35L56_IRQ1_MASK_18:
124 case CS35L56_IRQ1_MASK_20:
125 case CS35L56_DSP_VIRTUAL1_MBOX_1:
126 case CS35L56_DSP_VIRTUAL1_MBOX_2:
127 case CS35L56_DSP_VIRTUAL1_MBOX_3:
128 case CS35L56_DSP_VIRTUAL1_MBOX_4:
129 case CS35L56_DSP_VIRTUAL1_MBOX_5:
130 case CS35L56_DSP_VIRTUAL1_MBOX_6:
131 case CS35L56_DSP_VIRTUAL1_MBOX_7:
132 case CS35L56_DSP_VIRTUAL1_MBOX_8:
133 case CS35L56_DSP_RESTRICT_STS1:
134 case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
135 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
136 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
137 case CS35L56_DSP1_SCRATCH1:
138 case CS35L56_DSP1_SCRATCH2:
139 case CS35L56_DSP1_SCRATCH3:
140 case CS35L56_DSP1_SCRATCH4:
141 return true;
142 default:
143 return cs35l56_is_dsp_memory(reg);
144 }
145 }
146
cs35l56_precious_reg(struct device * dev,unsigned int reg)147 static bool cs35l56_precious_reg(struct device *dev, unsigned int reg)
148 {
149 switch (reg) {
150 case CS35L56_DSP1_XMEM_PACKED_0 ... CS35L56_DSP1_XMEM_PACKED_6143:
151 case CS35L56_DSP1_YMEM_PACKED_0 ... CS35L56_DSP1_YMEM_PACKED_4604:
152 case CS35L56_DSP1_PMEM_0 ... CS35L56_DSP1_PMEM_5114:
153 return true;
154 default:
155 return false;
156 }
157 }
158
cs35l56_volatile_reg(struct device * dev,unsigned int reg)159 static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
160 {
161 switch (reg) {
162 case CS35L56_DEVID:
163 case CS35L56_REVID:
164 case CS35L56_RELID:
165 case CS35L56_OTPID:
166 case CS35L56_SFT_RESET:
167 case CS35L56_GLOBAL_ENABLES: /* owned by firmware */
168 case CS35L56_BLOCK_ENABLES: /* owned by firmware */
169 case CS35L56_BLOCK_ENABLES2: /* owned by firmware */
170 case CS35L56_REFCLK_INPUT: /* owned by firmware */
171 case CS35L56_GLOBAL_SAMPLE_RATE: /* owned by firmware */
172 case CS35L56_DACPCM1_INPUT: /* owned by firmware */
173 case CS35L56_DACPCM2_INPUT: /* owned by firmware */
174 case CS35L56_DSP1RX1_INPUT: /* owned by firmware */
175 case CS35L56_DSP1RX2_INPUT: /* owned by firmware */
176 case CS35L56_IRQ1_STATUS:
177 case CS35L56_IRQ1_EINT_1 ... CS35L56_IRQ1_EINT_8:
178 case CS35L56_IRQ1_EINT_18:
179 case CS35L56_IRQ1_EINT_20:
180 case CS35L56_DSP_VIRTUAL1_MBOX_1:
181 case CS35L56_DSP_VIRTUAL1_MBOX_2:
182 case CS35L56_DSP_VIRTUAL1_MBOX_3:
183 case CS35L56_DSP_VIRTUAL1_MBOX_4:
184 case CS35L56_DSP_VIRTUAL1_MBOX_5:
185 case CS35L56_DSP_VIRTUAL1_MBOX_6:
186 case CS35L56_DSP_VIRTUAL1_MBOX_7:
187 case CS35L56_DSP_VIRTUAL1_MBOX_8:
188 case CS35L56_DSP_RESTRICT_STS1:
189 case CS35L56_DSP1_SYS_INFO_ID ... CS35L56_DSP1_SYS_INFO_END:
190 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0:
191 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1:
192 case CS35L56_DSP1_SCRATCH1:
193 case CS35L56_DSP1_SCRATCH2:
194 case CS35L56_DSP1_SCRATCH3:
195 case CS35L56_DSP1_SCRATCH4:
196 return true;
197 case CS35L56_MAIN_RENDER_USER_MUTE:
198 case CS35L56_MAIN_RENDER_USER_VOLUME:
199 case CS35L56_MAIN_POSTURE_NUMBER:
200 return false;
201 default:
202 return cs35l56_is_dsp_memory(reg);
203 }
204 }
205
206 /*
207 * The firmware boot sequence can overwrite the ASP1 config registers so that
208 * they don't match regmap's view of their values. Rewrite the values from the
209 * regmap cache into the hardware registers.
210 */
cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base * cs35l56_base)211 int cs35l56_force_sync_asp1_registers_from_cache(struct cs35l56_base *cs35l56_base)
212 {
213 struct reg_sequence asp1_regs[] = {
214 { .reg = CS35L56_ASP1_ENABLES1 },
215 { .reg = CS35L56_ASP1_CONTROL1 },
216 { .reg = CS35L56_ASP1_CONTROL2 },
217 { .reg = CS35L56_ASP1_CONTROL3 },
218 { .reg = CS35L56_ASP1_FRAME_CONTROL1 },
219 { .reg = CS35L56_ASP1_FRAME_CONTROL5 },
220 { .reg = CS35L56_ASP1_DATA_CONTROL1 },
221 { .reg = CS35L56_ASP1_DATA_CONTROL5 },
222 };
223 int i, ret;
224
225 /* Read values from regmap cache into a write sequence */
226 for (i = 0; i < ARRAY_SIZE(asp1_regs); ++i) {
227 ret = regmap_read(cs35l56_base->regmap, asp1_regs[i].reg, &asp1_regs[i].def);
228 if (ret)
229 goto err;
230 }
231
232 /* Write the values cache-bypassed so that they will be written to silicon */
233 ret = regmap_multi_reg_write_bypassed(cs35l56_base->regmap, asp1_regs,
234 ARRAY_SIZE(asp1_regs));
235 if (ret)
236 goto err;
237
238 return 0;
239
240 err:
241 dev_err(cs35l56_base->dev, "Failed to sync ASP1 registers: %d\n", ret);
242
243 return ret;
244 }
245 EXPORT_SYMBOL_NS_GPL(cs35l56_force_sync_asp1_registers_from_cache, SND_SOC_CS35L56_SHARED);
246
cs35l56_mbox_send(struct cs35l56_base * cs35l56_base,unsigned int command)247 int cs35l56_mbox_send(struct cs35l56_base *cs35l56_base, unsigned int command)
248 {
249 unsigned int val;
250 int ret;
251
252 regmap_write(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1, command);
253 ret = regmap_read_poll_timeout(cs35l56_base->regmap, CS35L56_DSP_VIRTUAL1_MBOX_1,
254 val, (val == 0),
255 CS35L56_MBOX_POLL_US, CS35L56_MBOX_TIMEOUT_US);
256 if (ret) {
257 dev_warn(cs35l56_base->dev, "MBOX command %#x failed: %d\n", command, ret);
258 return ret;
259 }
260
261 return 0;
262 }
263 EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send, SND_SOC_CS35L56_SHARED);
264
cs35l56_firmware_shutdown(struct cs35l56_base * cs35l56_base)265 int cs35l56_firmware_shutdown(struct cs35l56_base *cs35l56_base)
266 {
267 int ret;
268 unsigned int reg;
269 unsigned int val;
270
271 ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_SHUTDOWN);
272 if (ret)
273 return ret;
274
275 if (cs35l56_base->rev < CS35L56_REVID_B0)
276 reg = CS35L56_DSP1_PM_CUR_STATE_A1;
277 else
278 reg = CS35L56_DSP1_PM_CUR_STATE;
279
280 ret = regmap_read_poll_timeout(cs35l56_base->regmap, reg,
281 val, (val == CS35L56_HALO_STATE_SHUTDOWN),
282 CS35L56_HALO_STATE_POLL_US,
283 CS35L56_HALO_STATE_TIMEOUT_US);
284 if (ret < 0)
285 dev_err(cs35l56_base->dev, "Failed to poll PM_CUR_STATE to 1 is %d (ret %d)\n",
286 val, ret);
287 return ret;
288 }
289 EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown, SND_SOC_CS35L56_SHARED);
290
cs35l56_wait_for_firmware_boot(struct cs35l56_base * cs35l56_base)291 int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
292 {
293 unsigned int reg;
294 unsigned int val = 0;
295 int read_ret, poll_ret;
296
297 if (cs35l56_base->rev < CS35L56_REVID_B0)
298 reg = CS35L56_DSP1_HALO_STATE_A1;
299 else
300 reg = CS35L56_DSP1_HALO_STATE;
301
302 /*
303 * This can't be a regmap_read_poll_timeout() because cs35l56 will NAK
304 * I2C until it has booted which would terminate the poll
305 */
306 poll_ret = read_poll_timeout(regmap_read, read_ret,
307 (val < 0xFFFF) && (val >= CS35L56_HALO_STATE_BOOT_DONE),
308 CS35L56_HALO_STATE_POLL_US,
309 CS35L56_HALO_STATE_TIMEOUT_US,
310 false,
311 cs35l56_base->regmap, reg, &val);
312
313 if (poll_ret) {
314 dev_err(cs35l56_base->dev, "Firmware boot timed out(%d): HALO_STATE=%#x\n",
315 read_ret, val);
316 return -EIO;
317 }
318
319 return 0;
320 }
321 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware_boot, SND_SOC_CS35L56_SHARED);
322
cs35l56_wait_control_port_ready(void)323 void cs35l56_wait_control_port_ready(void)
324 {
325 /* Wait for control port to be ready (datasheet tIRS). */
326 usleep_range(CS35L56_CONTROL_PORT_READY_US, 2 * CS35L56_CONTROL_PORT_READY_US);
327 }
328 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port_ready, SND_SOC_CS35L56_SHARED);
329
cs35l56_wait_min_reset_pulse(void)330 void cs35l56_wait_min_reset_pulse(void)
331 {
332 /* Satisfy minimum reset pulse width spec */
333 usleep_range(CS35L56_RESET_PULSE_MIN_US, 2 * CS35L56_RESET_PULSE_MIN_US);
334 }
335 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse, SND_SOC_CS35L56_SHARED);
336
337 static const struct reg_sequence cs35l56_system_reset_seq[] = {
338 REG_SEQ0(CS35L56_DSP1_HALO_STATE, 0),
339 REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_SYSTEM_RESET),
340 };
341
cs35l56_system_reset(struct cs35l56_base * cs35l56_base,bool is_soundwire)342 void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
343 {
344 /*
345 * Must enter cache-only first so there can't be any more register
346 * accesses other than the controlled system reset sequence below.
347 */
348 regcache_cache_only(cs35l56_base->regmap, true);
349 regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
350 cs35l56_system_reset_seq,
351 ARRAY_SIZE(cs35l56_system_reset_seq));
352
353 /* On SoundWire the registers won't be accessible until it re-enumerates. */
354 if (is_soundwire)
355 return;
356
357 cs35l56_wait_control_port_ready();
358 regcache_cache_only(cs35l56_base->regmap, false);
359 }
360 EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset, SND_SOC_CS35L56_SHARED);
361
cs35l56_irq_request(struct cs35l56_base * cs35l56_base,int irq)362 int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq)
363 {
364 int ret;
365
366 if (!irq)
367 return 0;
368
369 ret = devm_request_threaded_irq(cs35l56_base->dev, irq, NULL, cs35l56_irq,
370 IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_LOW,
371 "cs35l56", cs35l56_base);
372 if (!ret)
373 cs35l56_base->irq = irq;
374 else
375 dev_err(cs35l56_base->dev, "Failed to get IRQ: %d\n", ret);
376
377 return ret;
378 }
379 EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request, SND_SOC_CS35L56_SHARED);
380
cs35l56_irq(int irq,void * data)381 irqreturn_t cs35l56_irq(int irq, void *data)
382 {
383 struct cs35l56_base *cs35l56_base = data;
384 unsigned int status1 = 0, status8 = 0, status20 = 0;
385 unsigned int mask1, mask8, mask20;
386 unsigned int val;
387 int rv;
388
389 irqreturn_t ret = IRQ_NONE;
390
391 if (!cs35l56_base->init_done)
392 return IRQ_NONE;
393
394 mutex_lock(&cs35l56_base->irq_lock);
395
396 rv = pm_runtime_resume_and_get(cs35l56_base->dev);
397 if (rv < 0) {
398 dev_err(cs35l56_base->dev, "irq: failed to get pm_runtime: %d\n", rv);
399 goto err_unlock;
400 }
401
402 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_STATUS, &val);
403 if ((val & CS35L56_IRQ1_STS_MASK) == 0) {
404 dev_dbg(cs35l56_base->dev, "Spurious IRQ: no pending interrupt\n");
405 goto err;
406 }
407
408 /* Ack interrupts */
409 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_1, &status1);
410 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_1, &mask1);
411 status1 &= ~mask1;
412 regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_1, status1);
413
414 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_8, &status8);
415 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_8, &mask8);
416 status8 &= ~mask8;
417 regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_8, status8);
418
419 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_20, &status20);
420 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, &mask20);
421 status20 &= ~mask20;
422 /* We don't want EINT20 but they default to unmasked: force mask */
423 regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
424
425 dev_dbg(cs35l56_base->dev, "%s: %#x %#x\n", __func__, status1, status8);
426
427 /* Check to see if unmasked bits are active */
428 if (!status1 && !status8 && !status20)
429 goto err;
430
431 if (status1 & CS35L56_AMP_SHORT_ERR_EINT1_MASK)
432 dev_crit(cs35l56_base->dev, "Amp short error\n");
433
434 if (status8 & CS35L56_TEMP_ERR_EINT1_MASK)
435 dev_crit(cs35l56_base->dev, "Overtemp error\n");
436
437 ret = IRQ_HANDLED;
438
439 err:
440 pm_runtime_put(cs35l56_base->dev);
441 err_unlock:
442 mutex_unlock(&cs35l56_base->irq_lock);
443
444 return ret;
445 }
446 EXPORT_SYMBOL_NS_GPL(cs35l56_irq, SND_SOC_CS35L56_SHARED);
447
cs35l56_is_fw_reload_needed(struct cs35l56_base * cs35l56_base)448 int cs35l56_is_fw_reload_needed(struct cs35l56_base *cs35l56_base)
449 {
450 unsigned int val;
451 int ret;
452
453 /*
454 * In secure mode FIRMWARE_MISSING is cleared by the BIOS loader so
455 * can't be used here to test for memory retention.
456 * Assume that tuning must be re-loaded.
457 */
458 if (cs35l56_base->secured)
459 return true;
460
461 ret = pm_runtime_resume_and_get(cs35l56_base->dev);
462 if (ret) {
463 dev_err(cs35l56_base->dev, "Failed to runtime_get: %d\n", ret);
464 return ret;
465 }
466
467 ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &val);
468 if (ret)
469 dev_err(cs35l56_base->dev, "Failed to read PROTECTION_STATUS: %d\n", ret);
470 else
471 ret = !!(val & CS35L56_FIRMWARE_MISSING);
472
473 pm_runtime_put_autosuspend(cs35l56_base->dev);
474
475 return ret;
476 }
477 EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_needed, SND_SOC_CS35L56_SHARED);
478
479 static const struct reg_sequence cs35l56_hibernate_seq[] = {
480 /* This must be the last register access */
481 REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE),
482 };
483
484 static const struct reg_sequence cs35l56_hibernate_wake_seq[] = {
485 REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1, CS35L56_MBOX_CMD_WAKEUP),
486 };
487
cs35l56_issue_wake_event(struct cs35l56_base * cs35l56_base)488 static void cs35l56_issue_wake_event(struct cs35l56_base *cs35l56_base)
489 {
490 /*
491 * Dummy transactions to trigger I2C/SPI auto-wake. Issue two
492 * transactions to meet the minimum required time from the rising edge
493 * to the last falling edge of wake.
494 *
495 * It uses bypassed write because we must wake the chip before
496 * disabling regmap cache-only.
497 *
498 * This can NAK on I2C which will terminate the write sequence so the
499 * single-write sequence is issued twice.
500 */
501 regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
502 cs35l56_hibernate_wake_seq,
503 ARRAY_SIZE(cs35l56_hibernate_wake_seq));
504
505 usleep_range(CS35L56_WAKE_HOLD_TIME_US, 2 * CS35L56_WAKE_HOLD_TIME_US);
506
507 regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
508 cs35l56_hibernate_wake_seq,
509 ARRAY_SIZE(cs35l56_hibernate_wake_seq));
510
511 cs35l56_wait_control_port_ready();
512 }
513
cs35l56_runtime_suspend_common(struct cs35l56_base * cs35l56_base)514 int cs35l56_runtime_suspend_common(struct cs35l56_base *cs35l56_base)
515 {
516 unsigned int val;
517 int ret;
518
519 if (!cs35l56_base->init_done)
520 return 0;
521
522 /* Firmware must have entered a power-save state */
523 ret = regmap_read_poll_timeout(cs35l56_base->regmap,
524 CS35L56_TRANSDUCER_ACTUAL_PS,
525 val, (val >= CS35L56_PS3),
526 CS35L56_PS3_POLL_US,
527 CS35L56_PS3_TIMEOUT_US);
528 if (ret)
529 dev_warn(cs35l56_base->dev, "PS3 wait failed: %d\n", ret);
530
531 /* Clear BOOT_DONE so it can be used to detect a reboot */
532 regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, CS35L56_OTP_BOOT_DONE_MASK);
533
534 if (!cs35l56_base->can_hibernate) {
535 regcache_cache_only(cs35l56_base->regmap, true);
536 dev_dbg(cs35l56_base->dev, "Suspended: no hibernate");
537
538 return 0;
539 }
540
541 /*
542 * Must enter cache-only first so there can't be any more register
543 * accesses other than the controlled hibernate sequence below.
544 */
545 regcache_cache_only(cs35l56_base->regmap, true);
546
547 regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
548 cs35l56_hibernate_seq,
549 ARRAY_SIZE(cs35l56_hibernate_seq));
550
551 dev_dbg(cs35l56_base->dev, "Suspended: hibernate");
552
553 return 0;
554 }
555 EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_common, SND_SOC_CS35L56_SHARED);
556
cs35l56_runtime_resume_common(struct cs35l56_base * cs35l56_base,bool is_soundwire)557 int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_soundwire)
558 {
559 unsigned int val;
560 int ret;
561
562 if (!cs35l56_base->init_done)
563 return 0;
564
565 if (!cs35l56_base->can_hibernate)
566 goto out_sync;
567
568 /* Must be done before releasing cache-only */
569 if (!is_soundwire)
570 cs35l56_issue_wake_event(cs35l56_base);
571
572 out_sync:
573 regcache_cache_only(cs35l56_base->regmap, false);
574
575 ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
576 if (ret) {
577 dev_err(cs35l56_base->dev, "Hibernate wake failed: %d\n", ret);
578 goto err;
579 }
580
581 ret = cs35l56_mbox_send(cs35l56_base, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE);
582 if (ret)
583 goto err;
584
585 /* BOOT_DONE will be 1 if the amp reset */
586 regmap_read(cs35l56_base->regmap, CS35L56_IRQ1_EINT_4, &val);
587 if (val & CS35L56_OTP_BOOT_DONE_MASK) {
588 dev_dbg(cs35l56_base->dev, "Registers reset in suspend\n");
589 regcache_mark_dirty(cs35l56_base->regmap);
590 }
591
592 regcache_sync(cs35l56_base->regmap);
593
594 dev_dbg(cs35l56_base->dev, "Resumed");
595
596 return 0;
597
598 err:
599 regcache_cache_only(cs35l56_base->regmap, true);
600
601 regmap_multi_reg_write_bypassed(cs35l56_base->regmap,
602 cs35l56_hibernate_seq,
603 ARRAY_SIZE(cs35l56_hibernate_seq));
604
605 return ret;
606 }
607 EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common, SND_SOC_CS35L56_SHARED);
608
609 static const struct cs_dsp_region cs35l56_dsp1_regions[] = {
610 { .type = WMFW_HALO_PM_PACKED, .base = CS35L56_DSP1_PMEM_0 },
611 { .type = WMFW_HALO_XM_PACKED, .base = CS35L56_DSP1_XMEM_PACKED_0 },
612 { .type = WMFW_HALO_YM_PACKED, .base = CS35L56_DSP1_YMEM_PACKED_0 },
613 { .type = WMFW_ADSP2_XM, .base = CS35L56_DSP1_XMEM_UNPACKED24_0 },
614 { .type = WMFW_ADSP2_YM, .base = CS35L56_DSP1_YMEM_UNPACKED24_0 },
615 };
616
cs35l56_init_cs_dsp(struct cs35l56_base * cs35l56_base,struct cs_dsp * cs_dsp)617 void cs35l56_init_cs_dsp(struct cs35l56_base *cs35l56_base, struct cs_dsp *cs_dsp)
618 {
619 cs_dsp->num = 1;
620 cs_dsp->type = WMFW_HALO;
621 cs_dsp->rev = 0;
622 cs_dsp->dev = cs35l56_base->dev;
623 cs_dsp->regmap = cs35l56_base->regmap;
624 cs_dsp->base = CS35L56_DSP1_CORE_BASE;
625 cs_dsp->base_sysinfo = CS35L56_DSP1_SYS_INFO_ID;
626 cs_dsp->mem = cs35l56_dsp1_regions;
627 cs_dsp->num_mems = ARRAY_SIZE(cs35l56_dsp1_regions);
628 cs_dsp->no_core_startstop = true;
629 }
630 EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp, SND_SOC_CS35L56_SHARED);
631
cs35l56_read_prot_status(struct cs35l56_base * cs35l56_base,bool * fw_missing,unsigned int * fw_version)632 int cs35l56_read_prot_status(struct cs35l56_base *cs35l56_base,
633 bool *fw_missing, unsigned int *fw_version)
634 {
635 unsigned int prot_status;
636 int ret;
637
638 ret = regmap_read(cs35l56_base->regmap, CS35L56_PROTECTION_STATUS, &prot_status);
639 if (ret) {
640 dev_err(cs35l56_base->dev, "Get PROTECTION_STATUS failed: %d\n", ret);
641 return ret;
642 }
643
644 *fw_missing = !!(prot_status & CS35L56_FIRMWARE_MISSING);
645
646 ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP1_FW_VER, fw_version);
647 if (ret) {
648 dev_err(cs35l56_base->dev, "Get FW VER failed: %d\n", ret);
649 return ret;
650 }
651
652 return 0;
653 }
654 EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status, SND_SOC_CS35L56_SHARED);
655
cs35l56_hw_init(struct cs35l56_base * cs35l56_base)656 int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
657 {
658 int ret;
659 unsigned int devid, revid, otpid, secured, fw_ver;
660 bool fw_missing;
661
662 /*
663 * When the system is not using a reset_gpio ensure the device is
664 * awake, otherwise the device has just been released from reset and
665 * the driver must wait for the control port to become usable.
666 */
667 if (!cs35l56_base->reset_gpio)
668 cs35l56_issue_wake_event(cs35l56_base);
669 else
670 cs35l56_wait_control_port_ready();
671
672 /*
673 * The HALO_STATE register is in different locations on Ax and B0
674 * devices so the REVID needs to be determined before waiting for the
675 * firmware to boot.
676 */
677 ret = regmap_read(cs35l56_base->regmap, CS35L56_REVID, &revid);
678 if (ret < 0) {
679 dev_err(cs35l56_base->dev, "Get Revision ID failed\n");
680 return ret;
681 }
682 cs35l56_base->rev = revid & (CS35L56_AREVID_MASK | CS35L56_MTLREVID_MASK);
683
684 ret = cs35l56_wait_for_firmware_boot(cs35l56_base);
685 if (ret)
686 return ret;
687
688 ret = regmap_read(cs35l56_base->regmap, CS35L56_DEVID, &devid);
689 if (ret < 0) {
690 dev_err(cs35l56_base->dev, "Get Device ID failed\n");
691 return ret;
692 }
693 devid &= CS35L56_DEVID_MASK;
694
695 switch (devid) {
696 case 0x35A56:
697 break;
698 default:
699 dev_err(cs35l56_base->dev, "Unknown device %x\n", devid);
700 return ret;
701 }
702
703 ret = regmap_read(cs35l56_base->regmap, CS35L56_DSP_RESTRICT_STS1, &secured);
704 if (ret) {
705 dev_err(cs35l56_base->dev, "Get Secure status failed\n");
706 return ret;
707 }
708
709 /* When any bus is restricted treat the device as secured */
710 if (secured & CS35L56_RESTRICTED_MASK)
711 cs35l56_base->secured = true;
712
713 ret = regmap_read(cs35l56_base->regmap, CS35L56_OTPID, &otpid);
714 if (ret < 0) {
715 dev_err(cs35l56_base->dev, "Get OTP ID failed\n");
716 return ret;
717 }
718
719 ret = cs35l56_read_prot_status(cs35l56_base, &fw_missing, &fw_ver);
720 if (ret)
721 return ret;
722
723 dev_info(cs35l56_base->dev, "Cirrus Logic CS35L56%s Rev %02X OTP%d fw:%d.%d.%d (patched=%u)\n",
724 cs35l56_base->secured ? "s" : "", cs35l56_base->rev, otpid,
725 fw_ver >> 16, (fw_ver >> 8) & 0xff, fw_ver & 0xff, !fw_missing);
726
727 /* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
728 regmap_write(cs35l56_base->regmap, CS35L56_IRQ1_MASK_20, 0xffffffff);
729 regmap_update_bits(cs35l56_base->regmap, CS35L56_IRQ1_MASK_1,
730 CS35L56_AMP_SHORT_ERR_EINT1_MASK,
731 0);
732 regmap_update_bits(cs35l56_base->regmap, CS35L56_IRQ1_MASK_8,
733 CS35L56_TEMP_ERR_EINT1_MASK,
734 0);
735
736 return 0;
737 }
738 EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init, SND_SOC_CS35L56_SHARED);
739
cs35l56_get_speaker_id(struct cs35l56_base * cs35l56_base)740 int cs35l56_get_speaker_id(struct cs35l56_base *cs35l56_base)
741 {
742 struct gpio_descs *descs;
743 int speaker_id;
744 int i, ret;
745
746 /* Read the speaker type qualifier from the motherboard GPIOs */
747 descs = gpiod_get_array_optional(cs35l56_base->dev, "spk-id", GPIOD_IN);
748 if (!descs) {
749 return -ENOENT;
750 } else if (IS_ERR(descs)) {
751 ret = PTR_ERR(descs);
752 return dev_err_probe(cs35l56_base->dev, ret, "Failed to get spk-id-gpios\n");
753 }
754
755 speaker_id = 0;
756 for (i = 0; i < descs->ndescs; i++) {
757 ret = gpiod_get_value_cansleep(descs->desc[i]);
758 if (ret < 0) {
759 dev_err_probe(cs35l56_base->dev, ret, "Failed to read spk-id[%d]\n", i);
760 goto err;
761 }
762
763 speaker_id |= (ret << i);
764 }
765
766 dev_dbg(cs35l56_base->dev, "Speaker ID = %d\n", speaker_id);
767 ret = speaker_id;
768 err:
769 gpiod_put_array(descs);
770
771 return ret;
772 }
773 EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id, SND_SOC_CS35L56_SHARED);
774
775 static const u32 cs35l56_bclk_valid_for_pll_freq_table[] = {
776 [0x0C] = 128000,
777 [0x0F] = 256000,
778 [0x11] = 384000,
779 [0x12] = 512000,
780 [0x15] = 768000,
781 [0x17] = 1024000,
782 [0x1A] = 1500000,
783 [0x1B] = 1536000,
784 [0x1C] = 2000000,
785 [0x1D] = 2048000,
786 [0x1E] = 2400000,
787 [0x20] = 3000000,
788 [0x21] = 3072000,
789 [0x23] = 4000000,
790 [0x24] = 4096000,
791 [0x25] = 4800000,
792 [0x27] = 6000000,
793 [0x28] = 6144000,
794 [0x29] = 6250000,
795 [0x2A] = 6400000,
796 [0x2E] = 8000000,
797 [0x2F] = 8192000,
798 [0x30] = 9600000,
799 [0x32] = 12000000,
800 [0x33] = 12288000,
801 [0x37] = 13500000,
802 [0x38] = 19200000,
803 [0x39] = 22579200,
804 [0x3B] = 24576000,
805 };
806
cs35l56_get_bclk_freq_id(unsigned int freq)807 int cs35l56_get_bclk_freq_id(unsigned int freq)
808 {
809 int i;
810
811 if (freq == 0)
812 return -EINVAL;
813
814 /* The BCLK frequency must be a valid PLL REFCLK */
815 for (i = 0; i < ARRAY_SIZE(cs35l56_bclk_valid_for_pll_freq_table); ++i) {
816 if (cs35l56_bclk_valid_for_pll_freq_table[i] == freq)
817 return i;
818 }
819
820 return -EINVAL;
821 }
822 EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id, SND_SOC_CS35L56_SHARED);
823
824 static const char * const cs35l56_supplies[/* auto-sized */] = {
825 "VDD_P",
826 "VDD_IO",
827 "VDD_A",
828 };
829
cs35l56_fill_supply_names(struct regulator_bulk_data * data)830 void cs35l56_fill_supply_names(struct regulator_bulk_data *data)
831 {
832 int i;
833
834 BUILD_BUG_ON(ARRAY_SIZE(cs35l56_supplies) != CS35L56_NUM_BULK_SUPPLIES);
835 for (i = 0; i < ARRAY_SIZE(cs35l56_supplies); i++)
836 data[i].supply = cs35l56_supplies[i];
837 }
838 EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names, SND_SOC_CS35L56_SHARED);
839
840 const char * const cs35l56_tx_input_texts[] = {
841 "None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH",
842 "VDDBMON", "VBSTMON", "DSP1TX1", "DSP1TX2", "DSP1TX3", "DSP1TX4",
843 "DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON",
844 "INTERPOLATOR", "SDW1RX1", "SDW1RX2",
845 };
846 EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts, SND_SOC_CS35L56_SHARED);
847
848 const unsigned int cs35l56_tx_input_values[] = {
849 CS35L56_INPUT_SRC_NONE,
850 CS35L56_INPUT_SRC_ASP1RX1,
851 CS35L56_INPUT_SRC_ASP1RX2,
852 CS35L56_INPUT_SRC_VMON,
853 CS35L56_INPUT_SRC_IMON,
854 CS35L56_INPUT_SRC_ERR_VOL,
855 CS35L56_INPUT_SRC_CLASSH,
856 CS35L56_INPUT_SRC_VDDBMON,
857 CS35L56_INPUT_SRC_VBSTMON,
858 CS35L56_INPUT_SRC_DSP1TX1,
859 CS35L56_INPUT_SRC_DSP1TX2,
860 CS35L56_INPUT_SRC_DSP1TX3,
861 CS35L56_INPUT_SRC_DSP1TX4,
862 CS35L56_INPUT_SRC_DSP1TX5,
863 CS35L56_INPUT_SRC_DSP1TX6,
864 CS35L56_INPUT_SRC_DSP1TX7,
865 CS35L56_INPUT_SRC_DSP1TX8,
866 CS35L56_INPUT_SRC_TEMPMON,
867 CS35L56_INPUT_SRC_INTERPOLATOR,
868 CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1,
869 CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2,
870 };
871 EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values, SND_SOC_CS35L56_SHARED);
872
873 struct regmap_config cs35l56_regmap_i2c = {
874 .reg_bits = 32,
875 .val_bits = 32,
876 .reg_stride = 4,
877 .reg_format_endian = REGMAP_ENDIAN_BIG,
878 .val_format_endian = REGMAP_ENDIAN_BIG,
879 .max_register = CS35L56_DSP1_PMEM_5114,
880 .reg_defaults = cs35l56_reg_defaults,
881 .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
882 .volatile_reg = cs35l56_volatile_reg,
883 .readable_reg = cs35l56_readable_reg,
884 .precious_reg = cs35l56_precious_reg,
885 .cache_type = REGCACHE_MAPLE,
886 };
887 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c, SND_SOC_CS35L56_SHARED);
888
889 struct regmap_config cs35l56_regmap_spi = {
890 .reg_bits = 32,
891 .val_bits = 32,
892 .pad_bits = 16,
893 .reg_stride = 4,
894 .reg_format_endian = REGMAP_ENDIAN_BIG,
895 .val_format_endian = REGMAP_ENDIAN_BIG,
896 .max_register = CS35L56_DSP1_PMEM_5114,
897 .reg_defaults = cs35l56_reg_defaults,
898 .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
899 .volatile_reg = cs35l56_volatile_reg,
900 .readable_reg = cs35l56_readable_reg,
901 .precious_reg = cs35l56_precious_reg,
902 .cache_type = REGCACHE_MAPLE,
903 };
904 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi, SND_SOC_CS35L56_SHARED);
905
906 struct regmap_config cs35l56_regmap_sdw = {
907 .reg_bits = 32,
908 .val_bits = 32,
909 .reg_stride = 4,
910 .reg_format_endian = REGMAP_ENDIAN_LITTLE,
911 .val_format_endian = REGMAP_ENDIAN_BIG,
912 .max_register = CS35L56_DSP1_PMEM_5114,
913 .reg_defaults = cs35l56_reg_defaults,
914 .num_reg_defaults = ARRAY_SIZE(cs35l56_reg_defaults),
915 .volatile_reg = cs35l56_volatile_reg,
916 .readable_reg = cs35l56_readable_reg,
917 .precious_reg = cs35l56_precious_reg,
918 .cache_type = REGCACHE_MAPLE,
919 };
920 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw, SND_SOC_CS35L56_SHARED);
921
922 MODULE_DESCRIPTION("ASoC CS35L56 Shared");
923 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
924 MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
925 MODULE_LICENSE("GPL");
926