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