/* In most projects are many audio cases, such as music, handfree, * receiver, games, audio-to-haptics, PMIC record, bypass mode, * portrait, landscape, etc. Even in multiple audios, one or * two of the chips will work for the special case, such as * ultrasonic application. In order to support these variable-numbers * of audio cases, flexible configs have been introduced in the * dsp firmware.
*/
cfg_info = kzalloc(sizeof(struct tasdevice_config_info), GFP_KERNEL); if (!cfg_info) {
*status = -ENOMEM; goto out;
}
if (tas_priv->rcabin.fw_hdr.binary_version_num >= 0x105) { if (config_offset + 64 > (int)config_size) {
*status = -EINVAL;
dev_err(tas_priv->dev, "add conf: Out of boundary\n"); goto out;
} /* If in the RCA bin file are several profiles with the * keyword "init", init_profile_id only store the last * init profile id.
*/ if (strnstr(&config_data[config_offset], "init", 64)) {
tas_priv->rcabin.init_profile_id =
tas_priv->rcabin.ncfgs - 1;
dev_dbg(tas_priv->dev, "%s: init profile id = %d\n",
__func__, tas_priv->rcabin.init_profile_id);
}
config_offset += 64;
}
if (config_offset + 4 > (int)config_size) {
*status = -EINVAL;
dev_err(tas_priv->dev, "add config: Out of boundary\n"); goto out;
}
/* Several kinds of dsp/algorithm firmwares can run on tas2781, * the number and size of blk are not fixed and different among * these firmwares.
*/
bk_da = cfg_info->blk_data = kcalloc(cfg_info->nblocks, sizeof(struct tasdev_blk_data *), GFP_KERNEL); if (!bk_da) {
*status = -ENOMEM; goto out;
}
cfg_info->real_nblocks = 0; for (i = 0; i < cfg_info->nblocks; i++) { if (config_offset + 12 > config_size) {
*status = -EINVAL;
dev_err(tas_priv->dev, "%s: Out of boundary: i = %d nblocks = %u!\n",
__func__, i, cfg_info->nblocks); break;
}
bk_da[i] = kzalloc(sizeof(struct tasdev_blk_data), GFP_KERNEL); if (!bk_da[i]) {
*status = -ENOMEM; break;
}
/* fixed m68k compiling issue: * 1. mapping table can save code field. * 2. storing the dev_idx as a member of block can reduce unnecessary * time and system resource comsumption of dev_idx mapping every * time the block data writing to the dsp.
*/
block->dev_idx = map_dev_idx(tas_fmw, block);
/* * Calibration parameters locations and data schema in dsp firmware. * The number of items are flexible, but not more than 20. The dsp tool * will reseve 20*24-byte space for fct params. In some cases, the * number of fct param is less than 20, the data will be saved from the * beginning, the rest part will be stuffed with zero. * * fct_param_num (not more than 20) * for (i = 0; i < fct_param_num; i++) { * Alias of fct param (20 bytes) * Book (1 byte) * Page (1 byte) * Offset (1 byte) * CoeffLength (1 byte) = 0x1 * } * if (20 - fct_param_num) * 24*(20 - fct_param_num) pieces of '0' as stuffing * * As follow: * umg_SsmKEGCye = Book, Page, Offset, CoeffLength * iks_E0 = Book, Page, Offset, CoeffLength * yep_LsqM0 = Book, Page, Offset, CoeffLength * oyz_U0_ujx = Book, Page, Offset, CoeffLength * iks_GC_GMgq = Book, Page, Offset, CoeffLength * gou_Yao = Book, Page, Offset, CoeffLength * kgd_Wsc_Qsbp = Book, Page, Offset, CoeffLength * yec_CqseSsqs = Book, Page, Offset, CoeffLength * iks_SogkGgog2 = Book, Page, Offset, CoeffLength * yec_Sae_Y = Book, Page, Offset, CoeffLength * Re_Int = Book, Page, Offset, CoeffLength * SigFlag = Book, Page, Offset, CoeffLength * a1_Int = Book, Page, Offset, CoeffLength * a2_Int = Book, Page, Offset, CoeffLength
*/ for (i = 0; i < 20; i++) { constunsignedchar *dat = &data[24 * i];
/* * check whether current fct param is empty.
*/ if (dat[23] != 1) break;
if (!strncmp(dat, "umg_SsmKEGCye", 20))
r->pow_reg = TASDEVICE_REG(dat[20], dat[21], dat[22]); /* high 32-bit of real-time spk impedance */ elseif (!strncmp(dat, "iks_E0", 20))
r->r0_reg = TASDEVICE_REG(dat[20], dat[21], dat[22]); /* inverse of real-time spk impedance */ elseif (!strncmp(dat, "yep_LsqM0", 20))
r->invr0_reg =
TASDEVICE_REG(dat[20], dat[21], dat[22]); /* low 32-bit of real-time spk impedance */ elseif (!strncmp(dat, "oyz_U0_ujx", 20))
r->r0_low_reg =
TASDEVICE_REG(dat[20], dat[21], dat[22]); /* Delta Thermal Limit */ elseif (!strncmp(dat, "iks_GC_GMgq", 20))
r->tlimit_reg =
TASDEVICE_REG(dat[20], dat[21], dat[22]); /* Thermal data for PG 1.0 device */ elseif (!strncmp(dat, "gou_Yao", 20))
memcpy(p->thr, &dat[20], 3); /* Pilot tone enable flag, usually the sine wave */ elseif (!strncmp(dat, "kgd_Wsc_Qsbp", 20))
memcpy(p->plt_flg, &dat[20], 3); /* Pilot tone gain for calibration */ elseif (!strncmp(dat, "yec_CqseSsqs", 20))
memcpy(p->sin_gn, &dat[20], 3); /* Pilot tone gain for calibration, useless in PG 2.0 */ elseif (!strncmp(dat, "iks_SogkGgog2", 20))
memcpy(p->sin_gn2, &dat[20], 3); /* Thermal data for PG 2.0 device */ elseif (!strncmp(dat, "yec_Sae_Y", 20))
memcpy(p->thr2, &dat[20], 3); /* Spk Equivalent Resistance in fixed-point format */ elseif (!strncmp(dat, "Re_Int", 20))
memcpy(p->r0_reg, &dat[20], 3); /* Check whether the spk connection is open */ elseif (!strncmp(dat, "SigFlag", 20))
memcpy(p->tf_reg, &dat[20], 3); /* check spk resonant frequency */ elseif (!strncmp(dat, "a1_Int", 20))
memcpy(p->a1_reg, &dat[20], 3); /* check spk resonant frequency */ elseif (!strncmp(dat, "a2_Int", 20))
memcpy(p->a2_reg, &dat[20], 3);
}
}
/* The max number of config in firmware greater than 4 pieces of * tas2781s is different from the one lower than 4 pieces of * tas2781s.
*/
max_confs = (fw_hdr->ndev >= 4) ?
TASDEVICE_MAXCONFIG_NUM_KERNEL_MULTIPLE_AMPS :
TASDEVICE_MAXCONFIG_NUM_KERNEL; if (tas_fmw->nr_configurations == 0 ||
tas_fmw->nr_configurations > max_confs) {
dev_err(tas_priv->dev, "%s: Conf is invalid\n", __func__);
offset = -EINVAL; goto out;
}
if (conf_no >= rca->ncfgs || conf_no < 0 || !cfg_info) {
dev_err(tas_priv->dev, "conf_no should be not more than %u\n",
rca->ncfgs); return;
}
blk_data = cfg_info[conf_no]->blk_data;
if (block_type > 5 || block_type < 2) {
dev_err(tas_priv->dev, "block_type should be in range from 2 to 5\n"); break;
} if (block_type != blk_data[j]->block_type) continue;
for (k = 0; k < (int)blk_data[j]->n_subblks; k++) { if (blk_data[j]->dev_idx) {
chn = blk_data[j]->dev_idx - 1;
chnend = blk_data[j]->dev_idx;
} else {
chn = 0;
chnend = tas_priv->ndev;
} for (; chn < chnend; chn++)
tas_priv->tasdevice[chn].is_loading = true;
rc = tasdevice_process_block(tas_priv,
blk_data[j]->regdata + length,
blk_data[j]->dev_idx,
blk_data[j]->block_size - length);
length += rc; if (blk_data[j]->block_size < length) {
dev_err(tas_priv->dev, "%s: %u %u out of boundary\n",
__func__, length,
blk_data[j]->block_size); break;
}
} if (length != blk_data[j]->block_size)
dev_err(tas_priv->dev, "%s: %u %u size is not same\n",
__func__, length, blk_data[j]->block_size);
}
}
EXPORT_SYMBOL_NS_GPL(tasdevice_select_cfg_blk, "SND_SOC_TAS2781_FMWLIB");
n = block->nr_cmds * 4; if (offset + n > fmw->size) {
dev_err(tas_fmw->dev, "%s: File Size(%lu) error offset = %d n = %d\n",
__func__, (unsignedlong)fmw->size, offset, n);
offset = -EINVAL; goto out;
} /* instead of kzalloc+memcpy */
block->data = kmemdup(&data[offset], n, GFP_KERNEL); if (!block->data) {
offset = -ENOMEM; goto out;
}
offset += n;
out: return offset;
}
/* When parsing error occurs, all the memory resource will be released * in the end of tasdevice_rca_ready.
*/ staticint fw_parse_data(struct tasdevice_fw *tas_fmw, struct tasdevice_data *img_data, conststruct firmware *fmw, int offset)
{ constunsignedchar *data = (unsignedchar *)fmw->data; struct tasdev_blk *blk; unsignedint i; int n;
img_data->dev_blks = kcalloc(img_data->nr_blk, sizeof(struct tasdev_blk), GFP_KERNEL); if (!img_data->dev_blks) {
offset = -ENOMEM; goto out;
} for (i = 0; i < img_data->nr_blk; i++) {
blk = &(img_data->dev_blks[i]);
offset = fw_parse_block_data(tas_fmw, blk, fmw, offset); if (offset < 0) {
offset = -EINVAL; goto out;
}
}
out: return offset;
}
/* When parsing error occurs, all the memory resource will be released * in the end of tasdevice_rca_ready.
*/ staticint fw_parse_program_data(struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw, conststruct firmware *fmw, int offset)
{ unsignedchar *buf = (unsignedchar *)fmw->data; struct tasdevice_prog *program; int i;
if (tas_fmw->nr_programs == 0) { /*Not error in calibration Data file, return directly*/
dev_info(tas_priv->dev, "%s: No Programs data, maybe calbin\n",
__func__); goto out;
}
tas_fmw->programs =
kcalloc(tas_fmw->nr_programs, sizeof(struct tasdevice_prog),
GFP_KERNEL); if (!tas_fmw->programs) {
offset = -ENOMEM; goto out;
} for (i = 0; i < tas_fmw->nr_programs; i++) { int n = 0;
/* When parsing error occurs, all the memory resource will be released * in the end of tasdevice_rca_ready.
*/ staticint fw_parse_configuration_data( struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw, conststruct firmware *fmw, int offset)
{ unsignedchar *data = (unsignedchar *)fmw->data; struct tasdevice_config *config; unsignedint i; int n;
if (page == TAS2781_YRAM1_PAGE) { if (reg >= TAS2781_YRAM1_START_REG) {
cd->offset = reg;
cd->len = len;
in = true;
} elseif (reg + len > TAS2781_YRAM1_START_REG) {
cd->offset = TAS2781_YRAM1_START_REG;
cd->len = len - TAS2781_YRAM1_START_REG + reg;
in = true;
}
} elseif (page == TAS2781_YRAM3_PAGE)
in = check_inpage_yram_rg(cd, reg, len);
return in;
}
/* Return Code: * true -- the registers are in the inpage yram * false -- the registers are NOT in the inpage yram
*/ staticbool check_inpage_yram(struct tas_crc *cd, unsignedchar book, unsignedchar page, unsignedchar reg, unsignedchar len)
{ bool in = false;
if (book == TAS2781_YRAM_BOOK1) {
in = check_inpage_yram_bk1(cd, page, reg, len); goto end;
} if (book == TAS2781_YRAM_BOOK2 && page == TAS2781_YRAM5_PAGE)
in = check_inpage_yram_rg(cd, reg, len);
if ((page >= TAS2781_YRAM4_START_PAGE &&
page <= TAS2781_YRAM4_END_PAGE) ||
(page >= TAS2781_YRAM2_START_PAGE &&
page <= TAS2781_YRAM2_END_PAGE)) { if (reg <= TAS2781_YRAM2_END_REG &&
reg >= TAS2781_YRAM2_START_REG) {
cd->offset = reg;
cd->len = len;
in = true;
} elseif (reg < TAS2781_YRAM2_START_REG) { if (reg + len - 1 >= TAS2781_YRAM2_START_REG) {
cd->offset = TAS2781_YRAM2_START_REG;
cd->len = reg + len - TAS2781_YRAM2_START_REG;
in = true;
}
}
}
return in;
}
/* Return Code: * true -- the registers are in the inblock yram * false -- the registers are NOT in the inblock yram
*/ staticbool check_inblock_yram(struct tas_crc *cd, unsignedchar book, unsignedchar page, unsignedchar reg, unsignedchar len)
{ bool in = false;
if (book == TAS2781_YRAM_BOOK1 || book == TAS2781_YRAM_BOOK2)
in = check_inblock_yram_bk(cd, page, reg, len);
while (block->nr_retry > 0) { if (block->is_pchksum_present) {
ret = tasdevice_dev_write(tas_priv, chn,
TASDEVICE_CHECKSUM_REG, 0); if (ret < 0) break;
}
if (block->is_ychksum_present)
crc_chksum = 0;
nr_cmds = 0;
while (nr_cmds < block->nr_cmds) {
data = block->data + nr_cmds * 4;
book = data[0];
page = data[1];
offset = data[2];
val = data[3];
nr_cmds++; /*Single byte write*/ if (offset <= 0x7F) {
ret = tasdevice_dev_write(tas_priv, chn,
TASDEVICE_REG(book, page, offset),
val); if (ret < 0) goto end; if (block->is_ychksum_present) {
ret = tasdev_bytes_chksum(tas_priv,
block, chn, book, page, offset,
1, val, &crc_chksum); if (ret < 0) break;
} continue;
} /*sleep command*/ if (offset == 0x81) { /*book -- data[0] page -- data[1]*/
sleep_time = ((book << 8) + page)*1000;
usleep_range(sleep_time, sleep_time + 50); continue;
} /*Multiple bytes write*/ if (offset == 0x85) {
data += 4;
len = (book << 8) + page;
book = data[0];
page = data[1];
offset = data[2];
ret = tasdev_multibytes_wr(tas_priv,
block, chn, book, page, offset, data,
len, &nr_cmds, &crc_chksum); if (ret < 0) break;
}
} if (ret == -EAGAIN) { if (block->nr_retry > 0) continue;
} elseif (ret < 0) /*err in current device, skip it*/ break;
if (block->is_pchksum_present) {
ret = tasdev_block_chksum(tas_priv, block, chn); if (ret == -EAGAIN) { if (block->nr_retry > 0) continue;
} elseif (ret < 0) /*err in current device, skip it*/ break;
}
if (block->is_ychksum_present) { /* TBD, open it when FW ready */
dev_err(tas_priv->dev, "Blk YChkSum: FW = 0x%x, YCRC = 0x%x\n",
block->ychksum, crc_chksum);
tas_priv->tasdevice[chn].err_code &=
~ERROR_YRAM_CRCCHK;
ret = 0;
} /*skip current blk*/ break;
}
end: return ret;
}
staticint tasdevice_load_block(struct tasdevice_priv *tas_priv, struct tasdev_blk *block)
{ int chnend = 0; int ret = 0; int chn = 0; int rc = 0;
switch (block->type) { case MAIN_ALL_DEVICES:
chn = 0;
chnend = tas_priv->ndev; break; case MAIN_DEVICE_A: case COEFF_DEVICE_A: case PRE_DEVICE_A:
chn = 0;
chnend = 1; break; case MAIN_DEVICE_B: case COEFF_DEVICE_B: case PRE_DEVICE_B:
chn = 1;
chnend = 2; break; case MAIN_DEVICE_C: case COEFF_DEVICE_C: case PRE_DEVICE_C:
chn = 2;
chnend = 3; break; case MAIN_DEVICE_D: case COEFF_DEVICE_D: case PRE_DEVICE_D:
chn = 3;
chnend = 4; break; default:
dev_dbg(tas_priv->dev, "load blk: Other Type = 0x%02x\n",
block->type); break;
}
for (; chn < chnend; chn++) {
block->nr_retry = 6; if (tas_priv->tasdevice[chn].is_loading == false) continue;
ret = tasdev_load_blk(tas_priv, block, chn); if (ret < 0)
dev_err(tas_priv->dev, "dev %d, Blk (%d) load error\n",
chn, block->type);
rc |= ret;
}
offset = fw_parse_variable_hdr(tas_priv, fw_hdr, fmw, offset); if (offset < 0) goto out; if (fw_hdr->ndev != 1) {
dev_err(tas_priv->dev, "%s: calbin must be 1, but currently ndev(%u)\n",
__func__, fw_hdr->ndev);
offset = -EINVAL;
}
out: return offset;
}
/* When calibrated data parsing error occurs, DSP can still work with default * calibrated data, memory resource related to calibrated data will be * released in the tasdevice_codec_remove.
*/ staticint fw_parse_calibration_data(struct tasdevice_priv *tas_priv, struct tasdevice_fw *tas_fmw, conststruct firmware *fmw, int offset)
{ struct tasdevice_calibration *calibration; unsignedchar *data = (unsignedchar *)fmw->data; unsignedint i, n;
if (!ci) return; for (i = 0; i < rca->ncfgs; i++) { if (!ci[i]) continue; if (ci[i]->blk_data) { for (j = 0; j < (int)ci[i]->real_nblocks; j++) { if (!ci[i]->blk_data[j]) continue;
kfree(ci[i]->blk_data[j]->regdata);
kfree(ci[i]->blk_data[j]);
}
kfree(ci[i]->blk_data);
}
kfree(ci[i]);
}
kfree(ci);
}
EXPORT_SYMBOL_NS_GPL(tasdevice_config_info_remove, "SND_SOC_TAS2781_FMWLIB");
staticint tasdevice_load_data(struct tasdevice_priv *tas_priv, struct tasdevice_data *dev_data)
{ struct tasdev_blk *block; unsignedint i; int ret = 0;
for (i = 0; i < dev_data->nr_blk; i++) {
block = &(dev_data->dev_blks[i]);
ret = tas_priv->tasdevice_load_block(tas_priv, block); if (ret < 0) break;
}
return ret;
}
staticvoid tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
{ struct tasdevice_fw *cal_fmw = priv->tasdevice[i].cali_data_fmw; struct calidata *cali_data = &priv->cali_data; struct cali_reg *p = &cali_data->cali_reg_array; unsignedchar *data = cali_data->data; struct tasdevice_calibration *cal; int k = i * (cali_data->cali_dat_sz_per_dev + 1); int rc;
/* Load the calibrated data from cal bin file */ if (!priv->is_user_space_calidata && cal_fmw) {
cal = cal_fmw->calibrations;
if (cal)
load_calib_data(priv, &cal->dev_data); return;
} if (!priv->is_user_space_calidata) return; /* load calibrated data from user space */ if (data[k] != i) {
dev_err(priv->dev, "%s: no cal-data for dev %d from usr-spc\n",
__func__, i); return;
}
k++;
rc = tasdevice_dev_bulk_write(priv, i, p->r0_reg, &(data[k]), 4); if (rc < 0) {
dev_err(priv->dev, "chn %d r0_reg bulk_wr err = %d\n", i, rc); return;
}
k += 4;
rc = tasdevice_dev_bulk_write(priv, i, p->r0_low_reg, &(data[k]), 4); if (rc < 0) {
dev_err(priv->dev, "chn %d r0_low_reg err = %d\n", i, rc); return;
}
k += 4;
rc = tasdevice_dev_bulk_write(priv, i, p->invr0_reg, &(data[k]), 4); if (rc < 0) {
dev_err(priv->dev, "chn %d invr0_reg err = %d\n", i, rc); return;
}
k += 4;
rc = tasdevice_dev_bulk_write(priv, i, p->pow_reg, &(data[k]), 4); if (rc < 0) {
dev_err(priv->dev, "chn %d pow_reg bulk_wr err = %d\n", i, rc); return;
}
k += 4;
rc = tasdevice_dev_bulk_write(priv, i, p->tlimit_reg, &(data[k]), 4); if (rc < 0) {
dev_err(priv->dev, "chn %d tlimit_reg err = %d\n", i, rc); return;
}
}
int tasdevice_select_tuningprm_cfg(void *context, int prm_no, int cfg_no, int rca_conf_no)
{ struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; struct tasdevice_rca *rca = &(tas_priv->rcabin); struct tasdevice_config_info **cfg_info = rca->cfg_info; struct tasdevice_fw *tas_fmw = tas_priv->fmw; struct tasdevice_prog *program; struct tasdevice_config *conf; int prog_status = 0; int status, i;
if (!tas_fmw) {
dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__); goto out;
}
if (cfg_no >= tas_fmw->nr_configurations) {
dev_err(tas_priv->dev, "%s: cfg(%d) is not in range of conf %u\n",
__func__, cfg_no, tas_fmw->nr_configurations); goto out;
}
if (prm_no >= tas_fmw->nr_programs) {
dev_err(tas_priv->dev, "%s: prm(%d) is not in range of Programs %u\n",
__func__, prm_no, tas_fmw->nr_programs); goto out;
}
if (rca_conf_no >= rca->ncfgs || rca_conf_no < 0 ||
!cfg_info) {
dev_err(tas_priv->dev, "conf_no:%d should be in range from 0 to %u\n",
rca_conf_no, rca->ncfgs-1); goto out;
}
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) { if (cfg_info[rca_conf_no]->active_dev & (1 << i)) { if (prm_no >= 0
&& (tas_priv->tasdevice[i].cur_prog != prm_no
|| tas_priv->force_fwload_status)) {
tas_priv->tasdevice[i].cur_conf = -1;
tas_priv->tasdevice[i].is_loading = true;
prog_status++;
}
} else
tas_priv->tasdevice[i].is_loading = false;
tas_priv->tasdevice[i].is_loaderr = false;
}
if (prog_status) {
program = &(tas_fmw->programs[prm_no]);
tasdevice_load_data(tas_priv, &(program->dev_data)); for (i = 0; i < tas_priv->ndev; i++) { if (tas_priv->tasdevice[i].is_loaderr == true) continue; if (tas_priv->tasdevice[i].is_loaderr == false &&
tas_priv->tasdevice[i].is_loading == true)
tas_priv->tasdevice[i].cur_prog = prm_no;
}
}
for (i = 0, status = 0; i < tas_priv->ndev; i++) { if (cfg_no >= 0
&& tas_priv->tasdevice[i].cur_conf != cfg_no
&& (cfg_info[rca_conf_no]->active_dev & (1 << i))
&& (tas_priv->tasdevice[i].is_loaderr == false)) {
status++;
tas_priv->tasdevice[i].is_loading = true;
} else
tas_priv->tasdevice[i].is_loading = false;
}
if (status) {
conf = &(tas_fmw->configs[cfg_no]);
status = 0;
tasdevice_load_data(tas_priv, &(conf->dev_data)); for (i = 0; i < tas_priv->ndev; i++) { if (tas_priv->tasdevice[i].is_loaderr == true) {
status |= BIT(i + 4); continue;
}
int tasdevice_prmg_load(void *context, int prm_no)
{ struct tasdevice_priv *tas_priv = (struct tasdevice_priv *) context; struct tasdevice_fw *tas_fmw = tas_priv->fmw; struct tasdevice_prog *program; int prog_status = 0; int i;
if (!tas_fmw) {
dev_err(tas_priv->dev, "%s: Firmware is NULL\n", __func__); goto out;
}
if (prm_no >= tas_fmw->nr_programs) {
dev_err(tas_priv->dev, "%s: prm(%d) is not in range of Programs %u\n",
__func__, prm_no, tas_fmw->nr_programs); goto out;
}
for (i = 0, prog_status = 0; i < tas_priv->ndev; i++) { if (prm_no >= 0 && tas_priv->tasdevice[i].cur_prog != prm_no) {
tas_priv->tasdevice[i].cur_conf = -1;
tas_priv->tasdevice[i].is_loading = true;
prog_status++;
}
}
if (prog_status) {
program = &(tas_fmw->programs[prm_no]);
tasdevice_load_data(tas_priv, &(program->dev_data)); for (i = 0; i < tas_priv->ndev; i++) { if (tas_priv->tasdevice[i].is_loaderr == true) continue; elseif (tas_priv->tasdevice[i].is_loaderr == false
&& tas_priv->tasdevice[i].is_loading == true)
tas_priv->tasdevice[i].cur_prog = prm_no;
}
}
/* * Only RCA-based Playback can still work with no dsp program running * inside the chip.
*/ switch (tas_priv->fw_state) { case TASDEVICE_RCA_FW_OK: case TASDEVICE_DSP_FW_ALL_OK: break; default: return;
}
if (state == 0) { if (tas_fmw && tas_priv->cur_prog < tas_fmw->nr_programs) { /* dsp mode or tuning mode */
profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
tasdevice_select_tuningprm_cfg(tas_priv,
tas_priv->cur_prog, tas_priv->cur_conf,
profile_cfg_id);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.