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