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