@@ -389,10 +389,10 @@ static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw,
389
389
int i , n = ARRAY_SIZE (non_ppc3_mapping_table );
390
390
unsigned char dev_idx = 0 ;
391
391
392
- if (fw_fixed_hdr -> ppcver >= PPC3_VERSION_TAS2781 ) {
392
+ if (fw_fixed_hdr -> ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN ) {
393
393
p = (struct blktyp_devidx_map * )ppc3_tas2781_mapping_table ;
394
394
n = ARRAY_SIZE (ppc3_tas2781_mapping_table );
395
- } else if (fw_fixed_hdr -> ppcver >= PPC3_VERSION ) {
395
+ } else if (fw_fixed_hdr -> ppcver >= PPC3_VERSION_BASE ) {
396
396
p = (struct blktyp_devidx_map * )ppc3_mapping_table ;
397
397
n = ARRAY_SIZE (ppc3_mapping_table );
398
398
}
@@ -559,6 +559,124 @@ static int fw_parse_configuration_data_kernel(
559
559
return offset ;
560
560
}
561
561
562
+ static void fct_param_address_parser (struct cali_reg * r ,
563
+ struct tasdevice_fw * tas_fmw , const unsigned char * data )
564
+ {
565
+ struct fct_param_address * p = & tas_fmw -> fct_par_addr ;
566
+ unsigned int i ;
567
+
568
+ /*
569
+ * Calibration parameters locations and data schema in dsp firmware.
570
+ * The number of items are flexible, but not more than 20. The dsp tool
571
+ * will reseve 20*24-byte space for fct params. In some cases, the
572
+ * number of fct param is less than 20, the data will be saved from the
573
+ * beginning, the rest part will be stuffed with zero.
574
+ *
575
+ * fct_param_num (not more than 20)
576
+ * for (i = 0; i < fct_param_num; i++) {
577
+ * Alias of fct param (20 bytes)
578
+ * Book (1 byte)
579
+ * Page (1 byte)
580
+ * Offset (1 byte)
581
+ * CoeffLength (1 byte) = 0x1
582
+ * }
583
+ * if (20 - fct_param_num)
584
+ * 24*(20 - fct_param_num) pieces of '0' as stuffing
585
+ *
586
+ * As follow:
587
+ * umg_SsmKEGCye = Book, Page, Offset, CoeffLength
588
+ * iks_E0 = Book, Page, Offset, CoeffLength
589
+ * yep_LsqM0 = Book, Page, Offset, CoeffLength
590
+ * oyz_U0_ujx = Book, Page, Offset, CoeffLength
591
+ * iks_GC_GMgq = Book, Page, Offset, CoeffLength
592
+ * gou_Yao = Book, Page, Offset, CoeffLength
593
+ * kgd_Wsc_Qsbp = Book, Page, Offset, CoeffLength
594
+ * yec_CqseSsqs = Book, Page, Offset, CoeffLength
595
+ * iks_SogkGgog2 = Book, Page, Offset, CoeffLength
596
+ * yec_Sae_Y = Book, Page, Offset, CoeffLength
597
+ * Re_Int = Book, Page, Offset, CoeffLength
598
+ * SigFlag = Book, Page, Offset, CoeffLength
599
+ * a1_Int = Book, Page, Offset, CoeffLength
600
+ * a2_Int = Book, Page, Offset, CoeffLength
601
+ */
602
+ for (i = 0 ; i < 20 ; i ++ ) {
603
+ const unsigned char * dat = & data [24 * i ];
604
+
605
+ /*
606
+ * check whether current fct param is empty.
607
+ */
608
+ if (dat [23 ] != 1 )
609
+ break ;
610
+
611
+ if (!strncmp (dat , "umg_SsmKEGCye" , 20 ))
612
+ r -> pow_reg = TASDEVICE_REG (dat [20 ], dat [21 ], dat [22 ]);
613
+ /* high 32-bit of real-time spk impedance */
614
+ else if (!strncmp (dat , "iks_E0" , 20 ))
615
+ r -> r0_reg = TASDEVICE_REG (dat [20 ], dat [21 ], dat [22 ]);
616
+ /* inverse of real-time spk impedance */
617
+ else if (!strncmp (dat , "yep_LsqM0" , 20 ))
618
+ r -> invr0_reg =
619
+ TASDEVICE_REG (dat [20 ], dat [21 ], dat [22 ]);
620
+ /* low 32-bit of real-time spk impedance */
621
+ else if (!strncmp (dat , "oyz_U0_ujx" , 20 ))
622
+ r -> r0_low_reg =
623
+ TASDEVICE_REG (dat [20 ], dat [21 ], dat [22 ]);
624
+ /* Delta Thermal Limit */
625
+ else if (!strncmp (dat , "iks_GC_GMgq" , 20 ))
626
+ r -> tlimit_reg =
627
+ TASDEVICE_REG (dat [20 ], dat [21 ], dat [22 ]);
628
+ /* Thermal data for PG 1.0 device */
629
+ else if (!strncmp (dat , "gou_Yao" , 20 ))
630
+ memcpy (p -> thr , & dat [20 ], 3 );
631
+ /* Pilot tone enable flag, usually the sine wave */
632
+ else if (!strncmp (dat , "kgd_Wsc_Qsbp" , 20 ))
633
+ memcpy (p -> plt_flg , & dat [20 ], 3 );
634
+ /* Pilot tone gain for calibration */
635
+ else if (!strncmp (dat , "yec_CqseSsqs" , 20 ))
636
+ memcpy (p -> sin_gn , & dat [20 ], 3 );
637
+ /* Pilot tone gain for calibration, useless in PG 2.0 */
638
+ else if (!strncmp (dat , "iks_SogkGgog2" , 20 ))
639
+ memcpy (p -> sin_gn2 , & dat [20 ], 3 );
640
+ /* Thermal data for PG 2.0 device */
641
+ else if (!strncmp (dat , "yec_Sae_Y" , 20 ))
642
+ memcpy (p -> thr2 , & dat [20 ], 3 );
643
+ /* Spk Equivalent Resistance in fixed-point format */
644
+ else if (!strncmp (dat , "Re_Int" , 20 ))
645
+ memcpy (p -> r0_reg , & dat [20 ], 3 );
646
+ /* Check whether the spk connection is open */
647
+ else if (!strncmp (dat , "SigFlag" , 20 ))
648
+ memcpy (p -> tf_reg , & dat [20 ], 3 );
649
+ /* check spk resonant frequency */
650
+ else if (!strncmp (dat , "a1_Int" , 20 ))
651
+ memcpy (p -> a1_reg , & dat [20 ], 3 );
652
+ /* check spk resonant frequency */
653
+ else if (!strncmp (dat , "a2_Int" , 20 ))
654
+ memcpy (p -> a2_reg , & dat [20 ], 3 );
655
+ }
656
+ }
657
+
658
+ static int fw_parse_fct_param_address (struct tasdevice_priv * tas_priv ,
659
+ struct tasdevice_fw * tas_fmw , const struct firmware * fmw , int offset )
660
+ {
661
+ struct calidata * cali_data = & tas_priv -> cali_data ;
662
+ struct cali_reg * r = & cali_data -> cali_reg_array ;
663
+ const unsigned char * data = fmw -> data ;
664
+
665
+ if (offset + 520 > fmw -> size ) {
666
+ dev_err (tas_priv -> dev , "%s: File Size error\n" , __func__ );
667
+ return - EINVAL ;
668
+ }
669
+
670
+ /* skip reserved part */
671
+ offset += 40 ;
672
+
673
+ fct_param_address_parser (r , tas_fmw , & data [offset ]);
674
+
675
+ offset += 480 ;
676
+
677
+ return offset ;
678
+ }
679
+
562
680
static int fw_parse_variable_header_kernel (
563
681
struct tasdevice_priv * tas_priv , const struct firmware * fmw ,
564
682
int offset )
@@ -1686,13 +1804,29 @@ static int tasdevice_load_block(struct tasdevice_priv *tas_priv,
1686
1804
return rc ;
1687
1805
}
1688
1806
1807
+ static void dspbin_type_check (struct tasdevice_priv * tas_priv ,
1808
+ unsigned int ppcver )
1809
+ {
1810
+ if (ppcver >= PPC3_VERSION_TAS2781_ALPHA_MIN ) {
1811
+ if (ppcver >= PPC3_VERSION_TAS2781_BETA_MIN )
1812
+ tas_priv -> dspbin_typ = TASDEV_BETA ;
1813
+ else if (ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN )
1814
+ tas_priv -> dspbin_typ = TASDEV_BASIC ;
1815
+ else
1816
+ tas_priv -> dspbin_typ = TASDEV_ALPHA ;
1817
+ }
1818
+ if (tas_priv -> dspbin_typ != TASDEV_BASIC )
1819
+ tas_priv -> fw_parse_fct_param_address =
1820
+ fw_parse_fct_param_address ;
1821
+ }
1822
+
1689
1823
static int dspfw_default_callback (struct tasdevice_priv * tas_priv ,
1690
1824
unsigned int drv_ver , unsigned int ppcver )
1691
1825
{
1692
1826
int rc = 0 ;
1693
1827
1694
1828
if (drv_ver == 0x100 ) {
1695
- if (ppcver >= PPC3_VERSION ) {
1829
+ if (ppcver >= PPC3_VERSION_BASE ) {
1696
1830
tas_priv -> fw_parse_variable_header =
1697
1831
fw_parse_variable_header_kernel ;
1698
1832
tas_priv -> fw_parse_program_data =
@@ -1701,6 +1835,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
1701
1835
fw_parse_configuration_data_kernel ;
1702
1836
tas_priv -> tasdevice_load_block =
1703
1837
tasdevice_load_block_kernel ;
1838
+ dspbin_type_check (tas_priv , ppcver );
1704
1839
} else {
1705
1840
switch (ppcver ) {
1706
1841
case 0x00 :
@@ -1716,7 +1851,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
1716
1851
default :
1717
1852
dev_err (tas_priv -> dev ,
1718
1853
"%s: PPCVer must be 0x0 or 0x%02x" ,
1719
- __func__ , PPC3_VERSION );
1854
+ __func__ , PPC3_VERSION_BASE );
1720
1855
dev_err (tas_priv -> dev , " Current:0x%02x\n" ,
1721
1856
ppcver );
1722
1857
rc = - EINVAL ;
@@ -1952,28 +2087,25 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw,
1952
2087
struct tasdevice_fw_fixed_hdr * fw_fixed_hdr ;
1953
2088
struct tasdevice_fw * tas_fmw ;
1954
2089
int offset = 0 ;
1955
- int ret = 0 ;
2090
+ int ret ;
1956
2091
1957
2092
if (!fmw || !fmw -> data ) {
1958
2093
dev_err (tas_priv -> dev , "%s: Failed to read firmware %s\n" ,
1959
2094
__func__ , tas_priv -> coef_binaryname );
1960
- ret = - EINVAL ;
1961
- goto out ;
2095
+ return - EINVAL ;
1962
2096
}
1963
2097
1964
2098
tas_priv -> fmw = kzalloc (sizeof (struct tasdevice_fw ), GFP_KERNEL );
1965
- if (!tas_priv -> fmw ) {
1966
- ret = - ENOMEM ;
1967
- goto out ;
1968
- }
2099
+ if (!tas_priv -> fmw )
2100
+ return - ENOMEM ;
2101
+
1969
2102
tas_fmw = tas_priv -> fmw ;
1970
2103
tas_fmw -> dev = tas_priv -> dev ;
1971
2104
offset = fw_parse_header (tas_priv , tas_fmw , fmw , offset );
1972
2105
1973
- if (offset == - EINVAL ) {
1974
- ret = - EINVAL ;
1975
- goto out ;
1976
- }
2106
+ if (offset == - EINVAL )
2107
+ return - EINVAL ;
2108
+
1977
2109
fw_fixed_hdr = & (tas_fmw -> fw_hdr .fixed_hdr );
1978
2110
/* Support different versions of firmware */
1979
2111
switch (fw_fixed_hdr -> drv_ver ) {
@@ -2006,28 +2138,32 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw,
2006
2138
ret = dspfw_default_callback (tas_priv ,
2007
2139
fw_fixed_hdr -> drv_ver , fw_fixed_hdr -> ppcver );
2008
2140
if (ret )
2009
- goto out ;
2141
+ return ret ;
2010
2142
break ;
2011
2143
}
2012
2144
2013
2145
offset = tas_priv -> fw_parse_variable_header (tas_priv , fmw , offset );
2014
- if (offset < 0 ) {
2015
- ret = offset ;
2016
- goto out ;
2017
- }
2146
+ if (offset < 0 )
2147
+ return offset ;
2148
+
2018
2149
offset = tas_priv -> fw_parse_program_data (tas_priv , tas_fmw , fmw ,
2019
2150
offset );
2020
- if (offset < 0 ) {
2021
- ret = offset ;
2022
- goto out ;
2023
- }
2151
+ if (offset < 0 )
2152
+ return offset ;
2153
+
2024
2154
offset = tas_priv -> fw_parse_configuration_data (tas_priv ,
2025
2155
tas_fmw , fmw , offset );
2026
2156
if (offset < 0 )
2027
- ret = offset ;
2157
+ return offset ;
2028
2158
2029
- out :
2030
- return ret ;
2159
+ if (tas_priv -> fw_parse_fct_param_address ) {
2160
+ offset = tas_priv -> fw_parse_fct_param_address (tas_priv ,
2161
+ tas_fmw , fmw , offset );
2162
+ if (offset < 0 )
2163
+ return offset ;
2164
+ }
2165
+
2166
+ return 0 ;
2031
2167
}
2032
2168
2033
2169
int tasdevice_dsp_parser (void * context )
0 commit comments