@@ -40,16 +40,11 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_set_patch, SND_SOC_CS35L56_SHARED);
4040static const struct reg_default cs35l56_reg_defaults [] = {
4141 /* no defaults for OTP_MEM - first read populates cache */
4242
43- { CS35L56_ASP1_ENABLES1 , 0x00000000 },
44- { CS35L56_ASP1_CONTROL1 , 0x00000028 },
45- { CS35L56_ASP1_CONTROL2 , 0x18180200 },
46- { CS35L56_ASP1_CONTROL3 , 0x00000002 },
47- { CS35L56_ASP1_FRAME_CONTROL1 , 0x03020100 },
48- { CS35L56_ASP1_FRAME_CONTROL5 , 0x00020100 },
49- { CS35L56_ASP1_DATA_CONTROL1 , 0x00000018 },
50- { CS35L56_ASP1_DATA_CONTROL5 , 0x00000018 },
51-
52- /* no defaults for ASP1TX mixer */
43+ /*
44+ * No defaults for ASP1 control or ASP1TX mixer. See
45+ * cs35l56_populate_asp1_register_defaults() and
46+ * cs35l56_sync_asp1_mixer_widgets_with_firmware().
47+ */
5348
5449 { CS35L56_SWIRE_DP3_CH1_INPUT , 0x00000018 },
5550 { CS35L56_SWIRE_DP3_CH2_INPUT , 0x00000019 },
@@ -210,26 +205,52 @@ static bool cs35l56_volatile_reg(struct device *dev, unsigned int reg)
210205 }
211206}
212207
208+ static const struct reg_sequence cs35l56_asp1_defaults [] = {
209+ REG_SEQ0 (CS35L56_ASP1_ENABLES1 , 0x00000000 ),
210+ REG_SEQ0 (CS35L56_ASP1_CONTROL1 , 0x00000028 ),
211+ REG_SEQ0 (CS35L56_ASP1_CONTROL2 , 0x18180200 ),
212+ REG_SEQ0 (CS35L56_ASP1_CONTROL3 , 0x00000002 ),
213+ REG_SEQ0 (CS35L56_ASP1_FRAME_CONTROL1 , 0x03020100 ),
214+ REG_SEQ0 (CS35L56_ASP1_FRAME_CONTROL5 , 0x00020100 ),
215+ REG_SEQ0 (CS35L56_ASP1_DATA_CONTROL1 , 0x00000018 ),
216+ REG_SEQ0 (CS35L56_ASP1_DATA_CONTROL5 , 0x00000018 ),
217+ };
218+
219+ /*
220+ * The firmware can have control of the ASP so we don't provide regmap
221+ * with defaults for these registers, to prevent a regcache_sync() from
222+ * overwriting the firmware settings. But if the machine driver hooks up
223+ * the ASP it means the driver is taking control of the ASP, so then the
224+ * registers are populated with the defaults.
225+ */
226+ int cs35l56_init_asp1_regs_for_driver_control (struct cs35l56_base * cs35l56_base )
227+ {
228+ if (!cs35l56_base -> fw_owns_asp1 )
229+ return 0 ;
230+
231+ cs35l56_base -> fw_owns_asp1 = false;
232+
233+ return regmap_multi_reg_write (cs35l56_base -> regmap , cs35l56_asp1_defaults ,
234+ ARRAY_SIZE (cs35l56_asp1_defaults ));
235+ }
236+ EXPORT_SYMBOL_NS_GPL (cs35l56_init_asp1_regs_for_driver_control , SND_SOC_CS35L56_SHARED );
237+
213238/*
214239 * The firmware boot sequence can overwrite the ASP1 config registers so that
215240 * they don't match regmap's view of their values. Rewrite the values from the
216241 * regmap cache into the hardware registers.
217242 */
218243int cs35l56_force_sync_asp1_registers_from_cache (struct cs35l56_base * cs35l56_base )
219244{
220- struct reg_sequence asp1_regs [] = {
221- { .reg = CS35L56_ASP1_ENABLES1 },
222- { .reg = CS35L56_ASP1_CONTROL1 },
223- { .reg = CS35L56_ASP1_CONTROL2 },
224- { .reg = CS35L56_ASP1_CONTROL3 },
225- { .reg = CS35L56_ASP1_FRAME_CONTROL1 },
226- { .reg = CS35L56_ASP1_FRAME_CONTROL5 },
227- { .reg = CS35L56_ASP1_DATA_CONTROL1 },
228- { .reg = CS35L56_ASP1_DATA_CONTROL5 },
229- };
245+ struct reg_sequence asp1_regs [ARRAY_SIZE (cs35l56_asp1_defaults )];
230246 int i , ret ;
231247
232- /* Read values from regmap cache into a write sequence */
248+ if (cs35l56_base -> fw_owns_asp1 )
249+ return 0 ;
250+
251+ memcpy (asp1_regs , cs35l56_asp1_defaults , sizeof (asp1_regs ));
252+
253+ /* Read current values from regmap cache into the write sequence */
233254 for (i = 0 ; i < ARRAY_SIZE (asp1_regs ); ++ i ) {
234255 ret = regmap_read (cs35l56_base -> regmap , asp1_regs [i ].reg , & asp1_regs [i ].def );
235256 if (ret )
@@ -307,10 +328,10 @@ int cs35l56_wait_for_firmware_boot(struct cs35l56_base *cs35l56_base)
307328 reg = CS35L56_DSP1_HALO_STATE ;
308329
309330 /*
310- * This can't be a regmap_read_poll_timeout() because cs35l56 will NAK
311- * I2C until it has booted which would terminate the poll
331+ * The regmap must remain in cache-only until the chip has
332+ * booted, so use a bypassed read of the status register.
312333 */
313- poll_ret = read_poll_timeout (regmap_read , read_ret ,
334+ poll_ret = read_poll_timeout (regmap_read_bypassed , read_ret ,
314335 (val < 0xFFFF ) && (val >= CS35L56_HALO_STATE_BOOT_DONE ),
315336 CS35L56_HALO_STATE_POLL_US ,
316337 CS35L56_HALO_STATE_TIMEOUT_US ,
@@ -362,7 +383,8 @@ void cs35l56_system_reset(struct cs35l56_base *cs35l56_base, bool is_soundwire)
362383 return ;
363384
364385 cs35l56_wait_control_port_ready ();
365- regcache_cache_only (cs35l56_base -> regmap , false);
386+
387+ /* Leave in cache-only. This will be revoked when the chip has rebooted. */
366388}
367389EXPORT_SYMBOL_NS_GPL (cs35l56_system_reset , SND_SOC_CS35L56_SHARED );
368390
@@ -577,14 +599,14 @@ int cs35l56_runtime_resume_common(struct cs35l56_base *cs35l56_base, bool is_sou
577599 cs35l56_issue_wake_event (cs35l56_base );
578600
579601out_sync :
580- regcache_cache_only (cs35l56_base -> regmap , false);
581-
582602 ret = cs35l56_wait_for_firmware_boot (cs35l56_base );
583603 if (ret ) {
584604 dev_err (cs35l56_base -> dev , "Hibernate wake failed: %d\n" , ret );
585605 goto err ;
586606 }
587607
608+ regcache_cache_only (cs35l56_base -> regmap , false);
609+
588610 ret = cs35l56_mbox_send (cs35l56_base , CS35L56_MBOX_CMD_PREVENT_AUTO_HIBERNATE );
589611 if (ret )
590612 goto err ;
@@ -757,7 +779,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
757779 * devices so the REVID needs to be determined before waiting for the
758780 * firmware to boot.
759781 */
760- ret = regmap_read (cs35l56_base -> regmap , CS35L56_REVID , & revid );
782+ ret = regmap_read_bypassed (cs35l56_base -> regmap , CS35L56_REVID , & revid );
761783 if (ret < 0 ) {
762784 dev_err (cs35l56_base -> dev , "Get Revision ID failed\n" );
763785 return ret ;
@@ -768,7 +790,7 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
768790 if (ret )
769791 return ret ;
770792
771- ret = regmap_read (cs35l56_base -> regmap , CS35L56_DEVID , & devid );
793+ ret = regmap_read_bypassed (cs35l56_base -> regmap , CS35L56_DEVID , & devid );
772794 if (ret < 0 ) {
773795 dev_err (cs35l56_base -> dev , "Get Device ID failed\n" );
774796 return ret ;
@@ -787,6 +809,9 @@ int cs35l56_hw_init(struct cs35l56_base *cs35l56_base)
787809
788810 cs35l56_base -> type = devid & 0xFF ;
789811
812+ /* Silicon is now identified and booted so exit cache-only */
813+ regcache_cache_only (cs35l56_base -> regmap , false);
814+
790815 ret = regmap_read (cs35l56_base -> regmap , CS35L56_DSP_RESTRICT_STS1 , & secured );
791816 if (ret ) {
792817 dev_err (cs35l56_base -> dev , "Get Secure status failed\n" );
0 commit comments