@@ -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 ) ;
@@ -936,14 +932,6 @@ static void cs35l56_dsp_work(struct work_struct *work)
936932 else
937933 cs35l56_patch (cs35l56 , firmware_missing );
938934
939-
940- /*
941- * Set starting value of ASP1 mux widgets. Updating a mux takes
942- * the DAPM mutex. Post this to a separate job so that DAPM
943- * power-up can wait for dsp_work to complete without deadlocking
944- * on the DAPM mutex.
945- */
946- queue_work (cs35l56 -> dsp_wq , & cs35l56 -> mux_init_work );
947935err :
948936 pm_runtime_mark_last_busy (cs35l56 -> base .dev );
949937 pm_runtime_put_autosuspend (cs35l56 -> base .dev );
@@ -989,6 +977,13 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
989977 debugfs_create_bool ("can_hibernate" , 0444 , debugfs_root , & cs35l56 -> base .can_hibernate );
990978 debugfs_create_bool ("fw_patched" , 0444 , debugfs_root , & cs35l56 -> base .fw_patched );
991979
980+ /*
981+ * The widgets for the ASP1TX mixer can't be initialized
982+ * until the firmware has been downloaded and rebooted.
983+ */
984+ regcache_drop_region (cs35l56 -> base .regmap , CS35L56_ASP1TX1_INPUT , CS35L56_ASP1TX4_INPUT );
985+ cs35l56 -> asp1_mixer_widgets_initialized = false;
986+
992987 queue_work (cs35l56 -> dsp_wq , & cs35l56 -> dsp_work );
993988
994989 return 0 ;
@@ -999,7 +994,6 @@ static void cs35l56_component_remove(struct snd_soc_component *component)
999994 struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
1000995
1001996 cancel_work_sync (& cs35l56 -> dsp_work );
1002- cancel_work_sync (& cs35l56 -> mux_init_work );
1003997
1004998 if (cs35l56 -> dsp .cs_dsp .booted )
1005999 wm_adsp_power_down (& cs35l56 -> dsp );
@@ -1070,10 +1064,8 @@ int cs35l56_system_suspend(struct device *dev)
10701064
10711065 dev_dbg (dev , "system_suspend\n" );
10721066
1073- if (cs35l56 -> component ) {
1067+ if (cs35l56 -> component )
10741068 flush_work (& cs35l56 -> dsp_work );
1075- cancel_work_sync (& cs35l56 -> mux_init_work );
1076- }
10771069
10781070 /*
10791071 * The interrupt line is normally shared, but after we start suspending
@@ -1224,7 +1216,6 @@ static int cs35l56_dsp_init(struct cs35l56_private *cs35l56)
12241216 return - ENOMEM ;
12251217
12261218 INIT_WORK (& cs35l56 -> dsp_work , cs35l56_dsp_work );
1227- INIT_WORK (& cs35l56 -> mux_init_work , cs35l56_mux_init_work );
12281219
12291220 dsp = & cs35l56 -> dsp ;
12301221 cs35l56_init_cs_dsp (& cs35l56 -> base , & dsp -> cs_dsp );
0 commit comments