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 !(tas_priv->isspi && rc == -EXDEV)) { 926 is_err = true; 927 dev_err(tas_priv->dev, 928 "process_block: single write error\n"); 929 } 930 subblk_offset += 4; 931 } 932 } 933 break; 934 case TASDEVICE_CMD_BURST: { 935 unsigned short len = get_unaligned_be16(&data[2]); 936 937 subblk_offset += 2; 938 if (subblk_offset + 4 + len > sublocksize) { 939 dev_err(tas_priv->dev, 940 "%s: BST Out of boundary\n", 941 __func__); 942 is_err = true; 943 break; 944 } 945 if (len % 4) { 946 dev_err(tas_priv->dev, 947 "%s:Bst-len(%u)not div by 4\n", 948 __func__, len); 949 break; 950 } 951 952 rc = tasdevice_dev_bulk_write(tas_priv, chn, 953 TASDEVICE_REG(data[subblk_offset], 954 data[subblk_offset + 1], 955 data[subblk_offset + 2]), 956 &(data[subblk_offset + 4]), len); 957 if (rc < 0 && !(tas_priv->isspi && rc == -EXDEV)) { 958 is_err = true; 959 dev_err(tas_priv->dev, 960 "%s: bulk_write error = %d\n", 961 __func__, rc); 962 } 963 subblk_offset += (len + 4); 964 } 965 break; 966 case TASDEVICE_CMD_DELAY: { 967 unsigned int sleep_time = 0; 968 969 if (subblk_offset + 2 > sublocksize) { 970 dev_err(tas_priv->dev, 971 "%s: delay Out of boundary\n", 972 __func__); 973 is_err = true; 974 break; 975 } 976 sleep_time = get_unaligned_be16(&data[2]) * 1000; 977 usleep_range(sleep_time, sleep_time + 50); 978 subblk_offset += 2; 979 } 980 break; 981 case TASDEVICE_CMD_FIELD_W: 982 if (subblk_offset + 6 > sublocksize) { 983 dev_err(tas_priv->dev, 984 "%s: bit write Out of boundary\n", 985 __func__); 986 is_err = true; 987 break; 988 } 989 rc = tas_priv->update_bits(tas_priv, chn, 990 TASDEVICE_REG(data[subblk_offset + 2], 991 data[subblk_offset + 3], 992 data[subblk_offset + 4]), 993 data[subblk_offset + 1], 994 data[subblk_offset + 5]); 995 if (rc < 0 && !(tas_priv->isspi && rc == -EXDEV)) { 996 is_err = true; 997 dev_err(tas_priv->dev, 998 "%s: update_bits error = %d\n", 999 __func__, rc); 1000 } 1001 subblk_offset += 6; 1002 break; 1003 default: 1004 break; 1005 } 1006 if (is_err == true && blktyp != 0) { 1007 if (blktyp == 0x80) { 1008 tas_priv->tasdevice[chn].cur_prog = -1; 1009 tas_priv->tasdevice[chn].cur_conf = -1; 1010 } else 1011 tas_priv->tasdevice[chn].cur_conf = -1; 1012 } 1013 } 1014 1015 return subblk_offset; 1016 } 1017 1018 void tasdevice_select_cfg_blk(void *pContext, int conf_no, 1019 unsigned char block_type) 1020 { 1021 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) pContext; 1022 struct tasdevice_rca *rca = &(tas_priv->rcabin); 1023 struct tasdevice_config_info **cfg_info = rca->cfg_info; 1024 struct tasdev_blk_data **blk_data; 1025 int j, k, chn, chnend; 1026 1027 if (conf_no >= rca->ncfgs || conf_no < 0 || !cfg_info) { 1028 dev_err(tas_priv->dev, "conf_no should be not more than %u\n", 1029 rca->ncfgs); 1030 return; 1031 } 1032 blk_data = cfg_info[conf_no]->blk_data; 1033 1034 for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) { 1035 unsigned int length = 0, rc = 0; 1036 1037 if (block_type > 5 || block_type < 2) { 1038 dev_err(tas_priv->dev, 1039 "block_type should be in range from 2 to 5\n"); 1040 break; 1041 } 1042 if (block_type != blk_data[j]->block_type) 1043 continue; 1044 1045 for (k = 0; k < (int)blk_data[j]->n_subblks; k++) { 1046 if (blk_data[j]->dev_idx) { 1047 chn = blk_data[j]->dev_idx - 1; 1048 chnend = blk_data[j]->dev_idx; 1049 } else { 1050 chn = 0; 1051 chnend = tas_priv->ndev; 1052 } 1053 for (; chn < chnend; chn++) 1054 tas_priv->tasdevice[chn].is_loading = true; 1055 1056 rc = tasdevice_process_block(tas_priv, 1057 blk_data[j]->regdata + length, 1058 blk_data[j]->dev_idx, 1059 blk_data[j]->block_size - length); 1060 length += rc; 1061 if (blk_data[j]->block_size < length) { 1062 dev_err(tas_priv->dev, 1063 "%s: %u %u out of boundary\n", 1064 __func__, length, 1065 blk_data[j]->block_size); 1066 break; 1067 } 1068 } 1069 if (length != blk_data[j]->block_size) 1070 dev_err(tas_priv->dev, "%s: %u %u size is not same\n", 1071 __func__, length, blk_data[j]->block_size); 1072 } 1073 } 1074 EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, "SND_SOC_TAS2781_FMWLIB"); 1075 1076 static int tasdevice_load_block_kernel( 1077 struct tasdevice_priv *tasdevice, struct tasdev_blk *block) 1078 { 1079 const unsigned int blk_size = block->blk_size; 1080 unsigned int i, length; 1081 unsigned char *data = block->data; 1082 1083 for (i = 0, length = 0; i < block->nr_subblocks; i++) { 1084 int rc = tasdevice_process_block(tasdevice, data + length, 1085 block->dev_idx, blk_size - length); 1086 if (rc < 0) { 1087 dev_err(tasdevice->dev, 1088 "%s: %u %u sublock write error\n", 1089 __func__, length, blk_size); 1090 break; 1091 } 1092 length += (unsigned int)rc; 1093 if (blk_size < length) { 1094 dev_err(tasdevice->dev, "%s: %u %u out of boundary\n", 1095 __func__, length, blk_size); 1096 break; 1097 } 1098 } 1099 1100 return 0; 1101 } 1102 1103 static int fw_parse_variable_hdr(struct tasdevice_priv 1104 *tas_priv, struct tasdevice_dspfw_hdr *fw_hdr, 1105 const struct firmware *fmw, int offset) 1106 { 1107 const unsigned char *buf = fmw->data; 1108 int len = strlen((char *)&buf[offset]); 1109 1110 len++; 1111 1112 if (offset + len + 8 > fmw->size) { 1113 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); 1114 offset = -EINVAL; 1115 goto out; 1116 } 1117 1118 offset += len; 1119 1120 fw_hdr->device_family = get_unaligned_be32(&buf[offset]); 1121 if (fw_hdr->device_family != 0) { 1122 dev_err(tas_priv->dev, "%s: not TAS device\n", __func__); 1123 offset = -EINVAL; 1124 goto out; 1125 } 1126 offset += 4; 1127 1128 fw_hdr->device = get_unaligned_be32(&buf[offset]); 1129 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE || 1130 fw_hdr->device == 6) { 1131 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device); 1132 offset = -EINVAL; 1133 goto out; 1134 } 1135 offset += 4; 1136 fw_hdr->ndev = deviceNumber[fw_hdr->device]; 1137 1138 out: 1139 return offset; 1140 } 1141 1142 static int fw_parse_variable_header_git(struct tasdevice_priv 1143 *tas_priv, const struct firmware *fmw, int offset) 1144 { 1145 struct tasdevice_fw *tas_fmw = tas_priv->fmw; 1146 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); 1147 1148 offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset); 1149 if (offset < 0) 1150 goto out; 1151 if (fw_hdr->ndev != tas_priv->ndev) { 1152 dev_err(tas_priv->dev, 1153 "%s: ndev(%u) in dspbin mismatch ndev(%u) in DTS\n", 1154 __func__, fw_hdr->ndev, tas_priv->ndev); 1155 offset = -EINVAL; 1156 } 1157 1158 out: 1159 return offset; 1160 } 1161 1162 static int fw_parse_block_data(struct tasdevice_fw *tas_fmw, 1163 struct tasdev_blk *block, const struct firmware *fmw, int offset) 1164 { 1165 unsigned char *data = (unsigned char *)fmw->data; 1166 int n; 1167 1168 if (offset + 8 > fmw->size) { 1169 dev_err(tas_fmw->dev, "%s: Type error\n", __func__); 1170 offset = -EINVAL; 1171 goto out; 1172 } 1173 block->type = get_unaligned_be32(&data[offset]); 1174 offset += 4; 1175 1176 if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) { 1177 if (offset + 8 > fmw->size) { 1178 dev_err(tas_fmw->dev, "PChkSumPresent error\n"); 1179 offset = -EINVAL; 1180 goto out; 1181 } 1182 block->is_pchksum_present = data[offset]; 1183 offset++; 1184 1185 block->pchksum = data[offset]; 1186 offset++; 1187 1188 block->is_ychksum_present = data[offset]; 1189 offset++; 1190 1191 block->ychksum = data[offset]; 1192 offset++; 1193 } else { 1194 block->is_pchksum_present = 0; 1195 block->is_ychksum_present = 0; 1196 } 1197 1198 block->nr_cmds = get_unaligned_be32(&data[offset]); 1199 offset += 4; 1200 1201 n = block->nr_cmds * 4; 1202 if (offset + n > fmw->size) { 1203 dev_err(tas_fmw->dev, 1204 "%s: File Size(%lu) error offset = %d n = %d\n", 1205 __func__, (unsigned long)fmw->size, offset, n); 1206 offset = -EINVAL; 1207 goto out; 1208 } 1209 /* instead of kzalloc+memcpy */ 1210 block->data = kmemdup(&data[offset], n, GFP_KERNEL); 1211 if (!block->data) { 1212 offset = -ENOMEM; 1213 goto out; 1214 } 1215 offset += n; 1216 1217 out: 1218 return offset; 1219 } 1220 1221 /* When parsing error occurs, all the memory resource will be released 1222 * in the end of tasdevice_rca_ready. 1223 */ 1224 static int fw_parse_data(struct tasdevice_fw *tas_fmw, 1225 struct tasdevice_data *img_data, const struct firmware *fmw, 1226 int offset) 1227 { 1228 const unsigned char *data = (unsigned char *)fmw->data; 1229 struct tasdev_blk *blk; 1230 unsigned int i; 1231 int n; 1232 1233 if (offset + 64 > fmw->size) { 1234 dev_err(tas_fmw->dev, "%s: Name error\n", __func__); 1235 offset = -EINVAL; 1236 goto out; 1237 } 1238 memcpy(img_data->name, &data[offset], 64); 1239 offset += 64; 1240 1241 n = strlen((char *)&data[offset]); 1242 n++; 1243 if (offset + n + 2 > fmw->size) { 1244 dev_err(tas_fmw->dev, "%s: Description error\n", __func__); 1245 offset = -EINVAL; 1246 goto out; 1247 } 1248 offset += n; 1249 img_data->nr_blk = get_unaligned_be16(&data[offset]); 1250 offset += 2; 1251 1252 img_data->dev_blks = kzalloc_objs(struct tasdev_blk, img_data->nr_blk); 1253 if (!img_data->dev_blks) { 1254 offset = -ENOMEM; 1255 goto out; 1256 } 1257 for (i = 0; i < img_data->nr_blk; i++) { 1258 blk = &(img_data->dev_blks[i]); 1259 offset = fw_parse_block_data(tas_fmw, blk, fmw, offset); 1260 if (offset < 0) { 1261 offset = -EINVAL; 1262 goto out; 1263 } 1264 } 1265 1266 out: 1267 return offset; 1268 } 1269 1270 /* When parsing error occurs, all the memory resource will be released 1271 * in the end of tasdevice_rca_ready. 1272 */ 1273 static int fw_parse_program_data(struct tasdevice_priv *tas_priv, 1274 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset) 1275 { 1276 unsigned char *buf = (unsigned char *)fmw->data; 1277 struct tasdevice_prog *program; 1278 int i; 1279 1280 if (offset + 2 > fmw->size) { 1281 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); 1282 offset = -EINVAL; 1283 goto out; 1284 } 1285 tas_fmw->nr_programs = get_unaligned_be16(&buf[offset]); 1286 offset += 2; 1287 1288 if (tas_fmw->nr_programs == 0) { 1289 /*Not error in calibration Data file, return directly*/ 1290 dev_info(tas_priv->dev, "%s: No Programs data, maybe calbin\n", 1291 __func__); 1292 goto out; 1293 } 1294 1295 tas_fmw->programs = 1296 kzalloc_objs(struct tasdevice_prog, tas_fmw->nr_programs); 1297 if (!tas_fmw->programs) { 1298 offset = -ENOMEM; 1299 goto out; 1300 } 1301 for (i = 0; i < tas_fmw->nr_programs; i++) { 1302 int n = 0; 1303 1304 program = &(tas_fmw->programs[i]); 1305 if (offset + 64 > fmw->size) { 1306 dev_err(tas_priv->dev, "%s: mpName error\n", __func__); 1307 offset = -EINVAL; 1308 goto out; 1309 } 1310 offset += 64; 1311 1312 n = strlen((char *)&buf[offset]); 1313 /* skip '\0' and 5 unused bytes */ 1314 n += 6; 1315 if (offset + n > fmw->size) { 1316 dev_err(tas_priv->dev, "Description err\n"); 1317 offset = -EINVAL; 1318 goto out; 1319 } 1320 1321 offset += n; 1322 1323 offset = fw_parse_data(tas_fmw, &(program->dev_data), fmw, 1324 offset); 1325 if (offset < 0) 1326 goto out; 1327 } 1328 1329 out: 1330 return offset; 1331 } 1332 1333 /* When parsing error occurs, all the memory resource will be released 1334 * in the end of tasdevice_rca_ready. 1335 */ 1336 static int fw_parse_configuration_data( 1337 struct tasdevice_priv *tas_priv, 1338 struct tasdevice_fw *tas_fmw, 1339 const struct firmware *fmw, int offset) 1340 { 1341 unsigned char *data = (unsigned char *)fmw->data; 1342 struct tasdevice_config *config; 1343 unsigned int i; 1344 int n; 1345 1346 if (offset + 2 > fmw->size) { 1347 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); 1348 offset = -EINVAL; 1349 goto out; 1350 } 1351 tas_fmw->nr_configurations = get_unaligned_be16(&data[offset]); 1352 offset += 2; 1353 1354 if (tas_fmw->nr_configurations == 0) { 1355 dev_err(tas_priv->dev, "%s: Conf is zero\n", __func__); 1356 /*Not error for calibration Data file, return directly*/ 1357 goto out; 1358 } 1359 tas_fmw->configs = kzalloc_objs(struct tasdevice_config, 1360 tas_fmw->nr_configurations); 1361 if (!tas_fmw->configs) { 1362 offset = -ENOMEM; 1363 goto out; 1364 } 1365 for (i = 0; i < tas_fmw->nr_configurations; i++) { 1366 config = &(tas_fmw->configs[i]); 1367 if (offset + 64 > fmw->size) { 1368 dev_err(tas_priv->dev, "File Size err\n"); 1369 offset = -EINVAL; 1370 goto out; 1371 } 1372 memcpy(config->name, &data[offset], 64); 1373 offset += 64; 1374 1375 n = strlen((char *)&data[offset]); 1376 n += 15; 1377 if (offset + n > fmw->size) { 1378 dev_err(tas_priv->dev, "Description err\n"); 1379 offset = -EINVAL; 1380 goto out; 1381 } 1382 1383 offset += n; 1384 1385 offset = fw_parse_data(tas_fmw, &(config->dev_data), 1386 fmw, offset); 1387 if (offset < 0) 1388 goto out; 1389 } 1390 1391 out: 1392 return offset; 1393 } 1394 1395 static bool check_inpage_yram_rg(struct tas_crc *cd, 1396 unsigned char reg, unsigned char len) 1397 { 1398 bool in = false; 1399 1400 1401 if (reg <= TAS2781_YRAM5_END_REG && 1402 reg >= TAS2781_YRAM5_START_REG) { 1403 if (reg + len > TAS2781_YRAM5_END_REG) 1404 cd->len = TAS2781_YRAM5_END_REG - reg + 1; 1405 else 1406 cd->len = len; 1407 cd->offset = reg; 1408 in = true; 1409 } else if (reg < TAS2781_YRAM5_START_REG) { 1410 if (reg + len > TAS2781_YRAM5_START_REG) { 1411 cd->offset = TAS2781_YRAM5_START_REG; 1412 cd->len = len - TAS2781_YRAM5_START_REG + reg; 1413 in = true; 1414 } 1415 } 1416 1417 return in; 1418 } 1419 1420 static bool check_inpage_yram_bk1(struct tas_crc *cd, 1421 unsigned char page, unsigned char reg, unsigned char len) 1422 { 1423 bool in = false; 1424 1425 if (page == TAS2781_YRAM1_PAGE) { 1426 if (reg >= TAS2781_YRAM1_START_REG) { 1427 cd->offset = reg; 1428 cd->len = len; 1429 in = true; 1430 } else if (reg + len > TAS2781_YRAM1_START_REG) { 1431 cd->offset = TAS2781_YRAM1_START_REG; 1432 cd->len = len - TAS2781_YRAM1_START_REG + reg; 1433 in = true; 1434 } 1435 } else if (page == TAS2781_YRAM3_PAGE) 1436 in = check_inpage_yram_rg(cd, reg, len); 1437 1438 return in; 1439 } 1440 1441 /* Return Code: 1442 * true -- the registers are in the inpage yram 1443 * false -- the registers are NOT in the inpage yram 1444 */ 1445 static bool check_inpage_yram(struct tas_crc *cd, unsigned char book, 1446 unsigned char page, unsigned char reg, unsigned char len) 1447 { 1448 bool in = false; 1449 1450 if (book == TAS2781_YRAM_BOOK1) { 1451 in = check_inpage_yram_bk1(cd, page, reg, len); 1452 goto end; 1453 } 1454 if (book == TAS2781_YRAM_BOOK2 && page == TAS2781_YRAM5_PAGE) 1455 in = check_inpage_yram_rg(cd, reg, len); 1456 1457 end: 1458 return in; 1459 } 1460 1461 static bool check_inblock_yram_bk(struct tas_crc *cd, 1462 unsigned char page, unsigned char reg, unsigned char len) 1463 { 1464 bool in = false; 1465 1466 if ((page >= TAS2781_YRAM4_START_PAGE && 1467 page <= TAS2781_YRAM4_END_PAGE) || 1468 (page >= TAS2781_YRAM2_START_PAGE && 1469 page <= TAS2781_YRAM2_END_PAGE)) { 1470 if (reg <= TAS2781_YRAM2_END_REG && 1471 reg >= TAS2781_YRAM2_START_REG) { 1472 cd->offset = reg; 1473 cd->len = len; 1474 in = true; 1475 } else if (reg < TAS2781_YRAM2_START_REG) { 1476 if (reg + len - 1 >= TAS2781_YRAM2_START_REG) { 1477 cd->offset = TAS2781_YRAM2_START_REG; 1478 cd->len = reg + len - TAS2781_YRAM2_START_REG; 1479 in = true; 1480 } 1481 } 1482 } 1483 1484 return in; 1485 } 1486 1487 /* Return Code: 1488 * true -- the registers are in the inblock yram 1489 * false -- the registers are NOT in the inblock yram 1490 */ 1491 static bool check_inblock_yram(struct tas_crc *cd, unsigned char book, 1492 unsigned char page, unsigned char reg, unsigned char len) 1493 { 1494 bool in = false; 1495 1496 if (book == TAS2781_YRAM_BOOK1 || book == TAS2781_YRAM_BOOK2) 1497 in = check_inblock_yram_bk(cd, page, reg, len); 1498 1499 return in; 1500 } 1501 1502 static bool check_yram(struct tas_crc *cd, unsigned char book, 1503 unsigned char page, unsigned char reg, unsigned char len) 1504 { 1505 bool in; 1506 1507 in = check_inpage_yram(cd, book, page, reg, len); 1508 if (in) 1509 goto end; 1510 in = check_inblock_yram(cd, book, page, reg, len); 1511 1512 end: 1513 return in; 1514 } 1515 1516 static int tasdev_multibytes_chksum(struct tasdevice_priv *tasdevice, 1517 unsigned short chn, unsigned char book, unsigned char page, 1518 unsigned char reg, unsigned int len) 1519 { 1520 struct tas_crc crc_data; 1521 unsigned char crc_chksum = 0; 1522 unsigned char nBuf1[128]; 1523 int ret = 0; 1524 int i; 1525 bool in; 1526 1527 if ((reg + len - 1) > 127) { 1528 ret = -EINVAL; 1529 dev_err(tasdevice->dev, "firmware error\n"); 1530 goto end; 1531 } 1532 1533 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG)) 1534 && (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG)) 1535 && (reg == TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG)) 1536 && (len == 4)) { 1537 /*DSP swap command, pass */ 1538 ret = 0; 1539 goto end; 1540 } 1541 1542 in = check_yram(&crc_data, book, page, reg, len); 1543 if (!in) 1544 goto end; 1545 1546 if (len == 1) { 1547 dev_err(tasdevice->dev, "firmware error\n"); 1548 ret = -EINVAL; 1549 goto end; 1550 } 1551 1552 ret = tasdevice->dev_bulk_read(tasdevice, chn, 1553 TASDEVICE_REG(book, page, crc_data.offset), 1554 nBuf1, crc_data.len); 1555 if (ret < 0) 1556 goto end; 1557 1558 for (i = 0; i < crc_data.len; i++) { 1559 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG)) 1560 && (page == TASDEVICE_PAGE_ID( 1561 TAS2781_SA_COEFF_SWAP_REG)) 1562 && ((i + crc_data.offset) 1563 >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG)) 1564 && ((i + crc_data.offset) 1565 <= (TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG) 1566 + 4))) 1567 /*DSP swap command, bypass */ 1568 continue; 1569 else 1570 crc_chksum += crc8(tasdevice->crc8_lkp_tbl, &nBuf1[i], 1571 1, 0); 1572 } 1573 1574 ret = crc_chksum; 1575 1576 end: 1577 return ret; 1578 } 1579 1580 static int do_singlereg_checksum(struct tasdevice_priv *tasdevice, 1581 unsigned short chl, unsigned char book, unsigned char page, 1582 unsigned char reg, unsigned char val) 1583 { 1584 struct tas_crc crc_data; 1585 unsigned int nData1; 1586 int ret = 0; 1587 bool in; 1588 1589 if ((book == TASDEVICE_BOOK_ID(TAS2781_SA_COEFF_SWAP_REG)) 1590 && (page == TASDEVICE_PAGE_ID(TAS2781_SA_COEFF_SWAP_REG)) 1591 && (reg >= TASDEVICE_PAGE_REG(TAS2781_SA_COEFF_SWAP_REG)) 1592 && (reg <= (TASDEVICE_PAGE_REG( 1593 TAS2781_SA_COEFF_SWAP_REG) + 4))) { 1594 /*DSP swap command, pass */ 1595 ret = 0; 1596 goto end; 1597 } 1598 1599 in = check_yram(&crc_data, book, page, reg, 1); 1600 if (!in) 1601 goto end; 1602 ret = tasdevice->dev_read(tasdevice, chl, 1603 TASDEVICE_REG(book, page, reg), &nData1); 1604 if (ret < 0) 1605 goto end; 1606 1607 if (nData1 != val) { 1608 dev_err(tasdevice->dev, 1609 "B[0x%x]P[0x%x]R[0x%x] W[0x%x], R[0x%x]\n", 1610 book, page, reg, val, nData1); 1611 tasdevice->tasdevice[chl].err_code |= ERROR_YRAM_CRCCHK; 1612 ret = -EAGAIN; 1613 goto end; 1614 } 1615 1616 ret = crc8(tasdevice->crc8_lkp_tbl, &val, 1, 0); 1617 1618 end: 1619 return ret; 1620 } 1621 1622 static void set_err_prg_cfg(unsigned int type, struct tasdevice *dev) 1623 { 1624 if ((type == MAIN_ALL_DEVICES) || (type == MAIN_DEVICE_A) 1625 || (type == MAIN_DEVICE_B) || (type == MAIN_DEVICE_C) 1626 || (type == MAIN_DEVICE_D)) 1627 dev->cur_prog = -1; 1628 else 1629 dev->cur_conf = -1; 1630 } 1631 1632 static int tasdev_bytes_chksum(struct tasdevice_priv *tas_priv, 1633 struct tasdev_blk *block, int chn, unsigned char book, 1634 unsigned char page, unsigned char reg, unsigned int len, 1635 unsigned char val, unsigned char *crc_chksum) 1636 { 1637 int ret; 1638 1639 if (len > 1) 1640 ret = tasdev_multibytes_chksum(tas_priv, chn, book, page, reg, 1641 len); 1642 else 1643 ret = do_singlereg_checksum(tas_priv, chn, book, page, reg, 1644 val); 1645 1646 if (ret > 0) { 1647 *crc_chksum += (unsigned char)ret; 1648 goto end; 1649 } 1650 1651 if (ret != -EAGAIN) 1652 goto end; 1653 1654 block->nr_retry--; 1655 if (block->nr_retry > 0) 1656 goto end; 1657 1658 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]); 1659 1660 end: 1661 return ret; 1662 } 1663 1664 static int tasdev_multibytes_wr(struct tasdevice_priv *tas_priv, 1665 struct tasdev_blk *block, int chn, unsigned char book, 1666 unsigned char page, unsigned char reg, unsigned char *data, 1667 unsigned int len, unsigned int *nr_cmds, 1668 unsigned char *crc_chksum) 1669 { 1670 int ret; 1671 1672 if (len > 1) { 1673 ret = tasdevice_dev_bulk_write(tas_priv, chn, 1674 TASDEVICE_REG(book, page, reg), data + 3, len); 1675 if (ret < 0) 1676 goto end; 1677 if (block->is_ychksum_present) 1678 ret = tasdev_bytes_chksum(tas_priv, block, chn, 1679 book, page, reg, len, 0, crc_chksum); 1680 } else { 1681 ret = tasdevice_dev_write(tas_priv, chn, 1682 TASDEVICE_REG(book, page, reg), data[3]); 1683 if (ret < 0) 1684 goto end; 1685 if (block->is_ychksum_present) 1686 ret = tasdev_bytes_chksum(tas_priv, block, chn, book, 1687 page, reg, 1, data[3], crc_chksum); 1688 } 1689 1690 if (!block->is_ychksum_present || ret >= 0) { 1691 *nr_cmds += 1; 1692 if (len >= 2) 1693 *nr_cmds += ((len - 2) / 4) + 1; 1694 } 1695 1696 end: 1697 return ret; 1698 } 1699 1700 static int tasdev_block_chksum(struct tasdevice_priv *tas_priv, 1701 struct tasdev_blk *block, int chn) 1702 { 1703 unsigned int nr_value; 1704 int ret; 1705 1706 ret = tas_priv->dev_read(tas_priv, chn, TASDEVICE_CHECKSUM_REG, 1707 &nr_value); 1708 if (ret < 0) { 1709 dev_err(tas_priv->dev, "%s: Chn %d\n", __func__, chn); 1710 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]); 1711 goto end; 1712 } 1713 1714 if ((nr_value & 0xff) != block->pchksum) { 1715 dev_err(tas_priv->dev, "%s: Blk PChkSum Chn %d ", __func__, 1716 chn); 1717 dev_err(tas_priv->dev, "PChkSum = 0x%x, Reg = 0x%x\n", 1718 block->pchksum, (nr_value & 0xff)); 1719 tas_priv->tasdevice[chn].err_code |= ERROR_PRAM_CRCCHK; 1720 ret = -EAGAIN; 1721 block->nr_retry--; 1722 1723 if (block->nr_retry <= 0) 1724 set_err_prg_cfg(block->type, 1725 &tas_priv->tasdevice[chn]); 1726 } else 1727 tas_priv->tasdevice[chn].err_code &= ~ERROR_PRAM_CRCCHK; 1728 1729 end: 1730 return ret; 1731 } 1732 1733 static int tasdev_load_blk(struct tasdevice_priv *tas_priv, 1734 struct tasdev_blk *block, int chn) 1735 { 1736 unsigned int sleep_time; 1737 unsigned int len; 1738 unsigned int nr_cmds; 1739 unsigned char *data; 1740 unsigned char crc_chksum = 0; 1741 unsigned char offset; 1742 unsigned char book; 1743 unsigned char page; 1744 unsigned char val; 1745 int ret = 0; 1746 1747 while (block->nr_retry > 0) { 1748 if (block->is_pchksum_present) { 1749 ret = tasdevice_dev_write(tas_priv, chn, 1750 TASDEVICE_CHECKSUM_REG, 0); 1751 if (ret < 0) 1752 break; 1753 } 1754 1755 if (block->is_ychksum_present) 1756 crc_chksum = 0; 1757 1758 nr_cmds = 0; 1759 1760 while (nr_cmds < block->nr_cmds) { 1761 data = block->data + nr_cmds * 4; 1762 1763 book = data[0]; 1764 page = data[1]; 1765 offset = data[2]; 1766 val = data[3]; 1767 1768 nr_cmds++; 1769 /*Single byte write*/ 1770 if (offset <= 0x7F) { 1771 ret = tasdevice_dev_write(tas_priv, chn, 1772 TASDEVICE_REG(book, page, offset), 1773 val); 1774 if (ret < 0) 1775 goto end; 1776 if (block->is_ychksum_present) { 1777 ret = tasdev_bytes_chksum(tas_priv, 1778 block, chn, book, page, offset, 1779 1, val, &crc_chksum); 1780 if (ret < 0) 1781 break; 1782 } 1783 continue; 1784 } 1785 /*sleep command*/ 1786 if (offset == 0x81) { 1787 /*book -- data[0] page -- data[1]*/ 1788 sleep_time = ((book << 8) + page)*1000; 1789 usleep_range(sleep_time, sleep_time + 50); 1790 continue; 1791 } 1792 /*Multiple bytes write*/ 1793 if (offset == 0x85) { 1794 data += 4; 1795 len = (book << 8) + page; 1796 book = data[0]; 1797 page = data[1]; 1798 offset = data[2]; 1799 ret = tasdev_multibytes_wr(tas_priv, 1800 block, chn, book, page, offset, data, 1801 len, &nr_cmds, &crc_chksum); 1802 if (ret < 0) 1803 break; 1804 } 1805 } 1806 if (ret == -EAGAIN) { 1807 if (block->nr_retry > 0) 1808 continue; 1809 } else if (ret < 0) /*err in current device, skip it*/ 1810 break; 1811 1812 if (block->is_pchksum_present) { 1813 ret = tasdev_block_chksum(tas_priv, block, chn); 1814 if (ret == -EAGAIN) { 1815 if (block->nr_retry > 0) 1816 continue; 1817 } else if (ret < 0) /*err in current device, skip it*/ 1818 break; 1819 } 1820 1821 if (block->is_ychksum_present) { 1822 /* TBD, open it when FW ready */ 1823 dev_err(tas_priv->dev, 1824 "Blk YChkSum: FW = 0x%x, YCRC = 0x%x\n", 1825 block->ychksum, crc_chksum); 1826 1827 tas_priv->tasdevice[chn].err_code &= 1828 ~ERROR_YRAM_CRCCHK; 1829 ret = 0; 1830 } 1831 /*skip current blk*/ 1832 break; 1833 } 1834 1835 end: 1836 return ret; 1837 } 1838 1839 static int tasdevice_load_block(struct tasdevice_priv *tas_priv, 1840 struct tasdev_blk *block) 1841 { 1842 int chnend = 0; 1843 int ret = 0; 1844 int chn = 0; 1845 int rc = 0; 1846 1847 switch (block->type) { 1848 case MAIN_ALL_DEVICES: 1849 chn = 0; 1850 chnend = tas_priv->ndev; 1851 break; 1852 case MAIN_DEVICE_A: 1853 case COEFF_DEVICE_A: 1854 case PRE_DEVICE_A: 1855 chn = 0; 1856 chnend = 1; 1857 break; 1858 case MAIN_DEVICE_B: 1859 case COEFF_DEVICE_B: 1860 case PRE_DEVICE_B: 1861 chn = 1; 1862 chnend = 2; 1863 break; 1864 case MAIN_DEVICE_C: 1865 case COEFF_DEVICE_C: 1866 case PRE_DEVICE_C: 1867 chn = 2; 1868 chnend = 3; 1869 break; 1870 case MAIN_DEVICE_D: 1871 case COEFF_DEVICE_D: 1872 case PRE_DEVICE_D: 1873 chn = 3; 1874 chnend = 4; 1875 break; 1876 default: 1877 dev_dbg(tas_priv->dev, "load blk: Other Type = 0x%02x\n", 1878 block->type); 1879 break; 1880 } 1881 1882 for (; chn < chnend; chn++) { 1883 block->nr_retry = 6; 1884 if (tas_priv->tasdevice[chn].is_loading == false) 1885 continue; 1886 ret = tasdev_load_blk(tas_priv, block, chn); 1887 if (ret < 0) 1888 dev_err(tas_priv->dev, "dev %d, Blk (%d) load error\n", 1889 chn, block->type); 1890 rc |= ret; 1891 } 1892 1893 return rc; 1894 } 1895 1896 static void dspbin_type_check(struct tasdevice_priv *tas_priv, 1897 unsigned int ppcver) 1898 { 1899 if (ppcver >= PPC3_VERSION_TAS2781_ALPHA_MIN) { 1900 if (ppcver >= PPC3_VERSION_TAS2781_BETA_MIN) 1901 tas_priv->dspbin_typ = TASDEV_BETA; 1902 else if (ppcver >= PPC3_VERSION_TAS2781_BASIC_MIN) 1903 tas_priv->dspbin_typ = TASDEV_BASIC; 1904 else 1905 tas_priv->dspbin_typ = TASDEV_ALPHA; 1906 } 1907 if ((tas_priv->dspbin_typ != TASDEV_BASIC) && 1908 (ppcver < PPC3_VERSION_TAS5825_BASE)) 1909 tas_priv->fw_parse_fct_param_address = 1910 fw_parse_fct_param_address; 1911 } 1912 1913 static int dspfw_default_callback(struct tasdevice_priv *tas_priv, 1914 unsigned int drv_ver, unsigned int ppcver) 1915 { 1916 int rc = 0; 1917 1918 if (drv_ver == 0x100) { 1919 if (ppcver >= PPC3_VERSION_TAS5825_BASE) { 1920 tas_priv->fw_parse_variable_header = 1921 fw_parse_variable_header_kernel; 1922 tas_priv->fw_parse_program_data = 1923 fw_parse_tas5825_program_data_kernel; 1924 tas_priv->fw_parse_configuration_data = 1925 fw_parse_tas5825_configuration_data_kernel; 1926 tas_priv->tasdevice_load_block = 1927 tasdevice_load_block_kernel; 1928 dspbin_type_check(tas_priv, ppcver); 1929 } else if (ppcver >= PPC3_VERSION_BASE) { 1930 tas_priv->fw_parse_variable_header = 1931 fw_parse_variable_header_kernel; 1932 tas_priv->fw_parse_program_data = 1933 fw_parse_program_data_kernel; 1934 tas_priv->fw_parse_configuration_data = 1935 fw_parse_configuration_data_kernel; 1936 tas_priv->tasdevice_load_block = 1937 tasdevice_load_block_kernel; 1938 dspbin_type_check(tas_priv, ppcver); 1939 } else { 1940 switch (ppcver) { 1941 case 0x00: 1942 tas_priv->fw_parse_variable_header = 1943 fw_parse_variable_header_git; 1944 tas_priv->fw_parse_program_data = 1945 fw_parse_program_data; 1946 tas_priv->fw_parse_configuration_data = 1947 fw_parse_configuration_data; 1948 tas_priv->tasdevice_load_block = 1949 tasdevice_load_block; 1950 break; 1951 default: 1952 dev_err(tas_priv->dev, 1953 "%s: PPCVer must be 0x0 or 0x%02x", 1954 __func__, PPC3_VERSION_BASE); 1955 dev_err(tas_priv->dev, " Current:0x%02x\n", 1956 ppcver); 1957 rc = -EINVAL; 1958 break; 1959 } 1960 } 1961 } else { 1962 dev_err(tas_priv->dev, 1963 "DrvVer must be 0x0, 0x230 or above 0x230 "); 1964 dev_err(tas_priv->dev, "current is 0x%02x\n", drv_ver); 1965 rc = -EINVAL; 1966 } 1967 1968 return rc; 1969 } 1970 1971 static int fw_parse_header(struct tasdevice_priv *tas_priv, 1972 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset) 1973 { 1974 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); 1975 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr); 1976 static const unsigned char magic_number[] = { 0x35, 0x35, 0x35, 0x32 }; 1977 const unsigned char *buf = (unsigned char *)fmw->data; 1978 1979 if (offset + 92 > fmw->size) { 1980 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); 1981 offset = -EINVAL; 1982 goto out; 1983 } 1984 if (memcmp(&buf[offset], magic_number, 4)) { 1985 dev_err(tas_priv->dev, "%s: Magic num NOT match\n", __func__); 1986 offset = -EINVAL; 1987 goto out; 1988 } 1989 offset += 4; 1990 1991 /* Convert data[offset], data[offset + 1], data[offset + 2] and 1992 * data[offset + 3] into host 1993 */ 1994 fw_fixed_hdr->fwsize = get_unaligned_be32(&buf[offset]); 1995 offset += 4; 1996 if (fw_fixed_hdr->fwsize != fmw->size) { 1997 dev_err(tas_priv->dev, "File size not match, %lu %u", 1998 (unsigned long)fmw->size, fw_fixed_hdr->fwsize); 1999 offset = -EINVAL; 2000 goto out; 2001 } 2002 offset += 4; 2003 fw_fixed_hdr->ppcver = get_unaligned_be32(&buf[offset]); 2004 offset += 8; 2005 fw_fixed_hdr->drv_ver = get_unaligned_be32(&buf[offset]); 2006 offset += 72; 2007 2008 out: 2009 return offset; 2010 } 2011 2012 static int fw_parse_variable_hdr_cal(struct tasdevice_priv *tas_priv, 2013 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset) 2014 { 2015 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); 2016 2017 offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset); 2018 if (offset < 0) 2019 goto out; 2020 if (fw_hdr->ndev != 1) { 2021 dev_err(tas_priv->dev, 2022 "%s: calbin must be 1, but currently ndev(%u)\n", 2023 __func__, fw_hdr->ndev); 2024 offset = -EINVAL; 2025 } 2026 2027 out: 2028 return offset; 2029 } 2030 2031 static inline int check_cal_bin_data(struct device *dev, 2032 const unsigned char *data, const char *name) 2033 { 2034 if (data[2] != 0x85 || data[1] != 4) { 2035 dev_err(dev, "Invalid cal bin file in %s\n", name); 2036 return -1; 2037 } 2038 return 0; 2039 } 2040 2041 static void calbin_conversion(struct tasdevice_priv *priv, 2042 struct tasdevice_fw *tas_fmw) 2043 { 2044 struct calidata *cali_data = &priv->cali_data; 2045 unsigned char *calbin_data = cali_data->data; 2046 struct cali_reg *p = &cali_data->cali_reg_array; 2047 struct tasdevice_calibration *calibration; 2048 struct tasdevice_data *img_data; 2049 struct tasdev_blk *blk; 2050 unsigned char *data; 2051 int chn, k; 2052 2053 if (cali_data->total_sz != priv->ndev * 2054 (cali_data->cali_dat_sz_per_dev + 1)) { 2055 dev_err(priv->dev, "%s: cali_data size err\n", 2056 __func__); 2057 return; 2058 } 2059 calibration = &(tas_fmw->calibrations[0]); 2060 img_data = &(calibration->dev_data); 2061 2062 if (img_data->nr_blk != 1) { 2063 dev_err(priv->dev, "%s: Invalid nr_blk, wrong cal bin\n", 2064 __func__); 2065 return; 2066 } 2067 2068 blk = &(img_data->dev_blks[0]); 2069 if (blk->nr_cmds != 15) { 2070 dev_err(priv->dev, "%s: Invalid nr_cmds, wrong cal bin\n", 2071 __func__); 2072 return; 2073 } 2074 2075 switch (blk->type) { 2076 case COEFF_DEVICE_A: 2077 chn = 0; 2078 break; 2079 case COEFF_DEVICE_B: 2080 chn = 1; 2081 break; 2082 case COEFF_DEVICE_C: 2083 chn = 2; 2084 break; 2085 case COEFF_DEVICE_D: 2086 chn = 3; 2087 break; 2088 default: 2089 dev_err(priv->dev, "%s: Other Type = 0x%02x\n", 2090 __func__, blk->type); 2091 return; 2092 } 2093 k = chn * (cali_data->cali_dat_sz_per_dev + 1); 2094 2095 data = blk->data; 2096 if (check_cal_bin_data(priv->dev, data, "r0_reg") < 0) 2097 return; 2098 p->r0_reg = TASDEVICE_REG(data[4], data[5], data[6]); 2099 COPY_CAL_DATA(k); 2100 2101 data = blk->data + 12; 2102 if (check_cal_bin_data(priv->dev, data, "r0_low_reg") < 0) 2103 return; 2104 p->r0_low_reg = TASDEVICE_REG(data[4], data[5], data[6]); 2105 COPY_CAL_DATA(k + 4); 2106 2107 data = blk->data + 24; 2108 if (check_cal_bin_data(priv->dev, data, "invr0_reg") < 0) 2109 return; 2110 p->invr0_reg = TASDEVICE_REG(data[4], data[5], data[6]); 2111 COPY_CAL_DATA(k + 8); 2112 2113 data = blk->data + 36; 2114 if (check_cal_bin_data(priv->dev, data, "pow_reg") < 0) 2115 return; 2116 p->pow_reg = TASDEVICE_REG(data[4], data[5], data[6]); 2117 COPY_CAL_DATA(k + 12); 2118 2119 data = blk->data + 48; 2120 if (check_cal_bin_data(priv->dev, data, "tlimit_reg") < 0) 2121 return; 2122 p->tlimit_reg = TASDEVICE_REG(data[4], data[5], data[6]); 2123 COPY_CAL_DATA(k + 16); 2124 2125 calbin_data[k] = chn; 2126 } 2127 2128 /* When calibrated data parsing error occurs, DSP can still work with default 2129 * calibrated data, memory resource related to calibrated data will be 2130 * released in the tasdevice_codec_remove. 2131 */ 2132 static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv, 2133 struct tasdevice_fw *tas_fmw, const struct firmware *fmw, int offset) 2134 { 2135 struct tasdevice_calibration *calibration; 2136 unsigned char *data = (unsigned char *)fmw->data; 2137 unsigned int i, n; 2138 2139 if (offset + 2 > fmw->size) { 2140 dev_err(tas_priv->dev, "%s: Calibrations error\n", __func__); 2141 offset = -EINVAL; 2142 goto out; 2143 } 2144 tas_fmw->nr_calibrations = get_unaligned_be16(&data[offset]); 2145 offset += 2; 2146 2147 if (tas_fmw->nr_calibrations != 1) { 2148 dev_err(tas_priv->dev, 2149 "%s: only supports one calibration (%d)!\n", 2150 __func__, tas_fmw->nr_calibrations); 2151 goto out; 2152 } 2153 2154 tas_fmw->calibrations = kzalloc_objs(struct tasdevice_calibration, 2155 tas_fmw->nr_calibrations); 2156 if (!tas_fmw->calibrations) { 2157 offset = -ENOMEM; 2158 goto out; 2159 } 2160 for (i = 0; i < tas_fmw->nr_calibrations; i++) { 2161 if (offset + 64 > fmw->size) { 2162 dev_err(tas_priv->dev, "Calibrations error\n"); 2163 offset = -EINVAL; 2164 goto out; 2165 } 2166 calibration = &(tas_fmw->calibrations[i]); 2167 offset += 64; 2168 2169 n = strlen((char *)&data[offset]); 2170 /* skip '\0' and 2 unused bytes */ 2171 n += 3; 2172 if (offset + n > fmw->size) { 2173 dev_err(tas_priv->dev, "Description err\n"); 2174 offset = -EINVAL; 2175 goto out; 2176 } 2177 offset += n; 2178 2179 offset = fw_parse_data(tas_fmw, &(calibration->dev_data), fmw, 2180 offset); 2181 if (offset < 0) 2182 goto out; 2183 } 2184 2185 calbin_conversion(tas_priv, tas_fmw); 2186 out: 2187 return offset; 2188 } 2189 2190 int tas2781_load_calibration(void *context, char *file_name, 2191 unsigned short i) 2192 { 2193 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context; 2194 struct tasdevice *tasdev = &(tas_priv->tasdevice[i]); 2195 const struct firmware *fw_entry = NULL; 2196 struct tasdevice_fw *tas_fmw; 2197 struct firmware fmw; 2198 int offset = 0; 2199 int ret; 2200 2201 ret = request_firmware(&fw_entry, file_name, tas_priv->dev); 2202 if (ret) { 2203 dev_err(tas_priv->dev, "%s: Request firmware %s failed\n", 2204 __func__, file_name); 2205 goto out; 2206 } 2207 2208 if (!fw_entry->size) { 2209 dev_err(tas_priv->dev, "%s: file read error: size = %lu\n", 2210 __func__, (unsigned long)fw_entry->size); 2211 ret = -EINVAL; 2212 goto out; 2213 } 2214 fmw.size = fw_entry->size; 2215 fmw.data = fw_entry->data; 2216 2217 tas_fmw = tasdev->cali_data_fmw = kzalloc_obj(struct tasdevice_fw); 2218 if (!tasdev->cali_data_fmw) { 2219 ret = -ENOMEM; 2220 goto out; 2221 } 2222 tas_fmw->dev = tas_priv->dev; 2223 offset = fw_parse_header(tas_priv, tas_fmw, &fmw, offset); 2224 if (offset == -EINVAL) { 2225 dev_err(tas_priv->dev, "fw_parse_header EXIT!\n"); 2226 ret = offset; 2227 goto out; 2228 } 2229 offset = fw_parse_variable_hdr_cal(tas_priv, tas_fmw, &fmw, offset); 2230 if (offset == -EINVAL) { 2231 dev_err(tas_priv->dev, 2232 "%s: fw_parse_variable_header_cal EXIT!\n", __func__); 2233 ret = offset; 2234 goto out; 2235 } 2236 offset = fw_parse_program_data(tas_priv, tas_fmw, &fmw, offset); 2237 if (offset < 0) { 2238 dev_err(tas_priv->dev, "fw_parse_program_data EXIT!\n"); 2239 ret = offset; 2240 goto out; 2241 } 2242 offset = fw_parse_configuration_data(tas_priv, tas_fmw, &fmw, offset); 2243 if (offset < 0) { 2244 dev_err(tas_priv->dev, "fw_parse_configuration_data EXIT!\n"); 2245 ret = offset; 2246 goto out; 2247 } 2248 offset = fw_parse_calibration_data(tas_priv, tas_fmw, &fmw, offset); 2249 if (offset < 0) { 2250 dev_err(tas_priv->dev, "fw_parse_calibration_data EXIT!\n"); 2251 ret = offset; 2252 goto out; 2253 } 2254 2255 out: 2256 release_firmware(fw_entry); 2257 2258 return ret; 2259 } 2260 EXPORT_SYMBOL_NS_GPL(tas2781_load_calibration, "SND_SOC_TAS2781_FMWLIB"); 2261 2262 static int tasdevice_dspfw_ready(const struct firmware *fmw, 2263 void *context) 2264 { 2265 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2266 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr; 2267 struct tasdevice_fw *tas_fmw; 2268 int offset = 0; 2269 int ret; 2270 2271 if (!fmw || !fmw->data) { 2272 dev_err(tas_priv->dev, "%s: Failed to read firmware %s\n", 2273 __func__, tas_priv->coef_binaryname); 2274 return -EINVAL; 2275 } 2276 2277 tas_priv->fmw = kzalloc_obj(struct tasdevice_fw); 2278 if (!tas_priv->fmw) 2279 return -ENOMEM; 2280 2281 tas_fmw = tas_priv->fmw; 2282 tas_fmw->dev = tas_priv->dev; 2283 offset = fw_parse_header(tas_priv, tas_fmw, fmw, offset); 2284 2285 if (offset == -EINVAL) 2286 return -EINVAL; 2287 2288 fw_fixed_hdr = &(tas_fmw->fw_hdr.fixed_hdr); 2289 /* Support different versions of firmware */ 2290 switch (fw_fixed_hdr->drv_ver) { 2291 case 0x301: 2292 case 0x302: 2293 case 0x502: 2294 case 0x503: 2295 tas_priv->fw_parse_variable_header = 2296 fw_parse_variable_header_kernel; 2297 tas_priv->fw_parse_program_data = 2298 fw_parse_program_data_kernel; 2299 tas_priv->fw_parse_configuration_data = 2300 fw_parse_configuration_data_kernel; 2301 tas_priv->tasdevice_load_block = 2302 tasdevice_load_block_kernel; 2303 break; 2304 case 0x202: 2305 case 0x400: 2306 case 0x401: 2307 tas_priv->fw_parse_variable_header = 2308 fw_parse_variable_header_git; 2309 tas_priv->fw_parse_program_data = 2310 fw_parse_program_data; 2311 tas_priv->fw_parse_configuration_data = 2312 fw_parse_configuration_data; 2313 tas_priv->tasdevice_load_block = 2314 tasdevice_load_block; 2315 break; 2316 default: 2317 ret = dspfw_default_callback(tas_priv, 2318 fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver); 2319 if (ret) 2320 return ret; 2321 break; 2322 } 2323 2324 offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset); 2325 if (offset < 0) 2326 return offset; 2327 2328 offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw, 2329 offset); 2330 if (offset < 0) 2331 return offset; 2332 2333 offset = tas_priv->fw_parse_configuration_data(tas_priv, 2334 tas_fmw, fmw, offset); 2335 if (offset < 0) 2336 return offset; 2337 2338 if (tas_priv->fw_parse_fct_param_address) { 2339 offset = tas_priv->fw_parse_fct_param_address(tas_priv, 2340 tas_fmw, fmw, offset); 2341 if (offset < 0) 2342 return offset; 2343 } 2344 2345 return 0; 2346 } 2347 2348 int tasdevice_dsp_parser(void *context) 2349 { 2350 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *)context; 2351 const struct firmware *fw_entry; 2352 int ret; 2353 2354 ret = request_firmware(&fw_entry, tas_priv->coef_binaryname, 2355 tas_priv->dev); 2356 if (ret) { 2357 dev_err(tas_priv->dev, "%s: load %s error\n", __func__, 2358 tas_priv->coef_binaryname); 2359 goto out; 2360 } 2361 2362 ret = tasdevice_dspfw_ready(fw_entry, tas_priv); 2363 release_firmware(fw_entry); 2364 fw_entry = NULL; 2365 2366 out: 2367 return ret; 2368 } 2369 EXPORT_SYMBOL_NS_GPL(tasdevice_dsp_parser, "SND_SOC_TAS2781_FMWLIB"); 2370 2371 static void tas2781_clear_calfirmware(struct tasdevice_fw *tas_fmw) 2372 { 2373 struct tasdevice_calibration *calibration; 2374 struct tasdev_blk *block; 2375 struct tasdevice_data *im; 2376 unsigned int blks; 2377 int i; 2378 2379 if (!tas_fmw->calibrations) 2380 goto out; 2381 2382 for (i = 0; i < tas_fmw->nr_calibrations; i++) { 2383 calibration = &(tas_fmw->calibrations[i]); 2384 if (!calibration) 2385 continue; 2386 2387 im = &(calibration->dev_data); 2388 2389 if (!im->dev_blks) 2390 continue; 2391 2392 for (blks = 0; blks < im->nr_blk; blks++) { 2393 block = &(im->dev_blks[blks]); 2394 if (!block) 2395 continue; 2396 kfree(block->data); 2397 } 2398 kfree(im->dev_blks); 2399 } 2400 kfree(tas_fmw->calibrations); 2401 out: 2402 kfree(tas_fmw); 2403 } 2404 2405 void tasdevice_calbin_remove(void *context) 2406 { 2407 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2408 struct tasdevice *tasdev; 2409 int i; 2410 2411 if (!tas_priv) 2412 return; 2413 2414 for (i = 0; i < tas_priv->ndev; i++) { 2415 tasdev = &(tas_priv->tasdevice[i]); 2416 if (!tasdev->cali_data_fmw) 2417 continue; 2418 tas2781_clear_calfirmware(tasdev->cali_data_fmw); 2419 tasdev->cali_data_fmw = NULL; 2420 } 2421 } 2422 EXPORT_SYMBOL_NS_GPL(tasdevice_calbin_remove, "SND_SOC_TAS2781_FMWLIB"); 2423 2424 void tasdevice_config_info_remove(void *context) 2425 { 2426 struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; 2427 struct tasdevice_rca *rca = &(tas_priv->rcabin); 2428 struct tasdevice_config_info **ci = rca->cfg_info; 2429 int i, j; 2430 2431 if (!ci) 2432 return; 2433 for (i = 0; i < rca->ncfgs; i++) { 2434 if (!ci[i]) 2435 continue; 2436 if (ci[i]->blk_data) { 2437 for (j = 0; j < (int)ci[i]->real_nblocks; j++) { 2438 if (!ci[i]->blk_data[j]) 2439 continue; 2440 kfree(ci[i]->blk_data[j]->regdata); 2441 kfree(ci[i]->blk_data[j]); 2442 } 2443 kfree(ci[i]->blk_data); 2444 } 2445 kfree(ci[i]); 2446 } 2447 kfree(ci); 2448 } 2449 EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, "SND_SOC_TAS2781_FMWLIB"); 2450 2451 static int tasdevice_load_data(struct tasdevice_priv *tas_priv, 2452 struct tasdevice_data *dev_data) 2453 { 2454 struct tasdev_blk *block; 2455 unsigned int i; 2456 int ret = 0; 2457 2458 for (i = 0; i < dev_data->nr_blk; i++) { 2459 block = &(dev_data->dev_blks[i]); 2460 ret = tas_priv->tasdevice_load_block(tas_priv, block); 2461 if (ret < 0) 2462 break; 2463 } 2464 2465 return ret; 2466 } 2467 2468 static int tas2781_cali_preproc(struct tasdevice_priv *priv, int i) 2469 { 2470 struct tas2781_cali_specific *spec = priv->tasdevice[i].cali_specific; 2471 struct calidata *cali_data = &priv->cali_data; 2472 struct cali_reg *p = &cali_data->cali_reg_array; 2473 unsigned char *data = cali_data->data; 2474 int rc; 2475 2476 /* 2477 * On TAS2781, if the Speaker calibrated impedance is lower than 2478 * default value hard-coded inside the TAS2781, it will cuase vol 2479 * lower than normal. In order to fix this issue, the parameter of 2480 * SineGainI need updating. 2481 */ 2482 if (spec == NULL) { 2483 int k = i * (cali_data->cali_dat_sz_per_dev + 1); 2484 int re_org, re_cal, corrected_sin_gn, pg_id; 2485 unsigned char r0_deflt[4]; 2486 2487 spec = devm_kzalloc(priv->dev, sizeof(*spec), GFP_KERNEL); 2488 if (spec == NULL) 2489 return -ENOMEM; 2490 priv->tasdevice[i].cali_specific = spec; 2491 rc = priv->dev_bulk_read(priv, i, p->r0_reg, r0_deflt, 4); 2492 if (rc < 0) { 2493 dev_err(priv->dev, "invalid RE from %d = %d\n", i, rc); 2494 return rc; 2495 } 2496 /* 2497 * SineGainI need to be re-calculated, calculate the high 16 2498 * bits. 2499 */ 2500 re_org = r0_deflt[0] << 8 | r0_deflt[1]; 2501 re_cal = data[k + 1] << 8 | data[k + 2]; 2502 if (re_org > re_cal) { 2503 rc = tasdevice_dev_read(priv, i, TAS2781_PG_REG, 2504 &pg_id); 2505 if (rc < 0) { 2506 dev_err(priv->dev, "invalid PG id %d = %d\n", 2507 i, rc); 2508 return rc; 2509 } 2510 2511 spec->sin_gni_reg = (pg_id == TAS2781_PG_1_0) ? 2512 TASDEVICE_REG(0, 0x1b, 0x34) : 2513 TASDEVICE_REG(0, 0x18, 0x1c); 2514 2515 rc = priv->dev_bulk_read(priv, i, 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