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