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