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