@@ -32,33 +32,9 @@ static const struct reg_sequence cs35l41_hda_mute[] = {
{ CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute
};
-// only on amps where GPIO1 is used to control ext. VSPK switch
-static const struct reg_sequence cs35l41_start_ext_vspk[] = {
+static const struct reg_sequence cs35l41_safe_to_reset[] = {
{ 0x00000040, 0x00000055 },
{ 0x00000040, 0x000000AA },
- { 0x00007438, 0x00585941 },
- { 0x00007414, 0x08C82222 },
- { 0x0000742C, 0x00000009 },
- { 0x00011008, 0x00008001 },
- { 0x0000742C, 0x0000000F },
- { 0x0000742C, 0x00000079 },
- { 0x00007438, 0x00585941 },
- { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1
- { 0x0000742C, 0x000000F9 },
- { 0x00007438, 0x00580941 },
- { 0x00000040, 0x000000CC },
- { 0x00000040, 0x00000033 },
-};
-
-//only on amps where GPIO1 is used to control ext. VSPK switch
-static const struct reg_sequence cs35l41_stop_ext_vspk[] = {
- { 0x00000040, 0x00000055 },
- { 0x00000040, 0x000000AA },
- { 0x00007438, 0x00585941 },
- { 0x00002014, 0x00000000, 3000}, // set GLOBAL_EN = 0
- { 0x0000742C, 0x00000009 },
- { 0x00007438, 0x00580941 },
- { 0x00011008, 0x00000001 },
{ 0x0000393C, 0x000000C0, 6000},
{ 0x0000393C, 0x00000000 },
{ 0x00007414, 0x00C82222 },
@@ -73,7 +49,7 @@ static const struct reg_sequence cs35l41_safe_to_active[] = {
{ 0x0000742C, 0x0000000F },
{ 0x0000742C, 0x00000079 },
{ 0x00007438, 0x00585941 },
- { CS35L41_PWR_CTRL1, 0x00000001, 2000 }, // GLOBAL_EN = 1
+ { CS35L41_PWR_CTRL1, 0x00000001, 3000 }, // GLOBAL_EN = 1
{ 0x0000742C, 0x000000F9 },
{ 0x00007438, 0x00580941 },
{ 0x00000040, 0x000000CC },
@@ -85,7 +61,7 @@ static const struct reg_sequence cs35l41_active_to_safe[] = {
{ 0x00000040, 0x000000AA },
{ 0x00007438, 0x00585941 },
{ CS35L41_PWR_CTRL1, 0x00000000 },
- { 0x0000742C, 0x00000009, 2000 },
+ { 0x0000742C, 0x00000009, 3000 },
{ 0x00007438, 0x00580941 },
{ 0x00000040, 0x000000CC },
{ 0x00000040, 0x00000033 },
@@ -101,6 +77,21 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = {
{ 0x00000040, 0x00000033 },
};
+static bool cs35l41_hda_safe_reset(struct cs35l41_hda *cs35l41)
+{
+ switch (cs35l41->hw_cfg.bst_type) {
+ case CS35L41_EXT_BOOST:
+ regmap_write(cs35l41->regmap, CS35L41_GPIO1_CTRL1, 0x00000001);
+ regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_reset,
+ ARRAY_SIZE(cs35l41_safe_to_reset));
+ return true;
+ case CS35L41_EXT_BOOST_NO_VSPK_SWITCH:
+ return false;
+ default:
+ return true;
+ }
+};
+
static void cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable)
{
switch (cs35l41->hw_cfg.bst_type) {
@@ -110,13 +101,6 @@ static void cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable)
usleep_range(3000, 3100);
break;
case CS35L41_EXT_BOOST:
- if (enable)
- regmap_multi_reg_write(cs35l41->regmap, cs35l41_start_ext_vspk,
- ARRAY_SIZE(cs35l41_start_ext_vspk));
- else
- regmap_multi_reg_write(cs35l41->regmap, cs35l41_stop_ext_vspk,
- ARRAY_SIZE(cs35l41_stop_ext_vspk));
- break;
case CS35L41_EXT_BOOST_NO_VSPK_SWITCH:
if (enable)
regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_active,
@@ -140,6 +124,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)
regmap_multi_reg_write(reg, cs35l41_hda_config, ARRAY_SIZE(cs35l41_hda_config));
regmap_update_bits(reg, CS35L41_PWR_CTRL2,
CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
+ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
+ regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00008001);
break;
case HDA_GEN_PCM_ACT_PREPARE:
cs35l41_hda_global_enable(cs35l41, 1);
@@ -151,6 +137,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)
case HDA_GEN_PCM_ACT_CLOSE:
regmap_update_bits(reg, CS35L41_PWR_CTRL2,
CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
+ if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST)
+ regmap_write(reg, CS35L41_GPIO1_CTRL1, 0x00000001);
break;
default:
break;
@@ -504,7 +492,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
return 0;
err:
- if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH)
+ if (cs35l41_hda_safe_reset(cs35l41))
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
gpiod_put(cs35l41->reset_gpio);
@@ -518,7 +506,7 @@ void cs35l41_hda_remove(struct device *dev)
component_del(cs35l41->dev, &cs35l41_hda_comp_ops);
- if (cs35l41->hw_cfg.bst_type != CS35L41_EXT_BOOST_NO_VSPK_SWITCH)
+ if (cs35l41_hda_safe_reset(cs35l41))
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
gpiod_put(cs35l41->reset_gpio);
}
Regmap sequences for external boost with or without the GPIO1 as VSPK switch are almost the same. Unify them and use the GPIO1 VSPK switch to handle the difference. Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> --- sound/pci/hda/cs35l41_hda.c | 60 +++++++++++++++---------------------- 1 file changed, 24 insertions(+), 36 deletions(-)