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

source code of linux/sound/soc/codecs/tas2781-fmwlib.c