Lines Matching +full:data +full:- +full:out
1 // SPDX-License-Identifier: GPL-2.0
3 // tas2781-fmwlib.c -- TASDEVICE firmware support
5 // Copyright 2023 - 2024 Texas Instruments, Inc.
7 // Author: Shenghao Ding <shenghao-ding@ti.com>
43 /*should not include B0_P53_R44-R47 */
96 * receiver, games, audio-to-haptics, PMIC record, bypass mode, in tasdevice_add_config()
99 * ultrasonic application. In order to support these variable-numbers in tasdevice_add_config()
105 *status = -ENOMEM; in tasdevice_add_config()
106 goto out; in tasdevice_add_config()
109 if (tas_priv->rcabin.fw_hdr.binary_version_num >= 0x105) { in tasdevice_add_config()
111 *status = -EINVAL; in tasdevice_add_config()
112 dev_err(tas_priv->dev, "add conf: Out of boundary\n"); in tasdevice_add_config()
113 goto out; in tasdevice_add_config()
119 *status = -EINVAL; in tasdevice_add_config()
120 dev_err(tas_priv->dev, "add config: Out of boundary\n"); in tasdevice_add_config()
121 goto out; in tasdevice_add_config()
124 /* convert data[offset], data[offset + 1], data[offset + 2] and in tasdevice_add_config()
125 * data[offset + 3] into host in tasdevice_add_config()
127 cfg_info->nblocks = get_unaligned_be32(&config_data[config_offset]); in tasdevice_add_config()
134 bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks, in tasdevice_add_config()
137 *status = -ENOMEM; in tasdevice_add_config()
138 goto out; in tasdevice_add_config()
140 cfg_info->real_nblocks = 0; in tasdevice_add_config()
141 for (i = 0; i < cfg_info->nblocks; i++) { in tasdevice_add_config()
143 *status = -EINVAL; in tasdevice_add_config()
144 dev_err(tas_priv->dev, in tasdevice_add_config()
145 "%s: Out of boundary: i = %d nblocks = %u!\n", in tasdevice_add_config()
146 __func__, i, cfg_info->nblocks); in tasdevice_add_config()
151 *status = -ENOMEM; in tasdevice_add_config()
155 bk_da[i]->dev_idx = config_data[config_offset]; in tasdevice_add_config()
158 bk_da[i]->block_type = config_data[config_offset]; in tasdevice_add_config()
161 if (bk_da[i]->block_type == TASDEVICE_BIN_BLK_PRE_POWER_UP) { in tasdevice_add_config()
162 if (bk_da[i]->dev_idx == 0) in tasdevice_add_config()
163 cfg_info->active_dev = in tasdevice_add_config()
164 (1 << tas_priv->ndev) - 1; in tasdevice_add_config()
166 cfg_info->active_dev |= 1 << in tasdevice_add_config()
167 (bk_da[i]->dev_idx - 1); in tasdevice_add_config()
170 bk_da[i]->yram_checksum = in tasdevice_add_config()
173 bk_da[i]->block_size = in tasdevice_add_config()
177 bk_da[i]->n_subblks = in tasdevice_add_config()
182 if (config_offset + bk_da[i]->block_size > config_size) { in tasdevice_add_config()
183 *status = -EINVAL; in tasdevice_add_config()
184 dev_err(tas_priv->dev, in tasdevice_add_config()
185 "%s: Out of boundary: i = %d blks = %u!\n", in tasdevice_add_config()
186 __func__, i, cfg_info->nblocks); in tasdevice_add_config()
190 bk_da[i]->regdata = kmemdup(&config_data[config_offset], in tasdevice_add_config()
191 bk_da[i]->block_size, GFP_KERNEL); in tasdevice_add_config()
192 if (!bk_da[i]->regdata) { in tasdevice_add_config()
193 *status = -ENOMEM; in tasdevice_add_config()
194 goto out; in tasdevice_add_config()
197 config_offset += bk_da[i]->block_size; in tasdevice_add_config()
198 cfg_info->real_nblocks += 1; in tasdevice_add_config()
201 out: in tasdevice_add_config()
217 rca = &(tas_priv->rcabin); in tasdevice_rca_parser()
218 fw_hdr = &(rca->fw_hdr); in tasdevice_rca_parser()
219 if (!fmw || !fmw->data) { in tasdevice_rca_parser()
220 dev_err(tas_priv->dev, "Failed to read %s\n", in tasdevice_rca_parser()
221 tas_priv->rca_binaryname); in tasdevice_rca_parser()
222 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
223 ret = -EINVAL; in tasdevice_rca_parser()
224 goto out; in tasdevice_rca_parser()
226 buf = (unsigned char *)fmw->data; in tasdevice_rca_parser()
228 fw_hdr->img_sz = get_unaligned_be32(&buf[offset]); in tasdevice_rca_parser()
230 if (fw_hdr->img_sz != fmw->size) { in tasdevice_rca_parser()
231 dev_err(tas_priv->dev, in tasdevice_rca_parser()
232 "File size not match, %d %u", (int)fmw->size, in tasdevice_rca_parser()
233 fw_hdr->img_sz); in tasdevice_rca_parser()
234 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
235 ret = -EINVAL; in tasdevice_rca_parser()
236 goto out; in tasdevice_rca_parser()
239 fw_hdr->checksum = get_unaligned_be32(&buf[offset]); in tasdevice_rca_parser()
241 fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]); in tasdevice_rca_parser()
242 if (fw_hdr->binary_version_num < 0x103) { in tasdevice_rca_parser()
243 dev_err(tas_priv->dev, "File version 0x%04x is too low", in tasdevice_rca_parser()
244 fw_hdr->binary_version_num); in tasdevice_rca_parser()
245 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
246 ret = -EINVAL; in tasdevice_rca_parser()
247 goto out; in tasdevice_rca_parser()
250 fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]); in tasdevice_rca_parser()
252 fw_hdr->plat_type = buf[offset]; in tasdevice_rca_parser()
254 fw_hdr->dev_family = buf[offset]; in tasdevice_rca_parser()
256 fw_hdr->reserve = buf[offset]; in tasdevice_rca_parser()
258 fw_hdr->ndev = buf[offset]; in tasdevice_rca_parser()
260 if (fw_hdr->ndev != tas_priv->ndev) { in tasdevice_rca_parser()
261 dev_err(tas_priv->dev, in tasdevice_rca_parser()
263 fw_hdr->ndev, tas_priv->ndev); in tasdevice_rca_parser()
264 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
265 ret = -EINVAL; in tasdevice_rca_parser()
266 goto out; in tasdevice_rca_parser()
268 if (offset + TASDEVICE_DEVICE_SUM > fw_hdr->img_sz) { in tasdevice_rca_parser()
269 dev_err(tas_priv->dev, "rca_ready: Out of boundary!\n"); in tasdevice_rca_parser()
270 ret = -EINVAL; in tasdevice_rca_parser()
271 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
272 goto out; in tasdevice_rca_parser()
276 fw_hdr->devs[i] = buf[offset]; in tasdevice_rca_parser()
278 fw_hdr->nconfig = get_unaligned_be32(&buf[offset]); in tasdevice_rca_parser()
282 fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]); in tasdevice_rca_parser()
284 total_config_sz += fw_hdr->config_size[i]; in tasdevice_rca_parser()
287 if (fw_hdr->img_sz - total_config_sz != (unsigned int)offset) { in tasdevice_rca_parser()
288 dev_err(tas_priv->dev, "Bin file error!\n"); in tasdevice_rca_parser()
289 ret = -EINVAL; in tasdevice_rca_parser()
290 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
291 goto out; in tasdevice_rca_parser()
294 cfg_info = kcalloc(fw_hdr->nconfig, sizeof(*cfg_info), GFP_KERNEL); in tasdevice_rca_parser()
296 ret = -ENOMEM; in tasdevice_rca_parser()
297 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
298 goto out; in tasdevice_rca_parser()
300 rca->cfg_info = cfg_info; in tasdevice_rca_parser()
301 rca->ncfgs = 0; in tasdevice_rca_parser()
302 for (i = 0; i < (int)fw_hdr->nconfig; i++) { in tasdevice_rca_parser()
303 rca->ncfgs += 1; in tasdevice_rca_parser()
305 fw_hdr->config_size[i], &ret); in tasdevice_rca_parser()
307 tas_priv->fw_state = TASDEVICE_DSP_FW_FAIL; in tasdevice_rca_parser()
308 goto out; in tasdevice_rca_parser()
310 offset += (int)fw_hdr->config_size[i]; in tasdevice_rca_parser()
312 out: in tasdevice_rca_parser()
320 const unsigned char *data = fmw->data; in fw_parse_block_data_kernel() local
322 if (offset + 16 > fmw->size) { in fw_parse_block_data_kernel()
323 dev_err(tas_fmw->dev, "%s: File Size error\n", __func__); in fw_parse_block_data_kernel()
324 offset = -EINVAL; in fw_parse_block_data_kernel()
325 goto out; in fw_parse_block_data_kernel()
328 /* convert data[offset], data[offset + 1], data[offset + 2] and in fw_parse_block_data_kernel()
329 * data[offset + 3] into host in fw_parse_block_data_kernel()
331 block->type = get_unaligned_be32(&data[offset]); in fw_parse_block_data_kernel()
334 block->is_pchksum_present = data[offset]; in fw_parse_block_data_kernel()
337 block->pchksum = data[offset]; in fw_parse_block_data_kernel()
340 block->is_ychksum_present = data[offset]; in fw_parse_block_data_kernel()
343 block->ychksum = data[offset]; in fw_parse_block_data_kernel()
346 block->blk_size = get_unaligned_be32(&data[offset]); in fw_parse_block_data_kernel()
349 block->nr_subblocks = get_unaligned_be32(&data[offset]); in fw_parse_block_data_kernel()
352 if (offset + block->blk_size > fmw->size) { in fw_parse_block_data_kernel()
353 dev_err(tas_fmw->dev, "%s: nSublocks error\n", __func__); in fw_parse_block_data_kernel()
354 offset = -EINVAL; in fw_parse_block_data_kernel()
355 goto out; in fw_parse_block_data_kernel()
358 block->data = kmemdup(&data[offset], block->blk_size, GFP_KERNEL); in fw_parse_block_data_kernel()
359 if (!block->data) { in fw_parse_block_data_kernel()
360 offset = -ENOMEM; in fw_parse_block_data_kernel()
361 goto out; in fw_parse_block_data_kernel()
363 offset += block->blk_size; in fw_parse_block_data_kernel()
365 out: in fw_parse_block_data_kernel()
373 const unsigned char *data = fmw->data; in fw_parse_data_kernel() local
377 if (offset + 4 > fmw->size) { in fw_parse_data_kernel()
378 dev_err(tas_fmw->dev, "%s: File Size error\n", __func__); in fw_parse_data_kernel()
379 offset = -EINVAL; in fw_parse_data_kernel()
380 goto out; in fw_parse_data_kernel()
382 img_data->nr_blk = get_unaligned_be32(&data[offset]); in fw_parse_data_kernel()
385 img_data->dev_blks = kcalloc(img_data->nr_blk, in fw_parse_data_kernel()
387 if (!img_data->dev_blks) { in fw_parse_data_kernel()
388 offset = -ENOMEM; in fw_parse_data_kernel()
389 goto out; in fw_parse_data_kernel()
392 for (i = 0; i < img_data->nr_blk; i++) { in fw_parse_data_kernel()
393 blk = &(img_data->dev_blks[i]); in fw_parse_data_kernel()
396 offset = -EINVAL; in fw_parse_data_kernel()
401 out: in fw_parse_data_kernel()
412 for (i = 0; i < tas_fmw->nr_programs; i++) { in fw_parse_program_data_kernel()
413 program = &(tas_fmw->programs[i]); in fw_parse_program_data_kernel()
414 if (offset + 72 > fmw->size) { in fw_parse_program_data_kernel()
415 dev_err(tas_priv->dev, "%s: mpName error\n", __func__); in fw_parse_program_data_kernel()
416 offset = -EINVAL; in fw_parse_program_data_kernel()
417 goto out; in fw_parse_program_data_kernel()
422 offset = fw_parse_data_kernel(tas_fmw, &(program->dev_data), in fw_parse_program_data_kernel()
425 goto out; in fw_parse_program_data_kernel()
428 out: in fw_parse_program_data_kernel()
436 const unsigned char *data = fmw->data; in fw_parse_configuration_data_kernel() local
440 for (i = 0; i < tas_fmw->nr_configurations; i++) { in fw_parse_configuration_data_kernel()
441 config = &(tas_fmw->configs[i]); in fw_parse_configuration_data_kernel()
442 if (offset + 80 > fmw->size) { in fw_parse_configuration_data_kernel()
443 dev_err(tas_priv->dev, "%s: mpName error\n", __func__); in fw_parse_configuration_data_kernel()
444 offset = -EINVAL; in fw_parse_configuration_data_kernel()
445 goto out; in fw_parse_configuration_data_kernel()
447 memcpy(config->name, &data[offset], 64); in fw_parse_configuration_data_kernel()
451 offset = fw_parse_data_kernel(tas_fmw, &(config->dev_data), in fw_parse_configuration_data_kernel()
454 goto out; in fw_parse_configuration_data_kernel()
457 out: in fw_parse_configuration_data_kernel()
465 struct tasdevice_fw *tas_fmw = tas_priv->fmw; in fw_parse_variable_header_kernel()
466 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); in fw_parse_variable_header_kernel()
469 const unsigned char *buf = fmw->data; in fw_parse_variable_header_kernel()
473 if (offset + 12 + 4 * TASDEVICE_MAXPROGRAM_NUM_KERNEL > fmw->size) { in fw_parse_variable_header_kernel()
474 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); in fw_parse_variable_header_kernel()
475 offset = -EINVAL; in fw_parse_variable_header_kernel()
476 goto out; in fw_parse_variable_header_kernel()
478 fw_hdr->device_family = get_unaligned_be16(&buf[offset]); in fw_parse_variable_header_kernel()
479 if (fw_hdr->device_family != 0) { in fw_parse_variable_header_kernel()
480 dev_err(tas_priv->dev, "%s:not TAS device\n", __func__); in fw_parse_variable_header_kernel()
481 offset = -EINVAL; in fw_parse_variable_header_kernel()
482 goto out; in fw_parse_variable_header_kernel()
485 fw_hdr->device = get_unaligned_be16(&buf[offset]); in fw_parse_variable_header_kernel()
486 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE || in fw_parse_variable_header_kernel()
487 fw_hdr->device == 6) { in fw_parse_variable_header_kernel()
488 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device); in fw_parse_variable_header_kernel()
489 offset = -EINVAL; in fw_parse_variable_header_kernel()
490 goto out; in fw_parse_variable_header_kernel()
493 fw_hdr->ndev = deviceNumber[fw_hdr->device]; in fw_parse_variable_header_kernel()
495 if (fw_hdr->ndev != tas_priv->ndev) { in fw_parse_variable_header_kernel()
496 dev_err(tas_priv->dev, in fw_parse_variable_header_kernel()
498 __func__, fw_hdr->ndev, tas_priv->ndev); in fw_parse_variable_header_kernel()
499 offset = -EINVAL; in fw_parse_variable_header_kernel()
500 goto out; in fw_parse_variable_header_kernel()
503 tas_fmw->nr_programs = get_unaligned_be32(&buf[offset]); in fw_parse_variable_header_kernel()
506 if (tas_fmw->nr_programs == 0 || tas_fmw->nr_programs > in fw_parse_variable_header_kernel()
508 dev_err(tas_priv->dev, "mnPrograms is invalid\n"); in fw_parse_variable_header_kernel()
509 offset = -EINVAL; in fw_parse_variable_header_kernel()
510 goto out; in fw_parse_variable_header_kernel()
513 tas_fmw->programs = kcalloc(tas_fmw->nr_programs, in fw_parse_variable_header_kernel()
515 if (!tas_fmw->programs) { in fw_parse_variable_header_kernel()
516 offset = -ENOMEM; in fw_parse_variable_header_kernel()
517 goto out; in fw_parse_variable_header_kernel()
520 for (i = 0; i < tas_fmw->nr_programs; i++) { in fw_parse_variable_header_kernel()
521 program = &(tas_fmw->programs[i]); in fw_parse_variable_header_kernel()
522 program->prog_size = get_unaligned_be32(&buf[offset]); in fw_parse_variable_header_kernel()
527 offset += 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs); in fw_parse_variable_header_kernel()
529 tas_fmw->nr_configurations = get_unaligned_be32(&buf[offset]); in fw_parse_variable_header_kernel()
536 max_confs = (fw_hdr->ndev >= 4) ? in fw_parse_variable_header_kernel()
539 if (tas_fmw->nr_configurations == 0 || in fw_parse_variable_header_kernel()
540 tas_fmw->nr_configurations > max_confs) { in fw_parse_variable_header_kernel()
541 dev_err(tas_priv->dev, "%s: Conf is invalid\n", __func__); in fw_parse_variable_header_kernel()
542 offset = -EINVAL; in fw_parse_variable_header_kernel()
543 goto out; in fw_parse_variable_header_kernel()
546 if (offset + 4 * max_confs > fmw->size) { in fw_parse_variable_header_kernel()
547 dev_err(tas_priv->dev, "%s: mpConfigurations err\n", __func__); in fw_parse_variable_header_kernel()
548 offset = -EINVAL; in fw_parse_variable_header_kernel()
549 goto out; in fw_parse_variable_header_kernel()
552 tas_fmw->configs = kcalloc(tas_fmw->nr_configurations, in fw_parse_variable_header_kernel()
554 if (!tas_fmw->configs) { in fw_parse_variable_header_kernel()
555 offset = -ENOMEM; in fw_parse_variable_header_kernel()
556 goto out; in fw_parse_variable_header_kernel()
559 for (i = 0; i < tas_fmw->nr_programs; i++) { in fw_parse_variable_header_kernel()
560 config = &(tas_fmw->configs[i]); in fw_parse_variable_header_kernel()
561 config->cfg_size = get_unaligned_be32(&buf[offset]); in fw_parse_variable_header_kernel()
566 offset += 4 * (max_confs - tas_fmw->nr_programs); in fw_parse_variable_header_kernel()
568 out: in fw_parse_variable_header_kernel()
572 static int tasdevice_process_block(void *context, unsigned char *data, in tasdevice_process_block() argument
577 unsigned char subblk_typ = data[1]; in tasdevice_process_block()
583 chn = idx - 1; in tasdevice_process_block()
587 chnend = tas_priv->ndev; in tasdevice_process_block()
591 if (tas_priv->tasdevice[chn].is_loading == false) in tasdevice_process_block()
599 unsigned short len = get_unaligned_be16(&data[2]); in tasdevice_process_block()
603 dev_err(tas_priv->dev, in tasdevice_process_block()
604 "process_block: Out of boundary\n"); in tasdevice_process_block()
611 TASDEVICE_REG(data[subblk_offset], in tasdevice_process_block()
612 data[subblk_offset + 1], in tasdevice_process_block()
613 data[subblk_offset + 2]), in tasdevice_process_block()
614 data[subblk_offset + 3]); in tasdevice_process_block()
617 dev_err(tas_priv->dev, in tasdevice_process_block()
625 unsigned short len = get_unaligned_be16(&data[2]); in tasdevice_process_block()
629 dev_err(tas_priv->dev, in tasdevice_process_block()
630 "%s: BST Out of boundary\n", in tasdevice_process_block()
636 dev_err(tas_priv->dev, in tasdevice_process_block()
637 "%s:Bst-len(%u)not div by 4\n", in tasdevice_process_block()
643 TASDEVICE_REG(data[subblk_offset], in tasdevice_process_block()
644 data[subblk_offset + 1], in tasdevice_process_block()
645 data[subblk_offset + 2]), in tasdevice_process_block()
646 &(data[subblk_offset + 4]), len); in tasdevice_process_block()
649 dev_err(tas_priv->dev, in tasdevice_process_block()
660 dev_err(tas_priv->dev, in tasdevice_process_block()
661 "%s: delay Out of boundary\n", in tasdevice_process_block()
666 sleep_time = get_unaligned_be16(&data[2]) * 1000; in tasdevice_process_block()
673 dev_err(tas_priv->dev, in tasdevice_process_block()
674 "%s: bit write Out of boundary\n", in tasdevice_process_block()
680 TASDEVICE_REG(data[subblk_offset + 2], in tasdevice_process_block()
681 data[subblk_offset + 3], in tasdevice_process_block()
682 data[subblk_offset + 4]), in tasdevice_process_block()
683 data[subblk_offset + 1], in tasdevice_process_block()
684 data[subblk_offset + 5]); in tasdevice_process_block()
687 dev_err(tas_priv->dev, in tasdevice_process_block()
698 tas_priv->tasdevice[chn].cur_prog = -1; in tasdevice_process_block()
699 tas_priv->tasdevice[chn].cur_conf = -1; in tasdevice_process_block()
701 tas_priv->tasdevice[chn].cur_conf = -1; in tasdevice_process_block()
712 struct tasdevice_rca *rca = &(tas_priv->rcabin); in tasdevice_select_cfg_blk()
713 struct tasdevice_config_info **cfg_info = rca->cfg_info; in tasdevice_select_cfg_blk()
717 if (conf_no >= rca->ncfgs || conf_no < 0 || !cfg_info) { in tasdevice_select_cfg_blk()
718 dev_err(tas_priv->dev, "conf_no should be not more than %u\n", in tasdevice_select_cfg_blk()
719 rca->ncfgs); in tasdevice_select_cfg_blk()
722 blk_data = cfg_info[conf_no]->blk_data; in tasdevice_select_cfg_blk()
724 for (j = 0; j < (int)cfg_info[conf_no]->real_nblocks; j++) { in tasdevice_select_cfg_blk()
728 dev_err(tas_priv->dev, in tasdevice_select_cfg_blk()
732 if (block_type != blk_data[j]->block_type) in tasdevice_select_cfg_blk()
735 for (k = 0; k < (int)blk_data[j]->n_subblks; k++) { in tasdevice_select_cfg_blk()
736 if (blk_data[j]->dev_idx) { in tasdevice_select_cfg_blk()
737 chn = blk_data[j]->dev_idx - 1; in tasdevice_select_cfg_blk()
738 chnend = blk_data[j]->dev_idx; in tasdevice_select_cfg_blk()
741 chnend = tas_priv->ndev; in tasdevice_select_cfg_blk()
744 tas_priv->tasdevice[chn].is_loading = true; in tasdevice_select_cfg_blk()
747 blk_data[j]->regdata + length, in tasdevice_select_cfg_blk()
748 blk_data[j]->dev_idx, in tasdevice_select_cfg_blk()
749 blk_data[j]->block_size - length); in tasdevice_select_cfg_blk()
751 if (blk_data[j]->block_size < length) { in tasdevice_select_cfg_blk()
752 dev_err(tas_priv->dev, in tasdevice_select_cfg_blk()
753 "%s: %u %u out of boundary\n", in tasdevice_select_cfg_blk()
755 blk_data[j]->block_size); in tasdevice_select_cfg_blk()
759 if (length != blk_data[j]->block_size) in tasdevice_select_cfg_blk()
760 dev_err(tas_priv->dev, "%s: %u %u size is not same\n", in tasdevice_select_cfg_blk()
761 __func__, length, blk_data[j]->block_size); in tasdevice_select_cfg_blk()
769 struct tasdevice_dspfw_hdr *fw_hdr = &(tasdevice->fmw->fw_hdr); in tasdevice_load_block_kernel()
770 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr); in tasdevice_load_block_kernel()
771 const unsigned int blk_size = block->blk_size; in tasdevice_load_block_kernel()
773 unsigned char *data = block->data; in tasdevice_load_block_kernel() local
776 if (fw_fixed_hdr->ppcver >= PPC3_VERSION_TAS2781) { in tasdevice_load_block_kernel()
777 switch (block->type) { in tasdevice_load_block_kernel()
818 dev_info(tasdevice->dev, in tasdevice_load_block_kernel()
820 __func__, block->type); in tasdevice_load_block_kernel()
823 } else if (fw_fixed_hdr->ppcver >= in tasdevice_load_block_kernel()
825 switch (block->type) { in tasdevice_load_block_kernel()
858 dev_info(tasdevice->dev, in tasdevice_load_block_kernel()
860 __func__, block->type); in tasdevice_load_block_kernel()
864 switch (block->type) { in tasdevice_load_block_kernel()
897 dev_info(tasdevice->dev, in tasdevice_load_block_kernel()
899 __func__, block->type); in tasdevice_load_block_kernel()
904 for (i = 0, length = 0; i < block->nr_subblocks; i++) { in tasdevice_load_block_kernel()
905 int rc = tasdevice_process_block(tasdevice, data + length, in tasdevice_load_block_kernel()
906 dev_idx, blk_size - length); in tasdevice_load_block_kernel()
908 dev_err(tasdevice->dev, in tasdevice_load_block_kernel()
915 dev_err(tasdevice->dev, "%s: %u %u out of boundary\n", in tasdevice_load_block_kernel()
928 const unsigned char *buf = fmw->data; in fw_parse_variable_hdr()
933 if (offset + len + 8 > fmw->size) { in fw_parse_variable_hdr()
934 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); in fw_parse_variable_hdr()
935 offset = -EINVAL; in fw_parse_variable_hdr()
936 goto out; in fw_parse_variable_hdr()
941 fw_hdr->device_family = get_unaligned_be32(&buf[offset]); in fw_parse_variable_hdr()
942 if (fw_hdr->device_family != 0) { in fw_parse_variable_hdr()
943 dev_err(tas_priv->dev, "%s: not TAS device\n", __func__); in fw_parse_variable_hdr()
944 offset = -EINVAL; in fw_parse_variable_hdr()
945 goto out; in fw_parse_variable_hdr()
949 fw_hdr->device = get_unaligned_be32(&buf[offset]); in fw_parse_variable_hdr()
950 if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE || in fw_parse_variable_hdr()
951 fw_hdr->device == 6) { in fw_parse_variable_hdr()
952 dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device); in fw_parse_variable_hdr()
953 offset = -EINVAL; in fw_parse_variable_hdr()
954 goto out; in fw_parse_variable_hdr()
957 fw_hdr->ndev = deviceNumber[fw_hdr->device]; in fw_parse_variable_hdr()
959 out: in fw_parse_variable_hdr()
966 struct tasdevice_fw *tas_fmw = tas_priv->fmw; in fw_parse_variable_header_git()
967 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); in fw_parse_variable_header_git()
971 goto out; in fw_parse_variable_header_git()
972 if (fw_hdr->ndev != tas_priv->ndev) { in fw_parse_variable_header_git()
973 dev_err(tas_priv->dev, in fw_parse_variable_header_git()
975 __func__, fw_hdr->ndev, tas_priv->ndev); in fw_parse_variable_header_git()
976 offset = -EINVAL; in fw_parse_variable_header_git()
979 out: in fw_parse_variable_header_git()
986 unsigned char *data = (unsigned char *)fmw->data; in fw_parse_block_data() local
989 if (offset + 8 > fmw->size) { in fw_parse_block_data()
990 dev_err(tas_fmw->dev, "%s: Type error\n", __func__); in fw_parse_block_data()
991 offset = -EINVAL; in fw_parse_block_data()
992 goto out; in fw_parse_block_data()
994 block->type = get_unaligned_be32(&data[offset]); in fw_parse_block_data()
997 if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) { in fw_parse_block_data()
998 if (offset + 8 > fmw->size) { in fw_parse_block_data()
999 dev_err(tas_fmw->dev, "PChkSumPresent error\n"); in fw_parse_block_data()
1000 offset = -EINVAL; in fw_parse_block_data()
1001 goto out; in fw_parse_block_data()
1003 block->is_pchksum_present = data[offset]; in fw_parse_block_data()
1006 block->pchksum = data[offset]; in fw_parse_block_data()
1009 block->is_ychksum_present = data[offset]; in fw_parse_block_data()
1012 block->ychksum = data[offset]; in fw_parse_block_data()
1015 block->is_pchksum_present = 0; in fw_parse_block_data()
1016 block->is_ychksum_present = 0; in fw_parse_block_data()
1019 block->nr_cmds = get_unaligned_be32(&data[offset]); in fw_parse_block_data()
1022 n = block->nr_cmds * 4; in fw_parse_block_data()
1023 if (offset + n > fmw->size) { in fw_parse_block_data()
1024 dev_err(tas_fmw->dev, in fw_parse_block_data()
1026 __func__, (unsigned long)fmw->size, offset, n); in fw_parse_block_data()
1027 offset = -EINVAL; in fw_parse_block_data()
1028 goto out; in fw_parse_block_data()
1031 block->data = kmemdup(&data[offset], n, GFP_KERNEL); in fw_parse_block_data()
1032 if (!block->data) { in fw_parse_block_data()
1033 offset = -ENOMEM; in fw_parse_block_data()
1034 goto out; in fw_parse_block_data()
1038 out: in fw_parse_block_data()
1049 const unsigned char *data = (unsigned char *)fmw->data; in fw_parse_data() local
1054 if (offset + 64 > fmw->size) { in fw_parse_data()
1055 dev_err(tas_fmw->dev, "%s: Name error\n", __func__); in fw_parse_data()
1056 offset = -EINVAL; in fw_parse_data()
1057 goto out; in fw_parse_data()
1059 memcpy(img_data->name, &data[offset], 64); in fw_parse_data()
1062 n = strlen((char *)&data[offset]); in fw_parse_data()
1064 if (offset + n + 2 > fmw->size) { in fw_parse_data()
1065 dev_err(tas_fmw->dev, "%s: Description error\n", __func__); in fw_parse_data()
1066 offset = -EINVAL; in fw_parse_data()
1067 goto out; in fw_parse_data()
1070 img_data->nr_blk = get_unaligned_be16(&data[offset]); in fw_parse_data()
1073 img_data->dev_blks = kcalloc(img_data->nr_blk, in fw_parse_data()
1075 if (!img_data->dev_blks) { in fw_parse_data()
1076 offset = -ENOMEM; in fw_parse_data()
1077 goto out; in fw_parse_data()
1079 for (i = 0; i < img_data->nr_blk; i++) { in fw_parse_data()
1080 blk = &(img_data->dev_blks[i]); in fw_parse_data()
1083 offset = -EINVAL; in fw_parse_data()
1084 goto out; in fw_parse_data()
1088 out: in fw_parse_data()
1098 unsigned char *buf = (unsigned char *)fmw->data; in fw_parse_program_data()
1102 if (offset + 2 > fmw->size) { in fw_parse_program_data()
1103 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); in fw_parse_program_data()
1104 offset = -EINVAL; in fw_parse_program_data()
1105 goto out; in fw_parse_program_data()
1107 tas_fmw->nr_programs = get_unaligned_be16(&buf[offset]); in fw_parse_program_data()
1110 if (tas_fmw->nr_programs == 0) { in fw_parse_program_data()
1111 /*Not error in calibration Data file, return directly*/ in fw_parse_program_data()
1112 dev_info(tas_priv->dev, "%s: No Programs data, maybe calbin\n", in fw_parse_program_data()
1114 goto out; in fw_parse_program_data()
1117 tas_fmw->programs = in fw_parse_program_data()
1118 kcalloc(tas_fmw->nr_programs, sizeof(struct tasdevice_prog), in fw_parse_program_data()
1120 if (!tas_fmw->programs) { in fw_parse_program_data()
1121 offset = -ENOMEM; in fw_parse_program_data()
1122 goto out; in fw_parse_program_data()
1124 for (i = 0; i < tas_fmw->nr_programs; i++) { in fw_parse_program_data()
1127 program = &(tas_fmw->programs[i]); in fw_parse_program_data()
1128 if (offset + 64 > fmw->size) { in fw_parse_program_data()
1129 dev_err(tas_priv->dev, "%s: mpName error\n", __func__); in fw_parse_program_data()
1130 offset = -EINVAL; in fw_parse_program_data()
1131 goto out; in fw_parse_program_data()
1138 if (offset + n > fmw->size) { in fw_parse_program_data()
1139 dev_err(tas_priv->dev, "Description err\n"); in fw_parse_program_data()
1140 offset = -EINVAL; in fw_parse_program_data()
1141 goto out; in fw_parse_program_data()
1146 offset = fw_parse_data(tas_fmw, &(program->dev_data), fmw, in fw_parse_program_data()
1149 goto out; in fw_parse_program_data()
1152 out: in fw_parse_program_data()
1164 unsigned char *data = (unsigned char *)fmw->data; in fw_parse_configuration_data() local
1169 if (offset + 2 > fmw->size) { in fw_parse_configuration_data()
1170 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); in fw_parse_configuration_data()
1171 offset = -EINVAL; in fw_parse_configuration_data()
1172 goto out; in fw_parse_configuration_data()
1174 tas_fmw->nr_configurations = get_unaligned_be16(&data[offset]); in fw_parse_configuration_data()
1177 if (tas_fmw->nr_configurations == 0) { in fw_parse_configuration_data()
1178 dev_err(tas_priv->dev, "%s: Conf is zero\n", __func__); in fw_parse_configuration_data()
1179 /*Not error for calibration Data file, return directly*/ in fw_parse_configuration_data()
1180 goto out; in fw_parse_configuration_data()
1182 tas_fmw->configs = kcalloc(tas_fmw->nr_configurations, in fw_parse_configuration_data()
1184 if (!tas_fmw->configs) { in fw_parse_configuration_data()
1185 offset = -ENOMEM; in fw_parse_configuration_data()
1186 goto out; in fw_parse_configuration_data()
1188 for (i = 0; i < tas_fmw->nr_configurations; i++) { in fw_parse_configuration_data()
1189 config = &(tas_fmw->configs[i]); in fw_parse_configuration_data()
1190 if (offset + 64 > fmw->size) { in fw_parse_configuration_data()
1191 dev_err(tas_priv->dev, "File Size err\n"); in fw_parse_configuration_data()
1192 offset = -EINVAL; in fw_parse_configuration_data()
1193 goto out; in fw_parse_configuration_data()
1195 memcpy(config->name, &data[offset], 64); in fw_parse_configuration_data()
1198 n = strlen((char *)&data[offset]); in fw_parse_configuration_data()
1200 if (offset + n > fmw->size) { in fw_parse_configuration_data()
1201 dev_err(tas_priv->dev, "Description err\n"); in fw_parse_configuration_data()
1202 offset = -EINVAL; in fw_parse_configuration_data()
1203 goto out; in fw_parse_configuration_data()
1208 offset = fw_parse_data(tas_fmw, &(config->dev_data), in fw_parse_configuration_data()
1211 goto out; in fw_parse_configuration_data()
1214 out: in fw_parse_configuration_data()
1227 cd->len = TAS2781_YRAM5_END_REG - reg + 1; in check_inpage_yram_rg()
1229 cd->len = len; in check_inpage_yram_rg()
1230 cd->offset = reg; in check_inpage_yram_rg()
1234 cd->offset = TAS2781_YRAM5_START_REG; in check_inpage_yram_rg()
1235 cd->len = len - TAS2781_YRAM5_START_REG + reg; in check_inpage_yram_rg()
1250 cd->offset = reg; in check_inpage_yram_bk1()
1251 cd->len = len; in check_inpage_yram_bk1()
1254 cd->offset = TAS2781_YRAM1_START_REG; in check_inpage_yram_bk1()
1255 cd->len = len - TAS2781_YRAM1_START_REG + reg; in check_inpage_yram_bk1()
1265 * true -- the registers are in the inpage yram
1266 * false -- the registers are NOT in the inpage yram
1295 cd->offset = reg; in check_inblock_yram_bk()
1296 cd->len = len; in check_inblock_yram_bk()
1299 if (reg + len - 1 >= TAS2781_YRAM2_START_REG) { in check_inblock_yram_bk()
1300 cd->offset = TAS2781_YRAM2_START_REG; in check_inblock_yram_bk()
1301 cd->len = reg + len - TAS2781_YRAM2_START_REG; in check_inblock_yram_bk()
1311 * true -- the registers are in the inblock yram
1312 * false -- the registers are NOT in the inblock yram
1350 if ((reg + len - 1) > 127) { in tasdev_multibytes_chksum()
1351 ret = -EINVAL; in tasdev_multibytes_chksum()
1352 dev_err(tasdevice->dev, "firmware error\n"); in tasdev_multibytes_chksum()
1370 dev_err(tasdevice->dev, "firmware error\n"); in tasdev_multibytes_chksum()
1371 ret = -EINVAL; in tasdev_multibytes_chksum()
1393 crc_chksum += crc8(tasdevice->crc8_lkp_tbl, &nBuf1[i], in tasdev_multibytes_chksum()
1431 dev_err(tasdevice->dev, in do_singlereg_checksum()
1434 tasdevice->tasdevice[chl].err_code |= ERROR_YRAM_CRCCHK; in do_singlereg_checksum()
1435 ret = -EAGAIN; in do_singlereg_checksum()
1439 ret = crc8(tasdevice->crc8_lkp_tbl, &val, 1, 0); in do_singlereg_checksum()
1450 dev->cur_prog = -1; in set_err_prg_cfg()
1452 dev->cur_conf = -1; in set_err_prg_cfg()
1474 if (ret != -EAGAIN) in tasdev_bytes_chksum()
1477 block->nr_retry--; in tasdev_bytes_chksum()
1478 if (block->nr_retry > 0) in tasdev_bytes_chksum()
1481 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]); in tasdev_bytes_chksum()
1489 unsigned char page, unsigned char reg, unsigned char *data, in tasdev_multibytes_wr() argument
1497 TASDEVICE_REG(book, page, reg), data + 3, len); in tasdev_multibytes_wr()
1500 if (block->is_ychksum_present) in tasdev_multibytes_wr()
1505 TASDEVICE_REG(book, page, reg), data[3]); in tasdev_multibytes_wr()
1508 if (block->is_ychksum_present) in tasdev_multibytes_wr()
1510 page, reg, 1, data[3], crc_chksum); in tasdev_multibytes_wr()
1513 if (!block->is_ychksum_present || ret >= 0) { in tasdev_multibytes_wr()
1516 *nr_cmds += ((len - 2) / 4) + 1; in tasdev_multibytes_wr()
1532 dev_err(tas_priv->dev, "%s: Chn %d\n", __func__, chn); in tasdev_block_chksum()
1533 set_err_prg_cfg(block->type, &tas_priv->tasdevice[chn]); in tasdev_block_chksum()
1537 if ((nr_value & 0xff) != block->pchksum) { in tasdev_block_chksum()
1538 dev_err(tas_priv->dev, "%s: Blk PChkSum Chn %d ", __func__, in tasdev_block_chksum()
1540 dev_err(tas_priv->dev, "PChkSum = 0x%x, Reg = 0x%x\n", in tasdev_block_chksum()
1541 block->pchksum, (nr_value & 0xff)); in tasdev_block_chksum()
1542 tas_priv->tasdevice[chn].err_code |= ERROR_PRAM_CRCCHK; in tasdev_block_chksum()
1543 ret = -EAGAIN; in tasdev_block_chksum()
1544 block->nr_retry--; in tasdev_block_chksum()
1546 if (block->nr_retry <= 0) in tasdev_block_chksum()
1547 set_err_prg_cfg(block->type, in tasdev_block_chksum()
1548 &tas_priv->tasdevice[chn]); in tasdev_block_chksum()
1550 tas_priv->tasdevice[chn].err_code &= ~ERROR_PRAM_CRCCHK; in tasdev_block_chksum()
1562 unsigned char *data = block->data; in tasdev_load_blk() local
1570 while (block->nr_retry > 0) { in tasdev_load_blk()
1571 if (block->is_pchksum_present) { in tasdev_load_blk()
1578 if (block->is_ychksum_present) in tasdev_load_blk()
1583 while (nr_cmds < block->nr_cmds) { in tasdev_load_blk()
1584 data = block->data + nr_cmds * 4; in tasdev_load_blk()
1586 book = data[0]; in tasdev_load_blk()
1587 page = data[1]; in tasdev_load_blk()
1588 offset = data[2]; in tasdev_load_blk()
1589 val = data[3]; in tasdev_load_blk()
1599 if (block->is_ychksum_present) { in tasdev_load_blk()
1610 /*book -- data[0] page -- data[1]*/ in tasdev_load_blk()
1617 data += 4; in tasdev_load_blk()
1619 book = data[0]; in tasdev_load_blk()
1620 page = data[1]; in tasdev_load_blk()
1621 offset = data[2]; in tasdev_load_blk()
1623 block, chn, book, page, offset, data, in tasdev_load_blk()
1629 if (ret == -EAGAIN) { in tasdev_load_blk()
1630 if (block->nr_retry > 0) in tasdev_load_blk()
1635 if (block->is_pchksum_present) { in tasdev_load_blk()
1637 if (ret == -EAGAIN) { in tasdev_load_blk()
1638 if (block->nr_retry > 0) in tasdev_load_blk()
1644 if (block->is_ychksum_present) { in tasdev_load_blk()
1646 dev_err(tas_priv->dev, in tasdev_load_blk()
1648 block->ychksum, crc_chksum); in tasdev_load_blk()
1650 tas_priv->tasdevice[chn].err_code &= in tasdev_load_blk()
1670 switch (block->type) { in tasdevice_load_block()
1673 chnend = tas_priv->ndev; in tasdevice_load_block()
1700 dev_dbg(tas_priv->dev, "load blk: Other Type = 0x%02x\n", in tasdevice_load_block()
1701 block->type); in tasdevice_load_block()
1706 block->nr_retry = 6; in tasdevice_load_block()
1707 if (tas_priv->tasdevice[chn].is_loading == false) in tasdevice_load_block()
1711 dev_err(tas_priv->dev, "dev %d, Blk (%d) load error\n", in tasdevice_load_block()
1712 chn, block->type); in tasdevice_load_block()
1726 tas_priv->fw_parse_variable_header = in dspfw_default_callback()
1728 tas_priv->fw_parse_program_data = in dspfw_default_callback()
1730 tas_priv->fw_parse_configuration_data = in dspfw_default_callback()
1732 tas_priv->tasdevice_load_block = in dspfw_default_callback()
1737 tas_priv->fw_parse_variable_header = in dspfw_default_callback()
1739 tas_priv->fw_parse_program_data = in dspfw_default_callback()
1741 tas_priv->fw_parse_configuration_data = in dspfw_default_callback()
1743 tas_priv->tasdevice_load_block = in dspfw_default_callback()
1747 dev_err(tas_priv->dev, in dspfw_default_callback()
1750 dev_err(tas_priv->dev, " Current:0x%02x\n", in dspfw_default_callback()
1752 rc = -EINVAL; in dspfw_default_callback()
1757 dev_err(tas_priv->dev, in dspfw_default_callback()
1759 dev_err(tas_priv->dev, "current is 0x%02x\n", drv_ver); in dspfw_default_callback()
1760 rc = -EINVAL; in dspfw_default_callback()
1773 for (i = 0; i < dev_data->nr_blk; i++) { in load_calib_data()
1774 block = &(dev_data->dev_blks[i]); in load_calib_data()
1786 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); in fw_parse_header()
1787 struct tasdevice_fw_fixed_hdr *fw_fixed_hdr = &(fw_hdr->fixed_hdr); in fw_parse_header()
1789 const unsigned char *buf = (unsigned char *)fmw->data; in fw_parse_header()
1791 if (offset + 92 > fmw->size) { in fw_parse_header()
1792 dev_err(tas_priv->dev, "%s: File Size error\n", __func__); in fw_parse_header()
1793 offset = -EINVAL; in fw_parse_header()
1794 goto out; in fw_parse_header()
1797 dev_err(tas_priv->dev, "%s: Magic num NOT match\n", __func__); in fw_parse_header()
1798 offset = -EINVAL; in fw_parse_header()
1799 goto out; in fw_parse_header()
1803 /* Convert data[offset], data[offset + 1], data[offset + 2] and in fw_parse_header()
1804 * data[offset + 3] into host in fw_parse_header()
1806 fw_fixed_hdr->fwsize = get_unaligned_be32(&buf[offset]); in fw_parse_header()
1808 if (fw_fixed_hdr->fwsize != fmw->size) { in fw_parse_header()
1809 dev_err(tas_priv->dev, "File size not match, %lu %u", in fw_parse_header()
1810 (unsigned long)fmw->size, fw_fixed_hdr->fwsize); in fw_parse_header()
1811 offset = -EINVAL; in fw_parse_header()
1812 goto out; in fw_parse_header()
1815 fw_fixed_hdr->ppcver = get_unaligned_be32(&buf[offset]); in fw_parse_header()
1817 fw_fixed_hdr->drv_ver = get_unaligned_be32(&buf[offset]); in fw_parse_header()
1820 out: in fw_parse_header()
1827 struct tasdevice_dspfw_hdr *fw_hdr = &(tas_fmw->fw_hdr); in fw_parse_variable_hdr_cal()
1831 goto out; in fw_parse_variable_hdr_cal()
1832 if (fw_hdr->ndev != 1) { in fw_parse_variable_hdr_cal()
1833 dev_err(tas_priv->dev, in fw_parse_variable_hdr_cal()
1835 __func__, fw_hdr->ndev); in fw_parse_variable_hdr_cal()
1836 offset = -EINVAL; in fw_parse_variable_hdr_cal()
1839 out: in fw_parse_variable_hdr_cal()
1843 /* When calibrated data parsing error occurs, DSP can still work with default
1844 * calibrated data, memory resource related to calibrated data will be
1851 unsigned char *data = (unsigned char *)fmw->data; in fw_parse_calibration_data() local
1854 if (offset + 2 > fmw->size) { in fw_parse_calibration_data()
1855 dev_err(tas_priv->dev, "%s: Calibrations error\n", __func__); in fw_parse_calibration_data()
1856 offset = -EINVAL; in fw_parse_calibration_data()
1857 goto out; in fw_parse_calibration_data()
1859 tas_fmw->nr_calibrations = get_unaligned_be16(&data[offset]); in fw_parse_calibration_data()
1862 if (tas_fmw->nr_calibrations != 1) { in fw_parse_calibration_data()
1863 dev_err(tas_priv->dev, in fw_parse_calibration_data()
1865 __func__, tas_fmw->nr_calibrations); in fw_parse_calibration_data()
1866 goto out; in fw_parse_calibration_data()
1869 tas_fmw->calibrations = kcalloc(tas_fmw->nr_calibrations, in fw_parse_calibration_data()
1871 if (!tas_fmw->calibrations) { in fw_parse_calibration_data()
1872 offset = -ENOMEM; in fw_parse_calibration_data()
1873 goto out; in fw_parse_calibration_data()
1875 for (i = 0; i < tas_fmw->nr_calibrations; i++) { in fw_parse_calibration_data()
1876 if (offset + 64 > fmw->size) { in fw_parse_calibration_data()
1877 dev_err(tas_priv->dev, "Calibrations error\n"); in fw_parse_calibration_data()
1878 offset = -EINVAL; in fw_parse_calibration_data()
1879 goto out; in fw_parse_calibration_data()
1881 calibration = &(tas_fmw->calibrations[i]); in fw_parse_calibration_data()
1884 n = strlen((char *)&data[offset]); in fw_parse_calibration_data()
1887 if (offset + n > fmw->size) { in fw_parse_calibration_data()
1888 dev_err(tas_priv->dev, "Description err\n"); in fw_parse_calibration_data()
1889 offset = -EINVAL; in fw_parse_calibration_data()
1890 goto out; in fw_parse_calibration_data()
1894 offset = fw_parse_data(tas_fmw, &(calibration->dev_data), fmw, in fw_parse_calibration_data()
1897 goto out; in fw_parse_calibration_data()
1900 out: in fw_parse_calibration_data()
1908 struct tasdevice *tasdev = &(tas_priv->tasdevice[i]); in tas2781_load_calibration()
1915 ret = request_firmware(&fw_entry, file_name, tas_priv->dev); in tas2781_load_calibration()
1917 dev_err(tas_priv->dev, "%s: Request firmware %s failed\n", in tas2781_load_calibration()
1919 goto out; in tas2781_load_calibration()
1922 if (!fw_entry->size) { in tas2781_load_calibration()
1923 dev_err(tas_priv->dev, "%s: file read error: size = %lu\n", in tas2781_load_calibration()
1924 __func__, (unsigned long)fw_entry->size); in tas2781_load_calibration()
1925 ret = -EINVAL; in tas2781_load_calibration()
1926 goto out; in tas2781_load_calibration()
1928 fmw.size = fw_entry->size; in tas2781_load_calibration()
1929 fmw.data = fw_entry->data; in tas2781_load_calibration()
1931 tas_fmw = tasdev->cali_data_fmw = kzalloc(sizeof(struct tasdevice_fw), in tas2781_load_calibration()
1933 if (!tasdev->cali_data_fmw) { in tas2781_load_calibration()
1934 ret = -ENOMEM; in tas2781_load_calibration()
1935 goto out; in tas2781_load_calibration()
1937 tas_fmw->dev = tas_priv->dev; in tas2781_load_calibration()
1939 if (offset == -EINVAL) { in tas2781_load_calibration()
1940 dev_err(tas_priv->dev, "fw_parse_header EXIT!\n"); in tas2781_load_calibration()
1942 goto out; in tas2781_load_calibration()
1945 if (offset == -EINVAL) { in tas2781_load_calibration()
1946 dev_err(tas_priv->dev, in tas2781_load_calibration()
1949 goto out; in tas2781_load_calibration()
1953 dev_err(tas_priv->dev, "fw_parse_program_data EXIT!\n"); in tas2781_load_calibration()
1955 goto out; in tas2781_load_calibration()
1959 dev_err(tas_priv->dev, "fw_parse_configuration_data EXIT!\n"); in tas2781_load_calibration()
1961 goto out; in tas2781_load_calibration()
1965 dev_err(tas_priv->dev, "fw_parse_calibration_data EXIT!\n"); in tas2781_load_calibration()
1967 goto out; in tas2781_load_calibration()
1970 out: in tas2781_load_calibration()
1987 if (!fmw || !fmw->data) { in tasdevice_dspfw_ready()
1988 dev_err(tas_priv->dev, "%s: Failed to read firmware %s\n", in tasdevice_dspfw_ready()
1989 __func__, tas_priv->coef_binaryname); in tasdevice_dspfw_ready()
1990 ret = -EINVAL; in tasdevice_dspfw_ready()
1991 goto out; in tasdevice_dspfw_ready()
1994 tas_priv->fmw = kzalloc(sizeof(struct tasdevice_fw), GFP_KERNEL); in tasdevice_dspfw_ready()
1995 if (!tas_priv->fmw) { in tasdevice_dspfw_ready()
1996 ret = -ENOMEM; in tasdevice_dspfw_ready()
1997 goto out; in tasdevice_dspfw_ready()
1999 tas_fmw = tas_priv->fmw; in tasdevice_dspfw_ready()
2000 tas_fmw->dev = tas_priv->dev; in tasdevice_dspfw_ready()
2003 if (offset == -EINVAL) { in tasdevice_dspfw_ready()
2004 ret = -EINVAL; in tasdevice_dspfw_ready()
2005 goto out; in tasdevice_dspfw_ready()
2007 fw_fixed_hdr = &(tas_fmw->fw_hdr.fixed_hdr); in tasdevice_dspfw_ready()
2009 switch (fw_fixed_hdr->drv_ver) { in tasdevice_dspfw_ready()
2014 tas_priv->fw_parse_variable_header = in tasdevice_dspfw_ready()
2016 tas_priv->fw_parse_program_data = in tasdevice_dspfw_ready()
2018 tas_priv->fw_parse_configuration_data = in tasdevice_dspfw_ready()
2020 tas_priv->tasdevice_load_block = in tasdevice_dspfw_ready()
2026 tas_priv->fw_parse_variable_header = in tasdevice_dspfw_ready()
2028 tas_priv->fw_parse_program_data = in tasdevice_dspfw_ready()
2030 tas_priv->fw_parse_configuration_data = in tasdevice_dspfw_ready()
2032 tas_priv->tasdevice_load_block = in tasdevice_dspfw_ready()
2037 fw_fixed_hdr->drv_ver, fw_fixed_hdr->ppcver); in tasdevice_dspfw_ready()
2039 goto out; in tasdevice_dspfw_ready()
2043 offset = tas_priv->fw_parse_variable_header(tas_priv, fmw, offset); in tasdevice_dspfw_ready()
2046 goto out; in tasdevice_dspfw_ready()
2048 offset = tas_priv->fw_parse_program_data(tas_priv, tas_fmw, fmw, in tasdevice_dspfw_ready()
2052 goto out; in tasdevice_dspfw_ready()
2054 offset = tas_priv->fw_parse_configuration_data(tas_priv, in tasdevice_dspfw_ready()
2059 out: in tasdevice_dspfw_ready()
2069 ret = request_firmware(&fw_entry, tas_priv->coef_binaryname, in tasdevice_dsp_parser()
2070 tas_priv->dev); in tasdevice_dsp_parser()
2072 dev_err(tas_priv->dev, "%s: load %s error\n", __func__, in tasdevice_dsp_parser()
2073 tas_priv->coef_binaryname); in tasdevice_dsp_parser()
2074 goto out; in tasdevice_dsp_parser()
2081 out: in tasdevice_dsp_parser()
2094 if (!tas_fmw->calibrations) in tas2781_clear_calfirmware()
2095 goto out; in tas2781_clear_calfirmware()
2097 for (i = 0; i < tas_fmw->nr_calibrations; i++) { in tas2781_clear_calfirmware()
2098 calibration = &(tas_fmw->calibrations[i]); in tas2781_clear_calfirmware()
2102 im = &(calibration->dev_data); in tas2781_clear_calfirmware()
2104 if (!im->dev_blks) in tas2781_clear_calfirmware()
2107 for (blks = 0; blks < im->nr_blk; blks++) { in tas2781_clear_calfirmware()
2108 block = &(im->dev_blks[blks]); in tas2781_clear_calfirmware()
2111 kfree(block->data); in tas2781_clear_calfirmware()
2113 kfree(im->dev_blks); in tas2781_clear_calfirmware()
2115 kfree(tas_fmw->calibrations); in tas2781_clear_calfirmware()
2116 out: in tas2781_clear_calfirmware()
2129 for (i = 0; i < tas_priv->ndev; i++) { in tasdevice_calbin_remove()
2130 tasdev = &(tas_priv->tasdevice[i]); in tasdevice_calbin_remove()
2131 if (!tasdev->cali_data_fmw) in tasdevice_calbin_remove()
2133 tas2781_clear_calfirmware(tasdev->cali_data_fmw); in tasdevice_calbin_remove()
2134 tasdev->cali_data_fmw = NULL; in tasdevice_calbin_remove()
2142 struct tasdevice_rca *rca = &(tas_priv->rcabin); in tasdevice_config_info_remove()
2143 struct tasdevice_config_info **ci = rca->cfg_info; in tasdevice_config_info_remove()
2148 for (i = 0; i < rca->ncfgs; i++) { in tasdevice_config_info_remove()
2151 if (ci[i]->blk_data) { in tasdevice_config_info_remove()
2152 for (j = 0; j < (int)ci[i]->real_nblocks; j++) { in tasdevice_config_info_remove()
2153 if (!ci[i]->blk_data[j]) in tasdevice_config_info_remove()
2155 kfree(ci[i]->blk_data[j]->regdata); in tasdevice_config_info_remove()
2156 kfree(ci[i]->blk_data[j]); in tasdevice_config_info_remove()
2158 kfree(ci[i]->blk_data); in tasdevice_config_info_remove()
2173 for (i = 0; i < dev_data->nr_blk; i++) { in tasdevice_load_data()
2174 block = &(dev_data->dev_blks[i]); in tasdevice_load_data()
2175 ret = tas_priv->tasdevice_load_block(tas_priv, block); in tasdevice_load_data()
2188 cal_fmw = priv->tasdevice[i].cali_data_fmw; in tasdev_load_calibrated_data()
2190 /* No calibrated data for current devices, playback will go ahead. */ in tasdev_load_calibrated_data()
2194 cal = cal_fmw->calibrations; in tasdev_load_calibrated_data()
2198 load_calib_data(priv, &cal->dev_data); in tasdev_load_calibrated_data()
2205 struct tasdevice_rca *rca = &(tas_priv->rcabin); in tasdevice_select_tuningprm_cfg()
2206 struct tasdevice_config_info **cfg_info = rca->cfg_info; in tasdevice_select_tuningprm_cfg()
2207 struct tasdevice_fw *tas_fmw = tas_priv->fmw; in tasdevice_select_tuningprm_cfg()
2214 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__); in tasdevice_select_tuningprm_cfg()
2215 goto out; in tasdevice_select_tuningprm_cfg()
2218 if (cfg_no >= tas_fmw->nr_configurations) { in tasdevice_select_tuningprm_cfg()
2219 dev_err(tas_priv->dev, in tasdevice_select_tuningprm_cfg()
2221 __func__, cfg_no, tas_fmw->nr_configurations); in tasdevice_select_tuningprm_cfg()
2222 goto out; in tasdevice_select_tuningprm_cfg()
2225 if (prm_no >= tas_fmw->nr_programs) { in tasdevice_select_tuningprm_cfg()
2226 dev_err(tas_priv->dev, in tasdevice_select_tuningprm_cfg()
2228 __func__, prm_no, tas_fmw->nr_programs); in tasdevice_select_tuningprm_cfg()
2229 goto out; in tasdevice_select_tuningprm_cfg()
2232 if (rca_conf_no >= rca->ncfgs || rca_conf_no < 0 || in tasdevice_select_tuningprm_cfg()
2234 dev_err(tas_priv->dev, in tasdevice_select_tuningprm_cfg()
2236 rca_conf_no, rca->ncfgs-1); in tasdevice_select_tuningprm_cfg()
2237 goto out; in tasdevice_select_tuningprm_cfg()
2240 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) { in tasdevice_select_tuningprm_cfg()
2241 if (cfg_info[rca_conf_no]->active_dev & (1 << i)) { in tasdevice_select_tuningprm_cfg()
2243 && (tas_priv->tasdevice[i].cur_prog != prm_no in tasdevice_select_tuningprm_cfg()
2244 || tas_priv->force_fwload_status)) { in tasdevice_select_tuningprm_cfg()
2245 tas_priv->tasdevice[i].cur_conf = -1; in tasdevice_select_tuningprm_cfg()
2246 tas_priv->tasdevice[i].is_loading = true; in tasdevice_select_tuningprm_cfg()
2250 tas_priv->tasdevice[i].is_loading = false; in tasdevice_select_tuningprm_cfg()
2251 tas_priv->tasdevice[i].is_loaderr = false; in tasdevice_select_tuningprm_cfg()
2255 program = &(tas_fmw->programs[prm_no]); in tasdevice_select_tuningprm_cfg()
2256 tasdevice_load_data(tas_priv, &(program->dev_data)); in tasdevice_select_tuningprm_cfg()
2257 for (i = 0; i < tas_priv->ndev; i++) { in tasdevice_select_tuningprm_cfg()
2258 if (tas_priv->tasdevice[i].is_loaderr == true) in tasdevice_select_tuningprm_cfg()
2260 if (tas_priv->tasdevice[i].is_loaderr == false && in tasdevice_select_tuningprm_cfg()
2261 tas_priv->tasdevice[i].is_loading == true) in tasdevice_select_tuningprm_cfg()
2262 tas_priv->tasdevice[i].cur_prog = prm_no; in tasdevice_select_tuningprm_cfg()
2266 for (i = 0, status = 0; i < tas_priv->ndev; i++) { in tasdevice_select_tuningprm_cfg()
2268 && tas_priv->tasdevice[i].cur_conf != cfg_no in tasdevice_select_tuningprm_cfg()
2269 && (cfg_info[rca_conf_no]->active_dev & (1 << i)) in tasdevice_select_tuningprm_cfg()
2270 && (tas_priv->tasdevice[i].is_loaderr == false)) { in tasdevice_select_tuningprm_cfg()
2272 tas_priv->tasdevice[i].is_loading = true; in tasdevice_select_tuningprm_cfg()
2274 tas_priv->tasdevice[i].is_loading = false; in tasdevice_select_tuningprm_cfg()
2278 conf = &(tas_fmw->configs[cfg_no]); in tasdevice_select_tuningprm_cfg()
2280 tasdevice_load_data(tas_priv, &(conf->dev_data)); in tasdevice_select_tuningprm_cfg()
2281 for (i = 0; i < tas_priv->ndev; i++) { in tasdevice_select_tuningprm_cfg()
2282 if (tas_priv->tasdevice[i].is_loaderr == true) { in tasdevice_select_tuningprm_cfg()
2287 if (tas_priv->tasdevice[i].is_loaderr == false && in tasdevice_select_tuningprm_cfg()
2288 tas_priv->tasdevice[i].is_loading == true) { in tasdevice_select_tuningprm_cfg()
2290 tas_priv->tasdevice[i].cur_conf = cfg_no; in tasdevice_select_tuningprm_cfg()
2294 dev_dbg(tas_priv->dev, "%s: Unneeded loading dsp conf %d\n", in tasdevice_select_tuningprm_cfg()
2297 status |= cfg_info[rca_conf_no]->active_dev; in tasdevice_select_tuningprm_cfg()
2299 out: in tasdevice_select_tuningprm_cfg()
2308 struct tasdevice_fw *tas_fmw = tas_priv->fmw; in tasdevice_prmg_load()
2314 dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__); in tasdevice_prmg_load()
2315 goto out; in tasdevice_prmg_load()
2318 if (prm_no >= tas_fmw->nr_programs) { in tasdevice_prmg_load()
2319 dev_err(tas_priv->dev, in tasdevice_prmg_load()
2321 __func__, prm_no, tas_fmw->nr_programs); in tasdevice_prmg_load()
2322 goto out; in tasdevice_prmg_load()
2325 for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) { in tasdevice_prmg_load()
2326 if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) { in tasdevice_prmg_load()
2327 tas_priv->tasdevice[i].cur_conf = -1; in tasdevice_prmg_load()
2328 tas_priv->tasdevice[i].is_loading = true; in tasdevice_prmg_load()
2334 program = &(tas_fmw->programs[prm_no]); in tasdevice_prmg_load()
2335 tasdevice_load_data(tas_priv, &(program->dev_data)); in tasdevice_prmg_load()
2336 for (i = 0; i < tas_priv->ndev; i++) { in tasdevice_prmg_load()
2337 if (tas_priv->tasdevice[i].is_loaderr == true) in tasdevice_prmg_load()
2339 else if (tas_priv->tasdevice[i].is_loaderr == false in tasdevice_prmg_load()
2340 && tas_priv->tasdevice[i].is_loading == true) in tasdevice_prmg_load()
2341 tas_priv->tasdevice[i].cur_prog = prm_no; in tasdevice_prmg_load()
2345 out: in tasdevice_prmg_load()
2353 struct tasdevice_fw *tas_fmw = tas_priv->fmw; in tasdevice_tuning_switch()
2354 int profile_cfg_id = tas_priv->rcabin.profile_cfg_id; in tasdevice_tuning_switch()
2357 * Only RCA-based Playback can still work with no dsp program running in tasdevice_tuning_switch()
2360 switch (tas_priv->fw_state) { in tasdevice_tuning_switch()
2369 if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) { in tasdevice_tuning_switch()
2371 profile_cfg_id = tas_priv->rcabin.profile_cfg_id; in tasdevice_tuning_switch()
2373 tas_priv->cur_prog, tas_priv->cur_conf, in tasdevice_tuning_switch()
2388 MODULE_AUTHOR("Shenghao Ding, TI, <shenghao-ding@ti.com>");