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