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