summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/tas2781-fmwlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs/tas2781-fmwlib.c')
-rw-r--r--sound/soc/codecs/tas2781-fmwlib.c91
1 files changed, 49 insertions, 42 deletions
diff --git a/sound/soc/codecs/tas2781-fmwlib.c b/sound/soc/codecs/tas2781-fmwlib.c
index c6c47297a4fe..3639dcd0bbb2 100644
--- a/sound/soc/codecs/tas2781-fmwlib.c
+++ b/sound/soc/codecs/tas2781-fmwlib.c
@@ -21,7 +21,7 @@
#include <sound/soc.h>
#include <sound/tlv.h>
#include <sound/tas2781.h>
-
+#include <asm/unaligned.h>
#define ERROR_PRAM_CRCCHK 0x0000000
#define ERROR_YRAM_CRCCHK 0x0000001
@@ -125,8 +125,7 @@ static struct tasdevice_config_info *tasdevice_add_config(
/* convert data[offset], data[offset + 1], data[offset + 2] and
* data[offset + 3] into host
*/
- cfg_info->nblocks =
- be32_to_cpup((__be32 *)&config_data[config_offset]);
+ cfg_info->nblocks = get_unaligned_be32(&config_data[config_offset]);
config_offset += 4;
/* Several kinds of dsp/algorithm firmwares can run on tas2781,
@@ -170,14 +169,14 @@ static struct tasdevice_config_info *tasdevice_add_config(
}
bk_da[i]->yram_checksum =
- be16_to_cpup((__be16 *)&config_data[config_offset]);
+ get_unaligned_be16(&config_data[config_offset]);
config_offset += 2;
bk_da[i]->block_size =
- be32_to_cpup((__be32 *)&config_data[config_offset]);
+ get_unaligned_be32(&config_data[config_offset]);
config_offset += 4;
bk_da[i]->n_subblks =
- be32_to_cpup((__be32 *)&config_data[config_offset]);
+ get_unaligned_be32(&config_data[config_offset]);
config_offset += 4;
@@ -227,7 +226,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw)
}
buf = (unsigned char *)fmw->data;
- fw_hdr->img_sz = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->img_sz = get_unaligned_be32(&buf[offset]);
offset += 4;
if (fw_hdr->img_sz != fmw->size) {
dev_err(tas_priv->dev,
@@ -238,9 +237,9 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw)
goto out;
}
- fw_hdr->checksum = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->checksum = get_unaligned_be32(&buf[offset]);
offset += 4;
- fw_hdr->binary_version_num = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->binary_version_num = get_unaligned_be32(&buf[offset]);
if (fw_hdr->binary_version_num < 0x103) {
dev_err(tas_priv->dev, "File version 0x%04x is too low",
fw_hdr->binary_version_num);
@@ -249,7 +248,7 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw)
goto out;
}
offset += 4;
- fw_hdr->drv_fw_version = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->drv_fw_version = get_unaligned_be32(&buf[offset]);
offset += 8;
fw_hdr->plat_type = buf[offset];
offset += 1;
@@ -277,11 +276,11 @@ int tasdevice_rca_parser(void *context, const struct firmware *fmw)
for (i = 0; i < TASDEVICE_DEVICE_SUM; i++, offset++)
fw_hdr->devs[i] = buf[offset];
- fw_hdr->nconfig = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->nconfig = get_unaligned_be32(&buf[offset]);
offset += 4;
for (i = 0; i < TASDEVICE_CONFIG_SUM; i++) {
- fw_hdr->config_size[i] = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->config_size[i] = get_unaligned_be32(&buf[offset]);
offset += 4;
total_config_sz += fw_hdr->config_size[i];
}
@@ -330,7 +329,7 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw,
/* convert data[offset], data[offset + 1], data[offset + 2] and
* data[offset + 3] into host
*/
- block->type = be32_to_cpup((__be32 *)&data[offset]);
+ block->type = get_unaligned_be32(&data[offset]);
offset += 4;
block->is_pchksum_present = data[offset];
@@ -345,10 +344,10 @@ static int fw_parse_block_data_kernel(struct tasdevice_fw *tas_fmw,
block->ychksum = data[offset];
offset++;
- block->blk_size = be32_to_cpup((__be32 *)&data[offset]);
+ block->blk_size = get_unaligned_be32(&data[offset]);
offset += 4;
- block->nr_subblocks = be32_to_cpup((__be32 *)&data[offset]);
+ block->nr_subblocks = get_unaligned_be32(&data[offset]);
offset += 4;
if (offset + block->blk_size > fmw->size) {
@@ -381,7 +380,7 @@ static int fw_parse_data_kernel(struct tasdevice_fw *tas_fmw,
offset = -EINVAL;
goto out;
}
- img_data->nr_blk = be32_to_cpup((__be32 *)&data[offset]);
+ img_data->nr_blk = get_unaligned_be32(&data[offset]);
offset += 4;
img_data->dev_blks = kcalloc(img_data->nr_blk,
@@ -477,14 +476,14 @@ static int fw_parse_variable_header_kernel(
offset = -EINVAL;
goto out;
}
- fw_hdr->device_family = be16_to_cpup((__be16 *)&buf[offset]);
+ fw_hdr->device_family = get_unaligned_be16(&buf[offset]);
if (fw_hdr->device_family != 0) {
dev_err(tas_priv->dev, "%s:not TAS device\n", __func__);
offset = -EINVAL;
goto out;
}
offset += 2;
- fw_hdr->device = be16_to_cpup((__be16 *)&buf[offset]);
+ fw_hdr->device = get_unaligned_be16(&buf[offset]);
if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
fw_hdr->device == 6) {
dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
@@ -502,7 +501,7 @@ static int fw_parse_variable_header_kernel(
goto out;
}
- tas_fmw->nr_programs = be32_to_cpup((__be32 *)&buf[offset]);
+ tas_fmw->nr_programs = get_unaligned_be32(&buf[offset]);
offset += 4;
if (tas_fmw->nr_programs == 0 || tas_fmw->nr_programs >
@@ -521,14 +520,14 @@ static int fw_parse_variable_header_kernel(
for (i = 0; i < tas_fmw->nr_programs; i++) {
program = &(tas_fmw->programs[i]);
- program->prog_size = be32_to_cpup((__be32 *)&buf[offset]);
+ program->prog_size = get_unaligned_be32(&buf[offset]);
offset += 4;
}
/* Skip the unused prog_size */
offset += 4 * (TASDEVICE_MAXPROGRAM_NUM_KERNEL - tas_fmw->nr_programs);
- tas_fmw->nr_configurations = be32_to_cpup((__be32 *)&buf[offset]);
+ tas_fmw->nr_configurations = get_unaligned_be32(&buf[offset]);
offset += 4;
/* The max number of config in firmware greater than 4 pieces of
@@ -560,7 +559,7 @@ static int fw_parse_variable_header_kernel(
for (i = 0; i < tas_fmw->nr_programs; i++) {
config = &(tas_fmw->configs[i]);
- config->cfg_size = be32_to_cpup((__be32 *)&buf[offset]);
+ config->cfg_size = get_unaligned_be32(&buf[offset]);
offset += 4;
}
@@ -598,7 +597,7 @@ static int tasdevice_process_block(void *context, unsigned char *data,
switch (subblk_typ) {
case TASDEVICE_CMD_SING_W: {
int i;
- unsigned short len = be16_to_cpup((__be16 *)&data[2]);
+ unsigned short len = get_unaligned_be16(&data[2]);
subblk_offset += 2;
if (subblk_offset + 4 * len > sublocksize) {
@@ -624,7 +623,7 @@ static int tasdevice_process_block(void *context, unsigned char *data,
}
break;
case TASDEVICE_CMD_BURST: {
- unsigned short len = be16_to_cpup((__be16 *)&data[2]);
+ unsigned short len = get_unaligned_be16(&data[2]);
subblk_offset += 2;
if (subblk_offset + 4 + len > sublocksize) {
@@ -665,7 +664,7 @@ static int tasdevice_process_block(void *context, unsigned char *data,
is_err = true;
break;
}
- sleep_time = be16_to_cpup((__be16 *)&data[2]) * 1000;
+ sleep_time = get_unaligned_be16(&data[2]) * 1000;
usleep_range(sleep_time, sleep_time + 50);
subblk_offset += 2;
}
@@ -940,7 +939,7 @@ static int fw_parse_variable_hdr(struct tasdevice_priv
offset += len;
- fw_hdr->device_family = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->device_family = get_unaligned_be32(&buf[offset]);
if (fw_hdr->device_family != 0) {
dev_err(tas_priv->dev, "%s: not TAS device\n", __func__);
offset = -EINVAL;
@@ -948,7 +947,7 @@ static int fw_parse_variable_hdr(struct tasdevice_priv
}
offset += 4;
- fw_hdr->device = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_hdr->device = get_unaligned_be32(&buf[offset]);
if (fw_hdr->device >= TASDEVICE_DSP_TAS_MAX_DEVICE ||
fw_hdr->device == 6) {
dev_err(tas_priv->dev, "Unsupported dev %d\n", fw_hdr->device);
@@ -993,7 +992,7 @@ static int fw_parse_block_data(struct tasdevice_fw *tas_fmw,
offset = -EINVAL;
goto out;
}
- block->type = be32_to_cpup((__be32 *)&data[offset]);
+ block->type = get_unaligned_be32(&data[offset]);
offset += 4;
if (tas_fmw->fw_hdr.fixed_hdr.drv_ver >= PPC_DRIVER_CRCCHK) {
@@ -1018,7 +1017,7 @@ static int fw_parse_block_data(struct tasdevice_fw *tas_fmw,
block->is_ychksum_present = 0;
}
- block->nr_cmds = be32_to_cpup((__be32 *)&data[offset]);
+ block->nr_cmds = get_unaligned_be32(&data[offset]);
offset += 4;
n = block->nr_cmds * 4;
@@ -1069,7 +1068,7 @@ static int fw_parse_data(struct tasdevice_fw *tas_fmw,
goto out;
}
offset += n;
- img_data->nr_blk = be16_to_cpup((__be16 *)&data[offset]);
+ img_data->nr_blk = get_unaligned_be16(&data[offset]);
offset += 2;
img_data->dev_blks = kcalloc(img_data->nr_blk,
@@ -1106,7 +1105,7 @@ static int fw_parse_program_data(struct tasdevice_priv *tas_priv,
offset = -EINVAL;
goto out;
}
- tas_fmw->nr_programs = be16_to_cpup((__be16 *)&buf[offset]);
+ tas_fmw->nr_programs = get_unaligned_be16(&buf[offset]);
offset += 2;
if (tas_fmw->nr_programs == 0) {
@@ -1173,7 +1172,7 @@ static int fw_parse_configuration_data(
offset = -EINVAL;
goto out;
}
- tas_fmw->nr_configurations = be16_to_cpup((__be16 *)&data[offset]);
+ tas_fmw->nr_configurations = get_unaligned_be16(&data[offset]);
offset += 2;
if (tas_fmw->nr_configurations == 0) {
@@ -1805,7 +1804,7 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv,
/* Convert data[offset], data[offset + 1], data[offset + 2] and
* data[offset + 3] into host
*/
- fw_fixed_hdr->fwsize = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_fixed_hdr->fwsize = get_unaligned_be32(&buf[offset]);
offset += 4;
if (fw_fixed_hdr->fwsize != fmw->size) {
dev_err(tas_priv->dev, "File size not match, %lu %u",
@@ -1814,9 +1813,9 @@ static int fw_parse_header(struct tasdevice_priv *tas_priv,
goto out;
}
offset += 4;
- fw_fixed_hdr->ppcver = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_fixed_hdr->ppcver = get_unaligned_be32(&buf[offset]);
offset += 8;
- fw_fixed_hdr->drv_ver = be32_to_cpup((__be32 *)&buf[offset]);
+ fw_fixed_hdr->drv_ver = get_unaligned_be32(&buf[offset]);
offset += 72;
out:
@@ -1858,7 +1857,7 @@ static int fw_parse_calibration_data(struct tasdevice_priv *tas_priv,
offset = -EINVAL;
goto out;
}
- tas_fmw->nr_calibrations = be16_to_cpup((__be16 *)&data[offset]);
+ tas_fmw->nr_calibrations = get_unaligned_be16(&data[offset]);
offset += 2;
if (tas_fmw->nr_calibrations != 1) {
@@ -2193,7 +2192,7 @@ static void tasdev_load_calibrated_data(struct tasdevice_priv *priv, int i)
return;
cal = cal_fmw->calibrations;
- if (cal)
+ if (!cal)
return;
load_calib_data(priv, &cal->dev_data);
@@ -2354,14 +2353,21 @@ void tasdevice_tuning_switch(void *context, int state)
struct tasdevice_fw *tas_fmw = tas_priv->fmw;
int profile_cfg_id = tas_priv->rcabin.profile_cfg_id;
- if (tas_priv->fw_state == TASDEVICE_DSP_FW_FAIL) {
- dev_err(tas_priv->dev, "DSP bin file not loaded\n");
+ /*
+ * 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_priv->cur_prog < tas_fmw->nr_programs) {
- /*dsp mode or tuning mode*/
+ 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,
@@ -2370,9 +2376,10 @@ void tasdevice_tuning_switch(void *context, int state)
tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
TASDEVICE_BIN_BLK_PRE_POWER_UP);
- } else
+ } else {
tasdevice_select_cfg_blk(tas_priv, profile_cfg_id,
TASDEVICE_BIN_BLK_PRE_SHUTDOWN);
+ }
}
EXPORT_SYMBOL_NS_GPL(tasdevice_tuning_switch,
SND_SOC_TAS2781_FMWLIB);