@@ -68,63 +68,7 @@ static const char * const cs35l56_asp1_mux_control_names[] = {
6868 "ASP1 TX1 Source" , "ASP1 TX2 Source" , "ASP1 TX3 Source" , "ASP1 TX4 Source"
6969};
7070
71- static int cs35l56_dspwait_asp1tx_get (struct snd_kcontrol * kcontrol ,
72- struct snd_ctl_elem_value * ucontrol )
73- {
74- struct snd_soc_component * component = snd_soc_dapm_kcontrol_component (kcontrol );
75- struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
76- struct soc_enum * e = (struct soc_enum * )kcontrol -> private_value ;
77- int index = e -> shift_l ;
78- unsigned int addr , val ;
79- int ret ;
80-
81- /* Wait for mux to be initialized */
82- cs35l56_wait_dsp_ready (cs35l56 );
83- flush_work (& cs35l56 -> mux_init_work );
84-
85- addr = cs35l56_asp1_mixer_regs [index ];
86- ret = regmap_read (cs35l56 -> base .regmap , addr , & val );
87- if (ret )
88- return ret ;
89-
90- val &= CS35L56_ASP_TXn_SRC_MASK ;
91- ucontrol -> value .enumerated .item [0 ] = snd_soc_enum_val_to_item (e , val );
92-
93- return 0 ;
94- }
95-
96- static int cs35l56_dspwait_asp1tx_put (struct snd_kcontrol * kcontrol ,
97- struct snd_ctl_elem_value * ucontrol )
98- {
99- struct snd_soc_component * component = snd_soc_dapm_kcontrol_component (kcontrol );
100- struct snd_soc_dapm_context * dapm = snd_soc_dapm_kcontrol_dapm (kcontrol );
101- struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
102- struct soc_enum * e = (struct soc_enum * )kcontrol -> private_value ;
103- int item = ucontrol -> value .enumerated .item [0 ];
104- int index = e -> shift_l ;
105- unsigned int addr , val ;
106- bool changed ;
107- int ret ;
108-
109- /* Wait for mux to be initialized */
110- cs35l56_wait_dsp_ready (cs35l56 );
111- flush_work (& cs35l56 -> mux_init_work );
112-
113- addr = cs35l56_asp1_mixer_regs [index ];
114- val = snd_soc_enum_item_to_val (e , item );
115-
116- ret = regmap_update_bits_check (cs35l56 -> base .regmap , addr ,
117- CS35L56_ASP_TXn_SRC_MASK , val , & changed );
118- if (!ret )
119- return ret ;
120-
121- if (changed )
122- snd_soc_dapm_mux_update_power (dapm , kcontrol , item , e , NULL );
123-
124- return changed ;
125- }
126-
127- static void cs35l56_mark_asp1_mixer_widgets_dirty (struct cs35l56_private * cs35l56 )
71+ static int cs35l56_sync_asp1_mixer_widgets_with_firmware (struct cs35l56_private * cs35l56 )
12872{
12973 struct snd_soc_dapm_context * dapm = snd_soc_component_get_dapm (cs35l56 -> component );
13074 const char * prefix = cs35l56 -> component -> name_prefix ;
@@ -135,13 +79,19 @@ static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l5
13579 unsigned int val [4 ];
13680 int i , item , ret ;
13781
82+ if (cs35l56 -> asp1_mixer_widgets_initialized )
83+ return 0 ;
84+
13885 /*
13986 * Resume so we can read the registers from silicon if the regmap
14087 * cache has not yet been populated.
14188 */
14289 ret = pm_runtime_resume_and_get (cs35l56 -> base .dev );
14390 if (ret < 0 )
144- return ;
91+ return ret ;
92+
93+ /* Wait for firmware download and reboot */
94+ cs35l56_wait_dsp_ready (cs35l56 );
14595
14696 ret = regmap_bulk_read (cs35l56 -> base .regmap , CS35L56_ASP1TX1_INPUT ,
14797 val , ARRAY_SIZE (val ));
@@ -151,12 +101,9 @@ static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l5
151101
152102 if (ret ) {
153103 dev_err (cs35l56 -> base .dev , "Failed to read ASP1 mixer regs: %d\n" , ret );
154- return ;
104+ return ret ;
155105 }
156106
157- snd_soc_card_mutex_lock (dapm -> card );
158- WARN_ON (!dapm -> card -> instantiated );
159-
160107 for (i = 0 ; i < ARRAY_SIZE (cs35l56_asp1_mux_control_names ); ++ i ) {
161108 name = cs35l56_asp1_mux_control_names [i ];
162109
@@ -176,16 +123,65 @@ static void cs35l56_mark_asp1_mixer_widgets_dirty(struct cs35l56_private *cs35l5
176123 snd_soc_dapm_mux_update_power (dapm , kcontrol , item , e , NULL );
177124 }
178125
179- snd_soc_card_mutex_unlock (dapm -> card );
126+ cs35l56 -> asp1_mixer_widgets_initialized = true;
127+
128+ return 0 ;
180129}
181130
182- static void cs35l56_mux_init_work (struct work_struct * work )
131+ static int cs35l56_dspwait_asp1tx_get (struct snd_kcontrol * kcontrol ,
132+ struct snd_ctl_elem_value * ucontrol )
183133{
184- struct cs35l56_private * cs35l56 = container_of (work ,
185- struct cs35l56_private ,
186- mux_init_work );
134+ struct snd_soc_component * component = snd_soc_dapm_kcontrol_component (kcontrol );
135+ struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
136+ struct soc_enum * e = (struct soc_enum * )kcontrol -> private_value ;
137+ int index = e -> shift_l ;
138+ unsigned int addr , val ;
139+ int ret ;
187140
188- cs35l56_mark_asp1_mixer_widgets_dirty (cs35l56 );
141+ ret = cs35l56_sync_asp1_mixer_widgets_with_firmware (cs35l56 );
142+ if (ret )
143+ return ret ;
144+
145+ addr = cs35l56_asp1_mixer_regs [index ];
146+ ret = regmap_read (cs35l56 -> base .regmap , addr , & val );
147+ if (ret )
148+ return ret ;
149+
150+ val &= CS35L56_ASP_TXn_SRC_MASK ;
151+ ucontrol -> value .enumerated .item [0 ] = snd_soc_enum_val_to_item (e , val );
152+
153+ return 0 ;
154+ }
155+
156+ static int cs35l56_dspwait_asp1tx_put (struct snd_kcontrol * kcontrol ,
157+ struct snd_ctl_elem_value * ucontrol )
158+ {
159+ struct snd_soc_component * component = snd_soc_dapm_kcontrol_component (kcontrol );
160+ struct snd_soc_dapm_context * dapm = snd_soc_dapm_kcontrol_dapm (kcontrol );
161+ struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
162+ struct soc_enum * e = (struct soc_enum * )kcontrol -> private_value ;
163+ int item = ucontrol -> value .enumerated .item [0 ];
164+ int index = e -> shift_l ;
165+ unsigned int addr , val ;
166+ bool changed ;
167+ int ret ;
168+
169+ ret = cs35l56_sync_asp1_mixer_widgets_with_firmware (cs35l56 );
170+ if (ret )
171+ return ret ;
172+
173+ addr = cs35l56_asp1_mixer_regs [index ];
174+ val = snd_soc_enum_item_to_val (e , item );
175+
176+ ret = regmap_update_bits_check (cs35l56 -> base .regmap , addr ,
177+ CS35L56_ASP_TXn_SRC_MASK , val , & changed );
178+ if (!ret )
179+ return ret ;
180+
181+ if (changed )
182+ snd_soc_dapm_mux_update_power (dapm , kcontrol , item , e , NULL );
183+
184+ return changed ;
189185}
190186
191187static DECLARE_TLV_DB_SCALE (vol_tlv , -10000 , 25 , 0 ) ;
@@ -909,14 +905,6 @@ static void cs35l56_dsp_work(struct work_struct *work)
909905 else
910906 cs35l56_patch (cs35l56 );
911907
912-
913- /*
914- * Set starting value of ASP1 mux widgets. Updating a mux takes
915- * the DAPM mutex. Post this to a separate job so that DAPM
916- * power-up can wait for dsp_work to complete without deadlocking
917- * on the DAPM mutex.
918- */
919- queue_work (cs35l56 -> dsp_wq , & cs35l56 -> mux_init_work );
920908err :
921909 pm_runtime_mark_last_busy (cs35l56 -> base .dev );
922910 pm_runtime_put_autosuspend (cs35l56 -> base .dev );
@@ -953,6 +941,13 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
953941 debugfs_create_bool ("can_hibernate" , 0444 , debugfs_root , & cs35l56 -> base .can_hibernate );
954942 debugfs_create_bool ("fw_patched" , 0444 , debugfs_root , & cs35l56 -> base .fw_patched );
955943
944+ /*
945+ * The widgets for the ASP1TX mixer can't be initialized
946+ * until the firmware has been downloaded and rebooted.
947+ */
948+ regcache_drop_region (cs35l56 -> base .regmap , CS35L56_ASP1TX1_INPUT , CS35L56_ASP1TX4_INPUT );
949+ cs35l56 -> asp1_mixer_widgets_initialized = false;
950+
956951 queue_work (cs35l56 -> dsp_wq , & cs35l56 -> dsp_work );
957952
958953 return 0 ;
@@ -963,7 +958,6 @@ static void cs35l56_component_remove(struct snd_soc_component *component)
963958 struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
964959
965960 cancel_work_sync (& cs35l56 -> dsp_work );
966- cancel_work_sync (& cs35l56 -> mux_init_work );
967961
968962 if (cs35l56 -> dsp .cs_dsp .booted )
969963 wm_adsp_power_down (& cs35l56 -> dsp );
@@ -1034,10 +1028,8 @@ int cs35l56_system_suspend(struct device *dev)
10341028
10351029 dev_dbg (dev , "system_suspend\n" );
10361030
1037- if (cs35l56 -> component ) {
1031+ if (cs35l56 -> component )
10381032 flush_work (& cs35l56 -> dsp_work );
1039- cancel_work_sync (& cs35l56 -> mux_init_work );
1040- }
10411033
10421034 /*
10431035 * The interrupt line is normally shared, but after we start suspending
@@ -1188,7 +1180,6 @@ static int cs35l56_dsp_init(struct cs35l56_private *cs35l56)
11881180 return - ENOMEM ;
11891181
11901182 INIT_WORK (& cs35l56 -> dsp_work , cs35l56_dsp_work );
1191- INIT_WORK (& cs35l56 -> mux_init_work , cs35l56_mux_init_work );
11921183
11931184 dsp = & cs35l56 -> dsp ;
11941185 cs35l56_init_cs_dsp (& cs35l56 -> base , & dsp -> cs_dsp );
0 commit comments