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