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