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