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 <asm/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 77 struct tas_crc { 78 unsigned char offset; 79 unsigned char len; 80 }; 81 82 struct blktyp_devidx_map { 83 unsigned char blktyp; 84 unsigned char dev_idx; 85 }; 86 87 static 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 */ 92 static 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 116 static 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 132 static 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 148 static 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 263 out: 264 return cfg_info; 265 } 266 267 int 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 } 374 out: 375 return ret; 376 } 377 EXPORT_SYMBOL_NS_GPL(tasdevice_rca_parser, SND_SOC_TAS2781_FMWLIB); 378 379 /* fixed m68k compiling issue: mapping table can save code field */ 380 static 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 410 static 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 466 out: 467 return offset; 468 } 469 470 static 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 502 out: 503 return offset; 504 } 505 506 static 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 529 out: 530 return offset; 531 } 532 533 static 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 558 out: 559 return offset; 560 } 561 562 static 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 669 out: 670 return offset; 671 } 672 673 static 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 809 void 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 } 865 EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, SND_SOC_TAS2781_FMWLIB); 866 867 static 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 894 static 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 929 out: 930 return offset; 931 } 932 933 static 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 949 out: 950 return offset; 951 } 952 953 static 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 1008 out: 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 */ 1015 static 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 1058 out: 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 */ 1065 static 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 1122 out: 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 */ 1129 static 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 1184 out: 1185 return offset; 1186 } 1187 1188 static 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 1213 static 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 */ 1238 static 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 1250 end: 1251 return in; 1252 } 1253 1254 static 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 */ 1284 static 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 1295 static 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 1305 end: 1306 return in; 1307 } 1308 1309 static 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 1369 end: 1370 return ret; 1371 } 1372 1373 static 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 1411 end: 1412 return ret; 1413 } 1414 1415 static 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 1425 static 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 1453 end: 1454 return ret; 1455 } 1456 1457 static 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 1489 end: 1490 return ret; 1491 } 1492 1493 static 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 1522 end: 1523 return ret; 1524 } 1525 1526 static 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 1628 end: 1629 return ret; 1630 } 1631 1632 static 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 1689 static 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 1736 static 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 1753 static 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 1794 static 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 1809 out: 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 */ 1817 static 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 1870 out: 1871 return offset; 1872 } 1873 1874 int 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 1940 out: 1941 if (fw_entry) 1942 release_firmware(fw_entry); 1943 1944 return ret; 1945 } 1946 EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, SND_SOC_TAS2781_FMWLIB); 1947 1948 static 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 tas_priv->fw_parse_variable_header = 1996 fw_parse_variable_header_git; 1997 tas_priv->fw_parse_program_data = 1998 fw_parse_program_data; 1999 tas_priv->fw_parse_configuration_data = 2000 fw_parse_configuration_data; 2001 tas_priv->tasdevice_load_block = 2002 tasdevice_load_block; 2003 break; 2004 default: 2005 ret = dspfw_default_callback(tas_priv, 2006 fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver); 2007 if (ret) 2008 goto out; 2009 break; 2010 } 2011 2012 offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset); 2013 if (offset < 0) { 2014 ret = offset; 2015 goto out; 2016 } 2017 offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw, 2018 offset); 2019 if (offset < 0) { 2020 ret = offset; 2021 goto out; 2022 } 2023 offset = tas_priv->fw_parse_configuration_data(tas_priv, 2024 tas_fmw, fmw, offset); 2025 if (offset < 0) 2026 ret = offset; 2027 2028 out: 2029 return ret; 2030 } 2031 2032 int tasdevice_dsp_parser(void *context) 2033 { 2034 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context; 2035 const struct firmware *fw_entry; 2036 int ret; 2037 2038 ret = request_firmware(&fw_entry, tas_priv->coef_binaryname, 2039 tas_priv->dev); 2040 if (ret) { 2041 dev_err(tas_priv->dev, "%s: load %s error\n", __func__, 2042 tas_priv->coef_binaryname); 2043 goto out; 2044 } 2045 2046 ret = tasdevice_dspfw_ready(fw_entry, tas_priv); 2047 release_firmware(fw_entry); 2048 fw_entry = NULL; 2049 2050 out: 2051 return ret; 2052 } 2053 EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, SND_SOC_TAS2781_FMWLIB); 2054 2055 static void tas2781_clear_calfirmware(struct tasdevice_fw *tas_fmw) 2056 { 2057 struct tasdevice_calibration *calibration; 2058 struct tasdev_blk *block; 2059 struct tasdevice_data *im; 2060 unsigned int blks; 2061 int i; 2062 2063 if (!tas_fmw->calibrations) 2064 goto out; 2065 2066 for (i = 0; i < tas_fmw->nr_calibrations; i++) { 2067 calibration = &(tas_fmw->calibrations[i]); 2068 if (!calibration) 2069 continue; 2070 2071 im = &(calibration->dev_data); 2072 2073 if (!im->dev_blks) 2074 continue; 2075 2076 for (blks = 0; blks < im->nr_blk; blks++) { 2077 block = &(im->dev_blks[blks]); 2078 if (!block) 2079 continue; 2080 kfree(block->data); 2081 } 2082 kfree(im->dev_blks); 2083 } 2084 kfree(tas_fmw->calibrations); 2085 out: 2086 kfree(tas_fmw); 2087 } 2088 2089 void tasdevice_calbin_remove(void *context) 2090 { 2091 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2092 struct tasdevice *tasdev; 2093 int i; 2094 2095 if (!tas_priv) 2096 return; 2097 2098 for (i = 0; i < tas_priv->ndev; i++) { 2099 tasdev = &(tas_priv->tasdevice[i]); 2100 if (!tasdev->cali_data_fmw) 2101 continue; 2102 tas2781_clear_calfirmware(tasdev->cali_data_fmw); 2103 tasdev->cali_data_fmw = NULL; 2104 } 2105 } 2106 EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, SND_SOC_TAS2781_FMWLIB); 2107 2108 void tasdevice_config_info_remove(void *context) 2109 { 2110 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2111 struct tasdevice_rca *rca = &(tas_priv->rcabin); 2112 struct tasdevice_config_info **ci = rca->cfg_info; 2113 int i, j; 2114 2115 if (!ci) 2116 return; 2117 for (i = 0; i < rca->ncfgs; i++) { 2118 if (!ci[i]) 2119 continue; 2120 if (ci[i]->blk_data) { 2121 for (j = 0; j < (int)ci[i]->real_nblocks; j++) { 2122 if (!ci[i]->blk_data[j]) 2123 continue; 2124 kfree(ci[i]->blk_data[j]->regdata); 2125 kfree(ci[i]->blk_data[j]); 2126 } 2127 kfree(ci[i]->blk_data); 2128 } 2129 kfree(ci[i]); 2130 } 2131 kfree(ci); 2132 } 2133 EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, SND_SOC_TAS2781_FMWLIB); 2134 2135 static int tasdevice_load_data(struct tasdevice_priv *tas_priv, 2136 struct tasdevice_data *dev_data) 2137 { 2138 struct tasdev_blk *block; 2139 unsigned int i; 2140 int ret = 0; 2141 2142 for (i = 0; i < dev_data->nr_blk; i++) { 2143 block = &(dev_data->dev_blks[i]); 2144 ret = tas_priv->tasdevice_load_block(tas_priv, block); 2145 if (ret < 0) 2146 break; 2147 } 2148 2149 return ret; 2150 } 2151 2152 static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i) 2153 { 2154 struct tasdevice_calibration *cal; 2155 struct tasdevice_fw *cal_fmw; 2156 2157 cal_fmw = priv->tasdevice[i].cali_data_fmw; 2158 2159 /* No calibrated data for current devices, playback will go ahead. */ 2160 if (!cal_fmw) 2161 return; 2162 2163 cal = cal_fmw->calibrations; 2164 if (!cal) 2165 return; 2166 2167 load_calib_data(priv, &cal->dev_data); 2168 } 2169 2170 int tasdevice_select_tuningprm_cfg(void *context, int prm_no, 2171 int cfg_no, int rca_conf_no) 2172 { 2173 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2174 struct tasdevice_rca *rca = &(tas_priv->rcabin); 2175 struct tasdevice_config_info **cfg_info = rca->cfg_info; 2176 struct tasdevice_fw *tas_fmw = tas_priv->fmw; 2177 struct tasdevice_prog *program; 2178 struct tasdevice_config *conf; 2179 int prog_status = 0; 2180 int status, i; 2181 2182 if (!tas_fmw) { 2183 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__); 2184 goto out; 2185 } 2186 2187 if (cfg_no >= tas_fmw->nr_configurations) { 2188 dev_err(tas_priv->dev, 2189 "%s: cfg(%d) is not in range of conf %u\n", 2190 __func__, cfg_no, tas_fmw->nr_configurations); 2191 goto out; 2192 } 2193 2194 if (prm_no >= tas_fmw->nr_programs) { 2195 dev_err(tas_priv->dev, 2196 "%s: prm(%d) is not in range of Programs %u\n", 2197 __func__, prm_no, tas_fmw->nr_programs); 2198 goto out; 2199 } 2200 2201 if (rca_conf_no >= rca->ncfgs || rca_conf_no < 0 || 2202 !cfg_info) { 2203 dev_err(tas_priv->dev, 2204 "conf_no:%d should be in range from 0 to %u\n", 2205 rca_conf_no, rca->ncfgs-1); 2206 goto out; 2207 } 2208 2209 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) { 2210 if (cfg_info[rca_conf_no]->active_dev & (1 << i)) { 2211 if (prm_no >= 0 2212 && (tas_priv->tasdevice[i].cur_prog != prm_no 2213 || tas_priv->force_fwload_status)) { 2214 tas_priv->tasdevice[i].cur_conf = -1; 2215 tas_priv->tasdevice[i].is_loading = true; 2216 prog_status++; 2217 } 2218 } else 2219 tas_priv->tasdevice[i].is_loading = false; 2220 tas_priv->tasdevice[i].is_loaderr = false; 2221 } 2222 2223 if (prog_status) { 2224 program = &(tas_fmw->programs[prm_no]); 2225 tasdevice_load_data(tas_priv, &(program->dev_data)); 2226 for (i = 0; i < tas_priv->ndev; i++) { 2227 if (tas_priv->tasdevice[i].is_loaderr == true) 2228 continue; 2229 if (tas_priv->tasdevice[i].is_loaderr == false && 2230 tas_priv->tasdevice[i].is_loading == true) 2231 tas_priv->tasdevice[i].cur_prog = prm_no; 2232 } 2233 } 2234 2235 for (i = 0, status = 0; i < tas_priv->ndev; i++) { 2236 if (cfg_no >= 0 2237 && tas_priv->tasdevice[i].cur_conf != cfg_no 2238 && (cfg_info[rca_conf_no]->active_dev & (1 << i)) 2239 && (tas_priv->tasdevice[i].is_loaderr == false)) { 2240 status++; 2241 tas_priv->tasdevice[i].is_loading = true; 2242 } else 2243 tas_priv->tasdevice[i].is_loading = false; 2244 } 2245 2246 if (status) { 2247 conf = &(tas_fmw->configs[cfg_no]); 2248 status = 0; 2249 tasdevice_load_data(tas_priv, &(conf->dev_data)); 2250 for (i = 0; i < tas_priv->ndev; i++) { 2251 if (tas_priv->tasdevice[i].is_loaderr == true) { 2252 status |= BIT(i + 4); 2253 continue; 2254 } 2255 2256 if (tas_priv->tasdevice[i].is_loaderr == false && 2257 tas_priv->tasdevice[i].is_loading == true) { 2258 tasdev_load_calibrated_data(tas_priv, i); 2259 tas_priv->tasdevice[i].cur_conf = cfg_no; 2260 } 2261 } 2262 } else 2263 dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n", 2264 __func__, cfg_no); 2265 2266 status |= cfg_info[rca_conf_no]->active_dev; 2267 2268 out: 2269 return prog_status; 2270 } 2271 EXPORT_SYMBOL_NS_GPL(tasdevice_select_tuningprm_cfg, 2272 SND_SOC_TAS2781_FMWLIB); 2273 2274 int tasdevice_prmg_load(void *context, int prm_no) 2275 { 2276 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2277 struct tasdevice_fw *tas_fmw = tas_priv->fmw; 2278 struct tasdevice_prog *program; 2279 int prog_status = 0; 2280 int i; 2281 2282 if (!tas_fmw) { 2283 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__); 2284 goto out; 2285 } 2286 2287 if (prm_no >= tas_fmw->nr_programs) { 2288 dev_err(tas_priv->dev, 2289 "%s: prm(%d) is not in range of Programs %u\n", 2290 __func__, prm_no, tas_fmw->nr_programs); 2291 goto out; 2292 } 2293 2294 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) { 2295 if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) { 2296 tas_priv->tasdevice[i].cur_conf = -1; 2297 tas_priv->tasdevice[i].is_loading = true; 2298 prog_status++; 2299 } 2300 } 2301 2302 if (prog_status) { 2303 program = &(tas_fmw->programs[prm_no]); 2304 tasdevice_load_data(tas_priv, &(program->dev_data)); 2305 for (i = 0; i < tas_priv->ndev; i++) { 2306 if (tas_priv->tasdevice[i].is_loaderr == true) 2307 continue; 2308 else if (tas_priv->tasdevice[i].is_loaderr == false 2309 && tas_priv->tasdevice[i].is_loading == true) 2310 tas_priv->tasdevice[i].cur_prog = prm_no; 2311 } 2312 } 2313 2314 out: 2315 return prog_status; 2316 } 2317 EXPORT_SYMBOL_NS_GPL(tasdevice_prmg_load, SND_SOC_TAS2781_FMWLIB); 2318 2319 void tasdevice_tuning_switch(void *context, int state) 2320 { 2321 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2322 struct tasdevice_fw *tas_fmw = tas_priv->fmw; 2323 int profile_cfg_id = tas_priv->rcabin.profile_cfg_id; 2324 2325 /* 2326 * Only RCA-based Playback can still work with no dsp program running 2327 * inside the chip. 2328 */ 2329 switch (tas_priv->fw_state) { 2330 case TASDEVICE_RCA_FW_OK: 2331 case TASDEVICE_DSP_FW_ALL_OK: 2332 break; 2333 default: 2334 return; 2335 } 2336 2337 if (state == 0) { 2338 if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) { 2339 /* dsp mode or tuning mode */ 2340 profile_cfg_id = tas_priv->rcabin.profile_cfg_id; 2341 tasdevice_select_tuningprm_cfg(tas_priv, 2342 tas_priv->cur_prog, tas_priv->cur_conf, 2343 profile_cfg_id); 2344 } 2345 2346 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id, 2347 TASDEVICE_BIN_BLK_PRE_POWER_UP); 2348 } else { 2349 tasdevice_select_cfg_blk(tas_priv, profile_cfg_id, 2350 TASDEVICE_BIN_BLK_PRE_SHUTDOWN); 2351 } 2352 } 2353 EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch, 2354 SND_SOC_TAS2781_FMWLIB); 2355 2356 MODULE_DESCRIPTION("Texas Firmware Support"); 2357 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>"); 2358 MODULE_LICENSE("GPL"); 2359
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.