@@ -397,28 +397,21 @@ static const struct cs_dsp_client_ops cs35l56_hda_client_ops = {
397
397
398
398
static int cs35l56_hda_request_firmware_file (struct cs35l56_hda * cs35l56 ,
399
399
const struct firmware * * firmware , char * * filename ,
400
- const char * dir , const char * system_name ,
400
+ const char * base_name , const char * system_name ,
401
401
const char * amp_name ,
402
402
const char * filetype )
403
403
{
404
404
char * s , c ;
405
405
int ret = 0 ;
406
406
407
407
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 ,
411
409
system_name , amp_name , filetype );
412
410
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 ,
416
412
system_name , filetype );
417
413
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 );
422
415
423
416
if (!* filename )
424
417
return - ENOMEM ;
@@ -451,38 +444,52 @@ static int cs35l56_hda_request_firmware_file(struct cs35l56_hda *cs35l56,
451
444
return 0 ;
452
445
}
453
446
454
- static const char cirrus_dir [] = "cirrus/" ;
455
447
static void cs35l56_hda_request_firmware_files (struct cs35l56_hda * cs35l56 ,
448
+ unsigned int preloaded_fw_ver ,
456
449
const struct firmware * * wmfw_firmware ,
457
450
char * * wmfw_filename ,
458
451
const struct firmware * * coeff_firmware ,
459
452
char * * coeff_filename )
460
453
{
461
454
const char * system_name = cs35l56 -> system_name ;
462
455
const char * amp_name = cs35l56 -> amp_name ;
456
+ char base_name [37 ];
463
457
int ret ;
464
458
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
+
465
472
if (system_name && amp_name ) {
466
473
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" )) {
468
475
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" );
470
477
return ;
471
478
}
472
479
}
473
480
474
481
if (system_name ) {
475
482
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" )) {
477
484
if (amp_name )
478
485
cs35l56_hda_request_firmware_file (cs35l56 ,
479
486
coeff_firmware , coeff_filename ,
480
- cirrus_dir , system_name ,
487
+ base_name , system_name ,
481
488
amp_name , "bin" );
482
489
if (!* coeff_firmware )
483
490
cs35l56_hda_request_firmware_file (cs35l56 ,
484
491
coeff_firmware , coeff_filename ,
485
- cirrus_dir , system_name ,
492
+ base_name , system_name ,
486
493
NULL , "bin" );
487
494
return ;
488
495
}
@@ -493,26 +500,26 @@ static void cs35l56_hda_request_firmware_files(struct cs35l56_hda *cs35l56,
493
500
*/
494
501
if (amp_name )
495
502
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" );
497
504
if (!* coeff_firmware )
498
505
cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
499
- cirrus_dir , system_name , NULL , "bin" );
506
+ base_name , system_name , NULL , "bin" );
500
507
501
508
if (* coeff_firmware )
502
509
return ;
503
510
}
504
511
505
512
ret = cs35l56_hda_request_firmware_file (cs35l56 , wmfw_firmware , wmfw_filename ,
506
- cirrus_dir , NULL , NULL , "wmfw" );
513
+ base_name , NULL , NULL , "wmfw" );
507
514
if (!ret ) {
508
515
cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
509
- cirrus_dir , NULL , NULL , "bin" );
516
+ base_name , NULL , NULL , "bin" );
510
517
return ;
511
518
}
512
519
513
520
if (!* coeff_firmware )
514
521
cs35l56_hda_request_firmware_file (cs35l56 , coeff_firmware , coeff_filename ,
515
- cirrus_dir , NULL , NULL , "bin" );
522
+ base_name , NULL , NULL , "bin" );
516
523
}
517
524
518
525
static 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)
546
553
const struct firmware * wmfw_firmware = NULL ;
547
554
char * coeff_filename = NULL ;
548
555
char * wmfw_filename = NULL ;
549
- unsigned int firmware_missing ;
556
+ unsigned int preloaded_fw_ver ;
557
+ bool firmware_missing ;
550
558
int ret = 0 ;
551
559
552
560
/* Prepare for a new DSP power-up */
@@ -557,24 +565,21 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
557
565
558
566
pm_runtime_get_sync (cs35l56 -> base .dev );
559
567
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 )
563
575
goto err_pm_put ;
564
- }
565
576
566
- firmware_missing &= CS35L56_FIRMWARE_MISSING ;
577
+ if (firmware_missing )
578
+ preloaded_fw_ver = 0 ;
567
579
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 );
578
583
579
584
/*
580
585
* 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)
589
594
mutex_lock (& cs35l56 -> base .irq_lock );
590
595
591
596
/*
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.
596
601
*/
597
- if (! cs35l56 -> base . secured && (wmfw_firmware || coeff_firmware )) {
602
+ if (firmware_missing && (wmfw_firmware || coeff_firmware )) {
598
603
ret = cs35l56_firmware_shutdown (& cs35l56 -> base );
599
604
if (ret )
600
605
goto err ;
@@ -613,7 +618,7 @@ static int cs35l56_hda_fw_load(struct cs35l56_hda *cs35l56)
613
618
if (coeff_filename )
614
619
dev_dbg (cs35l56 -> base .dev , "Loaded Coefficients: %s\n" , coeff_filename );
615
620
616
- if (cs35l56 -> base . secured ) {
621
+ if (! firmware_missing ) {
617
622
ret = cs35l56_mbox_send (& cs35l56 -> base , CS35L56_MBOX_CMD_AUDIO_REINIT );
618
623
if (ret )
619
624
goto err_powered_up ;
0 commit comments