|
2 | 2 | // |
3 | 3 | // tas2781-fmwlib.c -- TASDEVICE firmware support |
4 | 4 | // |
5 | | -// Copyright 2023 - 2025 Texas Instruments, Inc. |
| 5 | +// Copyright 2023 - 2026 Texas Instruments, Inc. |
6 | 6 | // |
7 | 7 | // Author: Shenghao Ding <shenghao-ding@ti.com> |
8 | 8 | // Author: Baojun Xu <baojun.xu@ti.com> |
|
80 | 80 | #define POST_SOFTWARE_RESET_DEVICE_C 0x47 |
81 | 81 | #define POST_SOFTWARE_RESET_DEVICE_D 0x48 |
82 | 82 |
|
| 83 | +#define COPY_CAL_DATA(i) \ |
| 84 | + do { \ |
| 85 | + calbin_data[i + 1] = data[7]; \ |
| 86 | + calbin_data[i + 2] = data[8]; \ |
| 87 | + calbin_data[i + 3] = data[9]; \ |
| 88 | + calbin_data[i + 4] = data[10]; \ |
| 89 | + } while (0) |
| 90 | + |
83 | 91 | struct tas_crc { |
84 | 92 | unsigned char offset; |
85 | 93 | unsigned char len; |
@@ -1952,23 +1960,6 @@ static int dspfw_default_callback(struct tasdevice_priv *tas_priv, |
1952 | 1960 | return rc; |
1953 | 1961 | } |
1954 | 1962 |
|
1955 | | -static int load_calib_data(struct tasdevice_priv *tas_priv, |
1956 | | - struct tasdevice_data *dev_data) |
1957 | | -{ |
1958 | | - struct tasdev_blk *block; |
1959 | | - unsigned int i; |
1960 | | - int ret = 0; |
1961 | | - |
1962 | | - for (i = 0; i < dev_data->nr_blk; i++) { |
1963 | | - block = &(dev_data->dev_blks[i]); |
1964 | | - ret = tasdevice_load_block(tas_priv, block); |
1965 | | - if (ret < 0) |
1966 | | - break; |
1967 | | - } |
1968 | | - |
1969 | | - return ret; |
1970 | | -} |
1971 | | - |
1972 | 1963 | static int fw_parse_header(struct tasdevice_priv *tas_priv, |
1973 | 1964 | struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset) |
1974 | 1965 | { |
@@ -2029,6 +2020,103 @@ static int fw_parse_variable_hdr_cal(struct tasdevice_priv *tas_priv, |
2029 | 2020 | return offset; |
2030 | 2021 | } |
2031 | 2022 |
|
| 2023 | +static inline int check_cal_bin_data(struct device *dev, |
| 2024 | + const unsigned char *data, const char *name) |
| 2025 | +{ |
| 2026 | + if (data[2] != 0x85 || data[1] != 4) { |
| 2027 | + dev_err(dev, "Invalid cal bin file in %s\n", name); |
| 2028 | + return -1; |
| 2029 | + } |
| 2030 | + return 0; |
| 2031 | +} |
| 2032 | + |
| 2033 | +static void calbin_conversion(struct tasdevice_priv *priv, |
| 2034 | + struct tasdevice_fw *tas_fmw) |
| 2035 | +{ |
| 2036 | + struct calidata *cali_data = &priv->cali_data; |
| 2037 | + unsigned char *calbin_data = cali_data->data; |
| 2038 | + struct cali_reg *p = &cali_data->cali_reg_array; |
| 2039 | + struct tasdevice_calibration *calibration; |
| 2040 | + struct tasdevice_data *img_data; |
| 2041 | + struct tasdev_blk *blk; |
| 2042 | + unsigned char *data; |
| 2043 | + int chn, k; |
| 2044 | + |
| 2045 | + if (cali_data->total_sz != priv->ndev * |
| 2046 | + (cali_data->cali_dat_sz_per_dev + 1)) { |
| 2047 | + dev_err(priv->dev, "%s: cali_data size err\n", |
| 2048 | + __func__); |
| 2049 | + return; |
| 2050 | + } |
| 2051 | + calibration = &(tas_fmw->calibrations[0]); |
| 2052 | + img_data = &(calibration->dev_data); |
| 2053 | + |
| 2054 | + if (img_data->nr_blk != 1) { |
| 2055 | + dev_err(priv->dev, "%s: Invalid nr_blk, wrong cal bin\n", |
| 2056 | + __func__); |
| 2057 | + return; |
| 2058 | + } |
| 2059 | + |
| 2060 | + blk = &(img_data->dev_blks[0]); |
| 2061 | + if (blk->nr_cmds != 15) { |
| 2062 | + dev_err(priv->dev, "%s: Invalid nr_cmds, wrong cal bin\n", |
| 2063 | + __func__); |
| 2064 | + return; |
| 2065 | + } |
| 2066 | + |
| 2067 | + switch (blk->type) { |
| 2068 | + case COEFF_DEVICE_A: |
| 2069 | + chn = 0; |
| 2070 | + break; |
| 2071 | + case COEFF_DEVICE_B: |
| 2072 | + chn = 1; |
| 2073 | + break; |
| 2074 | + case COEFF_DEVICE_C: |
| 2075 | + chn = 2; |
| 2076 | + break; |
| 2077 | + case COEFF_DEVICE_D: |
| 2078 | + chn = 3; |
| 2079 | + break; |
| 2080 | + default: |
| 2081 | + dev_err(priv->dev, "%s: Other Type = 0x%02x\n", |
| 2082 | + __func__, blk->type); |
| 2083 | + return; |
| 2084 | + } |
| 2085 | + k = chn * (cali_data->cali_dat_sz_per_dev + 1); |
| 2086 | + |
| 2087 | + data = blk->data; |
| 2088 | + if (check_cal_bin_data(priv->dev, data, "r0_reg") < 0) |
| 2089 | + return; |
| 2090 | + p->r0_reg = TASDEVICE_REG(data[4], data[5], data[6]); |
| 2091 | + COPY_CAL_DATA(k); |
| 2092 | + |
| 2093 | + data = blk->data + 12; |
| 2094 | + if (check_cal_bin_data(priv->dev, data, "r0_low_reg") < 0) |
| 2095 | + return; |
| 2096 | + p->r0_low_reg = TASDEVICE_REG(data[4], data[5], data[6]); |
| 2097 | + COPY_CAL_DATA(k + 4); |
| 2098 | + |
| 2099 | + data = blk->data + 24; |
| 2100 | + if (check_cal_bin_data(priv->dev, data, "invr0_reg") < 0) |
| 2101 | + return; |
| 2102 | + p->invr0_reg = TASDEVICE_REG(data[4], data[5], data[6]); |
| 2103 | + COPY_CAL_DATA(k + 8); |
| 2104 | + |
| 2105 | + data = blk->data + 36; |
| 2106 | + if (check_cal_bin_data(priv->dev, data, "pow_reg") < 0) |
| 2107 | + return; |
| 2108 | + p->pow_reg = TASDEVICE_REG(data[4], data[5], data[6]); |
| 2109 | + COPY_CAL_DATA(k + 12); |
| 2110 | + |
| 2111 | + data = blk->data + 48; |
| 2112 | + if (check_cal_bin_data(priv->dev, data, "tlimit_reg") < 0) |
| 2113 | + return; |
| 2114 | + p->tlimit_reg = TASDEVICE_REG(data[4], data[5], data[6]); |
| 2115 | + COPY_CAL_DATA(k + 16); |
| 2116 | + |
| 2117 | + calbin_data[k] = chn; |
| 2118 | +} |
| 2119 | + |
2032 | 2120 | /* When calibrated data parsing error occurs, DSP can still work with default |
2033 | 2121 | * calibrated data, memory resource related to calibrated data will be |
2034 | 2122 | * released in the tasdevice_codec_remove. |
@@ -2086,6 +2174,7 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv, |
2086 | 2174 | goto out; |
2087 | 2175 | } |
2088 | 2176 |
|
| 2177 | + calbin_conversion(tas_priv, tas_fmw); |
2089 | 2178 | out: |
2090 | 2179 | return offset; |
2091 | 2180 | } |
@@ -2371,25 +2460,12 @@ static int tasdevice_load_data(struct tasdevice_priv *tas_priv, |
2371 | 2460 |
|
2372 | 2461 | static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i) |
2373 | 2462 | { |
2374 | | - struct tasdevice_fw *cal_fmw = priv->tasdevice[i].cali_data_fmw; |
2375 | 2463 | struct calidata *cali_data = &priv->cali_data; |
2376 | 2464 | struct cali_reg *p = &cali_data->cali_reg_array; |
2377 | 2465 | unsigned char *data = cali_data->data; |
2378 | | - struct tasdevice_calibration *cal; |
2379 | 2466 | int k = i * (cali_data->cali_dat_sz_per_dev + 1); |
2380 | 2467 | int rc; |
2381 | 2468 |
|
2382 | | - /* Load the calibrated data from cal bin file */ |
2383 | | - if (!priv->is_user_space_calidata && cal_fmw) { |
2384 | | - cal = cal_fmw->calibrations; |
2385 | | - |
2386 | | - if (cal) |
2387 | | - load_calib_data(priv, &cal->dev_data); |
2388 | | - return; |
2389 | | - } |
2390 | | - if (!priv->is_user_space_calidata) |
2391 | | - return; |
2392 | | - /* load calibrated data from user space */ |
2393 | 2469 | if (data[k] != i) { |
2394 | 2470 | dev_err(priv->dev, "%s: no cal-data for dev %d from usr-spc\n", |
2395 | 2471 | __func__, i); |
|
0 commit comments