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