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