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