3030 * ASP1_RX_WL = 24 bits per sample
3131 * ASP1_TX_WL = 24 bits per sample
3232 * ASP1_RXn_EN 1..3 and ASP1_TXn_EN 1..4 disabled
33+ *
34+ * Override any Windows-specific mixer settings applied by the firmware.
3335 */
3436static const struct reg_sequence cs35l56_hda_dai_config [] = {
3537 { CS35L56_ASP1_CONTROL1 , 0x00000021 },
3638 { CS35L56_ASP1_CONTROL2 , 0x20200200 },
3739 { CS35L56_ASP1_CONTROL3 , 0x00000003 },
40+ { CS35L56_ASP1_FRAME_CONTROL1 , 0x03020100 },
41+ { CS35L56_ASP1_FRAME_CONTROL5 , 0x00020100 },
3842 { CS35L56_ASP1_DATA_CONTROL5 , 0x00000018 },
3943 { CS35L56_ASP1_DATA_CONTROL1 , 0x00000018 },
4044 { CS35L56_ASP1_ENABLES1 , 0x00000000 },
45+ { CS35L56_ASP1TX1_INPUT , 0x00000018 },
46+ { CS35L56_ASP1TX2_INPUT , 0x00000019 },
47+ { CS35L56_ASP1TX3_INPUT , 0x00000020 },
48+ { CS35L56_ASP1TX4_INPUT , 0x00000028 },
49+
4150};
4251
4352static void cs35l56_hda_play (struct cs35l56_hda * cs35l56 )
@@ -133,6 +142,10 @@ static int cs35l56_hda_runtime_resume(struct device *dev)
133142 }
134143 }
135144
145+ ret = cs35l56_force_sync_asp1_registers_from_cache (& cs35l56 -> base );
146+ if (ret )
147+ goto err ;
148+
136149 return 0 ;
137150
138151err :
@@ -384,25 +397,21 @@ static const struct cs_dsp_client_ops cs35l56_hda_client_ops = {
384397
385398static int cs35l56_hda_request_firmware_file (struct cs35l56_hda * cs35l56 ,
386399 const struct firmware * * firmware , char * * filename ,
387- const char * dir , const char * system_name ,
400+ const char * base_name , const char * system_name ,
388401 const char * amp_name ,
389402 const char * filetype )
390403{
391404 char * s , c ;
392405 int ret = 0 ;
393406
394407 if (system_name && amp_name )
395- * filename = kasprintf (GFP_KERNEL , "%scs35l56%s-%02x-dsp1-misc-%s-%s.%s" , dir ,
396- cs35l56 -> base .secured ? "s" : "" , cs35l56 -> base .rev ,
408+ * filename = kasprintf (GFP_KERNEL , "%s-%s-%s.%s" , base_name ,
397409 system_name , amp_name , filetype );
398410 else if (system_name )
399- * filename = kasprintf (GFP_KERNEL , "%scs35l56%s-%02x-dsp1-misc-%s.%s" , dir ,
400- cs35l56 -> base .secured ? "s" : "" , cs35l56 -> base .rev ,
411+ * filename = kasprintf (GFP_KERNEL , "%s-%s.%s" , base_name ,
401412 system_name , filetype );
402413 else
403- * filename = kasprintf (GFP_KERNEL , "%scs35l56%s-%02x-dsp1-misc.%s" , dir ,
404- cs35l56 -> base .secured ? "s" : "" , cs35l56 -> base .rev ,
405- filetype );
414+ * filename = kasprintf (GFP_KERNEL , "%s.%s" , base_name , filetype );
406415
407416 if (!* filename )
408417 return - ENOMEM ;
@@ -435,64 +444,82 @@ static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56,
435444 return 0 ;
436445}
437446
438- static const char cirrus_dir [] = "cirrus/" ;
439447static void cs35l56_hda_request_firmware_files (struct cs35l56_hda * cs35l56 ,
448+ unsigned int preloaded_fw_ver ,
440449 const struct firmware * * wmfw_firmware ,
441450 char * * wmfw_filename ,
442451 const struct firmware * * coeff_firmware ,
443452 char * * coeff_filename )
444453{
445454 const char * system_name = cs35l56 -> system_name ;
446455 const char * amp_name = cs35l56 -> amp_name ;
456+ char base_name [37 ];
447457 int ret ;
448458
459+ if (preloaded_fw_ver ) {
460+ snprintf (base_name , sizeof (base_name ),
461+ "cirrus/cs35l56-%02x%s-%06x-dsp1-misc" ,
462+ cs35l56 -> base .rev ,
463+ cs35l56 -> base .secured ? "-s" : "" ,
464+ preloaded_fw_ver & 0xffffff );
465+ } else {
466+ snprintf (base_name , sizeof (base_name ),
467+ "cirrus/cs35l56-%02x%s-dsp1-misc" ,
468+ cs35l56 -> base .rev ,
469+ cs35l56 -> base .secured ? "-s" : "" );
470+ }
471+
449472 if (system_name && amp_name ) {
450473 if (!cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
451- cirrus_dir , system_name , amp_name , "wmfw" )) {
474+ base_name , system_name , amp_name , "wmfw" )) {
452475 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
453- cirrus_dir , system_name , amp_name , "bin" );
476+ base_name , system_name , amp_name , "bin" );
454477 return ;
455478 }
456479 }
457480
458481 if (system_name ) {
459482 if (!cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
460- cirrus_dir , system_name , NULL , "wmfw" )) {
483+ base_name , system_name , NULL , "wmfw" )) {
461484 if (amp_name )
462485 cs35l56_hda_request_firmware_file (cs35l56 ,
463486 coeff_firmware , coeff_filename ,
464- cirrus_dir , system_name ,
487+ base_name , system_name ,
465488 amp_name , "bin" );
466489 if (!* coeff_firmware )
467490 cs35l56_hda_request_firmware_file (cs35l56 ,
468491 coeff_firmware , coeff_filename ,
469- cirrus_dir , system_name ,
492+ base_name , system_name ,
470493 NULL , "bin" );
471494 return ;
472495 }
496+
497+ /*
498+ * Check for system-specific bin files without wmfw before
499+ * falling back to generic firmware
500+ */
501+ if (amp_name )
502+ cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
503+ base_name , system_name , amp_name , "bin" );
504+ if (!* coeff_firmware )
505+ cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
506+ base_name , system_name , NULL , "bin" );
507+
508+ if (* coeff_firmware )
509+ return ;
473510 }
474511
475512 ret = cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
476- cirrus_dir , NULL , NULL , "wmfw" );
513+ base_name , NULL , NULL , "wmfw" );
477514 if (!ret ) {
478515 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
479- cirrus_dir , NULL , NULL , "bin" );
516+ base_name , NULL , NULL , "bin" );
480517 return ;
481518 }
482519
483- /* When a firmware file is not found must still search for the coeff files */
484- if (system_name ) {
485- if (amp_name )
486- cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
487- cirrus_dir , system_name , amp_name , "bin" );
488- if (!* coeff_firmware )
489- cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
490- cirrus_dir , system_name , NULL , "bin" );
491- }
492-
493520 if (!* coeff_firmware )
494521 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
495- cirrus_dir , NULL , NULL , "bin" );
522+ base_name , NULL , NULL , "bin" );
496523}
497524
498525static void cs35l56_hda_release_firmware_files (const struct firmware * wmfw_firmware ,
@@ -526,7 +553,8 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
526553 const struct firmware * wmfw_firmware = NULL ;
527554 char * coeff_filename = NULL ;
528555 char * wmfw_filename = NULL ;
529- unsigned int firmware_missing ;
556+ unsigned int preloaded_fw_ver ;
557+ bool firmware_missing ;
530558 int ret = 0 ;
531559
532560 /* Prepare for a new DSP power-up */
@@ -537,24 +565,21 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
537565
538566 pm_runtime_get_sync (cs35l56 -> base .dev );
539567
540- ret = regmap_read (cs35l56 -> base .regmap , CS35L56_PROTECTION_STATUS , & firmware_missing );
541- if (ret ) {
542- dev_err (cs35l56 -> base .dev , "Failed to read PROTECTION_STATUS: %d\n" , ret );
568+ /*
569+ * The firmware can only be upgraded if it is currently running
570+ * from the built-in ROM. If not, the wmfw/bin must be for the
571+ * version of firmware that is running on the chip.
572+ */
573+ ret = cs35l56_read_prot_status (& cs35l56 -> base , & firmware_missing , & preloaded_fw_ver );
574+ if (ret )
543575 goto err_pm_put ;
544- }
545576
546- firmware_missing &= CS35L56_FIRMWARE_MISSING ;
577+ if (firmware_missing )
578+ preloaded_fw_ver = 0 ;
547579
548- /*
549- * Firmware can only be downloaded if the CS35L56 is secured or is
550- * running from the built-in ROM. If it is secured the BIOS will have
551- * downloaded firmware, and the wmfw/bin files will only contain
552- * tunings that are safe to download with the firmware running.
553- */
554- if (cs35l56 -> base .secured || firmware_missing ) {
555- cs35l56_hda_request_firmware_files (cs35l56 , & wmfw_firmware , & wmfw_filename ,
556- & coeff_firmware , & coeff_filename );
557- }
580+ cs35l56_hda_request_firmware_files (cs35l56 , preloaded_fw_ver ,
581+ & wmfw_firmware , & wmfw_filename ,
582+ & coeff_firmware , & coeff_filename );
558583
559584 /*
560585 * If the BIOS didn't patch the firmware a bin file is mandatory to
@@ -569,12 +594,12 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
569594 mutex_lock (& cs35l56 -> base .irq_lock );
570595
571596 /*
572- * When the device is running in secure mode the firmware files can
573- * only contain insecure tunings and therefore we do not need to
574- * shutdown the firmware to apply them and can use the lower cost
575- * reinit sequence instead.
597+ * If the firmware hasn't been patched it must be shutdown before
598+ * doing a full patch and reset afterwards. If it is already
599+ * running a patched version the firmware files only contain
600+ * tunings and we can use the lower cost reinit sequence instead.
576601 */
577- if (! cs35l56 -> base . secured && (wmfw_firmware || coeff_firmware )) {
602+ if (firmware_missing && (wmfw_firmware || coeff_firmware )) {
578603 ret = cs35l56_firmware_shutdown (& cs35l56 -> base );
579604 if (ret )
580605 goto err ;
@@ -593,7 +618,7 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
593618 if (coeff_filename )
594619 dev_dbg (cs35l56 -> base .dev , "Loaded Coefficients: %s\n" , coeff_filename );
595620
596- if (cs35l56 -> base . secured ) {
621+ if (! firmware_missing ) {
597622 ret = cs35l56_mbox_send (& cs35l56 -> base , CS35L56_MBOX_CMD_AUDIO_REINIT );
598623 if (ret )
599624 goto err_powered_up ;
@@ -976,6 +1001,9 @@ int cs35l56_hda_common_probe(struct cs35l56_hda *cs35l56, int id)
9761001
9771002 regmap_multi_reg_write (cs35l56 -> base .regmap , cs35l56_hda_dai_config ,
9781003 ARRAY_SIZE (cs35l56_hda_dai_config ));
1004+ ret = cs35l56_force_sync_asp1_registers_from_cache (& cs35l56 -> base );
1005+ if (ret )
1006+ goto err ;
9791007
9801008 /*
9811009 * By default only enable one ASP1TXn, where n=amplifier index,
@@ -1035,16 +1063,6 @@ const struct dev_pm_ops cs35l56_hda_pm_ops = {
10351063};
10361064EXPORT_SYMBOL_NS_GPL (cs35l56_hda_pm_ops , SND_HDA_SCODEC_CS35L56 );
10371065
1038- #if IS_ENABLED (CONFIG_SND_HDA_SCODEC_CS35L56_KUNIT_TEST )
1039- /* Hooks to export static function to KUnit test */
1040-
1041- int cs35l56_hda_test_hook_get_speaker_id (struct device * dev , int amp_index , int num_amps )
1042- {
1043- return cs35l56_hda_get_speaker_id (dev , amp_index , num_amps );
1044- }
1045- EXPORT_SYMBOL_NS_GPL (cs35l56_hda_test_hook_get_speaker_id , SND_HDA_SCODEC_CS35L56 );
1046- #endif
1047-
10481066MODULE_DESCRIPTION ("CS35L56 HDA Driver" );
10491067MODULE_IMPORT_NS (SND_HDA_CIRRUS_SCODEC );
10501068MODULE_IMPORT_NS (SND_HDA_CS_DSP_CONTROLS );
0 commit comments