1// SPDX-License-Identifier: GPL-2.0
2//
3// tasdevice-fmw.c -- TASDEVICE firmware support
4//
5// Copyright 2023 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
78struct tas_crc {
79	unsigned char offset;
80	unsigned char len;
81};
82
83static 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
87static 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
203out:
204	return cfg_info;
205}
206
207int 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	}
314out:
315	return ret;
316}
317EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, SND_SOC_TAS2781_FMWLIB);
318
319static 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
367out:
368	return offset;
369}
370
371static 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
403out:
404	return offset;
405}
406
407static 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
430out:
431	return offset;
432}
433
434static 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
459out:
460	return offset;
461}
462
463static 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
570out:
571	return offset;
572}
573
574static 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
710void 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}
766EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, SND_SOC_TAS2781_FMWLIB);
767
768static 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
926static 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
961out:
962	return offset;
963}
964
965static 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
981out:
982	return offset;
983}
984
985static 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
1040out:
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 */
1047static 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
1090out:
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 */
1097static 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
1154out:
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 */
1161static 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
1216out:
1217	return offset;
1218}
1219
1220static 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
1245static 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 */
1270static 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
1282end:
1283	return in;
1284}
1285
1286static 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 */
1316static 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
1327static 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
1337end:
1338	return in;
1339}
1340
1341static 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
1401end:
1402	return ret;
1403}
1404
1405static 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
1443end:
1444	return ret;
1445}
1446
1447static 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
1457static 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
1485end:
1486	return ret;
1487}
1488
1489static 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
1521end:
1522	return ret;
1523}
1524
1525static 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
1554end:
1555	return ret;
1556}
1557
1558static 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
1660end:
1661	return ret;
1662}
1663
1664static 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
1721static 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
1768static 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
1785static 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
1826static 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
1841out:
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 */
1849static 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
1902out:
1903	return offset;
1904}
1905
1906int 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;
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
1972out:
1973	if (fw_entry)
1974		release_firmware(fw_entry);
1975
1976	return ret;
1977}
1978EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, SND_SOC_TAS2781_FMWLIB);
1979
1980static 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
2060out:
2061	return ret;
2062}
2063
2064int 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
2082out:
2083	return ret;
2084}
2085EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, SND_SOC_TAS2781_FMWLIB);
2086
2087static 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);
2117out:
2118	kfree(tas_fmw);
2119}
2120
2121void 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}
2138EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, SND_SOC_TAS2781_FMWLIB);
2139
2140void 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}
2165EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, SND_SOC_TAS2781_FMWLIB);
2166
2167static 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
2184int tasdevice_select_tuningprm_cfg(void *context, int prm_no,
2185	int cfg_no, int rca_conf_no)
2186{
2187	struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2188	struct tasdevice_rca *rca = &(tas_priv->rcabin);
2189	struct tasdevice_config_info **cfg_info = rca->cfg_info;
2190	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2191	struct tasdevice_prog *program;
2192	struct tasdevice_config *conf;
2193	int prog_status = 0;
2194	int status, i;
2195
2196	if (!tas_fmw) {
2197		dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2198		goto out;
2199	}
2200
2201	if (cfg_no >= tas_fmw->nr_configurations) {
2202		dev_err(tas_priv->dev,
2203			"%s: cfg(%d) is not in range of conf %u\n",
2204			__func__, cfg_no, tas_fmw->nr_configurations);
2205		goto out;
2206	}
2207
2208	if (prm_no >= tas_fmw->nr_programs) {
2209		dev_err(tas_priv->dev,
2210			"%s: prm(%d) is not in range of Programs %u\n",
2211			__func__, prm_no, tas_fmw->nr_programs);
2212		goto out;
2213	}
2214
2215	if (rca_conf_no >= rca->ncfgs || rca_conf_no < 0 ||
2216		!cfg_info) {
2217		dev_err(tas_priv->dev,
2218			"conf_no:%d should be in range from 0 to %u\n",
2219			rca_conf_no, rca->ncfgs-1);
2220		goto out;
2221	}
2222
2223	for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2224		if (cfg_info[rca_conf_no]->active_dev & (1 << i)) {
2225			if (prm_no >= 0
2226				&& (tas_priv->tasdevice[i].cur_prog != prm_no
2227				|| tas_priv->force_fwload_status)) {
2228				tas_priv->tasdevice[i].cur_conf = -1;
2229				tas_priv->tasdevice[i].is_loading = true;
2230				prog_status++;
2231			}
2232		} else
2233			tas_priv->tasdevice[i].is_loading = false;
2234		tas_priv->tasdevice[i].is_loaderr = false;
2235	}
2236
2237	if (prog_status) {
2238		program = &(tas_fmw->programs[prm_no]);
2239		tasdevice_load_data(tas_priv, &(program->dev_data));
2240		for (i = 0; i < tas_priv->ndev; i++) {
2241			if (tas_priv->tasdevice[i].is_loaderr == true)
2242				continue;
2243			else if (tas_priv->tasdevice[i].is_loaderr == false
2244				&& tas_priv->tasdevice[i].is_loading == true) {
2245				struct tasdevice_fw *cal_fmw =
2246					tas_priv->tasdevice[i].cali_data_fmw;
2247
2248				if (cal_fmw) {
2249					struct tasdevice_calibration
2250						*cal = cal_fmw->calibrations;
2251
2252					if (cal)
2253						load_calib_data(tas_priv,
2254							&(cal->dev_data));
2255				}
2256				tas_priv->tasdevice[i].cur_prog = prm_no;
2257			}
2258		}
2259	}
2260
2261	for (i = 0, status = 0; i < tas_priv->ndev; i++) {
2262		if (cfg_no >= 0
2263			&& tas_priv->tasdevice[i].cur_conf != cfg_no
2264			&& (cfg_info[rca_conf_no]->active_dev & (1 << i))
2265			&& (tas_priv->tasdevice[i].is_loaderr == false)) {
2266			status++;
2267			tas_priv->tasdevice[i].is_loading = true;
2268		} else
2269			tas_priv->tasdevice[i].is_loading = false;
2270	}
2271
2272	if (status) {
2273		conf = &(tas_fmw->configs[cfg_no]);
2274		status = 0;
2275		tasdevice_load_data(tas_priv, &(conf->dev_data));
2276		for (i = 0; i < tas_priv->ndev; i++) {
2277			if (tas_priv->tasdevice[i].is_loaderr == true) {
2278				status |= 1 << (i + 4);
2279				continue;
2280			} else if (tas_priv->tasdevice[i].is_loaderr == false
2281				&& tas_priv->tasdevice[i].is_loading == true)
2282				tas_priv->tasdevice[i].cur_conf = cfg_no;
2283		}
2284	} else
2285		dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n",
2286			__func__, cfg_no);
2287
2288	status |= cfg_info[rca_conf_no]->active_dev;
2289
2290out:
2291	return prog_status;
2292}
2293EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg,
2294	SND_SOC_TAS2781_FMWLIB);
2295
2296int tasdevice_prmg_load(void *context, int prm_no)
2297{
2298	struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2299	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2300	struct tasdevice_prog *program;
2301	int prog_status = 0;
2302	int i;
2303
2304	if (!tas_fmw) {
2305		dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2306		goto out;
2307	}
2308
2309	if (prm_no >= tas_fmw->nr_programs) {
2310		dev_err(tas_priv->dev,
2311			"%s: prm(%d) is not in range of Programs %u\n",
2312			__func__, prm_no, tas_fmw->nr_programs);
2313		goto out;
2314	}
2315
2316	for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2317		if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
2318			tas_priv->tasdevice[i].cur_conf = -1;
2319			tas_priv->tasdevice[i].is_loading = true;
2320			prog_status++;
2321		}
2322	}
2323
2324	if (prog_status) {
2325		program = &(tas_fmw->programs[prm_no]);
2326		tasdevice_load_data(tas_priv, &(program->dev_data));
2327		for (i = 0; i < tas_priv->ndev; i++) {
2328			if (tas_priv->tasdevice[i].is_loaderr == true)
2329				continue;
2330			else if (tas_priv->tasdevice[i].is_loaderr == false
2331				&& tas_priv->tasdevice[i].is_loading == true)
2332				tas_priv->tasdevice[i].cur_prog = prm_no;
2333		}
2334	}
2335
2336out:
2337	return prog_status;
2338}
2339EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, SND_SOC_TAS2781_FMWLIB);
2340
2341int tasdevice_prmg_calibdata_load(void *context, int prm_no)
2342{
2343	struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2344	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2345	struct tasdevice_prog *program;
2346	int prog_status = 0;
2347	int i;
2348
2349	if (!tas_fmw) {
2350		dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__);
2351		goto out;
2352	}
2353
2354	if (prm_no >= tas_fmw->nr_programs) {
2355		dev_err(tas_priv->dev,
2356			"%s: prm(%d) is not in range of Programs %u\n",
2357			__func__, prm_no, tas_fmw->nr_programs);
2358		goto out;
2359	}
2360
2361	for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) {
2362		if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
2363			tas_priv->tasdevice[i].cur_conf = -1;
2364			tas_priv->tasdevice[i].is_loading = true;
2365			prog_status++;
2366		}
2367		tas_priv->tasdevice[i].is_loaderr = false;
2368	}
2369
2370	if (prog_status) {
2371		program = &(tas_fmw->programs[prm_no]);
2372		tasdevice_load_data(tas_priv, &(program->dev_data));
2373		for (i = 0; i < tas_priv->ndev; i++) {
2374			if (tas_priv->tasdevice[i].is_loaderr == true)
2375				continue;
2376			else if (tas_priv->tasdevice[i].is_loaderr == false
2377				&& tas_priv->tasdevice[i].is_loading == true) {
2378				struct tasdevice_fw *cal_fmw =
2379					tas_priv->tasdevice[i].cali_data_fmw;
2380
2381				if (cal_fmw) {
2382					struct tasdevice_calibration *cal =
2383						cal_fmw->calibrations;
2384
2385					if (cal)
2386						load_calib_data(tas_priv,
2387							&(cal->dev_data));
2388				}
2389				tas_priv->tasdevice[i].cur_prog = prm_no;
2390			}
2391		}
2392	}
2393
2394out:
2395	return prog_status;
2396}
2397EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_calibdata_load,
2398	SND_SOC_TAS2781_FMWLIB);
2399
2400void tasdevice_tuning_switch(void *context, int state)
2401{
2402	struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context;
2403	struct tasdevice_fw *tas_fmw = tas_priv->fmw;
2404	int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
2405
2406	if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
2407		dev_err(tas_priv->dev, "DSP bin file not loaded\n");
2408		return;
2409	}
2410
2411	if (state == 0) {
2412		if (tas_priv->cur_prog < tas_fmw->nr_programs) {
2413			/*dsp mode or tuning mode*/
2414			profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
2415			tasdevice_select_tuningprm_cfg(tas_priv,
2416				tas_priv->cur_prog, tas_priv->cur_conf,
2417				profile_cfg_id);
2418		}
2419
2420		tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
2421			TASDEVICE_BIN_BLK_PRE_POWER_UP);
2422	} else
2423		tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
2424			TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
2425}
2426EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch,
2427	SND_SOC_TAS2781_FMWLIB);
2428
2429MODULE_DESCRIPTION("Texas Firmware Support");
2430MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");
2431MODULE_LICENSE("GPL");
2432