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