@@ -389,10 +389,10 @@ static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw,
389389 int i , n = ARRAY_SIZE (non_ppc3_mapping_table );
390390 unsigned char dev_idx = 0 ;
391391
392- if (fw_fixed_hdr -> ppcver >= PPC3_VERSION_TAS2781 ) {
392+ if (fw_fixed_hdr -> ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN ) {
393393 p = (struct blktyp_devidx_map * )ppc3_tas2781_mapping_table ;
394394 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 ) {
396396 p = (struct blktyp_devidx_map * )ppc3_mapping_table ;
397397 n = ARRAY_SIZE (ppc3_mapping_table );
398398 }
@@ -559,6 +559,124 @@ static int fw_parse_configuration_data_kernel(
559559 return offset ;
560560}
561561
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+
562680static int fw_parse_variable_header_kernel (
563681 struct tasdevice_priv * tas_priv , const struct firmware * fmw ,
564682 int offset )
@@ -1686,13 +1804,29 @@ static int tasdevice_load_block(struct tasdevice_priv *tas_priv,
16861804 return rc ;
16871805}
16881806
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+
16891823static int dspfw_default_callback (struct tasdevice_priv * tas_priv ,
16901824 unsigned int drv_ver , unsigned int ppcver )
16911825{
16921826 int rc = 0 ;
16931827
16941828 if (drv_ver == 0x100 ) {
1695- if (ppcver >= PPC3_VERSION ) {
1829+ if (ppcver >= PPC3_VERSION_BASE ) {
16961830 tas_priv -> fw_parse_variable_header =
16971831 fw_parse_variable_header_kernel ;
16981832 tas_priv -> fw_parse_program_data =
@@ -1701,6 +1835,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
17011835 fw_parse_configuration_data_kernel ;
17021836 tas_priv -> tasdevice_load_block =
17031837 tasdevice_load_block_kernel ;
1838+ dspbin_type_check (tas_priv , ppcver );
17041839 } else {
17051840 switch (ppcver ) {
17061841 case 0x00 :
@@ -1716,7 +1851,7 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
17161851 default :
17171852 dev_err (tas_priv -> dev ,
17181853 "%s: PPCVer must be 0x0 or 0x%02x" ,
1719- __func__ , PPC3_VERSION );
1854+ __func__ , PPC3_VERSION_BASE );
17201855 dev_err (tas_priv -> dev , " Current:0x%02x\n" ,
17211856 ppcver );
17221857 rc = - EINVAL ;
@@ -1952,28 +2087,25 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw,
19522087 struct tasdevice_fw_fixed_hdr * fw_fixed_hdr ;
19532088 struct tasdevice_fw * tas_fmw ;
19542089 int offset = 0 ;
1955- int ret = 0 ;
2090+ int ret ;
19562091
19572092 if (!fmw || !fmw -> data ) {
19582093 dev_err (tas_priv -> dev , "%s: Failed to read firmware %s\n" ,
19592094 __func__ , tas_priv -> coef_binaryname );
1960- ret = - EINVAL ;
1961- goto out ;
2095+ return - EINVAL ;
19622096 }
19632097
19642098 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+
19692102 tas_fmw = tas_priv -> fmw ;
19702103 tas_fmw -> dev = tas_priv -> dev ;
19712104 offset = fw_parse_header (tas_priv , tas_fmw , fmw , offset );
19722105
1973- if (offset == - EINVAL ) {
1974- ret = - EINVAL ;
1975- goto out ;
1976- }
2106+ if (offset == - EINVAL )
2107+ return - EINVAL ;
2108+
19772109 fw_fixed_hdr = & (tas_fmw -> fw_hdr .fixed_hdr );
19782110 /* Support different versions of firmware */
19792111 switch (fw_fixed_hdr -> drv_ver ) {
@@ -2006,28 +2138,32 @@ static int tasdevice_dspfw_ready(const struct firmware *fmw,
20062138 ret = dspfw_default_callback (tas_priv ,
20072139 fw_fixed_hdr -> drv_ver , fw_fixed_hdr -> ppcver );
20082140 if (ret )
2009- goto out ;
2141+ return ret ;
20102142 break ;
20112143 }
20122144
20132145 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+
20182149 offset = tas_priv -> fw_parse_program_data (tas_priv , tas_fmw , fmw ,
20192150 offset );
2020- if (offset < 0 ) {
2021- ret = offset ;
2022- goto out ;
2023- }
2151+ if (offset < 0 )
2152+ return offset ;
2153+
20242154 offset = tas_priv -> fw_parse_configuration_data (tas_priv ,
20252155 tas_fmw , fmw , offset );
20262156 if (offset < 0 )
2027- ret = offset ;
2157+ return offset ;
20282158
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 ;
20312167}
20322168
20332169int tasdevice_dsp_parser (void * context )
0 commit comments