Skip to content

Commit bb06c20

Browse files
Lucas Tanuretiwai
authored andcommitted
ASoC: cs35l41: Support external boost
Add support for external boost voltage, where GPIO1 must control a switch to isolate CS35L41 from the external Boost Voltage Signed-off-by: Lucas Tanure <tanureal@opensource.cirrus.com> Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20220413083728.10730-17-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 4b047ec commit bb06c20

3 files changed

Lines changed: 41 additions & 17 deletions

File tree

include/sound/cs35l41.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@
701701
#define CS35L41_GPIO1_CTRL_SHIFT 16
702702
#define CS35L41_GPIO2_CTRL_MASK 0x07000000
703703
#define CS35L41_GPIO2_CTRL_SHIFT 24
704+
#define CS35L41_GPIO_LVL_SHIFT 15
705+
#define CS35L41_GPIO_LVL_MASK BIT(CS35L41_GPIO_LVL_SHIFT)
704706
#define CS35L41_GPIO_POL_MASK 0x1000
705707
#define CS35L41_GPIO_POL_SHIFT 12
706708

@@ -802,8 +804,6 @@ int cs35l41_register_errata_patch(struct device *dev, struct regmap *reg, unsign
802804
int cs35l41_set_channels(struct device *dev, struct regmap *reg,
803805
unsigned int tx_num, unsigned int *tx_slot,
804806
unsigned int rx_num, unsigned int *rx_slot);
805-
int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind, int boost_cap,
806-
int boost_ipk);
807807
int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg);
808808
int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
809809
struct cs35l41_hw_cfg *hw_cfg);

sound/soc/codecs/cs35l41-lib.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -954,8 +954,8 @@ static const unsigned char cs35l41_bst_slope_table[4] = {
954954
0x75, 0x6B, 0x3B, 0x28
955955
};
956956

957-
int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind,
958-
int boost_cap, int boost_ipk)
957+
static int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_ind,
958+
int boost_cap, int boost_ipk)
959959
{
960960
unsigned char bst_lbst_val, bst_cbst_range, bst_ipk_scaled;
961961
int ret;
@@ -1040,7 +1040,6 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in
10401040

10411041
return 0;
10421042
}
1043-
EXPORT_SYMBOL_GPL(cs35l41_boost_config);
10441043

10451044
static const struct reg_sequence cs35l41_safe_to_reset[] = {
10461045
{ 0x00000040, 0x00000055 },

sound/soc/codecs/cs35l41.c

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -578,15 +578,10 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
578578
cs35l41_pup_patch,
579579
ARRAY_SIZE(cs35l41_pup_patch));
580580

581-
regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
582-
CS35L41_GLOBAL_EN_MASK,
583-
1 << CS35L41_GLOBAL_EN_SHIFT);
584-
585-
usleep_range(1000, 1100);
581+
cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 1);
586582
break;
587583
case SND_SOC_DAPM_POST_PMD:
588-
regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
589-
CS35L41_GLOBAL_EN_MASK, 0);
584+
cs35l41_global_enable(cs35l41->regmap, cs35l41->hw_cfg.bst_type, 0);
590585

591586
ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS1,
592587
val, val & CS35L41_PDN_DONE_MASK,
@@ -1001,13 +996,13 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
1001996
if (!hw_cfg->valid)
1002997
return -EINVAL;
1003998

999+
if (hw_cfg->bst_type == CS35L41_EXT_BOOST_NO_VSPK_SWITCH)
1000+
return -EINVAL;
1001+
10041002
/* Required */
1005-
ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap,
1006-
hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk);
1007-
if (ret) {
1008-
dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
1003+
ret = cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, hw_cfg);
1004+
if (ret)
10091005
return ret;
1010-
}
10111006

10121007
/* Optional */
10131008
if (hw_cfg->dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && hw_cfg->dout_hiz >= 0)
@@ -1017,9 +1012,31 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
10171012
return 0;
10181013
}
10191014

1015+
static const struct snd_soc_dapm_route cs35l41_ext_bst_routes[] = {
1016+
{"Main AMP", NULL, "VSPK"},
1017+
};
1018+
1019+
static const struct snd_soc_dapm_widget cs35l41_ext_bst_widget[] = {
1020+
SND_SOC_DAPM_SUPPLY("VSPK", CS35L41_GPIO1_CTRL1, CS35L41_GPIO_LVL_SHIFT, 0, NULL, 0),
1021+
};
1022+
10201023
static int cs35l41_component_probe(struct snd_soc_component *component)
10211024
{
10221025
struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(component);
1026+
struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
1027+
int ret;
1028+
1029+
if (cs35l41->hw_cfg.bst_type == CS35L41_EXT_BOOST) {
1030+
ret = snd_soc_dapm_new_controls(dapm, cs35l41_ext_bst_widget,
1031+
ARRAY_SIZE(cs35l41_ext_bst_widget));
1032+
if (ret)
1033+
return ret;
1034+
1035+
ret = snd_soc_dapm_add_routes(dapm, cs35l41_ext_bst_routes,
1036+
ARRAY_SIZE(cs35l41_ext_bst_routes));
1037+
if (ret)
1038+
return ret;
1039+
}
10231040

10241041
return wm_adsp2_component_probe(&cs35l41->dsp, component);
10251042
}
@@ -1084,6 +1101,10 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf
10841101
unsigned int val;
10851102
int ret;
10861103

1104+
ret = device_property_read_u32(dev, "cirrus,boost-type", &val);
1105+
if (ret >= 0)
1106+
hw_cfg->bst_type = val;
1107+
10871108
ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
10881109
if (ret >= 0)
10891110
hw_cfg->bst_ipk = val;
@@ -1376,6 +1397,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
13761397

13771398
wm_adsp2_remove(&cs35l41->dsp);
13781399
err:
1400+
cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
13791401
regulator_bulk_disable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
13801402
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
13811403

@@ -1390,6 +1412,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41)
13901412

13911413
regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
13921414
wm_adsp2_remove(&cs35l41->dsp);
1415+
cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
13931416

13941417
pm_runtime_put_noidle(cs35l41->dev);
13951418

@@ -1409,6 +1432,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev)
14091432

14101433
dev_dbg(cs35l41->dev, "Enter hibernate\n");
14111434

1435+
cs35l41_safe_reset(cs35l41->regmap, cs35l41->hw_cfg.bst_type);
14121436
regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0088);
14131437
regmap_write(cs35l41->regmap, CS35L41_WAKESRC_CTL, 0x0188);
14141438

@@ -1505,6 +1529,7 @@ static int __maybe_unused cs35l41_runtime_resume(struct device *dev)
15051529
dev_err(cs35l41->dev, "Failed to restore register cache: %d\n", ret);
15061530
return ret;
15071531
}
1532+
cs35l41_init_boost(cs35l41->dev, cs35l41->regmap, &cs35l41->hw_cfg);
15081533

15091534
return 0;
15101535
}

0 commit comments

Comments
 (0)