xref: /linux/sound/pci/hda/tas2781_spi_fwlib.c (revision 5d6ba5ab8582aa35c1ee98e47af28e6f6772596c)
1 // SPDX-License-Identifier: GPL-2.0
2 //
3 // TAS2781 HDA SPI driver
4 //
5 // Copyright 2024 - 2025 Texas Instruments, Inc.
6 //
7 // Author: Baojun Xu <baojun.xu@ti.com>
8 
9 #include <linux/crc8.h>
10 #include <linux/firmware.h>
11 #include <linux/init.h>
12 #include <linux/interrupt.h>
13 #include <linux/module.h>
14 #include <linux/slab.h>
15 #include <linux/types.h>
16 #include <linux/unaligned.h>
17 #include <sound/pcm_params.h>
18 #include <sound/soc.h>
19 #include <sound/tas2781-dsp.h>
20 #include <sound/tlv.h>
21 
22 #include "tas2781-spi.h"
23 
24 #define OFFSET_ERROR_BIT			BIT(31)
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 /* fixed m68k compiling issue: mapping table can save code field */
89 static const struct blktyp_devidx_map ppc3_tas2781_mapping_table[] = {
90 	{ MAIN_ALL_DEVICES_1X, 0x80 },
91 	{ MAIN_DEVICE_A_1X, 0x81 },
92 	{ COEFF_DEVICE_A_1X, 0x81 },
93 	{ PRE_DEVICE_A_1X, 0x81 },
94 	{ PRE_SOFTWARE_RESET_DEVICE_A, 0xC1 },
95 	{ POST_SOFTWARE_RESET_DEVICE_A, 0xC1 },
96 	{ MAIN_DEVICE_B_1X, 0x82 },
97 	{ COEFF_DEVICE_B_1X, 0x82 },
98 	{ PRE_DEVICE_B_1X, 0x82 },
99 	{ PRE_SOFTWARE_RESET_DEVICE_B, 0xC2 },
100 	{ POST_SOFTWARE_RESET_DEVICE_B, 0xC2 },
101 	{ MAIN_DEVICE_C_1X, 0x83 },
102 	{ COEFF_DEVICE_C_1X, 0x83 },
103 	{ PRE_DEVICE_C_1X, 0x83 },
104 	{ PRE_SOFTWARE_RESET_DEVICE_C, 0xC3 },
105 	{ POST_SOFTWARE_RESET_DEVICE_C, 0xC3 },
106 	{ MAIN_DEVICE_D_1X, 0x84 },
107 	{ COEFF_DEVICE_D_1X, 0x84 },
108 	{ PRE_DEVICE_D_1X, 0x84 },
109 	{ PRE_SOFTWARE_RESET_DEVICE_D, 0xC4 },
110 	{ POST_SOFTWARE_RESET_DEVICE_D, 0xC4 },
111 };
112 
113 static const struct blktyp_devidx_map ppc3_mapping_table[] = {
114 	{ MAIN_ALL_DEVICES_1X, 0x80 },
115 	{ MAIN_DEVICE_A_1X, 0x81 },
116 	{ COEFF_DEVICE_A_1X, 0xC1 },
117 	{ PRE_DEVICE_A_1X, 0xC1 },
118 	{ MAIN_DEVICE_B_1X, 0x82 },
119 	{ COEFF_DEVICE_B_1X, 0xC2 },
120 	{ PRE_DEVICE_B_1X, 0xC2 },
121 	{ MAIN_DEVICE_C_1X, 0x83 },
122 	{ COEFF_DEVICE_C_1X, 0xC3 },
123 	{ PRE_DEVICE_C_1X, 0xC3 },
124 	{ MAIN_DEVICE_D_1X, 0x84 },
125 	{ COEFF_DEVICE_D_1X, 0xC4 },
126 	{ PRE_DEVICE_D_1X, 0xC4 },
127 };
128 
129 static const struct blktyp_devidx_map non_ppc3_mapping_table[] = {
130 	{ MAIN_ALL_DEVICES, 0x80 },
131 	{ MAIN_DEVICE_A, 0x81 },
132 	{ COEFF_DEVICE_A, 0xC1 },
133 	{ PRE_DEVICE_A, 0xC1 },
134 	{ MAIN_DEVICE_B, 0x82 },
135 	{ COEFF_DEVICE_B, 0xC2 },
136 	{ PRE_DEVICE_B, 0xC2 },
137 	{ MAIN_DEVICE_C, 0x83 },
138 	{ COEFF_DEVICE_C, 0xC3 },
139 	{ PRE_DEVICE_C, 0xC3 },
140 	{ MAIN_DEVICE_D, 0x84 },
141 	{ COEFF_DEVICE_D, 0xC4 },
142 	{ PRE_DEVICE_D, 0xC4 },
143 };
144 
145 /*
146  * Device support different configurations for different scene,
147  * like voice, music, calibration, was write in regbin file.
148  * Will be stored into tas_priv after regbin was loaded.
149  */
tasdevice_add_config(struct tasdevice_priv * tas_priv,unsigned char * config_data,unsigned int config_size,int * status)150 static struct tasdevice_config_info *tasdevice_add_config(
151 	struct tasdevice_priv *tas_priv, unsigned char *config_data,
152 	unsigned int config_size, int *status)
153 {
154 	struct tasdevice_config_info *cfg_info;
155 	struct tasdev_blk_data **bk_da;
156 	unsigned int config_offset = 0;
157 	unsigned int i;
158 
159 	/*
160 	 * In most projects are many audio cases, such as music, handfree,
161 	 * receiver, games, audio-to-haptics, PMIC record, bypass mode,
162 	 * portrait, landscape, etc. Even in multiple audios, one or
163 	 * two of the chips will work for the special case, such as
164 	 * ultrasonic application. In order to support these variable-numbers
165 	 * of audio cases, flexible configs have been introduced in the
166 	 * DSP firmware.
167 	 */
168 	cfg_info = kzalloc(sizeof(*cfg_info), GFP_KERNEL);
169 	if (!cfg_info) {
170 		*status = -ENOMEM;
171 		return NULL;
172 	}
173 
174 	if (tas_priv->rcabin.fw_hdr.binary_version_num >= 0x105) {
175 		if ((config_offset + 64) > config_size) {
176 			*status = -EINVAL;
177 			dev_err(tas_priv->dev, "add conf: Out of boundary\n");
178 			goto config_err;
179 		}
180 		config_offset += 64;
181 	}
182 
183 	if ((config_offset + 4) > config_size) {
184 		*status = -EINVAL;
185 		dev_err(tas_priv->dev, "add config: Out of boundary\n");
186 		goto config_err;
187 	}
188 
189 	/*
190 	 * convert data[offset], data[offset + 1], data[offset + 2] and
191 	 * data[offset + 3] into host
192 	 */
193 	cfg_info->nblocks = get_unaligned_be32(&config_data[config_offset]);
194 	config_offset += 4;
195 
196 	/*
197 	 * Several kinds of dsp/algorithm firmwares can run on tas2781,
198 	 * the number and size of blk are not fixed and different among
199 	 * these firmwares.
200 	 */
201 	bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks,
202 		sizeof(*bk_da), GFP_KERNEL);
203 	if (!bk_da) {
204 		*status = -ENOMEM;
205 		goto config_err;
206 	}
207 	cfg_info->real_nblocks = 0;
208 	for (i = 0; i < cfg_info->nblocks; i++) {
209 		if (config_offset + 12 > config_size) {
210 			*status = -EINVAL;
211 			dev_err(tas_priv->dev,
212 				"%s: Out of boundary: i = %d nblocks = %u!\n",
213 				__func__, i, cfg_info->nblocks);
214 			goto block_err;
215 		}
216 		bk_da[i] = kzalloc(sizeof(*bk_da[i]), GFP_KERNEL);
217 		if (!bk_da[i]) {
218 			*status = -ENOMEM;
219 			goto block_err;
220 		}
221 
222 		bk_da[i]->dev_idx = config_data[config_offset];
223 		config_offset++;
224 
225 		bk_da[i]->block_type = config_data[config_offset];
226 		config_offset++;
227 
228 		bk_da[i]->yram_checksum =
229 			get_unaligned_be16(&config_data[config_offset]);
230 		config_offset += 2;
231 		bk_da[i]->block_size =
232 			get_unaligned_be32(&config_data[config_offset]);
233 		config_offset += 4;
234 
235 		bk_da[i]->n_subblks =
236 			get_unaligned_be32(&config_data[config_offset]);
237 
238 		config_offset += 4;
239 
240 		if (config_offset + bk_da[i]->block_size > config_size) {
241 			*status = -EINVAL;
242 			dev_err(tas_priv->dev,
243 				"%s: Out of boundary: i = %d blks = %u!\n",
244 				__func__, i, cfg_info->nblocks);
245 			goto block_err;
246 		}
247 		/* instead of kzalloc+memcpy */
248 		bk_da[i]->regdata = kmemdup(&config_data[config_offset],
249 			bk_da[i]->block_size, GFP_KERNEL);
250 		if (!bk_da[i]->regdata) {
251 			*status = -ENOMEM;
252 			i++;
253 			goto block_err;
254 		}
255 
256 		config_offset += bk_da[i]->block_size;
257 		cfg_info->real_nblocks += 1;
258 	}
259 
260 	return cfg_info;
261 block_err:
262 	for (int j = 0; j < i; j++)
263 		kfree(bk_da[j]);
264 	kfree(bk_da);
265 config_err:
266 	kfree(cfg_info);
267 	return NULL;
268 }
269 
270 /* Regbin file parser function. */
tasdevice_spi_rca_parser(void * context,const struct firmware * fmw)271 int tasdevice_spi_rca_parser(void *context, const struct firmware *fmw)
272 {
273 	struct tasdevice_priv *tas_priv = context;
274 	struct tasdevice_config_info **cfg_info;
275 	struct tasdevice_rca_hdr *fw_hdr;
276 	struct tasdevice_rca *rca;
277 	unsigned int total_config_sz = 0;
278 	int offset = 0, ret = 0, i;
279 	unsigned char *buf;
280 
281 	rca = &tas_priv->rcabin;
282 	fw_hdr = &rca->fw_hdr;
283 	if (!fmw || !fmw->data) {
284 		dev_err(tas_priv->dev, "Failed to read %s\n",
285 			tas_priv->rca_binaryname);
286 		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
287 		return -EINVAL;
288 	}
289 	buf = (unsigned char *)fmw->data;
290 	fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
291 	offset += 4;
292 	if (fw_hdr->img_sz != fmw->size) {
293 		dev_err(tas_priv->dev,
294 			"File size not match, %d %u", (int)fmw->size,
295 			fw_hdr->img_sz);
296 		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
297 		return -EINVAL;
298 	}
299 
300 	fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
301 	offset += 4;
302 	fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
303 	if (fw_hdr->binary_version_num < 0x103) {
304 		dev_err(tas_priv->dev, "File version 0x%04x is too low",
305 			fw_hdr->binary_version_num);
306 		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
307 		return -EINVAL;
308 	}
309 	offset += 4;
310 	fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
311 	offset += 8;
312 	fw_hdr->plat_type = buf[offset++];
313 	fw_hdr->dev_family = buf[offset++];
314 	fw_hdr->reserve = buf[offset++];
315 	fw_hdr->ndev = buf[offset++];
316 	if (offset + TASDEVICE_DEVICE_SUM > fw_hdr->img_sz) {
317 		dev_err(tas_priv->dev, "rca_ready: Out of boundary!\n");
318 		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
319 		return -EINVAL;
320 	}
321 
322 	for (i = 0; i < TASDEVICE_DEVICE_SUM; i++, offset++)
323 		fw_hdr->devs[i] = buf[offset];
324 
325 	fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
326 	offset += 4;
327 
328 	for (i = 0; i < TASDEVICE_CONFIG_SUM; i++) {
329 		fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
330 		offset += 4;
331 		total_config_sz += fw_hdr->config_size[i];
332 	}
333 
334 	if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) {
335 		dev_err(tas_priv->dev, "Bin file err %d - %d != %d!\n",
336 			fw_hdr->img_sz, total_config_sz, (int)offset);
337 		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
338 		return -EINVAL;
339 	}
340 
341 	cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL);
342 	if (!cfg_info) {
343 		tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
344 		return -ENOMEM;
345 	}
346 	rca->cfg_info = cfg_info;
347 	rca->ncfgs = 0;
348 	for (i = 0; i < (int)fw_hdr->nconfig; i++) {
349 		rca->ncfgs += 1;
350 		cfg_info[i] = tasdevice_add_config(tas_priv, &buf[offset],
351 			fw_hdr->config_size[i], &ret);
352 		if (ret) {
353 			tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL;
354 			return ret;
355 		}
356 		offset += (int)fw_hdr->config_size[i];
357 	}
358 
359 	return ret;
360 }
361 
362 /* fixed m68k compiling issue: mapping table can save code field */
map_dev_idx(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block)363 static unsigned char map_dev_idx(struct tasdevice_fw *tas_fmw,
364 	struct tasdev_blk *block)
365 {
366 	struct blktyp_devidx_map *p =
367 		(struct blktyp_devidx_map *)non_ppc3_mapping_table;
368 	struct tasdevice_dspfw_hdr *fw_hdr = &tas_fmw->fw_hdr;
369 	struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &fw_hdr->fixed_hdr;
370 	int i, n = ARRAY_SIZE(non_ppc3_mapping_table);
371 	unsigned char dev_idx = 0;
372 
373 	if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN) {
374 		p = (struct blktyp_devidx_map *)ppc3_tas2781_mapping_table;
375 		n = ARRAY_SIZE(ppc3_tas2781_mapping_table);
376 	} else if (fw_fixed_hdr->ppcver >= PPC3_VERSION_BASE) {
377 		p = (struct blktyp_devidx_map *)ppc3_mapping_table;
378 		n = ARRAY_SIZE(ppc3_mapping_table);
379 	}
380 
381 	for (i = 0; i < n; i++) {
382 		if (block->type == p[i].blktyp) {
383 			dev_idx = p[i].dev_idx;
384 			break;
385 		}
386 	}
387 
388 	return dev_idx;
389 }
390 
391 /* Block parser function. */
fw_parse_block_data_kernel(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block,const struct firmware * fmw,int offset)392 static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw,
393 	struct tasdev_blk *block, const struct firmware *fmw, int offset)
394 {
395 	const unsigned char *data = fmw->data;
396 
397 	if (offset + 16 > fmw->size) {
398 		dev_err(tas_fmw->dev, "%s: File Size error\n", __func__);
399 		return -EINVAL;
400 	}
401 
402 	/*
403 	 * Convert data[offset], data[offset + 1], data[offset + 2] and
404 	 * data[offset + 3] into host.
405 	 */
406 	block->type = get_unaligned_be32(&data[offset]);
407 	offset += 4;
408 
409 	block->is_pchksum_present = data[offset++];
410 	block->pchksum = data[offset++];
411 	block->is_ychksum_present = data[offset++];
412 	block->ychksum = data[offset++];
413 	block->blk_size = get_unaligned_be32(&data[offset]);
414 	offset += 4;
415 	block->nr_subblocks = get_unaligned_be32(&data[offset]);
416 	offset += 4;
417 
418 	/*
419 	 * Fixed m68k compiling issue:
420 	 * 1. mapping table can save code field.
421 	 * 2. storing the dev_idx as a member of block can reduce unnecessary
422 	 *    time and system resource comsumption of dev_idx mapping every
423 	 *    time the block data writing to the dsp.
424 	 */
425 	block->dev_idx = map_dev_idx(tas_fmw, block);
426 
427 	if (offset + block->blk_size > fmw->size) {
428 		dev_err(tas_fmw->dev, "%s: nSublocks error\n", __func__);
429 		return -EINVAL;
430 	}
431 	/* instead of kzalloc+memcpy */
432 	block->data = kmemdup(&data[offset], block->blk_size, GFP_KERNEL);
433 	if (!block->data)
434 		return -ENOMEM;
435 
436 	offset += block->blk_size;
437 
438 	return offset;
439 }
440 
441 /* Data of block parser function. */
fw_parse_data_kernel(struct tasdevice_fw * tas_fmw,struct tasdevice_data * img_data,const struct firmware * fmw,int offset)442 static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw,
443 	struct tasdevice_data *img_data, const struct firmware *fmw,
444 	int offset)
445 {
446 	const unsigned char *data = fmw->data;
447 	struct tasdev_blk *blk;
448 	unsigned int i;
449 
450 	if (offset + 4 > fmw->size) {
451 		dev_err(tas_fmw->dev, "%s: File Size error\n", __func__);
452 		return -EINVAL;
453 	}
454 	img_data->nr_blk = get_unaligned_be32(&data[offset]);
455 	offset += 4;
456 
457 	img_data->dev_blks = kcalloc(img_data->nr_blk,
458 		sizeof(struct tasdev_blk), GFP_KERNEL);
459 	if (!img_data->dev_blks)
460 		return -ENOMEM;
461 
462 	for (i = 0; i < img_data->nr_blk; i++) {
463 		blk = &img_data->dev_blks[i];
464 		offset = fw_parse_block_data_kernel(
465 			tas_fmw, blk, fmw, offset);
466 		if (offset < 0) {
467 			kfree(img_data->dev_blks);
468 			return -EINVAL;
469 		}
470 	}
471 
472 	return offset;
473 }
474 
475 /* Data of DSP program parser function. */
fw_parse_program_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)476 static int fw_parse_program_data_kernel(
477 	struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw,
478 	const struct firmware *fmw, int offset)
479 {
480 	struct tasdevice_prog *program;
481 	unsigned int i;
482 
483 	for (i = 0; i < tas_fmw->nr_programs; i++) {
484 		program = &tas_fmw->programs[i];
485 		if (offset + 72 > fmw->size) {
486 			dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
487 			return -EINVAL;
488 		}
489 		/* skip 72 unused byts */
490 		offset += 72;
491 
492 		offset = fw_parse_data_kernel(tas_fmw, &program->dev_data,
493 			fmw, offset);
494 		if (offset < 0)
495 			break;
496 	}
497 
498 	return offset;
499 }
500 
501 /* Data of DSP configurations parser function. */
fw_parse_configuration_data_kernel(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)502 static int fw_parse_configuration_data_kernel(struct tasdevice_priv *tas_priv,
503 	struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
504 {
505 	const unsigned char *data = fmw->data;
506 	struct tasdevice_config *config;
507 	unsigned int i;
508 
509 	for (i = 0; i < tas_fmw->nr_configurations; i++) {
510 		config = &tas_fmw->configs[i];
511 		if (offset + 80 > fmw->size) {
512 			dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
513 			return -EINVAL;
514 		}
515 		memcpy(config->name, &data[offset], 64);
516 		/* skip extra 16 bytes */
517 		offset += 80;
518 
519 		offset = fw_parse_data_kernel(tas_fmw, &config->dev_data,
520 			fmw, offset);
521 		if (offset < 0)
522 			break;
523 	}
524 
525 	return offset;
526 }
527 
528 /* DSP firmware file header parser function for early PPC3 firmware binary. */
fw_parse_variable_header_kernel(struct tasdevice_priv * tas_priv,const struct firmware * fmw,int offset)529 static int fw_parse_variable_header_kernel(struct tasdevice_priv *tas_priv,
530 	const struct firmware *fmw, int offset)
531 {
532 	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
533 	struct tasdevice_dspfw_hdr *fw_hdr = &tas_fmw->fw_hdr;
534 	struct tasdevice_config *config;
535 	struct tasdevice_prog *program;
536 	const unsigned char *buf = fmw->data;
537 	unsigned short max_confs;
538 	unsigned int i;
539 
540 	if (offset + 12 + 4 * TASDEVICE_MAXPROGRAM_NUM_KERNEL > fmw->size) {
541 		dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
542 		return -EINVAL;
543 	}
544 	fw_hdr->device_family = get_unaligned_be16(&buf[offset]);
545 	if (fw_hdr->device_family != 0) {
546 		dev_err(tas_priv->dev, "%s:not TAS device\n", __func__);
547 		return -EINVAL;
548 	}
549 	offset += 2;
550 	fw_hdr->device = get_unaligned_be16(&buf[offset]);
551 	if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
552 	    fw_hdr->device == 6) {
553 		dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
554 		return -EINVAL;
555 	}
556 	offset += 2;
557 
558 	tas_fmw->nr_programs = get_unaligned_be32(&buf[offset]);
559 	offset += 4;
560 
561 	if (tas_fmw->nr_programs == 0 ||
562 	    tas_fmw->nr_programs > TASDEVICE_MAXPROGRAM_NUM_KERNEL) {
563 		dev_err(tas_priv->dev, "mnPrograms is invalid\n");
564 		return -EINVAL;
565 	}
566 
567 	tas_fmw->programs = kcalloc(tas_fmw->nr_programs,
568 		sizeof(*tas_fmw->programs), GFP_KERNEL);
569 	if (!tas_fmw->programs)
570 		return -ENOMEM;
571 
572 	for (i = 0; i < tas_fmw->nr_programs; i++) {
573 		program = &tas_fmw->programs[i];
574 		program->prog_size = get_unaligned_be32(&buf[offset]);
575 		offset += 4;
576 	}
577 
578 	/* Skip the unused prog_size */
579 	offset += 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs);
580 
581 	tas_fmw->nr_configurations = get_unaligned_be32(&buf[offset]);
582 	offset += 4;
583 
584 	/*
585 	 * The max number of config in firmware greater than 4 pieces of
586 	 * tas2781s is different from the one lower than 4 pieces of
587 	 * tas2781s.
588 	 */
589 	max_confs = TASDEVICE_MAXCONFIG_NUM_KERNEL;
590 	if (tas_fmw->nr_configurations == 0 ||
591 	    tas_fmw->nr_configurations > max_confs) {
592 		dev_err(tas_priv->dev, "%s: Conf is invalid\n", __func__);
593 		kfree(tas_fmw->programs);
594 		return -EINVAL;
595 	}
596 
597 	if (offset + 4 * max_confs > fmw->size) {
598 		dev_err(tas_priv->dev, "%s: mpConfigurations err\n", __func__);
599 		kfree(tas_fmw->programs);
600 		return -EINVAL;
601 	}
602 
603 	tas_fmw->configs = kcalloc(tas_fmw->nr_configurations,
604 		sizeof(*tas_fmw->configs), GFP_KERNEL);
605 	if (!tas_fmw->configs) {
606 		kfree(tas_fmw->programs);
607 		return -ENOMEM;
608 	}
609 
610 	for (i = 0; i < tas_fmw->nr_programs; i++) {
611 		config = &tas_fmw->configs[i];
612 		config->cfg_size = get_unaligned_be32(&buf[offset]);
613 		offset += 4;
614 	}
615 
616 	/* Skip the unused configs */
617 	offset += 4 * (max_confs - tas_fmw->nr_programs);
618 
619 	return offset;
620 }
621 
622 /*
623  * In sub-block data, have three type sub-block:
624  * 1. Single byte write.
625  * 2. Multi-byte write.
626  * 3. Delay.
627  * 4. Bits update.
628  * This function perform single byte write to device.
629  */
tasdevice_single_byte_wr(void * context,int dev_idx,unsigned char * data,int sublocksize)630 static int tasdevice_single_byte_wr(void *context, int dev_idx,
631 				    unsigned char *data, int sublocksize)
632 {
633 	struct tasdevice_priv *tas_priv = context;
634 	unsigned short len = get_unaligned_be16(&data[2]);
635 	int i, subblk_offset, rc;
636 
637 	subblk_offset = 4;
638 	if (subblk_offset + 4 * len > sublocksize) {
639 		dev_err(tas_priv->dev, "process_block: Out of boundary\n");
640 		return 0;
641 	}
642 
643 	for (i = 0; i < len; i++) {
644 		if (dev_idx == (tas_priv->index + 1) || dev_idx == 0) {
645 			rc = tasdevice_spi_dev_write(tas_priv,
646 				TASDEVICE_REG(data[subblk_offset],
647 				data[subblk_offset + 1],
648 				data[subblk_offset + 2]),
649 				data[subblk_offset + 3]);
650 			if (rc < 0) {
651 				dev_err(tas_priv->dev,
652 					"process_block: single write error\n");
653 				subblk_offset |= OFFSET_ERROR_BIT;
654 			}
655 		}
656 		subblk_offset += 4;
657 	}
658 
659 	return subblk_offset;
660 }
661 
662 /*
663  * In sub-block data, have three type sub-block:
664  * 1. Single byte write.
665  * 2. Multi-byte write.
666  * 3. Delay.
667  * 4. Bits update.
668  * This function perform multi-write to device.
669  */
tasdevice_burst_wr(void * context,int dev_idx,unsigned char * data,int sublocksize)670 static int tasdevice_burst_wr(void *context, int dev_idx, unsigned char *data,
671 	int sublocksize)
672 {
673 	struct tasdevice_priv *tas_priv = context;
674 	unsigned short len = get_unaligned_be16(&data[2]);
675 	int subblk_offset, rc;
676 
677 	subblk_offset = 4;
678 	if (subblk_offset + 4 + len > sublocksize) {
679 		dev_err(tas_priv->dev, "%s: BST Out of boundary\n", __func__);
680 		subblk_offset |= OFFSET_ERROR_BIT;
681 	}
682 	if (len % 4) {
683 		dev_err(tas_priv->dev, "%s:Bst-len(%u)not div by 4\n",
684 			__func__, len);
685 		subblk_offset |= OFFSET_ERROR_BIT;
686 	}
687 
688 	if (dev_idx == (tas_priv->index + 1) || dev_idx == 0) {
689 		rc = tasdevice_spi_dev_bulk_write(tas_priv,
690 			TASDEVICE_REG(data[subblk_offset],
691 				      data[subblk_offset + 1],
692 				      data[subblk_offset + 2]),
693 				      &data[subblk_offset + 4], len);
694 		if (rc < 0) {
695 			dev_err(tas_priv->dev, "%s: bulk_write error = %d\n",
696 				__func__, rc);
697 			subblk_offset |= OFFSET_ERROR_BIT;
698 		}
699 	}
700 	subblk_offset += (len + 4);
701 
702 	return subblk_offset;
703 }
704 
705 /* Just delay for ms.*/
tasdevice_delay(void * context,int dev_idx,unsigned char * data,int sublocksize)706 static int tasdevice_delay(void *context, int dev_idx, unsigned char *data,
707 	int sublocksize)
708 {
709 	struct tasdevice_priv *tas_priv = context;
710 	unsigned int sleep_time, subblk_offset = 2;
711 
712 	if (subblk_offset + 2 > sublocksize) {
713 		dev_err(tas_priv->dev, "%s: delay Out of boundary\n",
714 			__func__);
715 		subblk_offset |= OFFSET_ERROR_BIT;
716 	}
717 	if (dev_idx == (tas_priv->index + 1) || dev_idx == 0) {
718 		sleep_time = get_unaligned_be16(&data[2]) * 1000;
719 		fsleep(sleep_time);
720 	}
721 	subblk_offset += 2;
722 
723 	return subblk_offset;
724 }
725 
726 /*
727  * In sub-block data, have three type sub-block:
728  * 1. Single byte write.
729  * 2. Multi-byte write.
730  * 3. Delay.
731  * 4. Bits update.
732  * This function perform bits update.
733  */
tasdevice_field_wr(void * context,int dev_idx,unsigned char * data,int sublocksize)734 static int tasdevice_field_wr(void *context, int dev_idx, unsigned char *data,
735 	int sublocksize)
736 {
737 	struct tasdevice_priv *tas_priv = context;
738 	int rc, subblk_offset = 2;
739 
740 	if (subblk_offset + 6 > sublocksize) {
741 		dev_err(tas_priv->dev, "%s: bit write Out of boundary\n",
742 			__func__);
743 		subblk_offset |= OFFSET_ERROR_BIT;
744 	}
745 	if (dev_idx == (tas_priv->index + 1) || dev_idx == 0) {
746 		rc = tasdevice_spi_dev_update_bits(tas_priv,
747 			TASDEVICE_REG(data[subblk_offset + 2],
748 			data[subblk_offset + 3],
749 			data[subblk_offset + 4]),
750 			data[subblk_offset + 1],
751 			data[subblk_offset + 5]);
752 		if (rc < 0) {
753 			dev_err(tas_priv->dev, "%s: update_bits error = %d\n",
754 				__func__, rc);
755 			subblk_offset |= OFFSET_ERROR_BIT;
756 		}
757 	}
758 	subblk_offset += 6;
759 
760 	return subblk_offset;
761 }
762 
763 /* Data block process function. */
tasdevice_process_block(void * context,unsigned char * data,unsigned char dev_idx,int sublocksize)764 static int tasdevice_process_block(void *context, unsigned char *data,
765 	unsigned char dev_idx, int sublocksize)
766 {
767 	struct tasdevice_priv *tas_priv = context;
768 	int blktyp = dev_idx & 0xC0, subblk_offset;
769 	unsigned char subblk_typ = data[1];
770 
771 	switch (subblk_typ) {
772 	case TASDEVICE_CMD_SING_W:
773 		subblk_offset = tasdevice_single_byte_wr(tas_priv,
774 			dev_idx & 0x3f, data, sublocksize);
775 		break;
776 	case TASDEVICE_CMD_BURST:
777 		subblk_offset = tasdevice_burst_wr(tas_priv,
778 			dev_idx & 0x3f, data, sublocksize);
779 		break;
780 	case TASDEVICE_CMD_DELAY:
781 		subblk_offset = tasdevice_delay(tas_priv,
782 			dev_idx & 0x3f, data, sublocksize);
783 		break;
784 	case TASDEVICE_CMD_FIELD_W:
785 		subblk_offset = tasdevice_field_wr(tas_priv,
786 			dev_idx & 0x3f, data, sublocksize);
787 		break;
788 	default:
789 		subblk_offset = 2;
790 		break;
791 	}
792 	if (((subblk_offset & OFFSET_ERROR_BIT) != 0) && blktyp != 0) {
793 		if (blktyp == 0x80) {
794 			tas_priv->cur_prog = -1;
795 			tas_priv->cur_conf = -1;
796 		} else
797 			tas_priv->cur_conf = -1;
798 	}
799 	subblk_offset &= ~OFFSET_ERROR_BIT;
800 
801 	return subblk_offset;
802 }
803 
804 /*
805  * Device support different configurations for different scene,
806  * this function was used for choose different config.
807  */
tasdevice_spi_select_cfg_blk(void * pContext,int conf_no,unsigned char block_type)808 void tasdevice_spi_select_cfg_blk(void *pContext, int conf_no,
809 	unsigned char block_type)
810 {
811 	struct tasdevice_priv *tas_priv = pContext;
812 	struct tasdevice_rca *rca = &tas_priv->rcabin;
813 	struct tasdevice_config_info **cfg_info = rca->cfg_info;
814 	struct tasdev_blk_data **blk_data;
815 	unsigned int j, k;
816 
817 	if (conf_no >= rca->ncfgs || conf_no < 0 || !cfg_info) {
818 		dev_err(tas_priv->dev, "conf_no should be not more than %u\n",
819 			rca->ncfgs);
820 		return;
821 	}
822 	blk_data = cfg_info[conf_no]->blk_data;
823 
824 	for (j = 0; j < cfg_info[conf_no]->real_nblocks; j++) {
825 		unsigned int length = 0, rc = 0;
826 
827 		if (block_type > 5 || block_type < 2) {
828 			dev_err(tas_priv->dev,
829 				"block_type should be in range from 2 to 5\n");
830 			break;
831 		}
832 		if (block_type != blk_data[j]->block_type)
833 			continue;
834 
835 		for (k = 0; k < blk_data[j]->n_subblks; k++) {
836 			tas_priv->is_loading = true;
837 
838 			rc = tasdevice_process_block(tas_priv,
839 				blk_data[j]->regdata + length,
840 				blk_data[j]->dev_idx,
841 				blk_data[j]->block_size - length);
842 			length += rc;
843 			if (blk_data[j]->block_size < length) {
844 				dev_err(tas_priv->dev,
845 					"%s: %u %u out of boundary\n",
846 					__func__, length,
847 					blk_data[j]->block_size);
848 				break;
849 			}
850 		}
851 		if (length != blk_data[j]->block_size)
852 			dev_err(tas_priv->dev, "%s: %u %u size is not same\n",
853 				__func__, length, blk_data[j]->block_size);
854 	}
855 }
856 
857 /* Block process function. */
tasdevice_load_block_kernel(struct tasdevice_priv * tasdevice,struct tasdev_blk * block)858 static int tasdevice_load_block_kernel(
859 	struct tasdevice_priv *tasdevice, struct tasdev_blk *block)
860 {
861 	const unsigned int blk_size = block->blk_size;
862 	unsigned char *data = block->data;
863 	unsigned int i, length;
864 
865 	for (i = 0, length = 0; i < block->nr_subblocks; i++) {
866 		int rc = tasdevice_process_block(tasdevice, data + length,
867 			block->dev_idx, blk_size - length);
868 		if (rc < 0) {
869 			dev_err(tasdevice->dev,
870 				"%s: %u %u sublock write error\n",
871 				__func__, length, blk_size);
872 			return rc;
873 		}
874 		length += rc;
875 		if (blk_size < length) {
876 			dev_err(tasdevice->dev, "%s: %u %u out of boundary\n",
877 				__func__, length, blk_size);
878 			rc = -ENOMEM;
879 			return rc;
880 		}
881 	}
882 
883 	return 0;
884 }
885 
886 /* DSP firmware file header parser function. */
fw_parse_variable_hdr(struct tasdevice_priv * tas_priv,struct tasdevice_dspfw_hdr * fw_hdr,const struct firmware * fmw,int offset)887 static int fw_parse_variable_hdr(struct tasdevice_priv *tas_priv,
888 	struct tasdevice_dspfw_hdr *fw_hdr,
889 	const struct firmware *fmw, int offset)
890 {
891 	const unsigned char *buf = fmw->data;
892 	int len = strlen((char *)&buf[offset]);
893 
894 	len++;
895 
896 	if (offset + len + 8 > fmw->size) {
897 		dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
898 		return -EINVAL;
899 	}
900 
901 	offset += len;
902 
903 	fw_hdr->device_family = get_unaligned_be32(&buf[offset]);
904 	if (fw_hdr->device_family != 0) {
905 		dev_err(tas_priv->dev, "%s: not TAS device\n", __func__);
906 		return -EINVAL;
907 	}
908 	offset += 4;
909 
910 	fw_hdr->device = get_unaligned_be32(&buf[offset]);
911 	if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
912 	    fw_hdr->device == 6) {
913 		dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
914 		return -EINVAL;
915 	}
916 	offset += 4;
917 	fw_hdr->ndev = 1;
918 
919 	return offset;
920 }
921 
922 /* DSP firmware file header parser function for size variabled header. */
fw_parse_variable_header_git(struct tasdevice_priv * tas_priv,const struct firmware * fmw,int offset)923 static int fw_parse_variable_header_git(struct tasdevice_priv
924 	*tas_priv, const struct firmware *fmw, int offset)
925 {
926 	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
927 	struct tasdevice_dspfw_hdr *fw_hdr = &tas_fmw->fw_hdr;
928 
929 	offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset);
930 
931 	return offset;
932 }
933 
934 /* DSP firmware file block parser function. */
fw_parse_block_data(struct tasdevice_fw * tas_fmw,struct tasdev_blk * block,const struct firmware * fmw,int offset)935 static int fw_parse_block_data(struct tasdevice_fw *tas_fmw,
936 	struct tasdev_blk *block, const struct firmware *fmw, int offset)
937 {
938 	unsigned char *data = (unsigned char *)fmw->data;
939 	int n;
940 
941 	if (offset + 8 > fmw->size) {
942 		dev_err(tas_fmw->dev, "%s: Type error\n", __func__);
943 		return -EINVAL;
944 	}
945 	block->type = get_unaligned_be32(&data[offset]);
946 	offset += 4;
947 
948 	if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) {
949 		if (offset + 8 > fmw->size) {
950 			dev_err(tas_fmw->dev, "PChkSumPresent error\n");
951 			return -EINVAL;
952 		}
953 		block->is_pchksum_present = data[offset];
954 		offset++;
955 
956 		block->pchksum = data[offset];
957 		offset++;
958 
959 		block->is_ychksum_present = data[offset];
960 		offset++;
961 
962 		block->ychksum = data[offset];
963 		offset++;
964 	} else {
965 		block->is_pchksum_present = 0;
966 		block->is_ychksum_present = 0;
967 	}
968 
969 	block->nr_cmds = get_unaligned_be32(&data[offset]);
970 	offset += 4;
971 
972 	n = block->nr_cmds * 4;
973 	if (offset + n > fmw->size) {
974 		dev_err(tas_fmw->dev,
975 			"%s: File Size(%lu) error offset = %d n = %d\n",
976 			__func__, (unsigned long)fmw->size, offset, n);
977 		return -EINVAL;
978 	}
979 	/* instead of kzalloc+memcpy */
980 	block->data = kmemdup(&data[offset], n, GFP_KERNEL);
981 	if (!block->data)
982 		return -ENOMEM;
983 
984 	offset += n;
985 
986 	return offset;
987 }
988 
989 /*
990  * When parsing error occurs, all the memory resource will be released
991  * in the end of tasdevice_rca_ready.
992  */
fw_parse_data(struct tasdevice_fw * tas_fmw,struct tasdevice_data * img_data,const struct firmware * fmw,int offset)993 static int fw_parse_data(struct tasdevice_fw *tas_fmw,
994 	struct tasdevice_data *img_data, const struct firmware *fmw,
995 	int offset)
996 {
997 	const unsigned char *data = (unsigned char *)fmw->data;
998 	struct tasdev_blk *blk;
999 	unsigned int i, n;
1000 
1001 	if (offset + 64 > fmw->size) {
1002 		dev_err(tas_fmw->dev, "%s: Name error\n", __func__);
1003 		return -EINVAL;
1004 	}
1005 	memcpy(img_data->name, &data[offset], 64);
1006 	offset += 64;
1007 
1008 	n = strlen((char *)&data[offset]);
1009 	n++;
1010 	if (offset + n + 2 > fmw->size) {
1011 		dev_err(tas_fmw->dev, "%s: Description error\n", __func__);
1012 		return -EINVAL;
1013 	}
1014 	offset += n;
1015 	img_data->nr_blk = get_unaligned_be16(&data[offset]);
1016 	offset += 2;
1017 
1018 	img_data->dev_blks = kcalloc(img_data->nr_blk,
1019 		sizeof(*img_data->dev_blks), GFP_KERNEL);
1020 	if (!img_data->dev_blks)
1021 		return -ENOMEM;
1022 
1023 	for (i = 0; i < img_data->nr_blk; i++) {
1024 		blk = &img_data->dev_blks[i];
1025 		offset = fw_parse_block_data(tas_fmw, blk, fmw, offset);
1026 		if (offset < 0)
1027 			return -EINVAL;
1028 	}
1029 
1030 	return offset;
1031 }
1032 
1033 /*
1034  * When parsing error occurs, all the memory resource will be released
1035  * in the end of tasdevice_rca_ready.
1036  */
fw_parse_program_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1037 static int fw_parse_program_data(struct tasdevice_priv *tas_priv,
1038 	struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1039 {
1040 	unsigned char *buf = (unsigned char *)fmw->data;
1041 	struct tasdevice_prog *program;
1042 	int i;
1043 
1044 	if (offset + 2 > fmw->size) {
1045 		dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1046 		return -EINVAL;
1047 	}
1048 	tas_fmw->nr_programs = get_unaligned_be16(&buf[offset]);
1049 	offset += 2;
1050 
1051 	if (tas_fmw->nr_programs == 0) {
1052 		/* Not error in calibration Data file, return directly */
1053 		dev_dbg(tas_priv->dev, "%s: No Programs data, maybe calbin\n",
1054 			__func__);
1055 		return offset;
1056 	}
1057 
1058 	tas_fmw->programs =
1059 		kcalloc(tas_fmw->nr_programs, sizeof(*tas_fmw->programs),
1060 			GFP_KERNEL);
1061 	if (!tas_fmw->programs)
1062 		return -ENOMEM;
1063 
1064 	for (i = 0; i < tas_fmw->nr_programs; i++) {
1065 		int n = 0;
1066 
1067 		program = &tas_fmw->programs[i];
1068 		if (offset + 64 > fmw->size) {
1069 			dev_err(tas_priv->dev, "%s: mpName error\n", __func__);
1070 			return -EINVAL;
1071 		}
1072 		offset += 64;
1073 
1074 		n = strlen((char *)&buf[offset]);
1075 		/* skip '\0' and 5 unused bytes */
1076 		n += 6;
1077 		if (offset + n > fmw->size) {
1078 			dev_err(tas_priv->dev, "Description err\n");
1079 			return -EINVAL;
1080 		}
1081 
1082 		offset += n;
1083 
1084 		offset = fw_parse_data(tas_fmw, &program->dev_data, fmw,
1085 			offset);
1086 		if (offset < 0)
1087 			return offset;
1088 	}
1089 
1090 	return offset;
1091 }
1092 
1093 /*
1094  * When parsing error occurs, all the memory resource will be released
1095  * in the end of tasdevice_rca_ready.
1096  */
fw_parse_configuration_data(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1097 static int fw_parse_configuration_data(struct tasdevice_priv *tas_priv,
1098 	struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1099 {
1100 	unsigned char *data = (unsigned char *)fmw->data;
1101 	struct tasdevice_config *config;
1102 	unsigned int i, n;
1103 
1104 	if (offset + 2 > fmw->size) {
1105 		dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1106 		return -EINVAL;
1107 	}
1108 	tas_fmw->nr_configurations = get_unaligned_be16(&data[offset]);
1109 	offset += 2;
1110 
1111 	if (tas_fmw->nr_configurations == 0) {
1112 		dev_err(tas_priv->dev, "%s: Conf is zero\n", __func__);
1113 		/* Not error for calibration Data file, return directly */
1114 		return offset;
1115 	}
1116 	tas_fmw->configs = kcalloc(tas_fmw->nr_configurations,
1117 			sizeof(*tas_fmw->configs), GFP_KERNEL);
1118 	if (!tas_fmw->configs)
1119 		return -ENOMEM;
1120 	for (i = 0; i < tas_fmw->nr_configurations; i++) {
1121 		config = &tas_fmw->configs[i];
1122 		if (offset + 64 > fmw->size) {
1123 			dev_err(tas_priv->dev, "File Size err\n");
1124 			return -EINVAL;
1125 		}
1126 		memcpy(config->name, &data[offset], 64);
1127 		offset += 64;
1128 
1129 		n = strlen((char *)&data[offset]);
1130 		n += 15;
1131 		if (offset + n > fmw->size) {
1132 			dev_err(tas_priv->dev, "Description err\n");
1133 			return -EINVAL;
1134 		}
1135 		offset += n;
1136 		offset = fw_parse_data(tas_fmw, &config->dev_data,
1137 				       fmw, offset);
1138 		if (offset < 0)
1139 			break;
1140 	}
1141 
1142 	return offset;
1143 }
1144 
1145 /* yram5 page check. */
check_inpage_yram_rg(struct tas_crc * cd,unsigned char reg,unsigned char len)1146 static bool check_inpage_yram_rg(struct tas_crc *cd,
1147 	unsigned char reg, unsigned char len)
1148 {
1149 	bool in = false;
1150 
1151 	if (reg <= TAS2781_YRAM5_END_REG &&
1152 	    reg >= TAS2781_YRAM5_START_REG) {
1153 		if (reg + len > TAS2781_YRAM5_END_REG)
1154 			cd->len = TAS2781_YRAM5_END_REG - reg + 1;
1155 		else
1156 			cd->len = len;
1157 		cd->offset = reg;
1158 		in = true;
1159 	} else if (reg < TAS2781_YRAM5_START_REG) {
1160 		if (reg + len > TAS2781_YRAM5_START_REG) {
1161 			cd->offset = TAS2781_YRAM5_START_REG;
1162 			cd->len = len - TAS2781_YRAM5_START_REG + reg;
1163 			in = true;
1164 		}
1165 	}
1166 
1167 	return in;
1168 }
1169 
1170 /* DSP firmware yram block check. */
check_inpage_yram_bk1(struct tas_crc * cd,unsigned char page,unsigned char reg,unsigned char len)1171 static bool check_inpage_yram_bk1(struct tas_crc *cd,
1172 	unsigned char page, unsigned char reg, unsigned char len)
1173 {
1174 	bool in = false;
1175 
1176 	if (page == TAS2781_YRAM1_PAGE) {
1177 		if (reg >= TAS2781_YRAM1_START_REG) {
1178 			cd->offset = reg;
1179 			cd->len = len;
1180 			in = true;
1181 		} else if (reg + len > TAS2781_YRAM1_START_REG) {
1182 			cd->offset = TAS2781_YRAM1_START_REG;
1183 			cd->len = len - TAS2781_YRAM1_START_REG + reg;
1184 			in = true;
1185 		}
1186 	} else if (page == TAS2781_YRAM3_PAGE) {
1187 		in = check_inpage_yram_rg(cd, reg, len);
1188 	}
1189 
1190 	return in;
1191 }
1192 
1193 /*
1194  * Return Code:
1195  * true -- the registers are in the inpage yram
1196  * false -- the registers are NOT in the inpage yram
1197  */
check_inpage_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1198 static bool check_inpage_yram(struct tas_crc *cd, unsigned char book,
1199 	unsigned char page, unsigned char reg, unsigned char len)
1200 {
1201 	bool in = false;
1202 
1203 	if (book == TAS2781_YRAM_BOOK1)
1204 		in = check_inpage_yram_bk1(cd, page, reg, len);
1205 	else if (book == TAS2781_YRAM_BOOK2 && page == TAS2781_YRAM5_PAGE)
1206 		in = check_inpage_yram_rg(cd, reg, len);
1207 
1208 	return in;
1209 }
1210 
1211 /* yram4 page check. */
check_inblock_yram_bk(struct tas_crc * cd,unsigned char page,unsigned char reg,unsigned char len)1212 static bool check_inblock_yram_bk(struct tas_crc *cd,
1213 	unsigned char page, unsigned char reg, unsigned char len)
1214 {
1215 	bool in = false;
1216 
1217 	if ((page >= TAS2781_YRAM4_START_PAGE &&
1218 	     page <= TAS2781_YRAM4_END_PAGE) ||
1219 	    (page >= TAS2781_YRAM2_START_PAGE &&
1220 	     page <= TAS2781_YRAM2_END_PAGE)) {
1221 		if (reg <= TAS2781_YRAM2_END_REG &&
1222 		    reg >= TAS2781_YRAM2_START_REG) {
1223 			cd->offset = reg;
1224 			cd->len = len;
1225 			in = true;
1226 		} else if (reg < TAS2781_YRAM2_START_REG) {
1227 			if (reg + len - 1 >= TAS2781_YRAM2_START_REG) {
1228 				cd->offset = TAS2781_YRAM2_START_REG;
1229 				cd->len = reg + len - TAS2781_YRAM2_START_REG;
1230 				in = true;
1231 			}
1232 		}
1233 	}
1234 
1235 	return in;
1236 }
1237 
1238 /*
1239  * Return Code:
1240  * true -- the registers are in the inblock yram
1241  * false -- the registers are NOT in the inblock yram
1242  */
check_inblock_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1243 static bool check_inblock_yram(struct tas_crc *cd, unsigned char book,
1244 	unsigned char page, unsigned char reg, unsigned char len)
1245 {
1246 	bool in = false;
1247 
1248 	if (book == TAS2781_YRAM_BOOK1 || book == TAS2781_YRAM_BOOK2)
1249 		in = check_inblock_yram_bk(cd, page, reg, len);
1250 
1251 	return in;
1252 }
1253 
1254 /* yram page check. */
check_yram(struct tas_crc * cd,unsigned char book,unsigned char page,unsigned char reg,unsigned char len)1255 static bool check_yram(struct tas_crc *cd, unsigned char book,
1256 	unsigned char page, unsigned char reg, unsigned char len)
1257 {
1258 	bool in;
1259 
1260 	in = check_inpage_yram(cd, book, page, reg, len);
1261 	if (!in)
1262 		in = check_inblock_yram(cd, book, page, reg, len);
1263 
1264 	return in;
1265 }
1266 
1267 /* Checksum for data block. */
tasdev_multibytes_chksum(struct tasdevice_priv * tasdevice,unsigned char book,unsigned char page,unsigned char reg,unsigned int len)1268 static int tasdev_multibytes_chksum(struct tasdevice_priv *tasdevice,
1269 	unsigned char book, unsigned char page,
1270 	unsigned char reg, unsigned int len)
1271 {
1272 	struct tas_crc crc_data;
1273 	unsigned char crc_chksum = 0;
1274 	unsigned char nBuf1[128];
1275 	int ret = 0, i;
1276 	bool in;
1277 
1278 	if ((reg + len - 1) > 127) {
1279 		ret = -EINVAL;
1280 		dev_err(tasdevice->dev, "firmware error\n");
1281 		goto end;
1282 	}
1283 
1284 	if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1285 	    (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1286 	    (reg == TASDEVICE_REG_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1287 	    (len == 4)) {
1288 		/* DSP swap command, pass */
1289 		ret = 0;
1290 		goto end;
1291 	}
1292 
1293 	in = check_yram(&crc_data, book, page, reg, len);
1294 	if (!in)
1295 		goto end;
1296 
1297 	if (len == 1) {
1298 		dev_err(tasdevice->dev, "firmware error\n");
1299 		ret = -EINVAL;
1300 		goto end;
1301 	}
1302 
1303 	ret = tasdevice_spi_dev_bulk_read(tasdevice,
1304 		TASDEVICE_REG(book, page, crc_data.offset),
1305 		nBuf1, crc_data.len);
1306 	if (ret < 0)
1307 		goto end;
1308 
1309 	for (i = 0; i < crc_data.len; i++) {
1310 		if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1311 		    (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1312 		    ((i + crc_data.offset) >=
1313 			TASDEVICE_REG_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1314 		    ((i + crc_data.offset) <=
1315 			(TASDEVICE_REG_ID(TAS2781_SA_COEFF_SWAP_REG) + 4)))
1316 			/* DSP swap command, bypass */
1317 			continue;
1318 		else
1319 			crc_chksum += crc8(tasdevice->crc8_lkp_tbl, &nBuf1[i],
1320 				1, 0);
1321 	}
1322 
1323 	ret = crc_chksum;
1324 
1325 end:
1326 	return ret;
1327 }
1328 
1329 /* Checksum for single register. */
do_singlereg_checksum(struct tasdevice_priv * tasdevice,unsigned char book,unsigned char page,unsigned char reg,unsigned char val)1330 static int do_singlereg_checksum(struct tasdevice_priv *tasdevice,
1331 	unsigned char book, unsigned char page,
1332 	unsigned char reg, unsigned char val)
1333 {
1334 	struct tas_crc crc_data;
1335 	unsigned int nData1;
1336 	int ret = 0;
1337 	bool in;
1338 
1339 	/* DSP swap command, pass */
1340 	if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1341 	    (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1342 	    (reg >= TASDEVICE_REG_ID(TAS2781_SA_COEFF_SWAP_REG)) &&
1343 	    (reg <= (TASDEVICE_REG_ID(TAS2781_SA_COEFF_SWAP_REG) + 4)))
1344 		return 0;
1345 
1346 	in = check_yram(&crc_data, book, page, reg, 1);
1347 	if (!in)
1348 		return 0;
1349 	ret = tasdevice_spi_dev_read(tasdevice,
1350 		TASDEVICE_REG(book, page, reg), &nData1);
1351 	if (ret < 0)
1352 		return ret;
1353 
1354 	if (nData1 != val) {
1355 		dev_err(tasdevice->dev,
1356 			"B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n",
1357 			book, page, reg, val, nData1);
1358 		tasdevice->err_code |= ERROR_YRAM_CRCCHK;
1359 		return -EAGAIN;
1360 	}
1361 
1362 	ret = crc8(tasdevice->crc8_lkp_tbl, &val, 1, 0);
1363 
1364 	return ret;
1365 }
1366 
1367 /* Block type check. */
set_err_prg_cfg(unsigned int type,struct tasdevice_priv * p)1368 static void set_err_prg_cfg(unsigned int type, struct tasdevice_priv *p)
1369 {
1370 	if ((type == MAIN_ALL_DEVICES) || (type == MAIN_DEVICE_A) ||
1371 	    (type == MAIN_DEVICE_B) || (type == MAIN_DEVICE_C) ||
1372 	    (type == MAIN_DEVICE_D))
1373 		p->cur_prog = -1;
1374 	else
1375 		p->cur_conf = -1;
1376 }
1377 
1378 /* Checksum for data bytes. */
tasdev_bytes_chksum(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,unsigned char book,unsigned char page,unsigned char reg,unsigned int len,unsigned char val,unsigned char * crc_chksum)1379 static int tasdev_bytes_chksum(struct tasdevice_priv *tas_priv,
1380 	struct tasdev_blk *block, unsigned char book,
1381 	unsigned char page, unsigned char reg, unsigned int len,
1382 	unsigned char val, unsigned char *crc_chksum)
1383 {
1384 	int ret;
1385 
1386 	if (len > 1)
1387 		ret = tasdev_multibytes_chksum(tas_priv, book, page, reg,
1388 			len);
1389 	else
1390 		ret = do_singlereg_checksum(tas_priv, book, page, reg, val);
1391 
1392 	if (ret > 0) {
1393 		*crc_chksum += ret;
1394 		goto end;
1395 	}
1396 
1397 	if (ret != -EAGAIN)
1398 		goto end;
1399 
1400 	block->nr_retry--;
1401 	if (block->nr_retry > 0)
1402 		goto end;
1403 
1404 	set_err_prg_cfg(block->type, tas_priv);
1405 
1406 end:
1407 	return ret;
1408 }
1409 
1410 /* Multi-data byte write. */
tasdev_multibytes_wr(struct tasdevice_priv * tas_priv,struct tasdev_blk * block,unsigned char book,unsigned char page,unsigned char reg,unsigned char * data,unsigned int len,unsigned int * nr_cmds,unsigned char * crc_chksum)1411 static int tasdev_multibytes_wr(struct tasdevice_priv *tas_priv,
1412 	struct tasdev_blk *block, unsigned char book,
1413 	unsigned char page, unsigned char reg, unsigned char *data,
1414 	unsigned int len, unsigned int *nr_cmds,
1415 	unsigned char *crc_chksum)
1416 {
1417 	int ret;
1418 
1419 	if (len > 1) {
1420 		ret = tasdevice_spi_dev_bulk_write(tas_priv,
1421 			TASDEVICE_REG(book, page, reg), data + 3, len);
1422 		if (ret < 0)
1423 			return ret;
1424 		if (block->is_ychksum_present)
1425 			ret = tasdev_bytes_chksum(tas_priv, block,
1426 				book, page, reg, len, 0, crc_chksum);
1427 	} else {
1428 		ret = tasdevice_spi_dev_write(tas_priv,
1429 			TASDEVICE_REG(book, page, reg), data[3]);
1430 		if (ret < 0)
1431 			return ret;
1432 		if (block->is_ychksum_present)
1433 			ret = tasdev_bytes_chksum(tas_priv, block, book,
1434 				page, reg, 1, data[3], crc_chksum);
1435 	}
1436 
1437 	if (!block->is_ychksum_present || ret >= 0) {
1438 		*nr_cmds += 1;
1439 		if (len >= 2)
1440 			*nr_cmds += ((len - 2) / 4) + 1;
1441 	}
1442 
1443 	return ret;
1444 }
1445 
1446 /* Checksum for block. */
tasdev_block_chksum(struct tasdevice_priv * tas_priv,struct tasdev_blk * block)1447 static int tasdev_block_chksum(struct tasdevice_priv *tas_priv,
1448 	struct tasdev_blk *block)
1449 {
1450 	unsigned int nr_value;
1451 	int ret;
1452 
1453 	ret = tasdevice_spi_dev_read(tas_priv, TASDEVICE_CHECKSUM, &nr_value);
1454 	if (ret < 0) {
1455 		dev_err(tas_priv->dev, "%s: read error %d.\n", __func__, ret);
1456 		set_err_prg_cfg(block->type, tas_priv);
1457 		return ret;
1458 	}
1459 
1460 	if ((nr_value & 0xff) != block->pchksum) {
1461 		dev_err(tas_priv->dev, "%s: PChkSum err %d ", __func__, ret);
1462 		dev_err(tas_priv->dev, "PChkSum = 0x%x, Reg = 0x%x\n",
1463 			block->pchksum, (nr_value & 0xff));
1464 		tas_priv->err_code |= ERROR_PRAM_CRCCHK;
1465 		ret = -EAGAIN;
1466 		block->nr_retry--;
1467 
1468 		if (block->nr_retry <= 0)
1469 			set_err_prg_cfg(block->type, tas_priv);
1470 	} else {
1471 		tas_priv->err_code &= ~ERROR_PRAM_CRCCHK;
1472 	}
1473 
1474 	return ret;
1475 }
1476 
1477 /* Firmware block load function. */
tasdev_load_blk(struct tasdevice_priv * tas_priv,struct tasdev_blk * block)1478 static int tasdev_load_blk(struct tasdevice_priv *tas_priv,
1479 	struct tasdev_blk *block)
1480 {
1481 	unsigned int sleep_time, len, nr_cmds;
1482 	unsigned char offset, book, page, val;
1483 	unsigned char *data = block->data;
1484 	unsigned char crc_chksum = 0;
1485 	int ret = 0;
1486 
1487 	while (block->nr_retry > 0) {
1488 		if (block->is_pchksum_present) {
1489 			ret = tasdevice_spi_dev_write(tas_priv,
1490 				TASDEVICE_CHECKSUM, 0);
1491 			if (ret < 0)
1492 				break;
1493 		}
1494 
1495 		if (block->is_ychksum_present)
1496 			crc_chksum = 0;
1497 
1498 		nr_cmds = 0;
1499 
1500 		while (nr_cmds < block->nr_cmds) {
1501 			data = block->data + nr_cmds * 4;
1502 
1503 			book = data[0];
1504 			page = data[1];
1505 			offset = data[2];
1506 			val = data[3];
1507 
1508 			nr_cmds++;
1509 			/* Single byte write */
1510 			if (offset <= 0x7F) {
1511 				ret = tasdevice_spi_dev_write(tas_priv,
1512 					TASDEVICE_REG(book, page, offset),
1513 					val);
1514 				if (ret < 0)
1515 					break;
1516 				if (block->is_ychksum_present) {
1517 					ret = tasdev_bytes_chksum(tas_priv,
1518 						block, book, page, offset,
1519 						1, val, &crc_chksum);
1520 					if (ret < 0)
1521 						break;
1522 				}
1523 				continue;
1524 			}
1525 			/* sleep command */
1526 			if (offset == 0x81) {
1527 				/* book -- data[0] page -- data[1] */
1528 				sleep_time = ((book << 8) + page)*1000;
1529 				fsleep(sleep_time);
1530 				continue;
1531 			}
1532 			/* Multiple bytes write */
1533 			if (offset == 0x85) {
1534 				data += 4;
1535 				len = (book << 8) + page;
1536 				book = data[0];
1537 				page = data[1];
1538 				offset = data[2];
1539 				ret = tasdev_multibytes_wr(tas_priv,
1540 					block, book, page, offset, data,
1541 					len, &nr_cmds, &crc_chksum);
1542 				if (ret < 0)
1543 					break;
1544 			}
1545 		}
1546 		if (ret == -EAGAIN) {
1547 			if (block->nr_retry > 0)
1548 				continue;
1549 		} else if (ret < 0) {
1550 			/* err in current device, skip it */
1551 			break;
1552 		}
1553 
1554 		if (block->is_pchksum_present) {
1555 			ret = tasdev_block_chksum(tas_priv, block);
1556 			if (ret == -EAGAIN) {
1557 				if (block->nr_retry > 0)
1558 					continue;
1559 			} else if (ret < 0) {
1560 				/* err in current device, skip it */
1561 				break;
1562 			}
1563 		}
1564 
1565 		if (block->is_ychksum_present) {
1566 			/* TBD, open it when FW ready */
1567 			dev_err(tas_priv->dev,
1568 				"Blk YChkSum: FW = 0x%x, YCRC = 0x%x\n",
1569 				block->ychksum, crc_chksum);
1570 
1571 			tas_priv->err_code &=
1572 				~ERROR_YRAM_CRCCHK;
1573 			ret = 0;
1574 		}
1575 		/* skip current blk */
1576 		break;
1577 	}
1578 
1579 	return ret;
1580 }
1581 
1582 /* Firmware block load function. */
tasdevice_load_block(struct tasdevice_priv * tas_priv,struct tasdev_blk * block)1583 static int tasdevice_load_block(struct tasdevice_priv *tas_priv,
1584 	struct tasdev_blk *block)
1585 {
1586 	int ret = 0;
1587 
1588 	block->nr_retry = 6;
1589 	if (tas_priv->is_loading == false)
1590 		return 0;
1591 	ret = tasdev_load_blk(tas_priv, block);
1592 	if (ret < 0)
1593 		dev_err(tas_priv->dev, "Blk (%d) load error\n", block->type);
1594 
1595 	return ret;
1596 }
1597 
1598 /*
1599  * Select firmware binary parser & load callback functions by ppc3 version
1600  * and firmware binary version.
1601  */
dspfw_default_callback(struct tasdevice_priv * tas_priv,unsigned int drv_ver,unsigned int ppcver)1602 static int dspfw_default_callback(struct tasdevice_priv *tas_priv,
1603 	unsigned int drv_ver, unsigned int ppcver)
1604 {
1605 	int rc = 0;
1606 
1607 	if (drv_ver == 0x100) {
1608 		if (ppcver >= PPC3_VERSION_BASE) {
1609 			tas_priv->fw_parse_variable_header =
1610 				fw_parse_variable_header_kernel;
1611 			tas_priv->fw_parse_program_data =
1612 				fw_parse_program_data_kernel;
1613 			tas_priv->fw_parse_configuration_data =
1614 				fw_parse_configuration_data_kernel;
1615 			tas_priv->tasdevice_load_block =
1616 				tasdevice_load_block_kernel;
1617 		} else if (ppcver == 0x00) {
1618 			tas_priv->fw_parse_variable_header =
1619 				fw_parse_variable_header_git;
1620 			tas_priv->fw_parse_program_data =
1621 				fw_parse_program_data;
1622 			tas_priv->fw_parse_configuration_data =
1623 				fw_parse_configuration_data;
1624 			tas_priv->tasdevice_load_block =
1625 				tasdevice_load_block;
1626 		} else {
1627 			dev_err(tas_priv->dev,
1628 				"Wrong PPCVer :0x%08x\n", ppcver);
1629 			rc = -EINVAL;
1630 		}
1631 	} else {
1632 		dev_err(tas_priv->dev, "Wrong DrvVer : 0x%02x\n", drv_ver);
1633 		rc = -EINVAL;
1634 	}
1635 
1636 	return rc;
1637 }
1638 
1639 /* DSP firmware binary file header parser function. */
fw_parse_header(struct tasdevice_priv * tas_priv,struct tasdevice_fw * tas_fmw,const struct firmware * fmw,int offset)1640 static int fw_parse_header(struct tasdevice_priv *tas_priv,
1641 	struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset)
1642 {
1643 	struct tasdevice_dspfw_hdr *fw_hdr = &tas_fmw->fw_hdr;
1644 	struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &fw_hdr->fixed_hdr;
1645 	static const unsigned char magic_number[] = {0x35, 0x35, 0x35, 0x32, };
1646 	const unsigned char *buf = (unsigned char *)fmw->data;
1647 
1648 	if (offset + 92 > fmw->size) {
1649 		dev_err(tas_priv->dev, "%s: File Size error\n", __func__);
1650 		offset = -EINVAL;
1651 		goto out;
1652 	}
1653 	if (memcmp(&buf[offset], magic_number, 4)) {
1654 		dev_err(tas_priv->dev, "%s: Magic num NOT match\n", __func__);
1655 		offset = -EINVAL;
1656 		goto out;
1657 	}
1658 	offset += 4;
1659 
1660 	/*
1661 	 * Convert data[offset], data[offset + 1], data[offset + 2] and
1662 	 * data[offset + 3] into host
1663 	 */
1664 	fw_fixed_hdr->fwsize = get_unaligned_be32(&buf[offset]);
1665 	offset += 4;
1666 	if (fw_fixed_hdr->fwsize != fmw->size) {
1667 		dev_err(tas_priv->dev, "File size not match, %lu %u",
1668 			(unsigned long)fmw->size, fw_fixed_hdr->fwsize);
1669 		offset = -EINVAL;
1670 		goto out;
1671 	}
1672 	offset += 4;
1673 	fw_fixed_hdr->ppcver = get_unaligned_be32(&buf[offset]);
1674 	offset += 8;
1675 	fw_fixed_hdr->drv_ver = get_unaligned_be32(&buf[offset]);
1676 	offset += 72;
1677 
1678 out:
1679 	return offset;
1680 }
1681 
1682 /* DSP firmware binary file parser function. */
tasdevice_dspfw_ready(const struct firmware * fmw,void * context)1683 static int tasdevice_dspfw_ready(const struct firmware *fmw, void *context)
1684 {
1685 	struct tasdevice_priv *tas_priv = context;
1686 	struct tasdevice_fw_fixed_hdr *fw_fixed_hdr;
1687 	struct tasdevice_fw *tas_fmw;
1688 	int offset = 0, ret = 0;
1689 
1690 	if (!fmw || !fmw->data) {
1691 		dev_err(tas_priv->dev, "%s: Failed to read firmware %s\n",
1692 			__func__, tas_priv->coef_binaryname);
1693 		return -EINVAL;
1694 	}
1695 
1696 	tas_priv->fmw = kzalloc(sizeof(*tas_priv->fmw), GFP_KERNEL);
1697 	if (!tas_priv->fmw)
1698 		return -ENOMEM;
1699 	tas_fmw = tas_priv->fmw;
1700 	tas_fmw->dev = tas_priv->dev;
1701 	offset = fw_parse_header(tas_priv, tas_fmw, fmw, offset);
1702 
1703 	if (offset == -EINVAL)
1704 		return -EINVAL;
1705 
1706 	fw_fixed_hdr = &tas_fmw->fw_hdr.fixed_hdr;
1707 	/* Support different versions of firmware */
1708 	switch (fw_fixed_hdr->drv_ver) {
1709 	case 0x301:
1710 	case 0x302:
1711 	case 0x502:
1712 	case 0x503:
1713 		tas_priv->fw_parse_variable_header =
1714 			fw_parse_variable_header_kernel;
1715 		tas_priv->fw_parse_program_data =
1716 			fw_parse_program_data_kernel;
1717 		tas_priv->fw_parse_configuration_data =
1718 			fw_parse_configuration_data_kernel;
1719 		tas_priv->tasdevice_load_block =
1720 			tasdevice_load_block_kernel;
1721 		break;
1722 	case 0x202:
1723 	case 0x400:
1724 		tas_priv->fw_parse_variable_header =
1725 			fw_parse_variable_header_git;
1726 		tas_priv->fw_parse_program_data =
1727 			fw_parse_program_data;
1728 		tas_priv->fw_parse_configuration_data =
1729 			fw_parse_configuration_data;
1730 		tas_priv->tasdevice_load_block =
1731 			tasdevice_load_block;
1732 		break;
1733 	default:
1734 		ret = dspfw_default_callback(tas_priv,
1735 			fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver);
1736 		if (ret)
1737 			return ret;
1738 		break;
1739 	}
1740 
1741 	offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset);
1742 	if (offset < 0)
1743 		return offset;
1744 
1745 	offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw,
1746 		offset);
1747 	if (offset < 0)
1748 		return offset;
1749 
1750 	offset = tas_priv->fw_parse_configuration_data(tas_priv,
1751 		tas_fmw, fmw, offset);
1752 	if (offset < 0)
1753 		ret = offset;
1754 
1755 	return ret;
1756 }
1757 
1758 /* DSP firmware binary file parser function. */
tasdevice_spi_dsp_parser(void * context)1759 int tasdevice_spi_dsp_parser(void *context)
1760 {
1761 	struct tasdevice_priv *tas_priv = context;
1762 	const struct firmware *fw_entry;
1763 	int ret;
1764 
1765 	ret = request_firmware(&fw_entry, tas_priv->coef_binaryname,
1766 		tas_priv->dev);
1767 	if (ret) {
1768 		dev_err(tas_priv->dev, "%s: load %s error\n", __func__,
1769 			tas_priv->coef_binaryname);
1770 		return ret;
1771 	}
1772 
1773 	ret = tasdevice_dspfw_ready(fw_entry, tas_priv);
1774 	release_firmware(fw_entry);
1775 	fw_entry = NULL;
1776 
1777 	return ret;
1778 }
1779 
1780 /* DSP firmware program block data remove function. */
tasdev_dsp_prog_blk_remove(struct tasdevice_prog * prog)1781 static void tasdev_dsp_prog_blk_remove(struct tasdevice_prog *prog)
1782 {
1783 	struct tasdevice_data *tas_dt;
1784 	struct tasdev_blk *blk;
1785 	unsigned int i;
1786 
1787 	if (!prog)
1788 		return;
1789 
1790 	tas_dt = &prog->dev_data;
1791 
1792 	if (!tas_dt->dev_blks)
1793 		return;
1794 
1795 	for (i = 0; i < tas_dt->nr_blk; i++) {
1796 		blk = &tas_dt->dev_blks[i];
1797 		kfree(blk->data);
1798 	}
1799 	kfree(tas_dt->dev_blks);
1800 }
1801 
1802 /* DSP firmware program block data remove function. */
tasdev_dsp_prog_remove(struct tasdevice_prog * prog,unsigned short nr)1803 static void tasdev_dsp_prog_remove(struct tasdevice_prog *prog,
1804 	unsigned short nr)
1805 {
1806 	int i;
1807 
1808 	for (i = 0; i < nr; i++)
1809 		tasdev_dsp_prog_blk_remove(&prog[i]);
1810 	kfree(prog);
1811 }
1812 
1813 /* DSP firmware config block data remove function. */
tasdev_dsp_cfg_blk_remove(struct tasdevice_config * cfg)1814 static void tasdev_dsp_cfg_blk_remove(struct tasdevice_config *cfg)
1815 {
1816 	struct tasdevice_data *tas_dt;
1817 	struct tasdev_blk *blk;
1818 	unsigned int i;
1819 
1820 	if (cfg) {
1821 		tas_dt = &cfg->dev_data;
1822 
1823 		if (!tas_dt->dev_blks)
1824 			return;
1825 
1826 		for (i = 0; i < tas_dt->nr_blk; i++) {
1827 			blk = &tas_dt->dev_blks[i];
1828 			kfree(blk->data);
1829 		}
1830 		kfree(tas_dt->dev_blks);
1831 	}
1832 }
1833 
1834 /* DSP firmware config remove function. */
tasdev_dsp_cfg_remove(struct tasdevice_config * config,unsigned short nr)1835 static void tasdev_dsp_cfg_remove(struct tasdevice_config *config,
1836 	unsigned short nr)
1837 {
1838 	int i;
1839 
1840 	for (i = 0; i < nr; i++)
1841 		tasdev_dsp_cfg_blk_remove(&config[i]);
1842 	kfree(config);
1843 }
1844 
1845 /* DSP firmware remove function. */
tasdevice_spi_dsp_remove(void * context)1846 void tasdevice_spi_dsp_remove(void *context)
1847 {
1848 	struct tasdevice_priv *tas_dev = context;
1849 
1850 	if (!tas_dev->fmw)
1851 		return;
1852 
1853 	if (tas_dev->fmw->programs)
1854 		tasdev_dsp_prog_remove(tas_dev->fmw->programs,
1855 			tas_dev->fmw->nr_programs);
1856 	if (tas_dev->fmw->configs)
1857 		tasdev_dsp_cfg_remove(tas_dev->fmw->configs,
1858 			tas_dev->fmw->nr_configurations);
1859 	kfree(tas_dev->fmw);
1860 	tas_dev->fmw = NULL;
1861 }
1862 
1863 /* DSP firmware calibration data remove function. */
tas2781_clear_calfirmware(struct tasdevice_fw * tas_fmw)1864 static void tas2781_clear_calfirmware(struct tasdevice_fw *tas_fmw)
1865 {
1866 	struct tasdevice_calibration *calibration;
1867 	struct tasdev_blk *block;
1868 	unsigned int blks;
1869 	int i;
1870 
1871 	if (!tas_fmw->calibrations)
1872 		goto out;
1873 
1874 	for (i = 0; i < tas_fmw->nr_calibrations; i++) {
1875 		calibration = &tas_fmw->calibrations[i];
1876 		if (!calibration)
1877 			continue;
1878 
1879 		if (!calibration->dev_data.dev_blks)
1880 			continue;
1881 
1882 		for (blks = 0; blks < calibration->dev_data.nr_blk; blks++) {
1883 			block = &calibration->dev_data.dev_blks[blks];
1884 			if (!block)
1885 				continue;
1886 			kfree(block->data);
1887 		}
1888 		kfree(calibration->dev_data.dev_blks);
1889 	}
1890 	kfree(tas_fmw->calibrations);
1891 out:
1892 	kfree(tas_fmw);
1893 }
1894 
1895 /* Calibration data from firmware remove function. */
tasdevice_spi_calbin_remove(void * context)1896 void tasdevice_spi_calbin_remove(void *context)
1897 {
1898 	struct tasdevice_priv *tas_priv = context;
1899 
1900 	if (tas_priv->cali_data_fmw) {
1901 		tas2781_clear_calfirmware(tas_priv->cali_data_fmw);
1902 		tas_priv->cali_data_fmw = NULL;
1903 	}
1904 }
1905 
1906 /* Configuration remove function. */
tasdevice_spi_config_info_remove(void * context)1907 void tasdevice_spi_config_info_remove(void *context)
1908 {
1909 	struct tasdevice_priv *tas_priv = context;
1910 	struct tasdevice_rca *rca = &tas_priv->rcabin;
1911 	struct tasdevice_config_info **ci = rca->cfg_info;
1912 	unsigned int i, j;
1913 
1914 	if (!ci)
1915 		return;
1916 	for (i = 0; i < rca->ncfgs; i++) {
1917 		if (!ci[i])
1918 			continue;
1919 		if (ci[i]->blk_data) {
1920 			for (j = 0; j < ci[i]->real_nblocks; j++) {
1921 				if (!ci[i]->blk_data[j])
1922 					continue;
1923 				kfree(ci[i]->blk_data[j]->regdata);
1924 				kfree(ci[i]->blk_data[j]);
1925 			}
1926 			kfree(ci[i]->blk_data);
1927 		}
1928 		kfree(ci[i]);
1929 	}
1930 	kfree(ci);
1931 }
1932 
1933 /* DSP firmware program block data load function. */
tasdevice_load_data(struct tasdevice_priv * tas_priv,struct tasdevice_data * dev_data)1934 static int tasdevice_load_data(struct tasdevice_priv *tas_priv,
1935 	struct tasdevice_data *dev_data)
1936 {
1937 	struct tasdev_blk *block;
1938 	unsigned int i;
1939 	int ret = 0;
1940 
1941 	for (i = 0; i < dev_data->nr_blk; i++) {
1942 		block = &dev_data->dev_blks[i];
1943 		ret = tas_priv->tasdevice_load_block(tas_priv, block);
1944 		if (ret < 0)
1945 			break;
1946 	}
1947 
1948 	return ret;
1949 }
1950 
1951 /* DSP firmware program load interface function. */
tasdevice_spi_prmg_load(void * context,int prm_no)1952 int tasdevice_spi_prmg_load(void *context, int prm_no)
1953 {
1954 	struct tasdevice_priv *tas_priv = context;
1955 	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
1956 	struct tasdevice_prog *program;
1957 	struct tasdevice_config *conf;
1958 	int ret = 0;
1959 
1960 	if (!tas_fmw) {
1961 		dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
1962 		return -EINVAL;
1963 	}
1964 	if (prm_no >= 0 && prm_no <= tas_fmw->nr_programs) {
1965 		tas_priv->cur_conf = 0;
1966 		tas_priv->is_loading = true;
1967 		program = &tas_fmw->programs[prm_no];
1968 		ret = tasdevice_load_data(tas_priv, &program->dev_data);
1969 		if (ret < 0) {
1970 			dev_err(tas_priv->dev, "Program failed %d.\n", ret);
1971 			return ret;
1972 		}
1973 		tas_priv->cur_prog = prm_no;
1974 
1975 		conf = &tas_fmw->configs[tas_priv->cur_conf];
1976 		ret = tasdevice_load_data(tas_priv, &conf->dev_data);
1977 		if (ret < 0)
1978 			dev_err(tas_priv->dev, "Config failed %d.\n", ret);
1979 	} else {
1980 		dev_err(tas_priv->dev,
1981 			"%s: prm(%d) is not in range of Programs %u\n",
1982 			__func__, prm_no, tas_fmw->nr_programs);
1983 		return -EINVAL;
1984 	}
1985 
1986 	return ret;
1987 }
1988 
1989 /* RCABIN configuration switch interface function. */
tasdevice_spi_tuning_switch(void * context,int state)1990 void tasdevice_spi_tuning_switch(void *context, int state)
1991 {
1992 	struct tasdevice_priv *tas_priv = context;
1993 	int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
1994 
1995 	if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
1996 		dev_err(tas_priv->dev, "DSP bin file not loaded\n");
1997 		return;
1998 	}
1999 
2000 	if (state == 0)
2001 		tasdevice_spi_select_cfg_blk(tas_priv, profile_cfg_id,
2002 			TASDEVICE_BIN_BLK_PRE_POWER_UP);
2003 	else
2004 		tasdevice_spi_select_cfg_blk(tas_priv, profile_cfg_id,
2005 			TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
2006 }
2007