@@ -397,28 +397,21 @@ static const struct cs_dsp_client_ops cs35l56_hda_client_ops = {
397397
398398static int cs35l56_hda_request_firmware_file (struct cs35l56_hda * cs35l56 ,
399399 const struct firmware * * firmware , char * * filename ,
400- const char * dir , const char * system_name ,
400+ const char * base_name , const char * system_name ,
401401 const char * amp_name ,
402402 const char * filetype )
403403{
404404 char * s , c ;
405405 int ret = 0 ;
406406
407407 if (system_name && amp_name )
408- * filename = kasprintf (GFP_KERNEL , "%scs35l56-%02x%s-dsp1-misc-%s-%s.%s" , dir ,
409- cs35l56 -> base .rev ,
410- cs35l56 -> base .secured ? "-s" : "" ,
408+ * filename = kasprintf (GFP_KERNEL , "%s-%s-%s.%s" , base_name ,
411409 system_name , amp_name , filetype );
412410 else if (system_name )
413- * filename = kasprintf (GFP_KERNEL , "%scs35l56-%02x%s-dsp1-misc-%s.%s" , dir ,
414- cs35l56 -> base .rev ,
415- cs35l56 -> base .secured ? "-s" : "" ,
411+ * filename = kasprintf (GFP_KERNEL , "%s-%s.%s" , base_name ,
416412 system_name , filetype );
417413 else
418- * filename = kasprintf (GFP_KERNEL , "%scs35l56-%02x%s-dsp1-misc.%s" , dir ,
419- cs35l56 -> base .rev ,
420- cs35l56 -> base .secured ? "-s" : "" ,
421- filetype );
414+ * filename = kasprintf (GFP_KERNEL , "%s.%s" , base_name , filetype );
422415
423416 if (!* filename )
424417 return - ENOMEM ;
@@ -451,38 +444,52 @@ static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56,
451444 return 0 ;
452445}
453446
454- static const char cirrus_dir [] = "cirrus/" ;
455447static void cs35l56_hda_request_firmware_files (struct cs35l56_hda * cs35l56 ,
448+ unsigned int preloaded_fw_ver ,
456449 const struct firmware * * wmfw_firmware ,
457450 char * * wmfw_filename ,
458451 const struct firmware * * coeff_firmware ,
459452 char * * coeff_filename )
460453{
461454 const char * system_name = cs35l56 -> system_name ;
462455 const char * amp_name = cs35l56 -> amp_name ;
456+ char base_name [37 ];
463457 int ret ;
464458
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+
465472 if (system_name && amp_name ) {
466473 if (!cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
467- cirrus_dir , system_name , amp_name , "wmfw" )) {
474+ base_name , system_name , amp_name , "wmfw" )) {
468475 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
469- cirrus_dir , system_name , amp_name , "bin" );
476+ base_name , system_name , amp_name , "bin" );
470477 return ;
471478 }
472479 }
473480
474481 if (system_name ) {
475482 if (!cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
476- cirrus_dir , system_name , NULL , "wmfw" )) {
483+ base_name , system_name , NULL , "wmfw" )) {
477484 if (amp_name )
478485 cs35l56_hda_request_firmware_file (cs35l56 ,
479486 coeff_firmware , coeff_filename ,
480- cirrus_dir , system_name ,
487+ base_name , system_name ,
481488 amp_name , "bin" );
482489 if (!* coeff_firmware )
483490 cs35l56_hda_request_firmware_file (cs35l56 ,
484491 coeff_firmware , coeff_filename ,
485- cirrus_dir , system_name ,
492+ base_name , system_name ,
486493 NULL , "bin" );
487494 return ;
488495 }
@@ -493,26 +500,26 @@ static void cs35l56_hda_request_firmware_files(struct cs35l56_hda *cs35l56,
493500 */
494501 if (amp_name )
495502 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
496- cirrus_dir , system_name , amp_name , "bin" );
503+ base_name , system_name , amp_name , "bin" );
497504 if (!* coeff_firmware )
498505 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
499- cirrus_dir , system_name , NULL , "bin" );
506+ base_name , system_name , NULL , "bin" );
500507
501508 if (* coeff_firmware )
502509 return ;
503510 }
504511
505512 ret = cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
506- cirrus_dir , NULL , NULL , "wmfw" );
513+ base_name , NULL , NULL , "wmfw" );
507514 if (!ret ) {
508515 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
509- cirrus_dir , NULL , NULL , "bin" );
516+ base_name , NULL , NULL , "bin" );
510517 return ;
511518 }
512519
513520 if (!* coeff_firmware )
514521 cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
515- cirrus_dir , NULL , NULL , "bin" );
522+ base_name , NULL , NULL , "bin" );
516523}
517524
518525static void cs35l56_hda_release_firmware_files (const struct firmware * wmfw_firmware ,
@@ -546,7 +553,8 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
546553 const struct firmware * wmfw_firmware = NULL ;
547554 char * coeff_filename = NULL ;
548555 char * wmfw_filename = NULL ;
549- unsigned int firmware_missing ;
556+ unsigned int preloaded_fw_ver ;
557+ bool firmware_missing ;
550558 int ret = 0 ;
551559
552560 /* Prepare for a new DSP power-up */
@@ -557,24 +565,21 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
557565
558566 pm_runtime_get_sync (cs35l56 -> base .dev );
559567
560- ret = regmap_read (cs35l56 -> base .regmap , CS35L56_PROTECTION_STATUS , & firmware_missing );
561- if (ret ) {
562- 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 )
563575 goto err_pm_put ;
564- }
565576
566- firmware_missing &= CS35L56_FIRMWARE_MISSING ;
577+ if (firmware_missing )
578+ preloaded_fw_ver = 0 ;
567579
568- /*
569- * Firmware can only be downloaded if the CS35L56 is secured or is
570- * running from the built-in ROM. If it is secured the BIOS will have
571- * downloaded firmware, and the wmfw/bin files will only contain
572- * tunings that are safe to download with the firmware running.
573- */
574- if (cs35l56 -> base .secured || firmware_missing ) {
575- cs35l56_hda_request_firmware_files (cs35l56 , & wmfw_firmware , & wmfw_filename ,
576- & coeff_firmware , & coeff_filename );
577- }
580+ cs35l56_hda_request_firmware_files (cs35l56 , preloaded_fw_ver ,
581+ & wmfw_firmware , & wmfw_filename ,
582+ & coeff_firmware , & coeff_filename );
578583
579584 /*
580585 * If the BIOS didn't patch the firmware a bin file is mandatory to
@@ -589,12 +594,12 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
589594 mutex_lock (& cs35l56 -> base .irq_lock );
590595
591596 /*
592- * When the device is running in secure mode the firmware files can
593- * only contain insecure tunings and therefore we do not need to
594- * shutdown the firmware to apply them and can use the lower cost
595- * 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.
596601 */
597- if (! cs35l56 -> base . secured && (wmfw_firmware || coeff_firmware )) {
602+ if (firmware_missing && (wmfw_firmware || coeff_firmware )) {
598603 ret = cs35l56_firmware_shutdown (& cs35l56 -> base );
599604 if (ret )
600605 goto err ;
@@ -613,7 +618,7 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
613618 if (coeff_filename )
614619 dev_dbg (cs35l56 -> base .dev , "Loaded Coefficients: %s\n" , coeff_filename );
615620
616- if (cs35l56 -> base . secured ) {
621+ if (! firmware_missing ) {
617622 ret = cs35l56_mbox_send (& cs35l56 -> base , CS35L56_MBOX_CMD_AUDIO_REINIT );
618623 if (ret )
619624 goto err_powered_up ;
0 commit comments