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