1 // SPDX-License-Identifier: GPL-2.0-only
3 // Components shared between ASoC and HDA CS35L56 drivers
5 // Copyright (C) 2023 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
8 #include <linux/array_size.h>
9 #include <linux/firmware/cirrus/wmfw.h>
10 #include <linux/gpio/consumer.h>
11 #include <linux/regmap.h>
12 #include <linux/regulator/consumer.h>
13 #include <linux/types.h>
14 #include <sound/cs-amp-lib.h>
18 static const struct reg_sequence cs35l56_patch
[] = {
20 * Firmware can change these to non-defaults to satisfy SDCA.
21 * Ensure that they are at known defaults.
23 { CS35L56_ASP1_ENABLES1
, 0x00000000 },
24 { CS35L56_ASP1_CONTROL1
, 0x00000028 },
25 { CS35L56_ASP1_CONTROL2
, 0x18180200 },
26 { CS35L56_ASP1_CONTROL3
, 0x00000002 },
27 { CS35L56_ASP1_FRAME_CONTROL1
, 0x03020100 },
28 { CS35L56_ASP1_FRAME_CONTROL5
, 0x00020100 },
29 { CS35L56_ASP1_DATA_CONTROL1
, 0x00000018 },
30 { CS35L56_ASP1_DATA_CONTROL5
, 0x00000018 },
31 { CS35L56_ASP1TX1_INPUT
, 0x00000000 },
32 { CS35L56_ASP1TX2_INPUT
, 0x00000000 },
33 { CS35L56_ASP1TX3_INPUT
, 0x00000000 },
34 { CS35L56_ASP1TX4_INPUT
, 0x00000000 },
35 { CS35L56_SWIRE_DP3_CH1_INPUT
, 0x00000018 },
36 { CS35L56_SWIRE_DP3_CH2_INPUT
, 0x00000019 },
37 { CS35L56_SWIRE_DP3_CH3_INPUT
, 0x00000029 },
38 { CS35L56_SWIRE_DP3_CH4_INPUT
, 0x00000028 },
39 { CS35L56_IRQ1_MASK_18
, 0x1f7df0ff },
41 /* These are not reset by a soft-reset, so patch to defaults. */
42 { CS35L56_MAIN_RENDER_USER_MUTE
, 0x00000000 },
43 { CS35L56_MAIN_RENDER_USER_VOLUME
, 0x00000000 },
44 { CS35L56_MAIN_POSTURE_NUMBER
, 0x00000000 },
47 int cs35l56_set_patch(struct cs35l56_base
*cs35l56_base
)
49 return regmap_register_patch(cs35l56_base
->regmap
, cs35l56_patch
,
50 ARRAY_SIZE(cs35l56_patch
));
52 EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch
, "SND_SOC_CS35L56_SHARED");
54 static const struct reg_default cs35l56_reg_defaults
[] = {
55 /* no defaults for OTP_MEM - first read populates cache */
57 { CS35L56_ASP1_ENABLES1
, 0x00000000 },
58 { CS35L56_ASP1_CONTROL1
, 0x00000028 },
59 { CS35L56_ASP1_CONTROL2
, 0x18180200 },
60 { CS35L56_ASP1_CONTROL3
, 0x00000002 },
61 { CS35L56_ASP1_FRAME_CONTROL1
, 0x03020100 },
62 { CS35L56_ASP1_FRAME_CONTROL5
, 0x00020100 },
63 { CS35L56_ASP1_DATA_CONTROL1
, 0x00000018 },
64 { CS35L56_ASP1_DATA_CONTROL5
, 0x00000018 },
65 { CS35L56_ASP1TX1_INPUT
, 0x00000000 },
66 { CS35L56_ASP1TX2_INPUT
, 0x00000000 },
67 { CS35L56_ASP1TX3_INPUT
, 0x00000000 },
68 { CS35L56_ASP1TX4_INPUT
, 0x00000000 },
69 { CS35L56_SWIRE_DP3_CH1_INPUT
, 0x00000018 },
70 { CS35L56_SWIRE_DP3_CH2_INPUT
, 0x00000019 },
71 { CS35L56_SWIRE_DP3_CH3_INPUT
, 0x00000029 },
72 { CS35L56_SWIRE_DP3_CH4_INPUT
, 0x00000028 },
73 { CS35L56_IRQ1_MASK_1
, 0x83ffffff },
74 { CS35L56_IRQ1_MASK_2
, 0xffff7fff },
75 { CS35L56_IRQ1_MASK_4
, 0xe0ffffff },
76 { CS35L56_IRQ1_MASK_8
, 0xfc000fff },
77 { CS35L56_IRQ1_MASK_18
, 0x1f7df0ff },
78 { CS35L56_IRQ1_MASK_20
, 0x15c00000 },
79 { CS35L56_MAIN_RENDER_USER_MUTE
, 0x00000000 },
80 { CS35L56_MAIN_RENDER_USER_VOLUME
, 0x00000000 },
81 { CS35L56_MAIN_POSTURE_NUMBER
, 0x00000000 },
84 static bool cs35l56_is_dsp_memory(unsigned int reg
)
87 case CS35L56_DSP1_XMEM_PACKED_0
... CS35L56_DSP1_XMEM_PACKED_6143
:
88 case CS35L56_DSP1_XMEM_UNPACKED32_0
... CS35L56_DSP1_XMEM_UNPACKED32_4095
:
89 case CS35L56_DSP1_XMEM_UNPACKED24_0
... CS35L56_DSP1_XMEM_UNPACKED24_8191
:
90 case CS35L56_DSP1_YMEM_PACKED_0
... CS35L56_DSP1_YMEM_PACKED_4604
:
91 case CS35L56_DSP1_YMEM_UNPACKED32_0
... CS35L56_DSP1_YMEM_UNPACKED32_3070
:
92 case CS35L56_DSP1_YMEM_UNPACKED24_0
... CS35L56_DSP1_YMEM_UNPACKED24_6141
:
93 case CS35L56_DSP1_PMEM_0
... CS35L56_DSP1_PMEM_5114
:
100 static bool cs35l56_readable_reg(struct device
*dev
, unsigned int reg
)
107 case CS35L56_SFT_RESET
:
108 case CS35L56_GLOBAL_ENABLES
:
109 case CS35L56_BLOCK_ENABLES
:
110 case CS35L56_BLOCK_ENABLES2
:
111 case CS35L56_REFCLK_INPUT
:
112 case CS35L56_GLOBAL_SAMPLE_RATE
:
113 case CS35L56_OTP_MEM_53
:
114 case CS35L56_OTP_MEM_54
:
115 case CS35L56_OTP_MEM_55
:
116 case CS35L56_ASP1_ENABLES1
:
117 case CS35L56_ASP1_CONTROL1
:
118 case CS35L56_ASP1_CONTROL2
:
119 case CS35L56_ASP1_CONTROL3
:
120 case CS35L56_ASP1_FRAME_CONTROL1
:
121 case CS35L56_ASP1_FRAME_CONTROL5
:
122 case CS35L56_ASP1_DATA_CONTROL1
:
123 case CS35L56_ASP1_DATA_CONTROL5
:
124 case CS35L56_DACPCM1_INPUT
:
125 case CS35L56_DACPCM2_INPUT
:
126 case CS35L56_ASP1TX1_INPUT
:
127 case CS35L56_ASP1TX2_INPUT
:
128 case CS35L56_ASP1TX3_INPUT
:
129 case CS35L56_ASP1TX4_INPUT
:
130 case CS35L56_DSP1RX1_INPUT
:
131 case CS35L56_DSP1RX2_INPUT
:
132 case CS35L56_SWIRE_DP3_CH1_INPUT
:
133 case CS35L56_SWIRE_DP3_CH2_INPUT
:
134 case CS35L56_SWIRE_DP3_CH3_INPUT
:
135 case CS35L56_SWIRE_DP3_CH4_INPUT
:
136 case CS35L56_IRQ1_CFG
:
137 case CS35L56_IRQ1_STATUS
:
138 case CS35L56_IRQ1_EINT_1
... CS35L56_IRQ1_EINT_8
:
139 case CS35L56_IRQ1_EINT_18
:
140 case CS35L56_IRQ1_EINT_20
:
141 case CS35L56_IRQ1_MASK_1
:
142 case CS35L56_IRQ1_MASK_2
:
143 case CS35L56_IRQ1_MASK_4
:
144 case CS35L56_IRQ1_MASK_8
:
145 case CS35L56_IRQ1_MASK_18
:
146 case CS35L56_IRQ1_MASK_20
:
147 case CS35L56_DSP_VIRTUAL1_MBOX_1
:
148 case CS35L56_DSP_VIRTUAL1_MBOX_2
:
149 case CS35L56_DSP_VIRTUAL1_MBOX_3
:
150 case CS35L56_DSP_VIRTUAL1_MBOX_4
:
151 case CS35L56_DSP_VIRTUAL1_MBOX_5
:
152 case CS35L56_DSP_VIRTUAL1_MBOX_6
:
153 case CS35L56_DSP_VIRTUAL1_MBOX_7
:
154 case CS35L56_DSP_VIRTUAL1_MBOX_8
:
155 case CS35L56_DSP_RESTRICT_STS1
:
156 case CS35L56_DSP1_SYS_INFO_ID
... CS35L56_DSP1_SYS_INFO_END
:
157 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0
:
158 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1
:
159 case CS35L56_DSP1_SCRATCH1
:
160 case CS35L56_DSP1_SCRATCH2
:
161 case CS35L56_DSP1_SCRATCH3
:
162 case CS35L56_DSP1_SCRATCH4
:
165 return cs35l56_is_dsp_memory(reg
);
169 static bool cs35l56_precious_reg(struct device
*dev
, unsigned int reg
)
172 case CS35L56_DSP1_XMEM_PACKED_0
... CS35L56_DSP1_XMEM_PACKED_6143
:
173 case CS35L56_DSP1_YMEM_PACKED_0
... CS35L56_DSP1_YMEM_PACKED_4604
:
174 case CS35L56_DSP1_PMEM_0
... CS35L56_DSP1_PMEM_5114
:
181 static bool cs35l56_volatile_reg(struct device
*dev
, unsigned int reg
)
188 case CS35L56_SFT_RESET
:
189 case CS35L56_GLOBAL_ENABLES
: /* owned by firmware */
190 case CS35L56_BLOCK_ENABLES
: /* owned by firmware */
191 case CS35L56_BLOCK_ENABLES2
: /* owned by firmware */
192 case CS35L56_REFCLK_INPUT
: /* owned by firmware */
193 case CS35L56_GLOBAL_SAMPLE_RATE
: /* owned by firmware */
194 case CS35L56_DACPCM1_INPUT
: /* owned by firmware */
195 case CS35L56_DACPCM2_INPUT
: /* owned by firmware */
196 case CS35L56_DSP1RX1_INPUT
: /* owned by firmware */
197 case CS35L56_DSP1RX2_INPUT
: /* owned by firmware */
198 case CS35L56_IRQ1_STATUS
:
199 case CS35L56_IRQ1_EINT_1
... CS35L56_IRQ1_EINT_8
:
200 case CS35L56_IRQ1_EINT_18
:
201 case CS35L56_IRQ1_EINT_20
:
202 case CS35L56_DSP_VIRTUAL1_MBOX_1
:
203 case CS35L56_DSP_VIRTUAL1_MBOX_2
:
204 case CS35L56_DSP_VIRTUAL1_MBOX_3
:
205 case CS35L56_DSP_VIRTUAL1_MBOX_4
:
206 case CS35L56_DSP_VIRTUAL1_MBOX_5
:
207 case CS35L56_DSP_VIRTUAL1_MBOX_6
:
208 case CS35L56_DSP_VIRTUAL1_MBOX_7
:
209 case CS35L56_DSP_VIRTUAL1_MBOX_8
:
210 case CS35L56_DSP_RESTRICT_STS1
:
211 case CS35L56_DSP1_SYS_INFO_ID
... CS35L56_DSP1_SYS_INFO_END
:
212 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_0
:
213 case CS35L56_DSP1_AHBM_WINDOW_DEBUG_1
:
214 case CS35L56_DSP1_SCRATCH1
:
215 case CS35L56_DSP1_SCRATCH2
:
216 case CS35L56_DSP1_SCRATCH3
:
217 case CS35L56_DSP1_SCRATCH4
:
219 case CS35L56_MAIN_RENDER_USER_MUTE
:
220 case CS35L56_MAIN_RENDER_USER_VOLUME
:
221 case CS35L56_MAIN_POSTURE_NUMBER
:
224 return cs35l56_is_dsp_memory(reg
);
228 int cs35l56_mbox_send(struct cs35l56_base
*cs35l56_base
, unsigned int command
)
233 regmap_write(cs35l56_base
->regmap
, CS35L56_DSP_VIRTUAL1_MBOX_1
, command
);
234 ret
= regmap_read_poll_timeout(cs35l56_base
->regmap
, CS35L56_DSP_VIRTUAL1_MBOX_1
,
236 CS35L56_MBOX_POLL_US
, CS35L56_MBOX_TIMEOUT_US
);
238 dev_warn(cs35l56_base
->dev
, "MBOX command %#x failed: %d\n", command
, ret
);
244 EXPORT_SYMBOL_NS_GPL(cs35l56_mbox_send
, "SND_SOC_CS35L56_SHARED");
246 int cs35l56_firmware_shutdown(struct cs35l56_base
*cs35l56_base
)
251 ret
= cs35l56_mbox_send(cs35l56_base
, CS35L56_MBOX_CMD_SHUTDOWN
);
255 ret
= regmap_read_poll_timeout(cs35l56_base
->regmap
, CS35L56_DSP1_PM_CUR_STATE
,
256 val
, (val
== CS35L56_HALO_STATE_SHUTDOWN
),
257 CS35L56_HALO_STATE_POLL_US
,
258 CS35L56_HALO_STATE_TIMEOUT_US
);
260 dev_err(cs35l56_base
->dev
, "Failed to poll PM_CUR_STATE to 1 is %d (ret %d)\n",
264 EXPORT_SYMBOL_NS_GPL(cs35l56_firmware_shutdown
, "SND_SOC_CS35L56_SHARED");
266 int cs35l56_wait_for_firmware_boot(struct cs35l56_base
*cs35l56_base
)
268 unsigned int val
= 0;
269 int read_ret
, poll_ret
;
272 * The regmap must remain in cache-only until the chip has
273 * booted, so use a bypassed read of the status register.
275 poll_ret
= read_poll_timeout(regmap_read_bypassed
, read_ret
,
276 (val
< 0xFFFF) && (val
>= CS35L56_HALO_STATE_BOOT_DONE
),
277 CS35L56_HALO_STATE_POLL_US
,
278 CS35L56_HALO_STATE_TIMEOUT_US
,
280 cs35l56_base
->regmap
, CS35L56_DSP1_HALO_STATE
, &val
);
283 dev_err(cs35l56_base
->dev
, "Firmware boot timed out(%d): HALO_STATE=%#x\n",
290 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_for_firmware_boot
, "SND_SOC_CS35L56_SHARED");
292 void cs35l56_wait_control_port_ready(void)
294 /* Wait for control port to be ready (datasheet tIRS). */
295 usleep_range(CS35L56_CONTROL_PORT_READY_US
, 2 * CS35L56_CONTROL_PORT_READY_US
);
297 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_control_port_ready
, "SND_SOC_CS35L56_SHARED");
299 void cs35l56_wait_min_reset_pulse(void)
301 /* Satisfy minimum reset pulse width spec */
302 usleep_range(CS35L56_RESET_PULSE_MIN_US
, 2 * CS35L56_RESET_PULSE_MIN_US
);
304 EXPORT_SYMBOL_NS_GPL(cs35l56_wait_min_reset_pulse
, "SND_SOC_CS35L56_SHARED");
306 static const struct reg_sequence cs35l56_system_reset_seq
[] = {
307 REG_SEQ0(CS35L56_DSP1_HALO_STATE
, 0),
308 REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1
, CS35L56_MBOX_CMD_SYSTEM_RESET
),
311 void cs35l56_system_reset(struct cs35l56_base
*cs35l56_base
, bool is_soundwire
)
314 * Must enter cache-only first so there can't be any more register
315 * accesses other than the controlled system reset sequence below.
317 regcache_cache_only(cs35l56_base
->regmap
, true);
318 regmap_multi_reg_write_bypassed(cs35l56_base
->regmap
,
319 cs35l56_system_reset_seq
,
320 ARRAY_SIZE(cs35l56_system_reset_seq
));
322 /* On SoundWire the registers won't be accessible until it re-enumerates. */
326 cs35l56_wait_control_port_ready();
328 /* Leave in cache-only. This will be revoked when the chip has rebooted. */
330 EXPORT_SYMBOL_NS_GPL(cs35l56_system_reset
, "SND_SOC_CS35L56_SHARED");
332 int cs35l56_irq_request(struct cs35l56_base
*cs35l56_base
, int irq
)
339 ret
= devm_request_threaded_irq(cs35l56_base
->dev
, irq
, NULL
, cs35l56_irq
,
340 IRQF_ONESHOT
| IRQF_SHARED
| IRQF_TRIGGER_LOW
,
341 "cs35l56", cs35l56_base
);
343 cs35l56_base
->irq
= irq
;
345 dev_err(cs35l56_base
->dev
, "Failed to get IRQ: %d\n", ret
);
349 EXPORT_SYMBOL_NS_GPL(cs35l56_irq_request
, "SND_SOC_CS35L56_SHARED");
351 irqreturn_t
cs35l56_irq(int irq
, void *data
)
353 struct cs35l56_base
*cs35l56_base
= data
;
354 unsigned int status1
= 0, status8
= 0, status20
= 0;
355 unsigned int mask1
, mask8
, mask20
;
359 irqreturn_t ret
= IRQ_NONE
;
361 if (!cs35l56_base
->init_done
)
364 mutex_lock(&cs35l56_base
->irq_lock
);
366 rv
= pm_runtime_resume_and_get(cs35l56_base
->dev
);
368 dev_err(cs35l56_base
->dev
, "irq: failed to get pm_runtime: %d\n", rv
);
372 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_STATUS
, &val
);
373 if ((val
& CS35L56_IRQ1_STS_MASK
) == 0) {
374 dev_dbg(cs35l56_base
->dev
, "Spurious IRQ: no pending interrupt\n");
379 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_1
, &status1
);
380 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_1
, &mask1
);
382 regmap_write(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_1
, status1
);
384 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_8
, &status8
);
385 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_8
, &mask8
);
387 regmap_write(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_8
, status8
);
389 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_20
, &status20
);
390 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_20
, &mask20
);
392 /* We don't want EINT20 but they default to unmasked: force mask */
393 regmap_write(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_20
, 0xffffffff);
395 dev_dbg(cs35l56_base
->dev
, "%s: %#x %#x\n", __func__
, status1
, status8
);
397 /* Check to see if unmasked bits are active */
398 if (!status1
&& !status8
&& !status20
)
401 if (status1
& CS35L56_AMP_SHORT_ERR_EINT1_MASK
)
402 dev_crit(cs35l56_base
->dev
, "Amp short error\n");
404 if (status8
& CS35L56_TEMP_ERR_EINT1_MASK
)
405 dev_crit(cs35l56_base
->dev
, "Overtemp error\n");
410 pm_runtime_put(cs35l56_base
->dev
);
412 mutex_unlock(&cs35l56_base
->irq_lock
);
416 EXPORT_SYMBOL_NS_GPL(cs35l56_irq
, "SND_SOC_CS35L56_SHARED");
418 int cs35l56_is_fw_reload_needed(struct cs35l56_base
*cs35l56_base
)
424 * In secure mode FIRMWARE_MISSING is cleared by the BIOS loader so
425 * can't be used here to test for memory retention.
426 * Assume that tuning must be re-loaded.
428 if (cs35l56_base
->secured
)
431 ret
= pm_runtime_resume_and_get(cs35l56_base
->dev
);
433 dev_err(cs35l56_base
->dev
, "Failed to runtime_get: %d\n", ret
);
437 ret
= regmap_read(cs35l56_base
->regmap
, CS35L56_PROTECTION_STATUS
, &val
);
439 dev_err(cs35l56_base
->dev
, "Failed to read PROTECTION_STATUS: %d\n", ret
);
441 ret
= !!(val
& CS35L56_FIRMWARE_MISSING
);
443 pm_runtime_put_autosuspend(cs35l56_base
->dev
);
447 EXPORT_SYMBOL_NS_GPL(cs35l56_is_fw_reload_needed
, "SND_SOC_CS35L56_SHARED");
449 static const struct reg_sequence cs35l56_hibernate_seq
[] = {
450 /* This must be the last register access */
451 REG_SEQ0(CS35L56_DSP_VIRTUAL1_MBOX_1
, CS35L56_MBOX_CMD_ALLOW_AUTO_HIBERNATE
),
454 static void cs35l56_issue_wake_event(struct cs35l56_base
*cs35l56_base
)
459 * Dummy transactions to trigger I2C/SPI auto-wake. Issue two
460 * transactions to meet the minimum required time from the rising edge
461 * to the last falling edge of wake.
463 * It uses bypassed read because we must wake the chip before
464 * disabling regmap cache-only.
466 regmap_read_bypassed(cs35l56_base
->regmap
, CS35L56_IRQ1_STATUS
, &val
);
468 usleep_range(CS35L56_WAKE_HOLD_TIME_US
, 2 * CS35L56_WAKE_HOLD_TIME_US
);
470 regmap_read_bypassed(cs35l56_base
->regmap
, CS35L56_IRQ1_STATUS
, &val
);
472 cs35l56_wait_control_port_ready();
475 int cs35l56_runtime_suspend_common(struct cs35l56_base
*cs35l56_base
)
480 if (!cs35l56_base
->init_done
)
483 /* Firmware must have entered a power-save state */
484 ret
= regmap_read_poll_timeout(cs35l56_base
->regmap
,
485 CS35L56_TRANSDUCER_ACTUAL_PS
,
486 val
, (val
>= CS35L56_PS3
),
488 CS35L56_PS3_TIMEOUT_US
);
490 dev_warn(cs35l56_base
->dev
, "PS3 wait failed: %d\n", ret
);
492 /* Clear BOOT_DONE so it can be used to detect a reboot */
493 regmap_write(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_4
, CS35L56_OTP_BOOT_DONE_MASK
);
495 if (!cs35l56_base
->can_hibernate
) {
496 regcache_cache_only(cs35l56_base
->regmap
, true);
497 dev_dbg(cs35l56_base
->dev
, "Suspended: no hibernate");
503 * Must enter cache-only first so there can't be any more register
504 * accesses other than the controlled hibernate sequence below.
506 regcache_cache_only(cs35l56_base
->regmap
, true);
508 regmap_multi_reg_write_bypassed(cs35l56_base
->regmap
,
509 cs35l56_hibernate_seq
,
510 ARRAY_SIZE(cs35l56_hibernate_seq
));
512 dev_dbg(cs35l56_base
->dev
, "Suspended: hibernate");
516 EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_suspend_common
, "SND_SOC_CS35L56_SHARED");
518 int cs35l56_runtime_resume_common(struct cs35l56_base
*cs35l56_base
, bool is_soundwire
)
523 if (!cs35l56_base
->init_done
)
526 if (!cs35l56_base
->can_hibernate
)
529 /* Must be done before releasing cache-only */
531 cs35l56_issue_wake_event(cs35l56_base
);
534 ret
= cs35l56_wait_for_firmware_boot(cs35l56_base
);
536 dev_err(cs35l56_base
->dev
, "Hibernate wake failed: %d\n", ret
);
540 regcache_cache_only(cs35l56_base
->regmap
, false);
542 ret
= cs35l56_mbox_send(cs35l56_base
, CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE
);
546 /* BOOT_DONE will be 1 if the amp reset */
547 regmap_read(cs35l56_base
->regmap
, CS35L56_IRQ1_EINT_4
, &val
);
548 if (val
& CS35L56_OTP_BOOT_DONE_MASK
) {
549 dev_dbg(cs35l56_base
->dev
, "Registers reset in suspend\n");
550 regcache_mark_dirty(cs35l56_base
->regmap
);
553 regcache_sync(cs35l56_base
->regmap
);
555 dev_dbg(cs35l56_base
->dev
, "Resumed");
560 regcache_cache_only(cs35l56_base
->regmap
, true);
562 regmap_multi_reg_write_bypassed(cs35l56_base
->regmap
,
563 cs35l56_hibernate_seq
,
564 ARRAY_SIZE(cs35l56_hibernate_seq
));
568 EXPORT_SYMBOL_NS_GPL(cs35l56_runtime_resume_common
, "SND_SOC_CS35L56_SHARED");
570 static const struct cs_dsp_region cs35l56_dsp1_regions
[] = {
571 { .type
= WMFW_HALO_PM_PACKED
, .base
= CS35L56_DSP1_PMEM_0
},
572 { .type
= WMFW_HALO_XM_PACKED
, .base
= CS35L56_DSP1_XMEM_PACKED_0
},
573 { .type
= WMFW_HALO_YM_PACKED
, .base
= CS35L56_DSP1_YMEM_PACKED_0
},
574 { .type
= WMFW_ADSP2_XM
, .base
= CS35L56_DSP1_XMEM_UNPACKED24_0
},
575 { .type
= WMFW_ADSP2_YM
, .base
= CS35L56_DSP1_YMEM_UNPACKED24_0
},
578 void cs35l56_init_cs_dsp(struct cs35l56_base
*cs35l56_base
, struct cs_dsp
*cs_dsp
)
581 cs_dsp
->type
= WMFW_HALO
;
583 cs_dsp
->dev
= cs35l56_base
->dev
;
584 cs_dsp
->regmap
= cs35l56_base
->regmap
;
585 cs_dsp
->base
= CS35L56_DSP1_CORE_BASE
;
586 cs_dsp
->base_sysinfo
= CS35L56_DSP1_SYS_INFO_ID
;
587 cs_dsp
->mem
= cs35l56_dsp1_regions
;
588 cs_dsp
->num_mems
= ARRAY_SIZE(cs35l56_dsp1_regions
);
589 cs_dsp
->no_core_startstop
= true;
591 EXPORT_SYMBOL_NS_GPL(cs35l56_init_cs_dsp
, "SND_SOC_CS35L56_SHARED");
602 static_assert((sizeof(struct cs35l56_pte
) % sizeof(u32
)) == 0);
604 static int cs35l56_read_silicon_uid(struct cs35l56_base
*cs35l56_base
, u64
*uid
)
606 struct cs35l56_pte pte
;
610 ret
= regmap_raw_read(cs35l56_base
->regmap
, CS35L56_OTP_MEM_53
, &pte
, sizeof(pte
));
612 dev_err(cs35l56_base
->dev
, "Failed to read OTP: %d\n", ret
);
616 unique_id
= (u32
)pte
.lot
[2] | ((u32
)pte
.lot
[1] << 8) | ((u32
)pte
.lot
[0] << 16);
618 unique_id
|= (u32
)pte
.x
| ((u32
)pte
.y
<< 8) | ((u32
)pte
.wafer_id
<< 16) |
619 ((u32
)pte
.dvs
<< 24);
621 dev_dbg(cs35l56_base
->dev
, "UniqueID = %#llx\n", unique_id
);
628 /* Firmware calibration controls */
629 const struct cirrus_amp_cal_controls cs35l56_calibration_controls
= {
631 .mem_region
= WMFW_ADSP2_YM
,
632 .ambient
= "CAL_AMBIENT",
634 .status
= "CAL_STATUS",
635 .checksum
= "CAL_CHECKSUM",
637 EXPORT_SYMBOL_NS_GPL(cs35l56_calibration_controls
, "SND_SOC_CS35L56_SHARED");
639 int cs35l56_get_calibration(struct cs35l56_base
*cs35l56_base
)
644 /* Driver can't apply calibration to a secured part, so skip */
645 if (cs35l56_base
->secured
)
648 ret
= cs35l56_read_silicon_uid(cs35l56_base
, &silicon_uid
);
652 ret
= cs_amp_get_efi_calibration_data(cs35l56_base
->dev
, silicon_uid
,
653 cs35l56_base
->cal_index
,
654 &cs35l56_base
->cal_data
);
656 /* Only return an error status if probe should be aborted */
657 if ((ret
== -ENOENT
) || (ret
== -EOVERFLOW
))
663 cs35l56_base
->cal_data_valid
= true;
667 EXPORT_SYMBOL_NS_GPL(cs35l56_get_calibration
, "SND_SOC_CS35L56_SHARED");
669 int cs35l56_read_prot_status(struct cs35l56_base
*cs35l56_base
,
670 bool *fw_missing
, unsigned int *fw_version
)
672 unsigned int prot_status
;
675 ret
= regmap_read(cs35l56_base
->regmap
, CS35L56_PROTECTION_STATUS
, &prot_status
);
677 dev_err(cs35l56_base
->dev
, "Get PROTECTION_STATUS failed: %d\n", ret
);
681 *fw_missing
= !!(prot_status
& CS35L56_FIRMWARE_MISSING
);
683 ret
= regmap_read(cs35l56_base
->regmap
, CS35L56_DSP1_FW_VER
, fw_version
);
685 dev_err(cs35l56_base
->dev
, "Get FW VER failed: %d\n", ret
);
691 EXPORT_SYMBOL_NS_GPL(cs35l56_read_prot_status
, "SND_SOC_CS35L56_SHARED");
693 int cs35l56_hw_init(struct cs35l56_base
*cs35l56_base
)
696 unsigned int devid
, revid
, otpid
, secured
, fw_ver
;
700 * When the system is not using a reset_gpio ensure the device is
701 * awake, otherwise the device has just been released from reset and
702 * the driver must wait for the control port to become usable.
704 if (!cs35l56_base
->reset_gpio
)
705 cs35l56_issue_wake_event(cs35l56_base
);
707 cs35l56_wait_control_port_ready();
709 ret
= regmap_read_bypassed(cs35l56_base
->regmap
, CS35L56_REVID
, &revid
);
711 dev_err(cs35l56_base
->dev
, "Get Revision ID failed\n");
714 cs35l56_base
->rev
= revid
& (CS35L56_AREVID_MASK
| CS35L56_MTLREVID_MASK
);
716 ret
= cs35l56_wait_for_firmware_boot(cs35l56_base
);
720 ret
= regmap_read_bypassed(cs35l56_base
->regmap
, CS35L56_DEVID
, &devid
);
722 dev_err(cs35l56_base
->dev
, "Get Device ID failed\n");
725 devid
&= CS35L56_DEVID_MASK
;
733 dev_err(cs35l56_base
->dev
, "Unknown device %x\n", devid
);
737 cs35l56_base
->type
= devid
& 0xFF;
739 /* Silicon is now identified and booted so exit cache-only */
740 regcache_cache_only(cs35l56_base
->regmap
, false);
742 ret
= regmap_read(cs35l56_base
->regmap
, CS35L56_DSP_RESTRICT_STS1
, &secured
);
744 dev_err(cs35l56_base
->dev
, "Get Secure status failed\n");
748 /* When any bus is restricted treat the device as secured */
749 if (secured
& CS35L56_RESTRICTED_MASK
)
750 cs35l56_base
->secured
= true;
752 ret
= regmap_read(cs35l56_base
->regmap
, CS35L56_OTPID
, &otpid
);
754 dev_err(cs35l56_base
->dev
, "Get OTP ID failed\n");
758 ret
= cs35l56_read_prot_status(cs35l56_base
, &fw_missing
, &fw_ver
);
762 dev_info(cs35l56_base
->dev
, "Cirrus Logic CS35L%02X%s Rev %02X OTP%d fw:%d.%d.%d (patched=%u)\n",
763 cs35l56_base
->type
, cs35l56_base
->secured
? "s" : "", cs35l56_base
->rev
, otpid
,
764 fw_ver
>> 16, (fw_ver
>> 8) & 0xff, fw_ver
& 0xff, !fw_missing
);
766 /* Wake source and *_BLOCKED interrupts default to unmasked, so mask them */
767 regmap_write(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_20
, 0xffffffff);
768 regmap_update_bits(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_1
,
769 CS35L56_AMP_SHORT_ERR_EINT1_MASK
,
771 regmap_update_bits(cs35l56_base
->regmap
, CS35L56_IRQ1_MASK_8
,
772 CS35L56_TEMP_ERR_EINT1_MASK
,
777 EXPORT_SYMBOL_NS_GPL(cs35l56_hw_init
, "SND_SOC_CS35L56_SHARED");
779 int cs35l56_get_speaker_id(struct cs35l56_base
*cs35l56_base
)
781 struct gpio_descs
*descs
;
785 /* Attempt to read the speaker type from a device property first */
786 ret
= device_property_read_u32(cs35l56_base
->dev
, "cirrus,speaker-id", &speaker_id
);
788 dev_dbg(cs35l56_base
->dev
, "Speaker ID = %d\n", speaker_id
);
792 /* Read the speaker type qualifier from the motherboard GPIOs */
793 descs
= gpiod_get_array_optional(cs35l56_base
->dev
, "spk-id", GPIOD_IN
);
796 } else if (IS_ERR(descs
)) {
797 ret
= PTR_ERR(descs
);
798 return dev_err_probe(cs35l56_base
->dev
, ret
, "Failed to get spk-id-gpios\n");
802 for (i
= 0; i
< descs
->ndescs
; i
++) {
803 ret
= gpiod_get_value_cansleep(descs
->desc
[i
]);
805 dev_err_probe(cs35l56_base
->dev
, ret
, "Failed to read spk-id[%d]\n", i
);
809 speaker_id
|= (ret
<< i
);
812 dev_dbg(cs35l56_base
->dev
, "Speaker ID = %d\n", speaker_id
);
815 gpiod_put_array(descs
);
819 EXPORT_SYMBOL_NS_GPL(cs35l56_get_speaker_id
, "SND_SOC_CS35L56_SHARED");
821 static const u32 cs35l56_bclk_valid_for_pll_freq_table
[] = {
853 int cs35l56_get_bclk_freq_id(unsigned int freq
)
860 /* The BCLK frequency must be a valid PLL REFCLK */
861 for (i
= 0; i
< ARRAY_SIZE(cs35l56_bclk_valid_for_pll_freq_table
); ++i
) {
862 if (cs35l56_bclk_valid_for_pll_freq_table
[i
] == freq
)
868 EXPORT_SYMBOL_NS_GPL(cs35l56_get_bclk_freq_id
, "SND_SOC_CS35L56_SHARED");
870 static const char * const cs35l56_supplies
[/* auto-sized */] = {
876 void cs35l56_fill_supply_names(struct regulator_bulk_data
*data
)
880 BUILD_BUG_ON(ARRAY_SIZE(cs35l56_supplies
) != CS35L56_NUM_BULK_SUPPLIES
);
881 for (i
= 0; i
< ARRAY_SIZE(cs35l56_supplies
); i
++)
882 data
[i
].supply
= cs35l56_supplies
[i
];
884 EXPORT_SYMBOL_NS_GPL(cs35l56_fill_supply_names
, "SND_SOC_CS35L56_SHARED");
886 const char * const cs35l56_tx_input_texts
[] = {
887 "None", "ASP1RX1", "ASP1RX2", "VMON", "IMON", "ERRVOL", "CLASSH",
888 "VDDBMON", "VBSTMON", "DSP1TX1", "DSP1TX2", "DSP1TX3", "DSP1TX4",
889 "DSP1TX5", "DSP1TX6", "DSP1TX7", "DSP1TX8", "TEMPMON",
890 "INTERPOLATOR", "SDW1RX1", "SDW1RX2",
892 EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_texts
, "SND_SOC_CS35L56_SHARED");
894 const unsigned int cs35l56_tx_input_values
[] = {
895 CS35L56_INPUT_SRC_NONE
,
896 CS35L56_INPUT_SRC_ASP1RX1
,
897 CS35L56_INPUT_SRC_ASP1RX2
,
898 CS35L56_INPUT_SRC_VMON
,
899 CS35L56_INPUT_SRC_IMON
,
900 CS35L56_INPUT_SRC_ERR_VOL
,
901 CS35L56_INPUT_SRC_CLASSH
,
902 CS35L56_INPUT_SRC_VDDBMON
,
903 CS35L56_INPUT_SRC_VBSTMON
,
904 CS35L56_INPUT_SRC_DSP1TX1
,
905 CS35L56_INPUT_SRC_DSP1TX2
,
906 CS35L56_INPUT_SRC_DSP1TX3
,
907 CS35L56_INPUT_SRC_DSP1TX4
,
908 CS35L56_INPUT_SRC_DSP1TX5
,
909 CS35L56_INPUT_SRC_DSP1TX6
,
910 CS35L56_INPUT_SRC_DSP1TX7
,
911 CS35L56_INPUT_SRC_DSP1TX8
,
912 CS35L56_INPUT_SRC_TEMPMON
,
913 CS35L56_INPUT_SRC_INTERPOLATOR
,
914 CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL1
,
915 CS35L56_INPUT_SRC_SWIRE_DP1_CHANNEL2
,
917 EXPORT_SYMBOL_NS_GPL(cs35l56_tx_input_values
, "SND_SOC_CS35L56_SHARED");
919 const struct regmap_config cs35l56_regmap_i2c
= {
923 .reg_format_endian
= REGMAP_ENDIAN_BIG
,
924 .val_format_endian
= REGMAP_ENDIAN_BIG
,
925 .max_register
= CS35L56_DSP1_PMEM_5114
,
926 .reg_defaults
= cs35l56_reg_defaults
,
927 .num_reg_defaults
= ARRAY_SIZE(cs35l56_reg_defaults
),
928 .volatile_reg
= cs35l56_volatile_reg
,
929 .readable_reg
= cs35l56_readable_reg
,
930 .precious_reg
= cs35l56_precious_reg
,
931 .cache_type
= REGCACHE_MAPLE
,
933 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_i2c
, "SND_SOC_CS35L56_SHARED");
935 const struct regmap_config cs35l56_regmap_spi
= {
940 .reg_format_endian
= REGMAP_ENDIAN_BIG
,
941 .val_format_endian
= REGMAP_ENDIAN_BIG
,
942 .max_register
= CS35L56_DSP1_PMEM_5114
,
943 .reg_defaults
= cs35l56_reg_defaults
,
944 .num_reg_defaults
= ARRAY_SIZE(cs35l56_reg_defaults
),
945 .volatile_reg
= cs35l56_volatile_reg
,
946 .readable_reg
= cs35l56_readable_reg
,
947 .precious_reg
= cs35l56_precious_reg
,
948 .cache_type
= REGCACHE_MAPLE
,
950 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_spi
, "SND_SOC_CS35L56_SHARED");
952 const struct regmap_config cs35l56_regmap_sdw
= {
956 .reg_format_endian
= REGMAP_ENDIAN_LITTLE
,
957 .val_format_endian
= REGMAP_ENDIAN_BIG
,
958 .max_register
= CS35L56_DSP1_PMEM_5114
,
959 .reg_defaults
= cs35l56_reg_defaults
,
960 .num_reg_defaults
= ARRAY_SIZE(cs35l56_reg_defaults
),
961 .volatile_reg
= cs35l56_volatile_reg
,
962 .readable_reg
= cs35l56_readable_reg
,
963 .precious_reg
= cs35l56_precious_reg
,
964 .cache_type
= REGCACHE_MAPLE
,
966 EXPORT_SYMBOL_NS_GPL(cs35l56_regmap_sdw
, "SND_SOC_CS35L56_SHARED");
968 MODULE_DESCRIPTION("ASoC CS35L56 Shared");
969 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
970 MODULE_AUTHOR("Simon Trimmer <simont@opensource.cirrus.com>");
971 MODULE_LICENSE("GPL");
972 MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB");