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