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