Linux Audio

Check our new training course

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