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