@@ -706,17 +706,41 @@ static int cs35l56_write_cal(struct cs35l56_private *cs35l56)
706706 return ret ;
707707}
708708
709- static void cs35l56_reinit_patch (struct cs35l56_private * cs35l56 )
709+ static int cs35l56_dsp_download_and_power_up (struct cs35l56_private * cs35l56 ,
710+ bool load_firmware )
710711{
711712 int ret ;
712713
713- /* Use wm_adsp to load and apply the firmware patch and coefficient files */
714- ret = wm_adsp_power_up (& cs35l56 -> dsp , true);
714+ /*
715+ * Abort the first load if it didn't find the suffixed bins and
716+ * we have an alternate fallback suffix.
717+ */
718+ cs35l56 -> dsp .bin_mandatory = (load_firmware && cs35l56 -> fallback_fw_suffix );
719+
720+ ret = wm_adsp_power_up (& cs35l56 -> dsp , load_firmware );
721+ if ((ret == - ENOENT ) && cs35l56 -> dsp .bin_mandatory ) {
722+ cs35l56 -> dsp .fwf_suffix = cs35l56 -> fallback_fw_suffix ;
723+ cs35l56 -> fallback_fw_suffix = NULL ;
724+ cs35l56 -> dsp .bin_mandatory = false;
725+ ret = wm_adsp_power_up (& cs35l56 -> dsp , load_firmware );
726+ }
727+
715728 if (ret ) {
716- dev_dbg (cs35l56 -> base .dev , "%s: wm_adsp_power_up ret %d\n" , __func__ , ret );
717- return ;
729+ dev_dbg (cs35l56 -> base .dev , "wm_adsp_power_up ret %d\n" , ret );
730+ return ret ;
718731 }
719732
733+ return 0 ;
734+ }
735+
736+ static void cs35l56_reinit_patch (struct cs35l56_private * cs35l56 )
737+ {
738+ int ret ;
739+
740+ ret = cs35l56_dsp_download_and_power_up (cs35l56 , true);
741+ if (ret )
742+ return ;
743+
720744 cs35l56_write_cal (cs35l56 );
721745
722746 /* Always REINIT after applying patch or coefficients */
@@ -750,11 +774,9 @@ static void cs35l56_patch(struct cs35l56_private *cs35l56, bool firmware_missing
750774 * but only if firmware is missing. If firmware is already patched just
751775 * power-up wm_adsp without downloading firmware.
752776 */
753- ret = wm_adsp_power_up (& cs35l56 -> dsp , !!firmware_missing );
754- if (ret ) {
755- dev_dbg (cs35l56 -> base .dev , "%s: wm_adsp_power_up ret %d\n" , __func__ , ret );
777+ ret = cs35l56_dsp_download_and_power_up (cs35l56 , firmware_missing );
778+ if (ret )
756779 goto err ;
757- }
758780
759781 mutex_lock (& cs35l56 -> base .irq_lock );
760782
@@ -853,6 +875,34 @@ static void cs35l56_dsp_work(struct work_struct *work)
853875 pm_runtime_put_autosuspend (cs35l56 -> base .dev );
854876}
855877
878+ static int cs35l56_set_fw_suffix (struct cs35l56_private * cs35l56 )
879+ {
880+ if (cs35l56 -> dsp .fwf_suffix )
881+ return 0 ;
882+
883+ if (!cs35l56 -> sdw_peripheral )
884+ return 0 ;
885+
886+ cs35l56 -> dsp .fwf_suffix = devm_kasprintf (cs35l56 -> base .dev , GFP_KERNEL ,
887+ "l%uu%u" ,
888+ cs35l56 -> sdw_link_num ,
889+ cs35l56 -> sdw_unique_id );
890+ if (!cs35l56 -> dsp .fwf_suffix )
891+ return - ENOMEM ;
892+
893+ /*
894+ * There are published firmware files for L56 B0 silicon using
895+ * the ALSA prefix as the filename suffix. Default to trying these
896+ * first, with the new name as an alternate.
897+ */
898+ if ((cs35l56 -> base .type == 0x56 ) && (cs35l56 -> base .rev == 0xb0 )) {
899+ cs35l56 -> fallback_fw_suffix = cs35l56 -> dsp .fwf_suffix ;
900+ cs35l56 -> dsp .fwf_suffix = cs35l56 -> component -> name_prefix ;
901+ }
902+
903+ return 0 ;
904+ }
905+
856906static int cs35l56_component_probe (struct snd_soc_component * component )
857907{
858908 struct cs35l56_private * cs35l56 = snd_soc_component_get_drvdata (component );
@@ -892,6 +942,10 @@ static int cs35l56_component_probe(struct snd_soc_component *component)
892942 return - ENOMEM ;
893943
894944 cs35l56 -> component = component ;
945+ ret = cs35l56_set_fw_suffix (cs35l56 );
946+ if (ret )
947+ return ret ;
948+
895949 wm_adsp2_component_probe (& cs35l56 -> dsp , component );
896950
897951 debugfs_create_bool ("init_done" , 0444 , debugfs_root , & cs35l56 -> base .init_done );
0 commit comments