summaryrefslogtreecommitdiff
path: root/sound/soc/codecs
diff options
context:
space:
mode:
Diffstat (limited to 'sound/soc/codecs')
-rw-r--r--sound/soc/codecs/cs35l41-lib.c118
-rw-r--r--sound/soc/codecs/cs35l41.c20
-rw-r--r--sound/soc/codecs/cs43130.h138
-rw-r--r--sound/soc/codecs/sigmadsp.c25
4 files changed, 180 insertions, 121 deletions
diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c
index ac7cc492bcb0..4ec306cd2f47 100644
--- a/sound/soc/codecs/cs35l41-lib.c
+++ b/sound/soc/codecs/cs35l41-lib.c
@@ -1080,28 +1080,32 @@ static const struct reg_sequence cs35l41_safe_to_reset[] = {
{ 0x00000040, 0x00000033 },
};
-static const struct reg_sequence cs35l41_active_to_safe[] = {
+static const struct reg_sequence cs35l41_active_to_safe_start[] = {
{ 0x00000040, 0x00000055 },
{ 0x00000040, 0x000000AA },
{ 0x00007438, 0x00585941 },
{ CS35L41_PWR_CTRL1, 0x00000000 },
- { 0x0000742C, 0x00000009, 3000 },
+ { 0x0000742C, 0x00000009 },
+};
+
+static const struct reg_sequence cs35l41_active_to_safe_end[] = {
{ 0x00007438, 0x00580941 },
{ 0x00000040, 0x000000CC },
{ 0x00000040, 0x00000033 },
};
-static const struct reg_sequence cs35l41_safe_to_active[] = {
+static const struct reg_sequence cs35l41_safe_to_active_start[] = {
{ 0x00000040, 0x00000055 },
{ 0x00000040, 0x000000AA },
{ 0x0000742C, 0x0000000F },
{ 0x0000742C, 0x00000079 },
{ 0x00007438, 0x00585941 },
- { CS35L41_PWR_CTRL1, 0x00000001, 3000 }, // GLOBAL_EN = 1
+ { CS35L41_PWR_CTRL1, 0x00000001 }, // GLOBAL_EN = 1
+};
+
+static const struct reg_sequence cs35l41_safe_to_active_en_spk[] = {
{ 0x0000742C, 0x000000F9 },
{ 0x00007438, 0x00580941 },
- { 0x00000040, 0x000000CC },
- { 0x00000040, 0x00000033 },
};
static const struct reg_sequence cs35l41_reset_to_safe[] = {
@@ -1188,11 +1192,12 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type)
}
EXPORT_SYMBOL_GPL(cs35l41_safe_reset);
-int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type, int enable,
- struct completion *pll_lock)
+int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type,
+ int enable, struct completion *pll_lock, bool firmware_running)
{
int ret;
- unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3;
+ unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3, int_status, pup_pdn_mask;
+ unsigned int pwr_ctl1_val;
struct reg_sequence cs35l41_mdsync_down_seq[] = {
{CS35L41_PWR_CTRL3, 0},
{CS35L41_GPIO_PAD_CONTROL, 0},
@@ -1204,6 +1209,20 @@ int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type,
{CS35L41_PWR_CTRL1, 0x00000001, 3000},
};
+ pup_pdn_mask = enable ? CS35L41_PUP_DONE_MASK : CS35L41_PDN_DONE_MASK;
+
+ ret = regmap_read(regmap, CS35L41_PWR_CTRL1, &pwr_ctl1_val);
+ if (ret)
+ return ret;
+
+ if ((pwr_ctl1_val & CS35L41_GLOBAL_EN_MASK) && enable) {
+ dev_dbg(dev, "Cannot set Global Enable - already set.\n");
+ return 0;
+ } else if (!(pwr_ctl1_val & CS35L41_GLOBAL_EN_MASK) && !enable) {
+ dev_dbg(dev, "Cannot unset Global Enable - not set.\n");
+ return 0;
+ }
+
switch (b_type) {
case CS35L41_SHD_BOOST_ACTV:
case CS35L41_SHD_BOOST_PASS:
@@ -1240,20 +1259,85 @@ int cs35l41_global_enable(struct regmap *regmap, enum cs35l41_boost_type b_type,
ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq,
ARRAY_SIZE(cs35l41_mdsync_up_seq));
}
+
+ ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1,
+ int_status, int_status & pup_pdn_mask,
+ 1000, 100000);
+ if (ret)
+ dev_err(dev, "Enable(%d) failed: %d\n", enable, ret);
+
+ // Clear PUP/PDN status
+ regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask);
break;
case CS35L41_INT_BOOST:
ret = regmap_update_bits(regmap, CS35L41_PWR_CTRL1, CS35L41_GLOBAL_EN_MASK,
enable << CS35L41_GLOBAL_EN_SHIFT);
- usleep_range(3000, 3100);
+ if (ret) {
+ dev_err(dev, "CS35L41_PWR_CTRL1 set failed: %d\n", ret);
+ return ret;
+ }
+
+ ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1,
+ int_status, int_status & pup_pdn_mask,
+ 1000, 100000);
+ if (ret)
+ dev_err(dev, "Enable(%d) failed: %d\n", enable, ret);
+
+ /* Clear PUP/PDN status */
+ regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask);
break;
case CS35L41_EXT_BOOST:
case CS35L41_EXT_BOOST_NO_VSPK_SWITCH:
- if (enable)
- ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active,
- ARRAY_SIZE(cs35l41_safe_to_active));
- else
- ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe,
- ARRAY_SIZE(cs35l41_active_to_safe));
+ if (enable) {
+ /* Test Key is unlocked here */
+ ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active_start,
+ ARRAY_SIZE(cs35l41_safe_to_active_start));
+ if (ret)
+ return ret;
+
+ ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, int_status,
+ int_status & CS35L41_PUP_DONE_MASK, 1000, 100000);
+ if (ret) {
+ dev_err(dev, "Failed waiting for CS35L41_PUP_DONE_MASK: %d\n", ret);
+ /* Lock the test key, it was unlocked during the multi_reg_write */
+ cs35l41_test_key_lock(dev, regmap);
+ return ret;
+ }
+ regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PUP_DONE_MASK);
+
+ if (firmware_running)
+ ret = cs35l41_set_cspl_mbox_cmd(dev, regmap,
+ CSPL_MBOX_CMD_SPK_OUT_ENABLE);
+ else
+ ret = regmap_multi_reg_write(regmap, cs35l41_safe_to_active_en_spk,
+ ARRAY_SIZE(cs35l41_safe_to_active_en_spk));
+
+ /* Lock the test key, it was unlocked during the multi_reg_write */
+ cs35l41_test_key_lock(dev, regmap);
+ } else {
+ /* Test Key is unlocked here */
+ ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe_start,
+ ARRAY_SIZE(cs35l41_active_to_safe_start));
+ if (ret) {
+ /* Lock the test key, it was unlocked during the multi_reg_write */
+ cs35l41_test_key_lock(dev, regmap);
+ return ret;
+ }
+
+ ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1, int_status,
+ int_status & CS35L41_PDN_DONE_MASK, 1000, 100000);
+ if (ret) {
+ dev_err(dev, "Failed waiting for CS35L41_PDN_DONE_MASK: %d\n", ret);
+ /* Lock the test key, it was unlocked during the multi_reg_write */
+ cs35l41_test_key_lock(dev, regmap);
+ return ret;
+ }
+ regmap_write(regmap, CS35L41_IRQ1_STATUS1, CS35L41_PDN_DONE_MASK);
+
+ /* Test Key is locked here */
+ ret = regmap_multi_reg_write(regmap, cs35l41_active_to_safe_end,
+ ARRAY_SIZE(cs35l41_active_to_safe_end));
+ }
break;
default:
ret = -EINVAL;
@@ -1344,6 +1428,8 @@ static bool cs35l41_check_cspl_mbox_sts(enum cs35l41_cspl_mbox_cmd cmd,
return (sts == CSPL_MBOX_STS_RUNNING);
case CSPL_MBOX_CMD_STOP_PRE_REINIT:
return (sts == CSPL_MBOX_STS_RDY_FOR_REINIT);
+ case CSPL_MBOX_CMD_SPK_OUT_ENABLE:
+ return (sts == CSPL_MBOX_STS_RUNNING);
default:
return false;
}
diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index 6ac501f008ec..722b69a6de26 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -168,7 +168,7 @@ static int cs35l41_get_fs_mon_config_index(int freq)
static const DECLARE_TLV_DB_RANGE(dig_vol_tlv,
0, 0, TLV_DB_SCALE_ITEM(TLV_DB_GAIN_MUTE, 0, 1),
1, 913, TLV_DB_MINMAX_ITEM(-10200, 1200));
-static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 0, 1, 1);
+static DECLARE_TLV_DB_SCALE(amp_gain_tlv, 50, 100, 0);
static const struct snd_kcontrol_new dre_ctrl =
SOC_DAPM_SINGLE("Switch", CS35L41_PWR_CTRL3, 20, 1, 0);
@@ -491,7 +491,6 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
{
struct snd_soc_component *component = snd_soc_dapm_to_component(w->dapm);
struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
- unsigned int val;
int ret = 0;
switch (event) {
@@ -500,21 +499,12 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
cs35l41_pup_patch,
ARRAY_SIZE(cs35l41_pup_patch));
- cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1,
- &cs35l41->pll_lock);
+ ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type,
+ 1, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running);
break;
case SND_SOC_DAPM_POST_PMD:
- cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0,
- &cs35l41->pll_lock);
-
- ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
- val, val & CS35L41_PDN_DONE_MASK,
- 1000, 100000);
- if (ret)
- dev_warn(cs35l41->dev, "PDN failed: %d\n", ret);
-
- regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
- CS35L41_PDN_DONE_MASK);
+ ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type,
+ 0, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running);
regmap_multi_reg_write_bypassed(cs35l41->regmap,
cs35l41_pdn_patch,
diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h
index 1dd893674313..90e8895275e7 100644
--- a/sound/soc/codecs/cs43130.h
+++ b/sound/soc/codecs/cs43130.h
@@ -381,88 +381,88 @@ struct cs43130_clk_gen {
/* frm_size = 16 */
static const struct cs43130_clk_gen cs43130_16_clk_gen[] = {
- { 22579200, 32000, .v = { 441, 10, }, },
- { 22579200, 44100, .v = { 32, 1, }, },
- { 22579200, 48000, .v = { 147, 5, }, },
- { 22579200, 88200, .v = { 16, 1, }, },
- { 22579200, 96000, .v = { 147, 10, }, },
- { 22579200, 176400, .v = { 8, 1, }, },
- { 22579200, 192000, .v = { 147, 20, }, },
- { 22579200, 352800, .v = { 4, 1, }, },
- { 22579200, 384000, .v = { 147, 40, }, },
- { 24576000, 32000, .v = { 48, 1, }, },
- { 24576000, 44100, .v = { 5120, 147, }, },
- { 24576000, 48000, .v = { 32, 1, }, },
- { 24576000, 88200, .v = { 2560, 147, }, },
- { 24576000, 96000, .v = { 16, 1, }, },
- { 24576000, 176400, .v = { 1280, 147, }, },
- { 24576000, 192000, .v = { 8, 1, }, },
- { 24576000, 352800, .v = { 640, 147, }, },
- { 24576000, 384000, .v = { 4, 1, }, },
+ { 22579200, 32000, .v = { 10, 441, }, },
+ { 22579200, 44100, .v = { 1, 32, }, },
+ { 22579200, 48000, .v = { 5, 147, }, },
+ { 22579200, 88200, .v = { 1, 16, }, },
+ { 22579200, 96000, .v = { 10, 147, }, },
+ { 22579200, 176400, .v = { 1, 8, }, },
+ { 22579200, 192000, .v = { 20, 147, }, },
+ { 22579200, 352800, .v = { 1, 4, }, },
+ { 22579200, 384000, .v = { 40, 147, }, },
+ { 24576000, 32000, .v = { 1, 48, }, },
+ { 24576000, 44100, .v = { 147, 5120, }, },
+ { 24576000, 48000, .v = { 1, 32, }, },
+ { 24576000, 88200, .v = { 147, 2560, }, },
+ { 24576000, 96000, .v = { 1, 16, }, },
+ { 24576000, 176400, .v = { 147, 1280, }, },
+ { 24576000, 192000, .v = { 1, 8, }, },
+ { 24576000, 352800, .v = { 147, 640, }, },
+ { 24576000, 384000, .v = { 1, 4, }, },
};
/* frm_size = 32 */
static const struct cs43130_clk_gen cs43130_32_clk_gen[] = {
- { 22579200, 32000, .v = { 441, 20, }, },
- { 22579200, 44100, .v = { 16, 1, }, },
- { 22579200, 48000, .v = { 147, 10, }, },
- { 22579200, 88200, .v = { 8, 1, }, },
- { 22579200, 96000, .v = { 147, 20, }, },
- { 22579200, 176400, .v = { 4, 1, }, },
- { 22579200, 192000, .v = { 147, 40, }, },
- { 22579200, 352800, .v = { 2, 1, }, },
- { 22579200, 384000, .v = { 147, 80, }, },
- { 24576000, 32000, .v = { 24, 1, }, },
- { 24576000, 44100, .v = { 2560, 147, }, },
- { 24576000, 48000, .v = { 16, 1, }, },
- { 24576000, 88200, .v = { 1280, 147, }, },
- { 24576000, 96000, .v = { 8, 1, }, },
- { 24576000, 176400, .v = { 640, 147, }, },
- { 24576000, 192000, .v = { 4, 1, }, },
- { 24576000, 352800, .v = { 320, 147, }, },
- { 24576000, 384000, .v = { 2, 1, }, },
+ { 22579200, 32000, .v = { 20, 441, }, },
+ { 22579200, 44100, .v = { 1, 16, }, },
+ { 22579200, 48000, .v = { 10, 147, }, },
+ { 22579200, 88200, .v = { 1, 8, }, },
+ { 22579200, 96000, .v = { 20, 147, }, },
+ { 22579200, 176400, .v = { 1, 4, }, },
+ { 22579200, 192000, .v = { 40, 147, }, },
+ { 22579200, 352800, .v = { 1, 2, }, },
+ { 22579200, 384000, .v = { 80, 147, }, },
+ { 24576000, 32000, .v = { 1, 24, }, },
+ { 24576000, 44100, .v = { 147, 2560, }, },
+ { 24576000, 48000, .v = { 1, 16, }, },
+ { 24576000, 88200, .v = { 147, 1280, }, },
+ { 24576000, 96000, .v = { 1, 8, }, },
+ { 24576000, 176400, .v = { 147, 640, }, },
+ { 24576000, 192000, .v = { 1, 4, }, },
+ { 24576000, 352800, .v = { 147, 320, }, },
+ { 24576000, 384000, .v = { 1, 2, }, },
};
/* frm_size = 48 */
static const struct cs43130_clk_gen cs43130_48_clk_gen[] = {
- { 22579200, 32000, .v = { 147, 100, }, },
- { 22579200, 44100, .v = { 32, 3, }, },
- { 22579200, 48000, .v = { 49, 5, }, },
- { 22579200, 88200, .v = { 16, 3, }, },
- { 22579200, 96000, .v = { 49, 10, }, },
- { 22579200, 176400, .v = { 8, 3, }, },
- { 22579200, 192000, .v = { 49, 20, }, },
- { 22579200, 352800, .v = { 4, 3, }, },
- { 22579200, 384000, .v = { 49, 40, }, },
- { 24576000, 32000, .v = { 16, 1, }, },
- { 24576000, 44100, .v = { 5120, 441, }, },
- { 24576000, 48000, .v = { 32, 3, }, },
- { 24576000, 88200, .v = { 2560, 441, }, },
- { 24576000, 96000, .v = { 16, 3, }, },
- { 24576000, 176400, .v = { 1280, 441, }, },
- { 24576000, 192000, .v = { 8, 3, }, },
- { 24576000, 352800, .v = { 640, 441, }, },
- { 24576000, 384000, .v = { 4, 3, }, },
+ { 22579200, 32000, .v = { 100, 147, }, },
+ { 22579200, 44100, .v = { 3, 32, }, },
+ { 22579200, 48000, .v = { 5, 49, }, },
+ { 22579200, 88200, .v = { 3, 16, }, },
+ { 22579200, 96000, .v = { 10, 49, }, },
+ { 22579200, 176400, .v = { 3, 8, }, },
+ { 22579200, 192000, .v = { 20, 49, }, },
+ { 22579200, 352800, .v = { 3, 4, }, },
+ { 22579200, 384000, .v = { 40, 49, }, },
+ { 24576000, 32000, .v = { 1, 16, }, },
+ { 24576000, 44100, .v = { 441, 5120, }, },
+ { 24576000, 48000, .v = { 3, 32, }, },
+ { 24576000, 88200, .v = { 441, 2560, }, },
+ { 24576000, 96000, .v = { 3, 16, }, },
+ { 24576000, 176400, .v = { 441, 1280, }, },
+ { 24576000, 192000, .v = { 3, 8, }, },
+ { 24576000, 352800, .v = { 441, 640, }, },
+ { 24576000, 384000, .v = { 3, 4, }, },
};
/* frm_size = 64 */
static const struct cs43130_clk_gen cs43130_64_clk_gen[] = {
- { 22579200, 32000, .v = { 441, 40, }, },
- { 22579200, 44100, .v = { 8, 1, }, },
- { 22579200, 48000, .v = { 147, 20, }, },
- { 22579200, 88200, .v = { 4, 1, }, },
- { 22579200, 96000, .v = { 147, 40, }, },
- { 22579200, 176400, .v = { 2, 1, }, },
- { 22579200, 192000, .v = { 147, 80, }, },
+ { 22579200, 32000, .v = { 40, 441, }, },
+ { 22579200, 44100, .v = { 1, 8, }, },
+ { 22579200, 48000, .v = { 20, 147, }, },
+ { 22579200, 88200, .v = { 1, 4, }, },
+ { 22579200, 96000, .v = { 40, 147, }, },
+ { 22579200, 176400, .v = { 1, 2, }, },
+ { 22579200, 192000, .v = { 80, 147, }, },
{ 22579200, 352800, .v = { 1, 1, }, },
- { 24576000, 32000, .v = { 12, 1, }, },
- { 24576000, 44100, .v = { 1280, 147, }, },
- { 24576000, 48000, .v = { 8, 1, }, },
- { 24576000, 88200, .v = { 640, 147, }, },
- { 24576000, 96000, .v = { 4, 1, }, },
- { 24576000, 176400, .v = { 320, 147, }, },
- { 24576000, 192000, .v = { 2, 1, }, },
- { 24576000, 352800, .v = { 160, 147, }, },
+ { 24576000, 32000, .v = { 1, 12, }, },
+ { 24576000, 44100, .v = { 147, 1280, }, },
+ { 24576000, 48000, .v = { 1, 8, }, },
+ { 24576000, 88200, .v = { 147, 640, }, },
+ { 24576000, 96000, .v = { 1, 4, }, },
+ { 24576000, 176400, .v = { 147, 320, }, },
+ { 24576000, 192000, .v = { 1, 2, }, },
+ { 24576000, 352800, .v = { 147, 160, }, },
{ 24576000, 384000, .v = { 1, 1, }, },
};
diff --git a/sound/soc/codecs/sigmadsp.c b/sound/soc/codecs/sigmadsp.c
index 3047a6fbb380..b93c078a8040 100644
--- a/sound/soc/codecs/sigmadsp.c
+++ b/sound/soc/codecs/sigmadsp.c
@@ -669,36 +669,19 @@ static void sigmadsp_activate_ctrl(struct sigmadsp *sigmadsp,
struct sigmadsp_control *ctrl, unsigned int samplerate_mask)
{
struct snd_card *card = sigmadsp->component->card->snd_card;
- struct snd_kcontrol_volatile *vd;
- struct snd_ctl_elem_id id;
bool active;
- bool changed = false;
+ int changed;
active = sigmadsp_samplerate_valid(ctrl->samplerates, samplerate_mask);
-
- down_write(&card->controls_rwsem);
- if (!ctrl->kcontrol) {
- up_write(&card->controls_rwsem);
+ if (!ctrl->kcontrol)
return;
- }
-
- id = ctrl->kcontrol->id;
- vd = &ctrl->kcontrol->vd[0];
- if (active == (bool)(vd->access & SNDRV_CTL_ELEM_ACCESS_INACTIVE)) {
- vd->access ^= SNDRV_CTL_ELEM_ACCESS_INACTIVE;
- changed = true;
- }
- up_write(&card->controls_rwsem);
-
- if (active && changed) {
+ changed = snd_ctl_activate_id(card, &ctrl->kcontrol->id, active);
+ if (active && changed > 0) {
mutex_lock(&sigmadsp->lock);
if (ctrl->cached)
sigmadsp_ctrl_write(sigmadsp, ctrl, ctrl->cache);
mutex_unlock(&sigmadsp->lock);
}
-
- if (changed)
- snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_INFO, &id);
}
/**