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