1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // tas2781-fmwlib.c -- TASDEVICE firmware support
4 //
5 // Copyright 2023 - 2026 Texas Instruments, Inc.
6 //
7 // Author: Shenghao Ding <shenghao-ding@ti.com>
8 // Author: Baojun Xu <baojun.xu@ti.com>
9
10 #include <linux/crc8.h>
11 #include <linux/firmware.h>
12 #include <linux/i2c.h>
13 #include <linux/init.h>
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/of.h>
17 #include <linux/of_irq.h>
18 #include <linux/regmap.h>
19 #include <linux/slab.h>
20 #include <sound/pcm_params.h>
21 #include <sound/soc.h>
22 #include <sound/tlv.h>
23 #include <sound/tas2781.h>
24 #include <linux/unaligned.h>
25
26 #define ERROR_PRAM_CRCCHK 0x0000000
27 #define ERROR_YRAM_CRCCHK 0x0000001
28 #define PPC_DRIVER_CRCCHK 0x00000200
29
30 #define TAS2781_SA_COEFF_SWAP_REG TASDEVICE_REG(0, 0x35, 0x2c)
31 #define TAS2781_YRAM_BOOK1 140
32 #define TAS2781_YRAM1_PAGE 42
33 #define TAS2781_YRAM1_START_REG 88
34
35 #define TAS2781_PG_REG TASDEVICE_REG(0x00, 0x00, 0x7c)
36 #define TAS2781_PG_1_0 0xA0
37 #define TAS2781_PG_2_0 0xA8
38
39 #define TAS2781_YRAM2_START_PAGE 43
40 #define TAS2781_YRAM2_END_PAGE 49
41 #define TAS2781_YRAM2_START_REG 8
42 #define TAS2781_YRAM2_END_REG 127
43
44 #define TAS2781_YRAM3_PAGE 50
45 #define TAS2781_YRAM3_START_REG 8
46 #define TAS2781_YRAM3_END_REG 27
47
48 /*should not include B0_P53_R44-R47 */
49 #define TAS2781_YRAM_BOOK2 0
50 #define TAS2781_YRAM4_START_PAGE 50
51 #define TAS2781_YRAM4_END_PAGE 60
52
53 #define TAS2781_YRAM5_PAGE 61
54 #define TAS2781_YRAM5_START_REG TAS2781_YRAM3_START_REG
55 #define TAS2781_YRAM5_END_REG TAS2781_YRAM3_END_REG
56
57 #define TASDEVICE_CMD_SING_W 0x1
58 #define TASDEVICE_CMD_BURST 0x2
59 #define TASDEVICE_CMD_DELAY 0x3
60 #define TASDEVICE_CMD_FIELD_W 0x4
61
62 #define TASDEVICE_MAXPROGRAM_NUM_KERNEL 5
63 #define TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS 64
64 #define TASDEVICE_MAXCONFIG_NUM_KERNEL 10
65 #define MAIN_ALL_DEVICES_1X 0x01
66 #define MAIN_DEVICE_A_1X 0x02
67 #define MAIN_DEVICE_B_1X 0x03
68 #define MAIN_DEVICE_C_1X 0x04
69 #define MAIN_DEVICE_D_1X 0x05
70 #define COEFF_DEVICE_A_1X 0x12
71 #define COEFF_DEVICE_B_1X 0x13
72 #define COEFF_DEVICE_C_1X 0x14
73 #define COEFF_DEVICE_D_1X 0x15
74 #define PRE_DEVICE_A_1X 0x22
75 #define PRE_DEVICE_B_1X 0x23
76 #define PRE_DEVICE_C_1X 0x24
77 #define PRE_DEVICE_D_1X 0x25
78 #define PRE_SOFTWARE_RESET_DEVICE_A 0x41
79 #define PRE_SOFTWARE_RESET_DEVICE_B 0x42
80 #define PRE_SOFTWARE_RESET_DEVICE_C 0x43
81 #define PRE_SOFTWARE_RESET_DEVICE_D 0x44
82 #define POST_SOFTWARE_RESET_DEVICE_A 0x45
83 #define POST_SOFTWARE_RESET_DEVICE_B 0x46
84 #define POST_SOFTWARE_RESET_DEVICE_C 0x47
85 #define POST_SOFTWARE_RESET_DEVICE_D 0x48
86
87 #define COPY_CAL_DATA(i) \
88 do { \
89 calbin_data[i + 1] = data[7]; \
90 calbin_data[i + 2] = data[8]; \
91 calbin_data[i + 3] = data[9]; \
92 calbin_data[i + 4] = data[10]; \
93 } while (0)
94
95 struct tas_crc {
96 unsigned char offset;
97 unsigned char len;
98 };
99
100 struct blktyp_devidx_map {
101 unsigned char blktyp;
102 unsigned char dev_idx;
103 };
104
105 struct tas2781_cali_specific {
106 unsigned char sin_gni[4];
107 int sin_gni_reg;
108 bool is_sin_gn_flush;
109 };
110
111 static const char deviceNumber[TASDEVICE_DSP_TAS_MAX_DEVICE] = {
112 1, 2, 1, 2, 1, 1, 0, 2, 4, 3, 1, 2, 3, 4, 1, 2
113 };
114
115 /* fixed m68k compiling issue: mapping table can save code field */
116 static const struct blktyp_devidx_map ppc3_tas2781_mapping_table[] = {
117 { MAIN_ALL_DEVICES_1X, 0x80 },
118 { MAIN_DEVICE_A_1X, 0x81 },
119 { COEFF_DEVICE_A_1X, 0xC1 },
120 { PRE_DEVICE_A_1X, 0xC1 },
121 { PRE_SOFTWARE_RESET_DEVICE_A, 0xC1 },
122 { POST_SOFTWARE_RESET_DEVICE_A, 0xC1 },
123 { MAIN_DEVICE_B_1X, 0x82 },
124 { COEFF_DEVICE_B_1X, 0xC2 },
125 { PRE_DEVICE_B_1X, 0xC2 },
126 { PRE_SOFTWARE_RESET_DEVICE_B, 0xC2 },
127 { POST_SOFTWARE_RESET_DEVICE_B, 0xC2 },
128 { MAIN_DEVICE_C_1X, 0x83 },
129 { COEFF_DEVICE_C_1X, 0xC3 },
130 { PRE_DEVICE_C_1X, 0xC3 },
131 { PRE_SOFTWARE_RESET_DEVICE_C, 0xC3 },
132 { POST_SOFTWARE_RESET_DEVICE_C, 0xC3 },
133 { MAIN_DEVICE_D_1X, 0x84 },
134 { COEFF_DEVICE_D_1X, 0xC4 },
135 { PRE_DEVICE_D_1X, 0xC4 },
136 { PRE_SOFTWARE_RESET_DEVICE_D, 0xC4 },
137 { POST_SOFTWARE_RESET_DEVICE_D, 0xC4 },
138 };
139
140 static const struct blktyp_devidx_map ppc3_mapping_table[] = {
141 { MAIN_ALL_DEVICES_1X, 0x80 },
142 { MAIN_DEVICE_A_1X, 0x81 },
143 { COEFF_DEVICE_A_1X, 0xC1 },
144 { PRE_DEVICE_A_1X, 0xC1 },
145 { MAIN_DEVICE_B_1X, 0x82 },
146 { COEFF_DEVICE_B_1X, 0xC2 },
147 { PRE_DEVICE_B_1X, 0xC2 },
148 { MAIN_DEVICE_C_1X, 0x83 },
149 { COEFF_DEVICE_C_1X, 0xC3 },
150 { PRE_DEVICE_C_1X, 0xC3 },
151 { MAIN_DEVICE_D_1X, 0x84 },
152 { COEFF_DEVICE_D_1X, 0xC4 },
153 { PRE_DEVICE_D_1X, 0xC4 },
154 };
155
156 static const struct blktyp_devidx_map non_ppc3_mapping_table[] = {
157 { MAIN_ALL_DEVICES, 0x80 },
158 { MAIN_DEVICE_A, 0x81 },
159 { COEFF_DEVICE_A, 0xC1 },
160 { PRE_DEVICE_A, 0xC1 },
161 { MAIN_DEVICE_B, 0x82 },
162 { COEFF_DEVICE_B, 0xC2 },
163 { PRE_DEVICE_B, 0xC2 },
164 { MAIN_DEVICE_C, 0x83 },
165 { COEFF_DEVICE_C, 0xC3 },
166 { PRE_DEVICE_C, 0xC3 },
167 { MAIN_DEVICE_D, 0x84 },
168 { COEFF_DEVICE_D, 0xC4 },
169 { PRE_DEVICE_D, 0xC4 },
170 };
171
tasdevice_add_config(struct tasdevice_priv * tas_priv,unsigned char * config_data,unsigned int config_size,int * status)172 static struct tasdevice_config_info *tasdevice_add_config(
173 struct tasdevice_priv *tas_priv, unsigned char *config_data,
174 unsigned int config_size, int *status)
175 {
176 struct tasdevice_config_info *cfg_info;
177 struct tasdev_blk_data **bk_da;
178 unsigned int config_offset = 0;
179 unsigned int i;
180
181 /* In most projects are many audio cases, such as music, handfree,
182 * receiver, games, audio-to-haptics, PMIC record, bypass mode,
183 * portrait, landscape, etc. Even in multiple audios, one or
184 * two of the chips will work for the special case, such as
185 * ultrasonic application. In order to support these variable-numbers
186 * of audio cases, flexible configs have been introduced in the
187 * dsp firmware.
188 */
189 cfg_info = kzalloc_obj(struct tasdevice_config_info);
190 if (!cfg_info) {
191 *status = -ENOMEM;
192 goto out;
193 }
194
195 if (tas_priv->rcabin.fw_hdr.binary_version_num >= 0x105) {
196 if (config_offset + 64 > (int)config_size) {
197 *status = -EINVAL;
198 dev_err(tas_priv->dev, "add conf: Out of boundary\n");
199 goto out;
200 }
201 /* If in the RCA bin file are several profiles with the
202 * keyword "init", init_profile_id only store the last
203 * init profile id.
204 */
205 if (strnstr(&config_data[config_offset], "init", 64)) {
206 tas_priv->rcabin.init_profile_id =
207 tas_priv->rcabin.ncfgs - 1;
208 dev_dbg(tas_priv->dev, "%s: init profile id = %d\n",
209 __func__, tas_priv->rcabin.init_profile_id);
210 }
211 config_offset += 64;
212 }
213
214 if (config_offset + 4 > (int)config_size) {
215 *status = -EINVAL;
216 dev_err(tas_priv->dev, "add config: Out of boundary\n");
217 goto out;
218 }
219
220 /* convert data[offset], data[offset + 1], data[offset + 2] and
221 * data[offset + 3] into host
222 */
223 cfg_info->nblocks = get_unaligned_be32(&config_data[config_offset]);
224 config_offset += 4;
225
226 /* Several kinds of dsp/algorithm firmwares can run on tas2781,
227 * the number and size of blk are not fixed and different among
228 * these firmwares.
229 */
230 bk_da = cfg_info->blk_data = kzalloc_objs(struct tasdev_blk_data *,
231 cfg_info->nblocks);
232 if (!bk_da) {
233 *status = -ENOMEM;
234 goto out;
235 }
236 cfg_info->real_nblocks = 0;
237 for (i = 0; i < cfg_info->nblocks; i++) {
238 if (config_offset + 12 > config_size) {
239 *status = -EINVAL;
240 dev_err(tas_priv->dev,
241 "%s: Out of boundary: i = %d nblocks = %u!\n",
242 __func__, i, cfg_info->nblocks);
243 break;
244 }
245 bk_da[i] = kzalloc_obj(struct tasdev_blk_data);
246 if (!bk_da[i]) {
247 *status = -ENOMEM;
248 break;
249 }
250
251 bk_da[i]->dev_idx = config_data[config_offset];
252 config_offset++;
253
254 bk_da[i]->block_type = config_data[config_offset];
255 config_offset++;
256
257 if (bk_da[i]->block_type == TASDEVICE_BIN_BLK_PRE_POWER_UP) {
258 if (bk_da[i]->dev_idx == 0)
259 cfg_info->active_dev =
260 (1 << tas_priv->ndev) - 1;
261 else
262 cfg_info->active_dev |= 1 <<
263 (bk_da[i]->dev_idx - 1);
264
265 }
266 bk_da[i]->yram_checksum =
267 get_unaligned_be16(&config_data[config_offset]);
268 config_offset += 2;
269 bk_da[i]->block_size =
270 get_unaligned_be32(&config_data[config_offset]);
271 config_offset += 4;
272
273 bk_da[i]->n_subblks =
274 get_unaligned_be32(&config_data[config_offset]);
275
276 config_offset += 4;
277
278 if (config_offset + bk_da[i]->block_size > config_size) {
279 *status = -EINVAL;
280 dev_err(tas_priv->dev,
281 "%s: Out of boundary: i = %d blks = %u!\n",
282 __func__, i, cfg_info->nblocks);
283 break;
284 }
285 /* instead of kzalloc+memcpy */
286 bk_da[i]->regdata = kmemdup(&config_data[config_offset],
287 bk_da[i]->block_size, GFP_KERNEL);
288 if (!bk_da[i]->regdata) {
289 *status = -ENOMEM;
290 goto out;
291 }
292
293 config_offset += bk_da[i]->block_size;
294 cfg_info->real_nblocks += 1;
295 }
296
297 out:
298 return cfg_info;
299 }
300
tasdevice_rca_parser(void * context,const struct firmware * fmw)301 int tasdevice_rca_parser(void *context, const struct firmware *fmw)
302 {
303 struct tasdevice_priv *tas_priv = context;
304 struct tasdevice_config_info **cfg_info;
305 struct tasdevice_rca_hdr *fw_hdr;
306 struct tasdevice_rca *rca;
307 unsigned int total_config_sz = 0;
308 unsigned char *buf;
309 int offset = 0;
310 int ret = 0;
311 int i;
312
313 rca = &(tas_priv->rcabin);
314 /* Initialize to none */
315 rca->init_profile_id = -1;
316 fw_hdr = &(rca->fw_hdr);
317 if (!fmw || !fmw->data) {
318 dev_err(tas_priv->dev, "Failed to read %s\n",
319 tas_priv->rca_binaryname);
320 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
321 ret = -EINVAL;
322 goto out;
323 }
324 buf = (unsigned char *)fmw->data;
325
326 fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
327 offset += 4;
328 if (fw_hdr->img_sz != fmw->size) {
329 dev_err(tas_priv->dev,
330 "File size not match, %d %u", (int)fmw->size,
331 fw_hdr->img_sz);
332 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
333 ret = -EINVAL;
334 goto out;
335 }
336
337 fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
338 offset += 4;
339 fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
340 if (fw_hdr->binary_version_num < 0x103) {
341 dev_err(tas_priv->dev, "File version 0x%04x is too low",
342 fw_hdr->binary_version_num);
343 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
344 ret = -EINVAL;
345 goto out;
346 }
347 offset += 4;
348 fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
349 offset += 8;
350 fw_hdr->plat_type = buf[offset];
351 offset += 1;
352 fw_hdr->dev_family = buf[offset];
353 offset += 1;
354 fw_hdr->reserve = buf[offset];
355 offset += 1;
356 fw_hdr->ndev = buf[offset];
357 offset += 1;
358 if (fw_hdr->ndev != tas_priv->ndev) {
359 dev_err(tas_priv->dev,
360 "ndev(%u) in rcabin mismatch ndev(%u) in DTS\n",
361 fw_hdr->ndev, tas_priv->ndev);
362 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
363 ret = -EINVAL;
364 goto out;
365 }
366 if (offset + TASDEVICE_DEVICE_SUM > fw_hdr->img_sz) {
367 dev_err(tas_priv->dev, "rca_ready: Out of boundary!\n");
368 ret = -EINVAL;
369 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
370 goto out;
371 }
372
373 for (i = 0; i < TASDEVICE_DEVICE_SUM; i++, offset++)
374 fw_hdr->devs[i] = buf[offset];
375
376 fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
377 offset += 4;
378
379 for (i = 0; i < TASDEVICE_CONFIG_SUM; i++) {
380 fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
381 offset += 4;
382 total_config_sz += fw_hdr->config_size[i];
383 }
384
385 if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
386 dev_err(tas_priv->dev, "Bin file error!\n");
387 ret = -EINVAL;
388 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
389 goto out;
390 }
391
392 cfg_info = kzalloc_objs(*cfg_info, fw_hdr->nconfig);
393 if (!cfg_info) {
394 ret = -ENOMEM;
395 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
396 goto out;
397 }
398 rca->cfg_info = cfg_info;
399 rca->ncfgs = 0;
400 for (i = 0; i < (int)fw_hdr->nconfig; i++) {
401 rca->ncfgs += 1;
402 cfg_info[i] = tasdevice_add_config(tas_priv, &buf[offset],
403 fw_hdr->config_size[i], &ret);
404 if (ret) {
405 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
406 goto out;
407 }
408 offset += (int)fw_hdr->config_size[i];
409 }
410 out:
411 return ret;
412 }
413 EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, "SND_SOC_TAS2781_FMWLIB");
414
415 /* fixed m68k compiling issue: mapping table can save code field */
map_dev_idx(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block)416 static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw,
417 struct tasdev_blk *block)
418 {
419
420 struct blktyp_devidx_map *p =
421 (struct blktyp_devidx_map *)non_ppc3_mapping_table;
422 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
423 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr);
424
425 int i, n = ARRAY_SIZE(non_ppc3_mapping_table);
426 unsigned char dev_idx = 0;
427
428 if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN) {
429 p = (struct blktyp_devidx_map *)ppc3_tas2781_mapping_table;
430 n = ARRAY_SIZE(ppc3_tas2781_mapping_table);
431 } else if (fw_fixed_hdr->ppcver >= PPC3_VERSION_BASE) {
432 p = (struct blktyp_devidx_map *)ppc3_mapping_table;
433 n = ARRAY_SIZE(ppc3_mapping_table);
434 }
435
436 for (i = 0; i < n; i++) {
437 if (block->type == p[i].blktyp) {
438 dev_idx = p[i].dev_idx;
439 break;
440 }
441 }
442
443 return dev_idx;
444 }
445
fw_parse_block_data_kernel(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block,const struct firmware * fmw,int offset)446 static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw,
447 struct tasdev_blk *block, const struct firmware *fmw, int offset)
448 {
449 const unsigned char *data = fmw->data;
450
451 if (offset + 16 > fmw->size) {
452 dev_err(tas_fmw->dev, "%s: File Size error\n", __func__);
453 offset = -EINVAL;
454 goto out;
455 }
456
457 /* convert data[offset], data[offset + 1], data[offset + 2] and
458 * data[offset + 3] into host
459 */
460 block->type = get_unaligned_be32(&data[offset]);
461 offset += 4;
462
463 block->is_pchksum_present = data[offset];
464 offset++;
465
466 block->pchksum = data[offset];
467 offset++;
468
469 block->is_ychksum_present = data[offset];
470 offset++;
471
472 block->ychksum = data[offset];
473 offset++;
474
475 block->blk_size = get_unaligned_be32(&data[offset]);
476 offset += 4;
477
478 block->nr_subblocks = get_unaligned_be32(&data[offset]);
479 offset += 4;
480
481 /* fixed m68k compiling issue:
482 * 1. mapping table can save code field.
483 * 2. storing the dev_idx as a member of block can reduce unnecessary
484 * time and system resource comsumption of dev_idx mapping every
485 * time the block data writing to the dsp.
486 */
487 block->dev_idx = map_dev_idx(tas_fmw, block);
488
489 if (offset + block->blk_size > fmw->size) {
490 dev_err(tas_fmw->dev, "%s: nSublocks error\n", __func__);
491 offset = -EINVAL;
492 goto out;
493 }
494 /* instead of kzalloc+memcpy */
495 block->data = kmemdup(&data[offset], block->blk_size, GFP_KERNEL);
496 if (!block->data) {
497 offset = -ENOMEM;
498 goto out;
499 }
500 offset += block->blk_size;
501
502 out:
503 return offset;
504 }
505
fw_parse_data_kernel(struct tasdevice_fw * tas_fmw,struct tasdevice_data * img_data,const struct firmware * fmw,int offset)506 static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw,
507 struct tasdevice_data *img_data, const struct firmware *fmw,
508 int offset)
509 {
510 const unsigned char *data = fmw->data;
511 struct tasdev_blk *blk;
512 unsigned int i;
513
514 if (offset + 4 > fmw->size) {
515 dev_err(tas_fmw->dev, "%s: File Size error\n", __func__);
516 offset = -EINVAL;
517 goto out;
518 }
519 img_data->nr_blk = get_unaligned_be32(&data[offset]);
520 offset += 4;
521
522 img_data->dev_blks = kzalloc_objs(struct tasdev_blk, img_data->nr_blk);
523 if (!img_data->dev_blks) {
524 offset = -ENOMEM;
525 goto out;
526 }
527
528 for (i = 0; i < img_data->nr_blk; i++) {
529 blk = &(img_data->dev_blks[i]);
530 offset = fw_parse_block_data_kernel(tas_fmw, blk, fmw, offset);
531 if (offset < 0) {
532 offset = -EINVAL;
533 break;
534 }
535 }
536
537 out:
538 return offset;
539 }
540
fw_parse_tas5825_program_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)541 static int fw_parse_tas5825_program_data_kernel(
542 struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw,
543 const struct firmware *fmw, int offset)
544 {
545 struct tasdevice_prog *program;
546 unsigned int i;
547
548 for (i = 0; i < tas_fmw->nr_programs; i++) {
549 program = &(tas_fmw->programs[i]);
550 if (offset + 72 > fmw->size) {
551 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
552 return -EINVAL;
553 }
554 /* Skip 65 unused byts*/
555 offset += 65;
556 offset = fw_parse_data_kernel(tas_fmw, &(program->dev_data),
557 fmw, offset);
558 if (offset < 0)
559 return offset;
560 }
561
562 return offset;
563 }
564
fw_parse_tas5825_configuration_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)565 static int fw_parse_tas5825_configuration_data_kernel(
566 struct tasdevice_priv *tas_priv,
567 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
568 {
569 const unsigned char *data = fmw->data;
570 struct tasdevice_config *config;
571 unsigned int i;
572
573 for (i = 0; i < tas_fmw->nr_configurations; i++) {
574 config = &(tas_fmw->configs[i]);
575 if (offset + 80 > fmw->size) {
576 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
577 return -EINVAL;
578 }
579 memcpy(config->name, &data[offset], 64);
580 /* Skip extra 8 bytes*/
581 offset += 72;
582 offset = fw_parse_data_kernel(tas_fmw, &(config->dev_data),
583 fmw, offset);
584 if (offset < 0)
585 return offset;
586 }
587
588 return offset;
589 }
590
fw_parse_program_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)591 static int fw_parse_program_data_kernel(
592 struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw,
593 const struct firmware *fmw, int offset)
594 {
595 struct tasdevice_prog *program;
596 unsigned int i;
597
598 for (i = 0; i < tas_fmw->nr_programs; i++) {
599 program = &(tas_fmw->programs[i]);
600 if (offset + 72 > fmw->size) {
601 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
602 offset = -EINVAL;
603 goto out;
604 }
605 /*skip 72 unused byts*/
606 offset += 72;
607
608 offset = fw_parse_data_kernel(tas_fmw, &(program->dev_data),
609 fmw, offset);
610 if (offset < 0)
611 goto out;
612 }
613
614 out:
615 return offset;
616 }
617
fw_parse_configuration_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)618 static int fw_parse_configuration_data_kernel(
619 struct tasdevice_priv *tas_priv,
620 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
621 {
622 const unsigned char *data = fmw->data;
623 struct tasdevice_config *config;
624 unsigned int i;
625
626 for (i = 0; i < tas_fmw->nr_configurations; i++) {
627 config = &(tas_fmw->configs[i]);
628 if (offset + 80 > fmw->size) {
629 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
630 offset = -EINVAL;
631 goto out;
632 }
633 memcpy(config->name, &data[offset], 64);
634 /*skip extra 16 bytes*/
635 offset += 80;
636
637 offset = fw_parse_data_kernel(tas_fmw, &(config->dev_data),
638 fmw, offset);
639 if (offset < 0)
640 goto out;
641 }
642
643 out:
644 return offset;
645 }
646
fct_param_address_parser(struct cali_reg * r,struct tasdevice_fw * tas_fmw,const unsigned char * data)647 static void fct_param_address_parser(struct cali_reg *r,
648 struct tasdevice_fw *tas_fmw, const unsigned char *data)
649 {
650 struct fct_param_address *p = &tas_fmw->fct_par_addr;
651 unsigned int i;
652
653 /*
654 * Calibration parameters locations and data schema in dsp firmware.
655 * The number of items are flexible, but not more than 20. The dsp tool
656 * will reseve 20*24-byte space for fct params. In some cases, the
657 * number of fct param is less than 20, the data will be saved from the
658 * beginning, the rest part will be stuffed with zero.
659 *
660 * fct_param_num (not more than 20)
661 * for (i = 0; i < fct_param_num; i++) {
662 * Alias of fct param (20 bytes)
663 * Book (1 byte)
664 * Page (1 byte)
665 * Offset (1 byte)
666 * CoeffLength (1 byte) = 0x1
667 * }
668 * if (20 - fct_param_num)
669 * 24*(20 - fct_param_num) pieces of '0' as stuffing
670 *
671 * As follow:
672 * umg_SsmKEGCye = Book, Page, Offset, CoeffLength
673 * iks_E0 = Book, Page, Offset, CoeffLength
674 * yep_LsqM0 = Book, Page, Offset, CoeffLength
675 * oyz_U0_ujx = Book, Page, Offset, CoeffLength
676 * iks_GC_GMgq = Book, Page, Offset, CoeffLength
677 * gou_Yao = Book, Page, Offset, CoeffLength
678 * kgd_Wsc_Qsbp = Book, Page, Offset, CoeffLength
679 * yec_CqseSsqs = Book, Page, Offset, CoeffLength
680 * iks_SogkGgog2 = Book, Page, Offset, CoeffLength
681 * yec_Sae_Y = Book, Page, Offset, CoeffLength
682 * Re_Int = Book, Page, Offset, CoeffLength
683 * SigFlag = Book, Page, Offset, CoeffLength
684 * a1_Int = Book, Page, Offset, CoeffLength
685 * a2_Int = Book, Page, Offset, CoeffLength
686 */
687 for (i = 0; i < 20; i++) {
688 const unsigned char *dat = &data[24 * i];
689
690 /*
691 * check whether current fct param is empty.
692 */
693 if (dat[23] != 1)
694 break;
695
696 if (!strncmp(dat, "umg_SsmKEGCye", 20))
697 r->pow_reg = TASDEVICE_REG(dat[20], dat[21], dat[22]);
698 /* high 32-bit of real-time spk impedance */
699 else if (!strncmp(dat, "iks_E0", 20))
700 r->r0_reg = TASDEVICE_REG(dat[20], dat[21], dat[22]);
701 /* inverse of real-time spk impedance */
702 else if (!strncmp(dat, "yep_LsqM0", 20))
703 r->invr0_reg =
704 TASDEVICE_REG(dat[20], dat[21], dat[22]);
705 /* low 32-bit of real-time spk impedance */
706 else if (!strncmp(dat, "oyz_U0_ujx", 20))
707 r->r0_low_reg =
708 TASDEVICE_REG(dat[20], dat[21], dat[22]);
709 /* Delta Thermal Limit */
710 else if (!strncmp(dat, "iks_GC_GMgq", 20))
711 r->tlimit_reg =
712 TASDEVICE_REG(dat[20], dat[21], dat[22]);
713 /* Thermal data for PG 1.0 device */
714 else if (!strncmp(dat, "gou_Yao", 20))
715 memcpy(p->thr, &dat[20], 3);
716 /* Pilot tone enable flag, usually the sine wave */
717 else if (!strncmp(dat, "kgd_Wsc_Qsbp", 20))
718 memcpy(p->plt_flg, &dat[20], 3);
719 /* Pilot tone gain for calibration */
720 else if (!strncmp(dat, "yec_CqseSsqs", 20))
721 memcpy(p->sin_gn, &dat[20], 3);
722 /* Pilot tone gain for calibration, useless in PG 2.0 */
723 else if (!strncmp(dat, "iks_SogkGgog2", 20))
724 memcpy(p->sin_gn2, &dat[20], 3);
725 /* Thermal data for PG 2.0 device */
726 else if (!strncmp(dat, "yec_Sae_Y", 20))
727 memcpy(p->thr2, &dat[20], 3);
728 /* Spk Equivalent Resistance in fixed-point format */
729 else if (!strncmp(dat, "Re_Int", 20))
730 memcpy(p->r0_reg, &dat[20], 3);
731 /* Check whether the spk connection is open */
732 else if (!strncmp(dat, "SigFlag", 20))
733 memcpy(p->tf_reg, &dat[20], 3);
734 /* check spk resonant frequency */
735 else if (!strncmp(dat, "a1_Int", 20))
736 memcpy(p->a1_reg, &dat[20], 3);
737 /* check spk resonant frequency */
738 else if (!strncmp(dat, "a2_Int", 20))
739 memcpy(p->a2_reg, &dat[20], 3);
740 }
741 }
742
fw_parse_fct_param_address(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)743 static int fw_parse_fct_param_address(struct tasdevice_priv *tas_priv,
744 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
745 {
746 struct calidata *cali_data = &tas_priv->cali_data;
747 struct cali_reg *r = &cali_data->cali_reg_array;
748 const unsigned char *data = fmw->data;
749
750 if (offset + 520 > fmw->size) {
751 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
752 return -EINVAL;
753 }
754
755 /* skip reserved part */
756 offset += 40;
757
758 fct_param_address_parser(r, tas_fmw, &data[offset]);
759
760 offset += 480;
761
762 return offset;
763 }
764
fw_parse_variable_header_kernel(struct tasdevice_priv * tas_priv,const struct firmware * fmw,int offset)765 static int fw_parse_variable_header_kernel(
766 struct tasdevice_priv *tas_priv, const struct firmware *fmw,
767 int offset)
768 {
769 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
770 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
771 struct tasdevice_prog *program;
772 struct tasdevice_config *config;
773 const unsigned char *buf = fmw->data;
774 unsigned short max_confs;
775 unsigned int i;
776
777 if (offset + 12 + 4 * TASDEVICE_MAXPROGRAM_NUM_KERNEL > fmw->size) {
778 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
779 offset = -EINVAL;
780 goto out;
781 }
782 fw_hdr->device_family = get_unaligned_be16(&buf[offset]);
783 if (fw_hdr->device_family != 0) {
784 dev_err(tas_priv->dev, "%s:not TAS device\n", __func__);
785 offset = -EINVAL;
786 goto out;
787 }
788 offset += 2;
789 fw_hdr->device = get_unaligned_be16(&buf[offset]);
790 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
791 fw_hdr->device == 6) {
792 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
793 offset = -EINVAL;
794 goto out;
795 }
796 offset += 2;
797 fw_hdr->ndev = deviceNumber[fw_hdr->device];
798
799 if (fw_hdr->ndev != tas_priv->ndev) {
800 dev_err(tas_priv->dev,
801 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n",
802 __func__, fw_hdr->ndev, tas_priv->ndev);
803 offset = -EINVAL;
804 goto out;
805 }
806
807 tas_fmw->nr_programs = get_unaligned_be32(&buf[offset]);
808 offset += 4;
809
810 if (tas_fmw->nr_programs == 0 || tas_fmw->nr_programs >
811 TASDEVICE_MAXPROGRAM_NUM_KERNEL) {
812 dev_err(tas_priv->dev, "mnPrograms is invalid\n");
813 offset = -EINVAL;
814 goto out;
815 }
816
817 tas_fmw->programs = kzalloc_objs(struct tasdevice_prog,
818 tas_fmw->nr_programs);
819 if (!tas_fmw->programs) {
820 offset = -ENOMEM;
821 goto out;
822 }
823
824 for (i = 0; i < tas_fmw->nr_programs; i++) {
825 program = &(tas_fmw->programs[i]);
826 program->prog_size = get_unaligned_be32(&buf[offset]);
827 offset += 4;
828 }
829
830 /* Skip the unused prog_size */
831 offset += 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs);
832
833 tas_fmw->nr_configurations = get_unaligned_be32(&buf[offset]);
834 offset += 4;
835
836 /* The max number of config in firmware greater than 4 pieces of
837 * tas2781s is different from the one lower than 4 pieces of
838 * tas2781s.
839 */
840 max_confs = (fw_hdr->ndev >= 4) ?
841 TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS :
842 TASDEVICE_MAXCONFIG_NUM_KERNEL;
843 if (tas_fmw->nr_configurations == 0 ||
844 tas_fmw->nr_configurations > max_confs) {
845 dev_err(tas_priv->dev, "%s: Conf is invalid\n", __func__);
846 offset = -EINVAL;
847 goto out;
848 }
849
850 if (offset + 4 * max_confs > fmw->size) {
851 dev_err(tas_priv->dev, "%s: mpConfigurations err\n", __func__);
852 offset = -EINVAL;
853 goto out;
854 }
855
856 tas_fmw->configs = kzalloc_objs(struct tasdevice_config,
857 tas_fmw->nr_configurations);
858 if (!tas_fmw->configs) {
859 offset = -ENOMEM;
860 goto out;
861 }
862
863 for (i = 0; i < tas_fmw->nr_programs; i++) {
864 config = &(tas_fmw->configs[i]);
865 config->cfg_size = get_unaligned_be32(&buf[offset]);
866 offset += 4;
867 }
868
869 /* Skip the unused configs */
870 offset += 4 * (max_confs - tas_fmw->nr_programs);
871
872 out:
873 return offset;
874 }
875
tasdevice_process_block(void * context,unsigned char * data,unsigned char dev_idx,int sublocksize)876 static int tasdevice_process_block(void *context, unsigned char *data,
877 unsigned char dev_idx, int sublocksize)
878 {
879 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context;
880 int subblk_offset, chn, chnend, rc;
881 unsigned char subblk_typ = data[1];
882 int blktyp = dev_idx & 0xC0;
883 int idx = dev_idx & 0x3F;
884 bool is_err = false;
885
886 if (idx) {
887 chn = idx - 1;
888 chnend = idx;
889 } else {
890 if (tas_priv->isspi) {
891 chn = tas_priv->index;
892 chnend = chn + 1;
893 } else {
894 chn = 0;
895 chnend = tas_priv->ndev;
896 }
897 }
898
899 for (; chn < chnend; chn++) {
900 if (tas_priv->tasdevice[chn].is_loading == false)
901 continue;
902
903 is_err = false;
904 subblk_offset = 2;
905 switch (subblk_typ) {
906 case TASDEVICE_CMD_SING_W: {
907 int i;
908 unsigned short len = get_unaligned_be16(&data[2]);
909
910 subblk_offset += 2;
911 if (subblk_offset + 4 * len > sublocksize) {
912 dev_err(tas_priv->dev,
913 "process_block: Out of boundary\n");
914 is_err = true;
915 break;
916 }
917
918 for (i = 0; i < len; i++) {
919 rc = tasdevice_dev_write(tas_priv, chn,
920 TASDEVICE_REG(data[subblk_offset],
921 data[subblk_offset + 1],
922 data[subblk_offset + 2]),
923 data[subblk_offset + 3]);
924 if (rc < 0) {
925 is_err = true;
926 dev_err(tas_priv->dev,
927 "process_block: single write error\n");
928 }
929 subblk_offset += 4;
930 }
931 }
932 break;
933 case TASDEVICE_CMD_BURST: {
934 unsigned short len = get_unaligned_be16(&data[2]);
935
936 subblk_offset += 2;
937 if (subblk_offset + 4 + len > sublocksize) {
938 dev_err(tas_priv->dev,
939 "%s: BST Out of boundary\n",
940 __func__);
941 is_err = true;
942 break;
943 }
944 if (len % 4) {
945 dev_err(tas_priv->dev,
946 "%s:Bst-len(%u)not div by 4\n",
947 __func__, len);
948 break;
949 }
950
951 rc = tasdevice_dev_bulk_write(tas_priv, chn,
952 TASDEVICE_REG(data[subblk_offset],
953 data[subblk_offset + 1],
954 data[subblk_offset + 2]),
955 &(data[subblk_offset + 4]), len);
956 if (rc < 0) {
957 is_err = true;
958 dev_err(tas_priv->dev,
959 "%s: bulk_write error = %d\n",
960 __func__, rc);
961 }
962 subblk_offset += (len + 4);
963 }
964 break;
965 case TASDEVICE_CMD_DELAY: {
966 unsigned int sleep_time = 0;
967
968 if (subblk_offset + 2 > sublocksize) {
969 dev_err(tas_priv->dev,
970 "%s: delay Out of boundary\n",
971 __func__);
972 is_err = true;
973 break;
974 }
975 sleep_time = get_unaligned_be16(&data[2]) * 1000;
976 usleep_range(sleep_time, sleep_time + 50);
977 subblk_offset += 2;
978 }
979 break;
980 case TASDEVICE_CMD_FIELD_W:
981 if (subblk_offset + 6 > sublocksize) {
982 dev_err(tas_priv->dev,
983 "%s: bit write Out of boundary\n",
984 __func__);
985 is_err = true;
986 break;
987 }
988 rc = tas_priv->update_bits(tas_priv, chn,
989 TASDEVICE_REG(data[subblk_offset + 2],
990 data[subblk_offset + 3],
991 data[subblk_offset + 4]),
992 data[subblk_offset + 1],
993 data[subblk_offset + 5]);
994 if (rc < 0) {
995 is_err = true;
996 dev_err(tas_priv->dev,
997 "%s: update_bits error = %d\n",
998 __func__, rc);
999 }
1000 subblk_offset += 6;
1001 break;
1002 default:
1003 break;
1004 }
1005 if (is_err == true && blktyp != 0) {
1006 if (blktyp == 0x80) {
1007 tas_priv->tasdevice[chn].cur_prog = -1;
1008 tas_priv->tasdevice[chn].cur_conf = -1;
1009 } else
1010 tas_priv->tasdevice[chn].cur_conf = -1;
1011 }
1012 }
1013
1014 return subblk_offset;
1015 }
1016
tasdevice_select_cfg_blk(void * pContext,int conf_no,unsigned char block_type)1017 void tasdevice_select_cfg_blk(void *pContext, int conf_no,
1018 unsigned char block_type)
1019 {
1020 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) pContext;
1021 struct tasdevice_rca *rca = &(tas_priv->rcabin);
1022 struct tasdevice_config_info **cfg_info = rca->cfg_info;
1023 struct tasdev_blk_data **blk_data;
1024 int j, k, chn, chnend;
1025
1026 if (conf_no >= rca->ncfgs || conf_no < 0 || !cfg_info) {
1027 dev_err(tas_priv->dev, "conf_no should be not more than %u\n",
1028 rca->ncfgs);
1029 return;
1030 }
1031 blk_data = cfg_info[conf_no]->blk_data;
1032
1033 for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) {
1034 unsigned int length = 0, rc = 0;
1035
1036 if (block_type > 5 || block_type < 2) {
1037 dev_err(tas_priv->dev,
1038 "block_type should be in range from 2 to 5\n");
1039 break;
1040 }
1041 if (block_type != blk_data[j]->block_type)
1042 continue;
1043
1044 for (k = 0; k < (int)blk_data[j]->n_subblks; k++) {
1045 if (blk_data[j]->dev_idx) {
1046 chn = blk_data[j]->dev_idx - 1;
1047 chnend = blk_data[j]->dev_idx;
1048 } else {
1049 chn = 0;
1050 chnend = tas_priv->ndev;
1051 }
1052 for (; chn < chnend; chn++)
1053 tas_priv->tasdevice[chn].is_loading = true;
1054
1055 rc = tasdevice_process_block(tas_priv,
1056 blk_data[j]->regdata + length,
1057 blk_data[j]->dev_idx,
1058 blk_data[j]->block_size - length);
1059 length += rc;
1060 if (blk_data[j]->block_size < length) {
1061 dev_err(tas_priv->dev,
1062 "%s: %u %u out of boundary\n",
1063 __func__, length,
1064 blk_data[j]->block_size);
1065 break;
1066 }
1067 }
1068 if (length != blk_data[j]->block_size)
1069 dev_err(tas_priv->dev, "%s: %u %u size is not same\n",
1070 __func__, length, blk_data[j]->block_size);
1071 }
1072 }
1073 EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, "SND_SOC_TAS2781_FMWLIB");
1074
tasdevice_load_block_kernel(struct tasdevice_priv * tasdevice,struct tasdev_blk * block)1075 static int tasdevice_load_block_kernel(
1076 struct tasdevice_priv *tasdevice, struct tasdev_blk *block)
1077 {
1078 const unsigned int blk_size = block->blk_size;
1079 unsigned int i, length;
1080 unsigned char *data = block->data;
1081
1082 for (i = 0, length = 0; i < block->nr_subblocks; i++) {
1083 int rc = tasdevice_process_block(tasdevice, data + length,
1084 block->dev_idx, blk_size - length);
1085 if (rc < 0) {
1086 dev_err(tasdevice->dev,
1087 "%s: %u %u sublock write error\n",
1088 __func__, length, blk_size);
1089 break;
1090 }
1091 length += (unsigned int)rc;
1092 if (blk_size < length) {
1093 dev_err(tasdevice->dev, "%s: %u %u out of boundary\n",
1094 __func__, length, blk_size);
1095 break;
1096 }
1097 }
1098
1099 return 0;
1100 }
1101
fw_parse_variable_hdr(struct tasdevice_priv * tas_priv,struct tasdevice_dspfw_hdr * fw_hdr,const struct firmware * fmw,int offset)1102 static int fw_parse_variable_hdr(struct tasdevice_priv
1103 *tas_priv, struct tasdevice_dspfw_hdr *fw_hdr,
1104 const struct firmware *fmw, int offset)
1105 {
1106 const unsigned char *buf = fmw->data;
1107 int len = strlen((char *)&buf[offset]);
1108
1109 len++;
1110
1111 if (offset + len + 8 > fmw->size) {
1112 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1113 offset = -EINVAL;
1114 goto out;
1115 }
1116
1117 offset += len;
1118
1119 fw_hdr->device_family = get_unaligned_be32(&buf[offset]);
1120 if (fw_hdr->device_family != 0) {
1121 dev_err(tas_priv->dev, "%s: not TAS device\n", __func__);
1122 offset = -EINVAL;
1123 goto out;
1124 }
1125 offset += 4;
1126
1127 fw_hdr->device = get_unaligned_be32(&buf[offset]);
1128 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
1129 fw_hdr->device == 6) {
1130 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
1131 offset = -EINVAL;
1132 goto out;
1133 }
1134 offset += 4;
1135 fw_hdr->ndev = deviceNumber[fw_hdr->device];
1136
1137 out:
1138 return offset;
1139 }
1140
fw_parse_variable_header_git(struct tasdevice_priv * tas_priv,const struct firmware * fmw,int offset)1141 static int fw_parse_variable_header_git(struct tasdevice_priv
1142 *tas_priv, const struct firmware *fmw, int offset)
1143 {
1144 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
1145 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
1146
1147 offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset);
1148 if (offset < 0)
1149 goto out;
1150 if (fw_hdr->ndev != tas_priv->ndev) {
1151 dev_err(tas_priv->dev,
1152 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n",
1153 __func__, fw_hdr->ndev, tas_priv->ndev);
1154 offset = -EINVAL;
1155 }
1156
1157 out:
1158 return offset;
1159 }
1160
fw_parse_block_data(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block,const struct firmware * fmw,int offset)1161 static int fw_parse_block_data(struct tasdevice_fw *tas_fmw,
1162 struct tasdev_blk *block, const struct firmware *fmw, int offset)
1163 {
1164 unsigned char *data = (unsigned char *)fmw->data;
1165 int n;
1166
1167 if (offset + 8 > fmw->size) {
1168 dev_err(tas_fmw->dev, "%s: Type error\n", __func__);
1169 offset = -EINVAL;
1170 goto out;
1171 }
1172 block->type = get_unaligned_be32(&data[offset]);
1173 offset += 4;
1174
1175 if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) {
1176 if (offset + 8 > fmw->size) {
1177 dev_err(tas_fmw->dev, "PChkSumPresent error\n");
1178 offset = -EINVAL;
1179 goto out;
1180 }
1181 block->is_pchksum_present = data[offset];
1182 offset++;
1183
1184 block->pchksum = data[offset];
1185 offset++;
1186
1187 block->is_ychksum_present = data[offset];
1188 offset++;
1189
1190 block->ychksum = data[offset];
1191 offset++;
1192 } else {
1193 block->is_pchksum_present = 0;
1194 block->is_ychksum_present = 0;
1195 }
1196
1197 block->nr_cmds = get_unaligned_be32(&data[offset]);
1198 offset += 4;
1199
1200 n = block->nr_cmds * 4;
1201 if (offset + n > fmw->size) {
1202 dev_err(tas_fmw->dev,
1203 "%s: File Size(%lu) error offset = %d n = %d\n",
1204 __func__, (unsigned long)fmw->size, offset, n);
1205 offset = -EINVAL;
1206 goto out;
1207 }
1208 /* instead of kzalloc+memcpy */
1209 block->data = kmemdup(&data[offset], n, GFP_KERNEL);
1210 if (!block->data) {
1211 offset = -ENOMEM;
1212 goto out;
1213 }
1214 offset += n;
1215
1216 out:
1217 return offset;
1218 }
1219
1220 /* When parsing error occurs, all the memory resource will be released
1221 * in the end of tasdevice_rca_ready.
1222 */
fw_parse_data(struct tasdevice_fw * tas_fmw,struct tasdevice_data * img_data,const struct firmware * fmw,int offset)1223 static int fw_parse_data(struct tasdevice_fw *tas_fmw,
1224 struct tasdevice_data *img_data, const struct firmware *fmw,
1225 int offset)
1226 {
1227 const unsigned char *data = (unsigned char *)fmw->data;
1228 struct tasdev_blk *blk;
1229 unsigned int i;
1230 int n;
1231
1232 if (offset + 64 > fmw->size) {
1233 dev_err(tas_fmw->dev, "%s: Name error\n", __func__);
1234 offset = -EINVAL;
1235 goto out;
1236 }
1237 memcpy(img_data->name, &data[offset], 64);
1238 offset += 64;
1239
1240 n = strlen((char *)&data[offset]);
1241 n++;
1242 if (offset + n + 2 > fmw->size) {
1243 dev_err(tas_fmw->dev, "%s: Description error\n", __func__);
1244 offset = -EINVAL;
1245 goto out;
1246 }
1247 offset += n;
1248 img_data->nr_blk = get_unaligned_be16(&data[offset]);
1249 offset += 2;
1250
1251 img_data->dev_blks = kzalloc_objs(struct tasdev_blk, img_data->nr_blk);
1252 if (!img_data->dev_blks) {
1253 offset = -ENOMEM;
1254 goto out;
1255 }
1256 for (i = 0; i < img_data->nr_blk; i++) {
1257 blk = &(img_data->dev_blks[i]);
1258 offset = fw_parse_block_data(tas_fmw, blk, fmw, offset);
1259 if (offset < 0) {
1260 offset = -EINVAL;
1261 goto out;
1262 }
1263 }
1264
1265 out:
1266 return offset;
1267 }
1268
1269 /* When parsing error occurs, all the memory resource will be released
1270 * in the end of tasdevice_rca_ready.
1271 */
fw_parse_program_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1272 static int fw_parse_program_data(struct tasdevice_priv *tas_priv,
1273 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1274 {
1275 unsigned char *buf = (unsigned char *)fmw->data;
1276 struct tasdevice_prog *program;
1277 int i;
1278
1279 if (offset + 2 > fmw->size) {
1280 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1281 offset = -EINVAL;
1282 goto out;
1283 }
1284 tas_fmw->nr_programs = get_unaligned_be16(&buf[offset]);
1285 offset += 2;
1286
1287 if (tas_fmw->nr_programs == 0) {
1288 /*Not error in calibration Data file, return directly*/
1289 dev_info(tas_priv->dev, "%s: No Programs data, maybe calbin\n",
1290 __func__);
1291 goto out;
1292 }
1293
1294 tas_fmw->programs =
1295 kzalloc_objs(struct tasdevice_prog, tas_fmw->nr_programs);
1296 if (!tas_fmw->programs) {
1297 offset = -ENOMEM;
1298 goto out;
1299 }
1300 for (i = 0; i < tas_fmw->nr_programs; i++) {
1301 int n = 0;
1302
1303 program = &(tas_fmw->programs[i]);
1304 if (offset + 64 > fmw->size) {
1305 dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
1306 offset = -EINVAL;
1307 goto out;
1308 }
1309 offset += 64;
1310
1311 n = strlen((char *)&buf[offset]);
1312 /* skip '\0' and 5 unused bytes */
1313 n += 6;
1314 if (offset + n > fmw->size) {
1315 dev_err(tas_priv->dev, "Description err\n");
1316 offset = -EINVAL;
1317 goto out;
1318 }
1319
1320 offset += n;
1321
1322 offset = fw_parse_data(tas_fmw, &(program->dev_data), fmw,
1323 offset);
1324 if (offset < 0)
1325 goto out;
1326 }
1327
1328 out:
1329 return offset;
1330 }
1331
1332 /* When parsing error occurs, all the memory resource will be released
1333 * in the end of tasdevice_rca_ready.
1334 */
fw_parse_configuration_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1335 static int fw_parse_configuration_data(
1336 struct tasdevice_priv *tas_priv,
1337 struct tasdevice_fw *tas_fmw,
1338 const struct firmware *fmw, int offset)
1339 {
1340 unsigned char *data = (unsigned char *)fmw->data;
1341 struct tasdevice_config *config;
1342 unsigned int i;
1343 int n;
1344
1345 if (offset + 2 > fmw->size) {
1346 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1347 offset = -EINVAL;
1348 goto out;
1349 }
1350 tas_fmw->nr_configurations = get_unaligned_be16(&data[offset]);
1351 offset += 2;
1352
1353 if (tas_fmw->nr_configurations == 0) {
1354 dev_err(tas_priv->dev, "%s: Conf is zero\n", __func__);
1355 /*Not error for calibration Data file, return directly*/
1356 goto out;
1357 }
1358 tas_fmw->configs = kzalloc_objs(struct tasdevice_config,
1359 tas_fmw->nr_configurations);
1360 if (!tas_fmw->configs) {
1361 offset = -ENOMEM;
1362 goto out;
1363 }
1364 for (i = 0; i < tas_fmw->nr_configurations; i++) {
1365 config = &(tas_fmw->configs[i]);
1366 if (offset + 64 > fmw->size) {
1367 dev_err(tas_priv->dev, "File Size err\n");
1368 offset = -EINVAL;
1369 goto out;
1370 }
1371 memcpy(config->name, &data[offset], 64);
1372 offset += 64;
1373
1374 n = strlen((char *)&data[offset]);
1375 n += 15;
1376 if (offset + n > fmw->size) {
1377 dev_err(tas_priv->dev, "Description err\n");
1378 offset = -EINVAL;
1379 goto out;
1380 }
1381
1382 offset += n;
1383
1384 offset = fw_parse_data(tas_fmw, &(config->dev_data),
1385 fmw, offset);
1386 if (offset < 0)
1387 goto out;
1388 }
1389
1390 out:
1391 return offset;
1392 }
1393
check_inpage_yram_rg(struct tas_crc * cd,unsigned char reg,unsigned char len)1394 static bool check_inpage_yram_rg(struct tas_crc *cd,
1395 unsigned char reg, unsigned char len)
1396 {
1397 bool in = false;
1398
1399
1400 if (reg <= TAS2781_YRAM5_END_REG &&
1401 reg >= TAS2781_YRAM5_START_REG) {
1402 if (reg + len > TAS2781_YRAM5_END_REG)
1403 cd->len = TAS2781_YRAM5_END_REG - reg + 1;
1404 else
1405 cd->len = len;
1406 cd->offset = reg;
1407 in = true;
1408 } else if (reg < TAS2781_YRAM5_START_REG) {
1409 if (reg + len > TAS2781_YRAM5_START_REG) {
1410 cd->offset = TAS2781_YRAM5_START_REG;
1411 cd->len = len - TAS2781_YRAM5_START_REG + reg;
1412 in = true;
1413 }
1414 }
1415
1416 return in;
1417 }
1418
check_inpage_yram_bk1(struct tas_crc * cd,unsigned char page,unsigned char reg,unsigned char len)1419 static bool check_inpage_yram_bk1(struct tas_crc *cd,
1420 unsigned char page, unsigned char reg, unsigned char len)
1421 {
1422 bool in = false;
1423
1424 if (page == TAS2781_YRAM1_PAGE) {
1425 if (reg >= TAS2781_YRAM1_START_REG) {
1426 cd->offset = reg;
1427 cd->len = len;
1428 in = true;
1429 } else if (reg + len > TAS2781_YRAM1_START_REG) {
1430 cd->offset = TAS2781_YRAM1_START_REG;
1431 cd->len = len - TAS2781_YRAM1_START_REG + reg;
1432 in = true;
1433 }
1434 } else if (page == TAS2781_YRAM3_PAGE)
1435 in = check_inpage_yram_rg(cd, reg, len);
1436
1437 return in;
1438 }
1439
1440 /* Return Code:
1441 * true -- the registers are in the inpage yram
1442 * false -- the registers are NOT in the inpage yram
1443 */
check_inpage_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1444 static bool check_inpage_yram(struct tas_crc *cd, unsigned char book,
1445 unsigned char page, unsigned char reg, unsigned char len)
1446 {
1447 bool in = false;
1448
1449 if (book == TAS2781_YRAM_BOOK1) {
1450 in = check_inpage_yram_bk1(cd, page, reg, len);
1451 goto end;
1452 }
1453 if (book == TAS2781_YRAM_BOOK2 && page == TAS2781_YRAM5_PAGE)
1454 in = check_inpage_yram_rg(cd, reg, len);
1455
1456 end:
1457 return in;
1458 }
1459
check_inblock_yram_bk(struct tas_crc * cd,unsigned char page,unsigned char reg,unsigned char len)1460 static bool check_inblock_yram_bk(struct tas_crc *cd,
1461 unsigned char page, unsigned char reg, unsigned char len)
1462 {
1463 bool in = false;
1464
1465 if ((page >= TAS2781_YRAM4_START_PAGE &&
1466 page <= TAS2781_YRAM4_END_PAGE) ||
1467 (page >= TAS2781_YRAM2_START_PAGE &&
1468 page <= TAS2781_YRAM2_END_PAGE)) {
1469 if (reg <= TAS2781_YRAM2_END_REG &&
1470 reg >= TAS2781_YRAM2_START_REG) {
1471 cd->offset = reg;
1472 cd->len = len;
1473 in = true;
1474 } else if (reg < TAS2781_YRAM2_START_REG) {
1475 if (reg + len - 1 >= TAS2781_YRAM2_START_REG) {
1476 cd->offset = TAS2781_YRAM2_START_REG;
1477 cd->len = reg + len - TAS2781_YRAM2_START_REG;
1478 in = true;
1479 }
1480 }
1481 }
1482
1483 return in;
1484 }
1485
1486 /* Return Code:
1487 * true -- the registers are in the inblock yram
1488 * false -- the registers are NOT in the inblock yram
1489 */
check_inblock_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1490 static bool check_inblock_yram(struct tas_crc *cd, unsigned char book,
1491 unsigned char page, unsigned char reg, unsigned char len)
1492 {
1493 bool in = false;
1494
1495 if (book == TAS2781_YRAM_BOOK1 || book == TAS2781_YRAM_BOOK2)
1496 in = check_inblock_yram_bk(cd, page, reg, len);
1497
1498 return in;
1499 }
1500
check_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1501 static bool check_yram(struct tas_crc *cd, unsigned char book,
1502 unsigned char page, unsigned char reg, unsigned char len)
1503 {
1504 bool in;
1505
1506 in = check_inpage_yram(cd, book, page, reg, len);
1507 if (in)
1508 goto end;
1509 in = check_inblock_yram(cd, book, page, reg, len);
1510
1511 end:
1512 return in;
1513 }
1514
tasdev_multibytes_chksum(struct tasdevice_priv * tasdevice,unsigned short chn,unsigned char book,unsigned char page,unsigned char reg,unsigned int len)1515 static int tasdev_multibytes_chksum(struct tasdevice_priv *tasdevice,
1516 unsigned short chn, unsigned char book, unsigned char page,
1517 unsigned char reg, unsigned int len)
1518 {
1519 struct tas_crc crc_data;
1520 unsigned char crc_chksum = 0;
1521 unsigned char nBuf1[128];
1522 int ret = 0;
1523 int i;
1524 bool in;
1525
1526 if ((reg + len - 1) > 127) {
1527 ret = -EINVAL;
1528 dev_err(tasdevice->dev, "firmware error\n");
1529 goto end;
1530 }
1531
1532 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG))
1533 && (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG))
1534 && (reg == TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG))
1535 && (len == 4)) {
1536 /*DSP swap command, pass */
1537 ret = 0;
1538 goto end;
1539 }
1540
1541 in = check_yram(&crc_data, book, page, reg, len);
1542 if (!in)
1543 goto end;
1544
1545 if (len == 1) {
1546 dev_err(tasdevice->dev, "firmware error\n");
1547 ret = -EINVAL;
1548 goto end;
1549 }
1550
1551 ret = tasdevice->dev_bulk_read(tasdevice, chn,
1552 TASDEVICE_REG(book, page, crc_data.offset),
1553 nBuf1, crc_data.len);
1554 if (ret < 0)
1555 goto end;
1556
1557 for (i = 0; i < crc_data.len; i++) {
1558 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG))
1559 && (page == TASDEVICE_PAGE_ID(
1560 TAS2781_SA_COEFF_SWAP_REG))
1561 && ((i + crc_data.offset)
1562 >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG))
1563 && ((i + crc_data.offset)
1564 <= (TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG)
1565 + 4)))
1566 /*DSP swap command, bypass */
1567 continue;
1568 else
1569 crc_chksum += crc8(tasdevice->crc8_lkp_tbl, &nBuf1[i],
1570 1, 0);
1571 }
1572
1573 ret = crc_chksum;
1574
1575 end:
1576 return ret;
1577 }
1578
do_singlereg_checksum(struct tasdevice_priv * tasdevice,unsigned short chl,unsigned char book,unsigned char page,unsigned char reg,unsigned char val)1579 static int do_singlereg_checksum(struct tasdevice_priv *tasdevice,
1580 unsigned short chl, unsigned char book, unsigned char page,
1581 unsigned char reg, unsigned char val)
1582 {
1583 struct tas_crc crc_data;
1584 unsigned int nData1;
1585 int ret = 0;
1586 bool in;
1587
1588 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG))
1589 && (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG))
1590 && (reg >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG))
1591 && (reg <= (TASDEVICE_PAGE_REG(
1592 TAS2781_SA_COEFF_SWAP_REG) + 4))) {
1593 /*DSP swap command, pass */
1594 ret = 0;
1595 goto end;
1596 }
1597
1598 in = check_yram(&crc_data, book, page, reg, 1);
1599 if (!in)
1600 goto end;
1601 ret = tasdevice->dev_read(tasdevice, chl,
1602 TASDEVICE_REG(book, page, reg), &nData1);
1603 if (ret < 0)
1604 goto end;
1605
1606 if (nData1 != val) {
1607 dev_err(tasdevice->dev,
1608 "B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1609 book, page, reg, val, nData1);
1610 tasdevice->tasdevice[chl].err_code |= ERROR_YRAM_CRCCHK;
1611 ret = -EAGAIN;
1612 goto end;
1613 }
1614
1615 ret = crc8(tasdevice->crc8_lkp_tbl, &val, 1, 0);
1616
1617 end:
1618 return ret;
1619 }
1620
set_err_prg_cfg(unsigned int type,struct tasdevice * dev)1621 static void set_err_prg_cfg(unsigned int type, struct tasdevice *dev)
1622 {
1623 if ((type == MAIN_ALL_DEVICES) || (type == MAIN_DEVICE_A)
1624 || (type == MAIN_DEVICE_B) || (type == MAIN_DEVICE_C)
1625 || (type == MAIN_DEVICE_D))
1626 dev->cur_prog = -1;
1627 else
1628 dev->cur_conf = -1;
1629 }
1630
tasdev_bytes_chksum(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn,unsigned char book,unsigned char page,unsigned char reg,unsigned int len,unsigned char val,unsigned char * crc_chksum)1631 static int tasdev_bytes_chksum(struct tasdevice_priv *tas_priv,
1632 struct tasdev_blk *block, int chn, unsigned char book,
1633 unsigned char page, unsigned char reg, unsigned int len,
1634 unsigned char val, unsigned char *crc_chksum)
1635 {
1636 int ret;
1637
1638 if (len > 1)
1639 ret = tasdev_multibytes_chksum(tas_priv, chn, book, page, reg,
1640 len);
1641 else
1642 ret = do_singlereg_checksum(tas_priv, chn, book, page, reg,
1643 val);
1644
1645 if (ret > 0) {
1646 *crc_chksum += (unsigned char)ret;
1647 goto end;
1648 }
1649
1650 if (ret != -EAGAIN)
1651 goto end;
1652
1653 block->nr_retry--;
1654 if (block->nr_retry > 0)
1655 goto end;
1656
1657 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]);
1658
1659 end:
1660 return ret;
1661 }
1662
tasdev_multibytes_wr(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn,unsigned char book,unsigned char page,unsigned char reg,unsigned char * data,unsigned int len,unsigned int * nr_cmds,unsigned char * crc_chksum)1663 static int tasdev_multibytes_wr(struct tasdevice_priv *tas_priv,
1664 struct tasdev_blk *block, int chn, unsigned char book,
1665 unsigned char page, unsigned char reg, unsigned char *data,
1666 unsigned int len, unsigned int *nr_cmds,
1667 unsigned char *crc_chksum)
1668 {
1669 int ret;
1670
1671 if (len > 1) {
1672 ret = tasdevice_dev_bulk_write(tas_priv, chn,
1673 TASDEVICE_REG(book, page, reg), data + 3, len);
1674 if (ret < 0)
1675 goto end;
1676 if (block->is_ychksum_present)
1677 ret = tasdev_bytes_chksum(tas_priv, block, chn,
1678 book, page, reg, len, 0, crc_chksum);
1679 } else {
1680 ret = tasdevice_dev_write(tas_priv, chn,
1681 TASDEVICE_REG(book, page, reg), data[3]);
1682 if (ret < 0)
1683 goto end;
1684 if (block->is_ychksum_present)
1685 ret = tasdev_bytes_chksum(tas_priv, block, chn, book,
1686 page, reg, 1, data[3], crc_chksum);
1687 }
1688
1689 if (!block->is_ychksum_present || ret >= 0) {
1690 *nr_cmds += 1;
1691 if (len >= 2)
1692 *nr_cmds += ((len - 2) / 4) + 1;
1693 }
1694
1695 end:
1696 return ret;
1697 }
1698
tasdev_block_chksum(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn)1699 static int tasdev_block_chksum(struct tasdevice_priv *tas_priv,
1700 struct tasdev_blk *block, int chn)
1701 {
1702 unsigned int nr_value;
1703 int ret;
1704
1705 ret = tas_priv->dev_read(tas_priv, chn, TASDEVICE_CHECKSUM_REG,
1706 &nr_value);
1707 if (ret < 0) {
1708 dev_err(tas_priv->dev, "%s: Chn %d\n", __func__, chn);
1709 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]);
1710 goto end;
1711 }
1712
1713 if ((nr_value & 0xff) != block->pchksum) {
1714 dev_err(tas_priv->dev, "%s: Blk PChkSum Chn %d ", __func__,
1715 chn);
1716 dev_err(tas_priv->dev, "PChkSum = 0x%x, Reg = 0x%x\n",
1717 block->pchksum, (nr_value & 0xff));
1718 tas_priv->tasdevice[chn].err_code |= ERROR_PRAM_CRCCHK;
1719 ret = -EAGAIN;
1720 block->nr_retry--;
1721
1722 if (block->nr_retry <= 0)
1723 set_err_prg_cfg(block->type,
1724 &tas_priv->tasdevice[chn]);
1725 } else
1726 tas_priv->tasdevice[chn].err_code &= ~ERROR_PRAM_CRCCHK;
1727
1728 end:
1729 return ret;
1730 }
1731
tasdev_load_blk(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,int chn)1732 static int tasdev_load_blk(struct tasdevice_priv *tas_priv,
1733 struct tasdev_blk *block, int chn)
1734 {
1735 unsigned int sleep_time;
1736 unsigned int len;
1737 unsigned int nr_cmds;
1738 unsigned char *data;
1739 unsigned char crc_chksum = 0;
1740 unsigned char offset;
1741 unsigned char book;
1742 unsigned char page;
1743 unsigned char val;
1744 int ret = 0;
1745
1746 while (block->nr_retry > 0) {
1747 if (block->is_pchksum_present) {
1748 ret = tasdevice_dev_write(tas_priv, chn,
1749 TASDEVICE_CHECKSUM_REG, 0);
1750 if (ret < 0)
1751 break;
1752 }
1753
1754 if (block->is_ychksum_present)
1755 crc_chksum = 0;
1756
1757 nr_cmds = 0;
1758
1759 while (nr_cmds < block->nr_cmds) {
1760 data = block->data + nr_cmds * 4;
1761
1762 book = data[0];
1763 page = data[1];
1764 offset = data[2];
1765 val = data[3];
1766
1767 nr_cmds++;
1768 /*Single byte write*/
1769 if (offset <= 0x7F) {
1770 ret = tasdevice_dev_write(tas_priv, chn,
1771 TASDEVICE_REG(book, page, offset),
1772 val);
1773 if (ret < 0)
1774 goto end;
1775 if (block->is_ychksum_present) {
1776 ret = tasdev_bytes_chksum(tas_priv,
1777 block, chn, book, page, offset,
1778 1, val, &crc_chksum);
1779 if (ret < 0)
1780 break;
1781 }
1782 continue;
1783 }
1784 /*sleep command*/
1785 if (offset == 0x81) {
1786 /*book -- data[0] page -- data[1]*/
1787 sleep_time = ((book << 8) + page)*1000;
1788 usleep_range(sleep_time, sleep_time + 50);
1789 continue;
1790 }
1791 /*Multiple bytes write*/
1792 if (offset == 0x85) {
1793 data += 4;
1794 len = (book << 8) + page;
1795 book = data[0];
1796 page = data[1];
1797 offset = data[2];
1798 ret = tasdev_multibytes_wr(tas_priv,
1799 block, chn, book, page, offset, data,
1800 len, &nr_cmds, &crc_chksum);
1801 if (ret < 0)
1802 break;
1803 }
1804 }
1805 if (ret == -EAGAIN) {
1806 if (block->nr_retry > 0)
1807 continue;
1808 } else if (ret < 0) /*err in current device, skip it*/
1809 break;
1810
1811 if (block->is_pchksum_present) {
1812 ret = tasdev_block_chksum(tas_priv, block, chn);
1813 if (ret == -EAGAIN) {
1814 if (block->nr_retry > 0)
1815 continue;
1816 } else if (ret < 0) /*err in current device, skip it*/
1817 break;
1818 }
1819
1820 if (block->is_ychksum_present) {
1821 /* TBD, open it when FW ready */
1822 dev_err(tas_priv->dev,
1823 "Blk YChkSum: FW = 0x%x, YCRC = 0x%x\n",
1824 block->ychksum, crc_chksum);
1825
1826 tas_priv->tasdevice[chn].err_code &=
1827 ~ERROR_YRAM_CRCCHK;
1828 ret = 0;
1829 }
1830 /*skip current blk*/
1831 break;
1832 }
1833
1834 end:
1835 return ret;
1836 }
1837
tasdevice_load_block(struct tasdevice_priv * tas_priv,struct tasdev_blk * block)1838 static int tasdevice_load_block(struct tasdevice_priv *tas_priv,
1839 struct tasdev_blk *block)
1840 {
1841 int chnend = 0;
1842 int ret = 0;
1843 int chn = 0;
1844 int rc = 0;
1845
1846 switch (block->type) {
1847 case MAIN_ALL_DEVICES:
1848 chn = 0;
1849 chnend = tas_priv->ndev;
1850 break;
1851 case MAIN_DEVICE_A:
1852 case COEFF_DEVICE_A:
1853 case PRE_DEVICE_A:
1854 chn = 0;
1855 chnend = 1;
1856 break;
1857 case MAIN_DEVICE_B:
1858 case COEFF_DEVICE_B:
1859 case PRE_DEVICE_B:
1860 chn = 1;
1861 chnend = 2;
1862 break;
1863 case MAIN_DEVICE_C:
1864 case COEFF_DEVICE_C:
1865 case PRE_DEVICE_C:
1866 chn = 2;
1867 chnend = 3;
1868 break;
1869 case MAIN_DEVICE_D:
1870 case COEFF_DEVICE_D:
1871 case PRE_DEVICE_D:
1872 chn = 3;
1873 chnend = 4;
1874 break;
1875 default:
1876 dev_dbg(tas_priv->dev, "load blk: Other Type = 0x%02x\n",
1877 block->type);
1878 break;
1879 }
1880
1881 for (; chn < chnend; chn++) {
1882 block->nr_retry = 6;
1883 if (tas_priv->tasdevice[chn].is_loading == false)
1884 continue;
1885 ret = tasdev_load_blk(tas_priv, block, chn);
1886 if (ret < 0)
1887 dev_err(tas_priv->dev, "dev %d, Blk (%d) load error\n",
1888 chn, block->type);
1889 rc |= ret;
1890 }
1891
1892 return rc;
1893 }
1894
dspbin_type_check(struct tasdevice_priv * tas_priv,unsigned int ppcver)1895 static void dspbin_type_check(struct tasdevice_priv *tas_priv,
1896 unsigned int ppcver)
1897 {
1898 if (ppcver >= PPC3_VERSION_TAS2781_ALPHA_MIN) {
1899 if (ppcver >= PPC3_VERSION_TAS2781_BETA_MIN)
1900 tas_priv->dspbin_typ = TASDEV_BETA;
1901 else if (ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN)
1902 tas_priv->dspbin_typ = TASDEV_BASIC;
1903 else
1904 tas_priv->dspbin_typ = TASDEV_ALPHA;
1905 }
1906 if ((tas_priv->dspbin_typ != TASDEV_BASIC) &&
1907 (ppcver < PPC3_VERSION_TAS5825_BASE))
1908 tas_priv->fw_parse_fct_param_address =
1909 fw_parse_fct_param_address;
1910 }
1911
dspfw_default_callback(struct tasdevice_priv * tas_priv,unsigned int drv_ver,unsigned int ppcver)1912 static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
1913 unsigned int drv_ver, unsigned int ppcver)
1914 {
1915 int rc = 0;
1916
1917 if (drv_ver == 0x100) {
1918 if (ppcver >= PPC3_VERSION_TAS5825_BASE) {
1919 tas_priv->fw_parse_variable_header =
1920 fw_parse_variable_header_kernel;
1921 tas_priv->fw_parse_program_data =
1922 fw_parse_tas5825_program_data_kernel;
1923 tas_priv->fw_parse_configuration_data =
1924 fw_parse_tas5825_configuration_data_kernel;
1925 tas_priv->tasdevice_load_block =
1926 tasdevice_load_block_kernel;
1927 dspbin_type_check(tas_priv, ppcver);
1928 } else if (ppcver >= PPC3_VERSION_BASE) {
1929 tas_priv->fw_parse_variable_header =
1930 fw_parse_variable_header_kernel;
1931 tas_priv->fw_parse_program_data =
1932 fw_parse_program_data_kernel;
1933 tas_priv->fw_parse_configuration_data =
1934 fw_parse_configuration_data_kernel;
1935 tas_priv->tasdevice_load_block =
1936 tasdevice_load_block_kernel;
1937 dspbin_type_check(tas_priv, ppcver);
1938 } else {
1939 switch (ppcver) {
1940 case 0x00:
1941 tas_priv->fw_parse_variable_header =
1942 fw_parse_variable_header_git;
1943 tas_priv->fw_parse_program_data =
1944 fw_parse_program_data;
1945 tas_priv->fw_parse_configuration_data =
1946 fw_parse_configuration_data;
1947 tas_priv->tasdevice_load_block =
1948 tasdevice_load_block;
1949 break;
1950 default:
1951 dev_err(tas_priv->dev,
1952 "%s: PPCVer must be 0x0 or 0x%02x",
1953 __func__, PPC3_VERSION_BASE);
1954 dev_err(tas_priv->dev, " Current:0x%02x\n",
1955 ppcver);
1956 rc = -EINVAL;
1957 break;
1958 }
1959 }
1960 } else {
1961 dev_err(tas_priv->dev,
1962 "DrvVer must be 0x0, 0x230 or above 0x230 ");
1963 dev_err(tas_priv->dev, "current is 0x%02x\n", drv_ver);
1964 rc = -EINVAL;
1965 }
1966
1967 return rc;
1968 }
1969
fw_parse_header(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1970 static int fw_parse_header(struct tasdevice_priv *tas_priv,
1971 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1972 {
1973 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
1974 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr);
1975 static const unsigned char magic_number[] = { 0x35, 0x35, 0x35, 0x32 };
1976 const unsigned char *buf = (unsigned char *)fmw->data;
1977
1978 if (offset + 92 > fmw->size) {
1979 dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1980 offset = -EINVAL;
1981 goto out;
1982 }
1983 if (memcmp(&buf[offset], magic_number, 4)) {
1984 dev_err(tas_priv->dev, "%s: Magic num NOT match\n", __func__);
1985 offset = -EINVAL;
1986 goto out;
1987 }
1988 offset += 4;
1989
1990 /* Convert data[offset], data[offset + 1], data[offset + 2] and
1991 * data[offset + 3] into host
1992 */
1993 fw_fixed_hdr->fwsize = get_unaligned_be32(&buf[offset]);
1994 offset += 4;
1995 if (fw_fixed_hdr->fwsize != fmw->size) {
1996 dev_err(tas_priv->dev, "File size not match, %lu %u",
1997 (unsigned long)fmw->size, fw_fixed_hdr->fwsize);
1998 offset = -EINVAL;
1999 goto out;
2000 }
2001 offset += 4;
2002 fw_fixed_hdr->ppcver = get_unaligned_be32(&buf[offset]);
2003 offset += 8;
2004 fw_fixed_hdr->drv_ver = get_unaligned_be32(&buf[offset]);
2005 offset += 72;
2006
2007 out:
2008 return offset;
2009 }
2010
fw_parse_variable_hdr_cal(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)2011 static int fw_parse_variable_hdr_cal(struct tasdevice_priv *tas_priv,
2012 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
2013 {
2014 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr);
2015
2016 offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset);
2017 if (offset < 0)
2018 goto out;
2019 if (fw_hdr->ndev != 1) {
2020 dev_err(tas_priv->dev,
2021 "%s: calbin must be 1, but currently ndev(%u)\n",
2022 __func__, fw_hdr->ndev);
2023 offset = -EINVAL;
2024 }
2025
2026 out:
2027 return offset;
2028 }
2029
check_cal_bin_data(struct device * dev,const unsigned char * data,const char * name)2030 static inline int check_cal_bin_data(struct device *dev,
2031 const unsigned char *data, const char *name)
2032 {
2033 if (data[2] != 0x85 || data[1] != 4) {
2034 dev_err(dev, "Invalid cal bin file in %s\n", name);
2035 return -1;
2036 }
2037 return 0;
2038 }
2039
calbin_conversion(struct tasdevice_priv * priv,struct tasdevice_fw * tas_fmw)2040 static void calbin_conversion(struct tasdevice_priv *priv,
2041 struct tasdevice_fw *tas_fmw)
2042 {
2043 struct calidata *cali_data = &priv->cali_data;
2044 unsigned char *calbin_data = cali_data->data;
2045 struct cali_reg *p = &cali_data->cali_reg_array;
2046 struct tasdevice_calibration *calibration;
2047 struct tasdevice_data *img_data;
2048 struct tasdev_blk *blk;
2049 unsigned char *data;
2050 int chn, k;
2051
2052 if (cali_data->total_sz != priv->ndev *
2053 (cali_data->cali_dat_sz_per_dev + 1)) {
2054 dev_err(priv->dev, "%s: cali_data size err\n",
2055 __func__);
2056 return;
2057 }
2058 calibration = &(tas_fmw->calibrations[0]);
2059 img_data = &(calibration->dev_data);
2060
2061 if (img_data->nr_blk != 1) {
2062 dev_err(priv->dev, "%s: Invalid nr_blk, wrong cal bin\n",
2063 __func__);
2064 return;
2065 }
2066
2067 blk = &(img_data->dev_blks[0]);
2068 if (blk->nr_cmds != 15) {
2069 dev_err(priv->dev, "%s: Invalid nr_cmds, wrong cal bin\n",
2070 __func__);
2071 return;
2072 }
2073
2074 switch (blk->type) {
2075 case COEFF_DEVICE_A:
2076 chn = 0;
2077 break;
2078 case COEFF_DEVICE_B:
2079 chn = 1;
2080 break;
2081 case COEFF_DEVICE_C:
2082 chn = 2;
2083 break;
2084 case COEFF_DEVICE_D:
2085 chn = 3;
2086 break;
2087 default:
2088 dev_err(priv->dev, "%s: Other Type = 0x%02x\n",
2089 __func__, blk->type);
2090 return;
2091 }
2092 k = chn * (cali_data->cali_dat_sz_per_dev + 1);
2093
2094 data = blk->data;
2095 if (check_cal_bin_data(priv->dev, data, "r0_reg") < 0)
2096 return;
2097 p->r0_reg = TASDEVICE_REG(data[4], data[5], data[6]);
2098 COPY_CAL_DATA(k);
2099
2100 data = blk->data + 12;
2101 if (check_cal_bin_data(priv->dev, data, "r0_low_reg") < 0)
2102 return;
2103 p->r0_low_reg = TASDEVICE_REG(data[4], data[5], data[6]);
2104 COPY_CAL_DATA(k + 4);
2105
2106 data = blk->data + 24;
2107 if (check_cal_bin_data(priv->dev, data, "invr0_reg") < 0)
2108 return;
2109 p->invr0_reg = TASDEVICE_REG(data[4], data[5], data[6]);
2110 COPY_CAL_DATA(k + 8);
2111
2112 data = blk->data + 36;
2113 if (check_cal_bin_data(priv->dev, data, "pow_reg") < 0)
2114 return;
2115 p->pow_reg = TASDEVICE_REG(data[4], data[5], data[6]);
2116 COPY_CAL_DATA(k + 12);
2117
2118 data = blk->data + 48;
2119 if (check_cal_bin_data(priv->dev, data, "tlimit_reg") < 0)
2120 return;
2121 p->tlimit_reg = TASDEVICE_REG(data[4], data[5], data[6]);
2122 COPY_CAL_DATA(k + 16);
2123
2124 calbin_data[k] = chn;
2125 }
2126
2127 /* When calibrated data parsing error occurs, DSP can still work with default
2128 * calibrated data, memory resource related to calibrated data will be
2129 * released in the tasdevice_codec_remove.
2130 */
fw_parse_calibration_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)2131 static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv,
2132 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
2133 {
2134 struct tasdevice_calibration *calibration;
2135 unsigned char *data = (unsigned char *)fmw->data;
2136 unsigned int i, n;
2137
2138 if (offset + 2 > fmw->size) {
2139 dev_err(tas_priv->dev, "%s: Calibrations error\n", __func__);
2140 offset = -EINVAL;
2141 goto out;
2142 }
2143 tas_fmw->nr_calibrations = get_unaligned_be16(&data[offset]);
2144 offset += 2;
2145
2146 if (tas_fmw->nr_calibrations != 1) {
2147 dev_err(tas_priv->dev,
2148 "%s: only supports one calibration (%d)!\n",
2149 __func__, tas_fmw->nr_calibrations);
2150 goto out;
2151 }
2152
2153 tas_fmw->calibrations = kzalloc_objs(struct tasdevice_calibration,
2154 tas_fmw->nr_calibrations);
2155 if (!tas_fmw->calibrations) {
2156 offset = -ENOMEM;
2157 goto out;
2158 }
2159 for (i = 0; i < tas_fmw->nr_calibrations; i++) {
2160 if (offset + 64 > fmw->size) {
2161 dev_err(tas_priv->dev, "Calibrations error\n");
2162 offset = -EINVAL;
2163 goto out;
2164 }
2165 calibration = &(tas_fmw->calibrations[i]);
2166 offset += 64;
2167
2168 n = strlen((char *)&data[offset]);
2169 /* skip '\0' and 2 unused bytes */
2170 n += 3;
2171 if (offset + n > fmw->size) {
2172 dev_err(tas_priv->dev, "Description err\n");
2173 offset = -EINVAL;
2174 goto out;
2175 }
2176 offset += n;
2177
2178 offset = fw_parse_data(tas_fmw, &(calibration->dev_data), fmw,
2179 offset);
2180 if (offset < 0)
2181 goto out;
2182 }
2183
2184 calbin_conversion(tas_priv, tas_fmw);
2185 out:
2186 return offset;
2187 }
2188
tas2781_load_calibration(void * context,char * file_name,unsigned short i)2189 int tas2781_load_calibration(void *context, char *file_name,
2190 unsigned short i)
2191 {
2192 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context;
2193 struct tasdevice *tasdev = &(tas_priv->tasdevice[i]);
2194 const struct firmware *fw_entry = NULL;
2195 struct tasdevice_fw *tas_fmw;
2196 struct firmware fmw;
2197 int offset = 0;
2198 int ret;
2199
2200 ret = request_firmware(&fw_entry, file_name, tas_priv->dev);
2201 if (ret) {
2202 dev_err(tas_priv->dev, "%s: Request firmware %s failed\n",
2203 __func__, file_name);
2204 goto out;
2205 }
2206
2207 if (!fw_entry->size) {
2208 dev_err(tas_priv->dev, "%s: file read error: size = %lu\n",
2209 __func__, (unsigned long)fw_entry->size);
2210 ret = -EINVAL;
2211 goto out;
2212 }
2213 fmw.size = fw_entry->size;
2214 fmw.data = fw_entry->data;
2215
2216 tas_fmw = tasdev->cali_data_fmw = kzalloc_obj(struct tasdevice_fw);
2217 if (!tasdev->cali_data_fmw) {
2218 ret = -ENOMEM;
2219 goto out;
2220 }
2221 tas_fmw->dev = tas_priv->dev;
2222 offset = fw_parse_header(tas_priv, tas_fmw, &fmw, offset);
2223 if (offset == -EINVAL) {
2224 dev_err(tas_priv->dev, "fw_parse_header EXIT!\n");
2225 ret = offset;
2226 goto out;
2227 }
2228 offset = fw_parse_variable_hdr_cal(tas_priv, tas_fmw, &fmw, offset);
2229 if (offset == -EINVAL) {
2230 dev_err(tas_priv->dev,
2231 "%s: fw_parse_variable_header_cal EXIT!\n", __func__);
2232 ret = offset;
2233 goto out;
2234 }
2235 offset = fw_parse_program_data(tas_priv, tas_fmw, &fmw, offset);
2236 if (offset < 0) {
2237 dev_err(tas_priv->dev, "fw_parse_program_data EXIT!\n");
2238 ret = offset;
2239 goto out;
2240 }
2241 offset = fw_parse_configuration_data(tas_priv, tas_fmw, &fmw, offset);
2242 if (offset < 0) {
2243 dev_err(tas_priv->dev, "fw_parse_configuration_data EXIT!\n");
2244 ret = offset;
2245 goto out;
2246 }
2247 offset = fw_parse_calibration_data(tas_priv, tas_fmw, &fmw, offset);
2248 if (offset < 0) {
2249 dev_err(tas_priv->dev, "fw_parse_calibration_data EXIT!\n");
2250 ret = offset;
2251 goto out;
2252 }
2253
2254 out:
2255 release_firmware(fw_entry);
2256
2257 return ret;
2258 }
2259 EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, "SND_SOC_TAS2781_FMWLIB");
2260
tasdevice_dspfw_ready(const struct firmware * fmw,void * context)2261 static int tasdevice_dspfw_ready(const struct firmware *fmw,
2262 void *context)
2263 {
2264 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2265 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr;
2266 struct tasdevice_fw *tas_fmw;
2267 int offset = 0;
2268 int ret;
2269
2270 if (!fmw || !fmw->data) {
2271 dev_err(tas_priv->dev, "%s: Failed to read firmware %s\n",
2272 __func__, tas_priv->coef_binaryname);
2273 return -EINVAL;
2274 }
2275
2276 tas_priv->fmw = kzalloc_obj(struct tasdevice_fw);
2277 if (!tas_priv->fmw)
2278 return -ENOMEM;
2279
2280 tas_fmw = tas_priv->fmw;
2281 tas_fmw->dev = tas_priv->dev;
2282 offset = fw_parse_header(tas_priv, tas_fmw, fmw, offset);
2283
2284 if (offset == -EINVAL)
2285 return -EINVAL;
2286
2287 fw_fixed_hdr = &(tas_fmw->fw_hdr.fixed_hdr);
2288 /* Support different versions of firmware */
2289 switch (fw_fixed_hdr->drv_ver) {
2290 case 0x301:
2291 case 0x302:
2292 case 0x502:
2293 case 0x503:
2294 tas_priv->fw_parse_variable_header =
2295 fw_parse_variable_header_kernel;
2296 tas_priv->fw_parse_program_data =
2297 fw_parse_program_data_kernel;
2298 tas_priv->fw_parse_configuration_data =
2299 fw_parse_configuration_data_kernel;
2300 tas_priv->tasdevice_load_block =
2301 tasdevice_load_block_kernel;
2302 break;
2303 case 0x202:
2304 case 0x400:
2305 case 0x401:
2306 tas_priv->fw_parse_variable_header =
2307 fw_parse_variable_header_git;
2308 tas_priv->fw_parse_program_data =
2309 fw_parse_program_data;
2310 tas_priv->fw_parse_configuration_data =
2311 fw_parse_configuration_data;
2312 tas_priv->tasdevice_load_block =
2313 tasdevice_load_block;
2314 break;
2315 default:
2316 ret = dspfw_default_callback(tas_priv,
2317 fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver);
2318 if (ret)
2319 return ret;
2320 break;
2321 }
2322
2323 offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset);
2324 if (offset < 0)
2325 return offset;
2326
2327 offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw,
2328 offset);
2329 if (offset < 0)
2330 return offset;
2331
2332 offset = tas_priv->fw_parse_configuration_data(tas_priv,
2333 tas_fmw, fmw, offset);
2334 if (offset < 0)
2335 return offset;
2336
2337 if (tas_priv->fw_parse_fct_param_address) {
2338 offset = tas_priv->fw_parse_fct_param_address(tas_priv,
2339 tas_fmw, fmw, offset);
2340 if (offset < 0)
2341 return offset;
2342 }
2343
2344 return 0;
2345 }
2346
tasdevice_dsp_parser(void * context)2347 int tasdevice_dsp_parser(void *context)
2348 {
2349 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context;
2350 const struct firmware *fw_entry;
2351 int ret;
2352
2353 ret = request_firmware(&fw_entry, tas_priv->coef_binaryname,
2354 tas_priv->dev);
2355 if (ret) {
2356 dev_err(tas_priv->dev, "%s: load %s error\n", __func__,
2357 tas_priv->coef_binaryname);
2358 goto out;
2359 }
2360
2361 ret = tasdevice_dspfw_ready(fw_entry, tas_priv);
2362 release_firmware(fw_entry);
2363 fw_entry = NULL;
2364
2365 out:
2366 return ret;
2367 }
2368 EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, "SND_SOC_TAS2781_FMWLIB");
2369
tas2781_clear_calfirmware(struct tasdevice_fw * tas_fmw)2370 static void tas2781_clear_calfirmware(struct tasdevice_fw *tas_fmw)
2371 {
2372 struct tasdevice_calibration *calibration;
2373 struct tasdev_blk *block;
2374 struct tasdevice_data *im;
2375 unsigned int blks;
2376 int i;
2377
2378 if (!tas_fmw->calibrations)
2379 goto out;
2380
2381 for (i = 0; i < tas_fmw->nr_calibrations; i++) {
2382 calibration = &(tas_fmw->calibrations[i]);
2383 if (!calibration)
2384 continue;
2385
2386 im = &(calibration->dev_data);
2387
2388 if (!im->dev_blks)
2389 continue;
2390
2391 for (blks = 0; blks < im->nr_blk; blks++) {
2392 block = &(im->dev_blks[blks]);
2393 if (!block)
2394 continue;
2395 kfree(block->data);
2396 }
2397 kfree(im->dev_blks);
2398 }
2399 kfree(tas_fmw->calibrations);
2400 out:
2401 kfree(tas_fmw);
2402 }
2403
tasdevice_calbin_remove(void * context)2404 void tasdevice_calbin_remove(void *context)
2405 {
2406 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2407 struct tasdevice *tasdev;
2408 int i;
2409
2410 if (!tas_priv)
2411 return;
2412
2413 for (i = 0; i < tas_priv->ndev; i++) {
2414 tasdev = &(tas_priv->tasdevice[i]);
2415 if (!tasdev->cali_data_fmw)
2416 continue;
2417 tas2781_clear_calfirmware(tasdev->cali_data_fmw);
2418 tasdev->cali_data_fmw = NULL;
2419 }
2420 }
2421 EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, "SND_SOC_TAS2781_FMWLIB");
2422
tasdevice_config_info_remove(void * context)2423 void tasdevice_config_info_remove(void *context)
2424 {
2425 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2426 struct tasdevice_rca *rca = &(tas_priv->rcabin);
2427 struct tasdevice_config_info **ci = rca->cfg_info;
2428 int i, j;
2429
2430 if (!ci)
2431 return;
2432 for (i = 0; i < rca->ncfgs; i++) {
2433 if (!ci[i])
2434 continue;
2435 if (ci[i]->blk_data) {
2436 for (j = 0; j < (int)ci[i]->real_nblocks; j++) {
2437 if (!ci[i]->blk_data[j])
2438 continue;
2439 kfree(ci[i]->blk_data[j]->regdata);
2440 kfree(ci[i]->blk_data[j]);
2441 }
2442 kfree(ci[i]->blk_data);
2443 }
2444 kfree(ci[i]);
2445 }
2446 kfree(ci);
2447 }
2448 EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, "SND_SOC_TAS2781_FMWLIB");
2449
tasdevice_load_data(struct tasdevice_priv * tas_priv,struct tasdevice_data * dev_data)2450 static int tasdevice_load_data(struct tasdevice_priv *tas_priv,
2451 struct tasdevice_data *dev_data)
2452 {
2453 struct tasdev_blk *block;
2454 unsigned int i;
2455 int ret = 0;
2456
2457 for (i = 0; i < dev_data->nr_blk; i++) {
2458 block = &(dev_data->dev_blks[i]);
2459 ret = tas_priv->tasdevice_load_block(tas_priv, block);
2460 if (ret < 0)
2461 break;
2462 }
2463
2464 return ret;
2465 }
2466
tas2781_cali_preproc(struct tasdevice_priv * priv,int i)2467 static int tas2781_cali_preproc(struct tasdevice_priv *priv, int i)
2468 {
2469 struct tas2781_cali_specific *spec = priv->tasdevice[i].cali_specific;
2470 struct calidata *cali_data = &priv->cali_data;
2471 struct cali_reg *p = &cali_data->cali_reg_array;
2472 unsigned char *data = cali_data->data;
2473 int rc;
2474
2475 /*
2476 * On TAS2781, if the Speaker calibrated impedance is lower than
2477 * default value hard-coded inside the TAS2781, it will cuase vol
2478 * lower than normal. In order to fix this issue, the parameter of
2479 * SineGainI need updating.
2480 */
2481 if (spec == NULL) {
2482 int k = i * (cali_data->cali_dat_sz_per_dev + 1);
2483 int re_org, re_cal, corrected_sin_gn, pg_id;
2484 unsigned char r0_deflt[4];
2485
2486 spec = devm_kzalloc(priv->dev, sizeof(*spec), GFP_KERNEL);
2487 if (spec == NULL)
2488 return -ENOMEM;
2489 priv->tasdevice[i].cali_specific = spec;
2490 rc = tasdevice_dev_bulk_read(priv, i, p->r0_reg, r0_deflt, 4);
2491 if (rc < 0) {
2492 dev_err(priv->dev, "invalid RE from %d = %d\n", i, rc);
2493 return rc;
2494 }
2495 /*
2496 * SineGainI need to be re-calculated, calculate the high 16
2497 * bits.
2498 */
2499 re_org = r0_deflt[0] << 8 | r0_deflt[1];
2500 re_cal = data[k + 1] << 8 | data[k + 2];
2501 if (re_org > re_cal) {
2502 rc = tasdevice_dev_read(priv, i, TAS2781_PG_REG,
2503 &pg_id);
2504 if (rc < 0) {
2505 dev_err(priv->dev, "invalid PG id %d = %d\n",
2506 i, rc);
2507 return rc;
2508 }
2509
2510 spec->sin_gni_reg = (pg_id == TAS2781_PG_1_0) ?
2511 TASDEVICE_REG(0, 0x1b, 0x34) :
2512 TASDEVICE_REG(0, 0x18, 0x1c);
2513
2514 rc = tasdevice_dev_bulk_read(priv, i,
2515 spec->sin_gni_reg,
2516 spec->sin_gni, 4);
2517 if (rc < 0) {
2518 dev_err(priv->dev, "wrong sinegaini %d = %d\n",
2519 i, rc);
2520 return rc;
2521 }
2522 corrected_sin_gn = re_org * ((spec->sin_gni[0] << 8) +
2523 spec->sin_gni[1]);
2524 corrected_sin_gn /= re_cal;
2525 spec->sin_gni[0] = corrected_sin_gn >> 8;
2526 spec->sin_gni[1] = corrected_sin_gn & 0xff;
2527
2528 spec->is_sin_gn_flush = true;
2529 }
2530 }
2531
2532 if (spec->is_sin_gn_flush) {
2533 rc = tasdevice_dev_bulk_write(priv, i, spec->sin_gni_reg,
2534 spec->sin_gni, 4);
2535 if (rc < 0) {
2536 dev_err(priv->dev, "update failed %d = %d\n",
2537 i, rc);
2538 return rc;
2539 }
2540 }
2541
2542 return 0;
2543 }
2544
tasdev_load_calibrated_data(struct tasdevice_priv * priv,int i)2545 static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
2546 {
2547 struct calidata *cali_data = &priv->cali_data;
2548 struct cali_reg *p = &cali_data->cali_reg_array;
2549 unsigned char *data = cali_data->data;
2550 int k = i * (cali_data->cali_dat_sz_per_dev + 1);
2551 int rc;
2552
2553 if (data[k] != i) {
2554 dev_err(priv->dev, "%s: no cal-data for dev %d from usr-spc\n",
2555 __func__, i);
2556 return;
2557 }
2558 k++;
2559
2560 if (priv->chip_id == TAS2781) {
2561 rc = tas2781_cali_preproc(priv, i);
2562 if (rc < 0)
2563 return;
2564 }
2565
2566 rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4);
2567 if (rc < 0) {
2568 dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc);
2569 return;
2570 }
2571 k += 4;
2572 rc = tasdevice_dev_bulk_write(priv, i, p->r0_low_reg, &(data[k]), 4);
2573 if (rc < 0) {
2574 dev_err(priv->dev, "chn %d r0_low_reg err = %d\n", i, rc);
2575 return;
2576 }
2577 k += 4;
2578 rc = tasdevice_dev_bulk_write(priv, i, p->invr0_reg, &(data[k]), 4);
2579 if (rc < 0) {
2580 dev_err(priv->dev, "chn %d invr0_reg err = %d\n", i, rc);
2581 return;
2582 }
2583 k += 4;
2584 rc = tasdevice_dev_bulk_write(priv, i, p->pow_reg, &(data[k]), 4);
2585 if (rc < 0) {
2586 dev_err(priv->dev, "chn %d pow_reg bulk_wr err = %d\n", i, rc);
2587 return;
2588 }
2589 k += 4;
2590 rc = tasdevice_dev_bulk_write(priv, i, p->tlimit_reg, &(data[k]), 4);
2591 if (rc < 0) {
2592 dev_err(priv->dev, "chn %d tlimit_reg err = %d\n", i, rc);
2593 return;
2594 }
2595 }
2596
tasdevice_select_tuningprm_cfg(void * context,int prm_no,int cfg_no,int rca_conf_no)2597 int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
2598 int cfg_no, int rca_conf_no)
2599 {
2600 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2601 struct tasdevice_rca *rca = &(tas_priv->rcabin);
2602 struct tasdevice_config_info **cfg_info = rca->cfg_info;
2603 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2604 struct tasdevice_prog *program;
2605 struct tasdevice_config *conf;
2606 int prog_status = 0;
2607 int status, i;
2608
2609 if (!tas_fmw) {
2610 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2611 goto out;
2612 }
2613
2614 if (cfg_no >= tas_fmw->nr_configurations) {
2615 dev_err(tas_priv->dev,
2616 "%s: cfg(%d) is not in range of conf %u\n",
2617 __func__, cfg_no, tas_fmw->nr_configurations);
2618 goto out;
2619 }
2620
2621 if (prm_no >= tas_fmw->nr_programs) {
2622 dev_err(tas_priv->dev,
2623 "%s: prm(%d) is not in range of Programs %u\n",
2624 __func__, prm_no, tas_fmw->nr_programs);
2625 goto out;
2626 }
2627
2628 if (rca_conf_no >= rca->ncfgs || rca_conf_no < 0 ||
2629 !cfg_info) {
2630 dev_err(tas_priv->dev,
2631 "conf_no:%d should be in range from 0 to %u\n",
2632 rca_conf_no, rca->ncfgs-1);
2633 goto out;
2634 }
2635
2636 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2637 if (cfg_info[rca_conf_no]->active_dev & (1 << i)) {
2638 if (prm_no >= 0
2639 && (tas_priv->tasdevice[i].cur_prog != prm_no
2640 || tas_priv->force_fwload_status)) {
2641 tas_priv->tasdevice[i].cur_conf = -1;
2642 tas_priv->tasdevice[i].is_loading = true;
2643 prog_status++;
2644 }
2645 } else
2646 tas_priv->tasdevice[i].is_loading = false;
2647 tas_priv->tasdevice[i].is_loaderr = false;
2648 }
2649
2650 if (prog_status) {
2651 program = &(tas_fmw->programs[prm_no]);
2652 tasdevice_load_data(tas_priv, &(program->dev_data));
2653 for (i = 0; i < tas_priv->ndev; i++) {
2654 if (tas_priv->tasdevice[i].is_loaderr == true)
2655 continue;
2656 if (tas_priv->tasdevice[i].is_loaderr == false &&
2657 tas_priv->tasdevice[i].is_loading == true)
2658 tas_priv->tasdevice[i].cur_prog = prm_no;
2659 }
2660 }
2661
2662 for (i = 0, status = 0; i < tas_priv->ndev; i++) {
2663 if (cfg_no >= 0
2664 && tas_priv->tasdevice[i].cur_conf != cfg_no
2665 && (cfg_info[rca_conf_no]->active_dev & (1 << i))
2666 && (tas_priv->tasdevice[i].is_loaderr == false)) {
2667 status++;
2668 tas_priv->tasdevice[i].is_loading = true;
2669 } else
2670 tas_priv->tasdevice[i].is_loading = false;
2671 }
2672
2673 if (status) {
2674 conf = &(tas_fmw->configs[cfg_no]);
2675 status = 0;
2676 tasdevice_load_data(tas_priv, &(conf->dev_data));
2677 for (i = 0; i < tas_priv->ndev; i++) {
2678 if (tas_priv->tasdevice[i].is_loaderr == true) {
2679 status |= BIT(i + 4);
2680 continue;
2681 }
2682
2683 if (tas_priv->tasdevice[i].is_loaderr == false &&
2684 tas_priv->tasdevice[i].is_loading == true) {
2685 tasdev_load_calibrated_data(tas_priv, i);
2686 tas_priv->tasdevice[i].cur_conf = cfg_no;
2687 }
2688 }
2689 } else {
2690 dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n",
2691 __func__, cfg_no);
2692 }
2693
2694 status |= cfg_info[rca_conf_no]->active_dev;
2695
2696 out:
2697 return prog_status;
2698 }
2699 EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg, "SND_SOC_TAS2781_FMWLIB");
2700
tasdevice_prmg_load(void * context,int prm_no)2701 int tasdevice_prmg_load(void *context, int prm_no)
2702 {
2703 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2704 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2705 struct tasdevice_prog *program;
2706 int prog_status = 0;
2707 int i;
2708
2709 if (!tas_fmw) {
2710 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2711 goto out;
2712 }
2713
2714 if (prm_no >= tas_fmw->nr_programs) {
2715 dev_err(tas_priv->dev,
2716 "%s: prm(%d) is not in range of Programs %u\n",
2717 __func__, prm_no, tas_fmw->nr_programs);
2718 goto out;
2719 }
2720
2721 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2722 if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
2723 tas_priv->tasdevice[i].cur_conf = -1;
2724 tas_priv->tasdevice[i].is_loading = true;
2725 prog_status++;
2726 }
2727 }
2728
2729 if (prog_status) {
2730 program = &(tas_fmw->programs[prm_no]);
2731 tasdevice_load_data(tas_priv, &(program->dev_data));
2732 for (i = 0; i < tas_priv->ndev; i++) {
2733 if (tas_priv->tasdevice[i].is_loaderr == true)
2734 continue;
2735 else if (tas_priv->tasdevice[i].is_loaderr == false
2736 && tas_priv->tasdevice[i].is_loading == true)
2737 tas_priv->tasdevice[i].cur_prog = prm_no;
2738 }
2739 }
2740
2741 out:
2742 return prog_status;
2743 }
2744 EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, "SND_SOC_TAS2781_FMWLIB");
2745
tasdevice_tuning_switch(void * context,int state)2746 void tasdevice_tuning_switch(void *context, int state)
2747 {
2748 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2749 struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2750 int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
2751
2752 /*
2753 * Only RCA-based Playback can still work with no dsp program running
2754 * inside the chip.
2755 */
2756 switch (tas_priv->fw_state) {
2757 case TASDEVICE_RCA_FW_OK:
2758 case TASDEVICE_DSP_FW_ALL_OK:
2759 break;
2760 default:
2761 return;
2762 }
2763
2764 if (state == 0) {
2765 if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) {
2766 /* dsp mode or tuning mode */
2767 profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
2768 tasdevice_select_tuningprm_cfg(tas_priv,
2769 tas_priv->cur_prog, tas_priv->cur_conf,
2770 profile_cfg_id);
2771 }
2772
2773 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
2774 TASDEVICE_BIN_BLK_PRE_POWER_UP);
2775 } else {
2776 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
2777 TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
2778 }
2779 }
2780 EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch, "SND_SOC_TAS2781_FMWLIB");
2781
2782 MODULE_DESCRIPTION("Texas Firmware Support");
2783 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");
2784 MODULE_LICENSE("GPL");
2785