2022-03-23 16:29:32

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH v5 00/16] Support external boost at CS35l41 ASoC driver

Move the support for CS35L41 external boost to its shared library
for ASoC use.
This move resulted in cs35l41_hda_reg_sequence being removed,
and its steps were broken down into regmap writes or functions
from the library. And hardware configuration struct was unified
for its use in the shared lib.
While at it, some minor bugs were found and fixed it.

v5 changelog:
- Fixed wrong indentation at Documentation patch
- Use of consistent prefix

v4 changelog:
- Separated GPIO 1 and 2 function enums

v3 changelog:
- Remove patches already accepted
- Improved logic in documentation patch
- Documentation patch goes before its code
- Fixed missing Signed-off-by
- Fixed subject for HDA patches

v2 changelog:
- Instead of removing the log, playback actions will log the last regmap access.
- Documentation patch with the correct subject line and fixed bug reported by Rob Herring on the
provided example.

Previous versions:
v1: https://lkml.org/lkml/2022/3/3/759
v2: https://lkml.org/lkml/2022/3/4/743
v3: https://lkml.org/lkml/2022/3/8/975
v4: https://lkml.org/lkml/2022/3/17/267

David Rhodes (1):
ASoC: cs35l41: Document CS35l41 External Boost

Lucas Tanure (15):
ALSA: cs35l41: Unify hardware configuration
ALSA: cs35l41: Check hw_config before using it
ALSA: cs35l41: Move cs35l41_gpio_config to shared lib
ALSA: hda: cs35l41: Fix I2S params comments
ALSA: hda: cs35l41: Always configure the DAI
ALSA: hda: cs35l41: Add Boost type flag
ALSA: hda: cs35l41: Put the device into safe mode for external boost
ALSA: hda: cs35l41: Mute the device before shutdown
ALSA: cs35l41: Enable Internal Boost in shared lib
ALSA: hda: cs35l41: Move boost config to initialization code
ALSA: hda: cs35l41: Remove cs35l41_hda_reg_sequence struct
ALSA: hda: cs35l41: Reorganize log for playback actions
ALSA: hda: cs35l41: Handle all external boost setups the same way
ALSA: hda: cs35l41: Move external boost handling to lib for ASoC use
ASoC: cs35l41: Support external boost

.../bindings/sound/cirrus,cs35l41.yaml | 44 ++-
include/sound/cs35l41.h | 59 +++-
sound/pci/hda/cs35l41_hda.c | 295 ++++++------------
sound/pci/hda/cs35l41_hda.h | 27 +-
sound/soc/codecs/cs35l41-i2c.c | 4 +-
sound/soc/codecs/cs35l41-lib.c | 190 ++++++++++-
sound/soc/codecs/cs35l41-spi.c | 4 +-
sound/soc/codecs/cs35l41.c | 166 +++++-----
sound/soc/codecs/cs35l41.h | 5 +-
9 files changed, 443 insertions(+), 351 deletions(-)

--
2.35.1


2022-03-23 19:27:33

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH v5 05/16] ALSA: hda: cs35l41: Always configure the DAI

The dai configuration is always the same and should always configured
during the opening the stream.

Signed-off-by: Lucas Tanure <[email protected]>
---
sound/pci/hda/cs35l41_hda.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)

diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index d2addae8c085..f853530eb385 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -111,8 +111,6 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = {
static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = {
.probe = cs35l41_reset_to_safe,
.num_probe = ARRAY_SIZE(cs35l41_reset_to_safe),
- .open = cs35l41_hda_config,
- .num_open = ARRAY_SIZE(cs35l41_hda_config),
.prepare = cs35l41_safe_to_active,
.num_prepare = ARRAY_SIZE(cs35l41_safe_to_active),
.cleanup = cs35l41_active_to_safe,
@@ -120,8 +118,6 @@ static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = {
};

static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = {
- .open = cs35l41_hda_config,
- .num_open = ARRAY_SIZE(cs35l41_hda_config),
.prepare = cs35l41_start_ext_vspk,
.num_prepare = ARRAY_SIZE(cs35l41_start_ext_vspk),
.cleanup = cs35l41_stop_ext_vspk,
@@ -129,8 +125,6 @@ static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = {
};

static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_int_bst = {
- .open = cs35l41_hda_config,
- .num_open = ARRAY_SIZE(cs35l41_hda_config),
.prepare = cs35l41_hda_start_bst,
.num_prepare = ARRAY_SIZE(cs35l41_hda_start_bst),
.cleanup = cs35l41_hda_stop_bst,
@@ -146,8 +140,8 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)

switch (action) {
case HDA_GEN_PCM_ACT_OPEN:
- if (reg_seq->open)
- ret = regmap_multi_reg_write(reg, reg_seq->open, reg_seq->num_open);
+ ret = regmap_multi_reg_write(reg, cs35l41_hda_config,
+ ARRAY_SIZE(cs35l41_hda_config));
break;
case HDA_GEN_PCM_ACT_PREPARE:
if (reg_seq->prepare)
--
2.35.1

2022-03-23 22:15:11

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH v5 09/16] ALSA: cs35l41: Enable Internal Boost in shared lib

Internal Boost enable is the default option from reset, but with
external boost support, internal boost must be disabled.
Add the enable of internal boost in cs35l41_boost_config to
centralize the internal boost configuration.

Signed-off-by: Lucas Tanure <[email protected]>
Acked-by: Charles Keepax <[email protected]>
---
sound/soc/codecs/cs35l41-lib.c | 3 +++
1 file changed, 3 insertions(+)

diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c
index eeeaeaa0db82..03039d8488b9 100644
--- a/sound/soc/codecs/cs35l41-lib.c
+++ b/sound/soc/codecs/cs35l41-lib.c
@@ -1036,6 +1036,9 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in
return ret;
}

+ regmap_update_bits(regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
+ CS35L41_BST_EN_DEFAULT << CS35L41_BST_EN_SHIFT);
+
return 0;
}
EXPORT_SYMBOL_GPL(cs35l41_boost_config);
--
2.35.1

2022-03-24 02:05:50

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH v5 02/16] ALSA: cs35l41: Check hw_config before using it

The driver can receive an empty hw_config, so mark as valid if
successfully read from device tree/ACPI or set by the driver itself.
Platforms not marked with a valid hw config will not be supported.

Signed-off-by: Lucas Tanure <[email protected]>
Acked-by: Charles Keepax <[email protected]>
---
include/sound/cs35l41.h | 3 +-
sound/pci/hda/cs35l41_hda.c | 70 +++++++++++++++++++------------
sound/soc/codecs/cs35l41-lib.c | 16 ++++---
sound/soc/codecs/cs35l41.c | 76 +++++++++++++++++++++-------------
4 files changed, 104 insertions(+), 61 deletions(-)

diff --git a/include/sound/cs35l41.h b/include/sound/cs35l41.h
index abcf850f7110..4200379e0c26 100644
--- a/include/sound/cs35l41.h
+++ b/include/sound/cs35l41.h
@@ -538,7 +538,6 @@
#define CS35L41_OTP_SIZE_WORDS 32
#define CS35L41_NUM_OTP_ELEM 100

-#define CS35L41_VALID_PDATA 0x80000000
#define CS35L41_NUM_SUPPLIES 2

#define CS35L41_SCLK_MSTR_MASK 0x10
@@ -753,12 +752,14 @@ enum cs35l41_gpio2_func {
};

struct cs35l41_gpio_cfg {
+ bool valid;
bool pol_inv;
bool out_en;
unsigned int func;
};

struct cs35l41_hw_cfg {
+ bool valid;
int bst_ind;
int bst_ipk;
int bst_cap;
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index b79d6ad4b4f5..a14ad3b0d516 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -219,46 +219,52 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
bool internal_boost = false;
int ret;

+ if (!cs35l41->hw_cfg.valid)
+ return -EINVAL;
+
if (hw_cfg->vspk_always_on) {
cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst;
return 0;
}

- if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk)
+ if (hw_cfg->bst_ind > 0 || hw_cfg->bst_cap > 0 || hw_cfg->bst_ipk > 0)
internal_boost = true;

- switch (hw_cfg->gpio1.func) {
- case CS35L41_NOT_USED:
- break;
- case CS35l41_VSPK_SWITCH:
- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
- CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT);
- break;
- case CS35l41_SYNC:
- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
- CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT);
- break;
- default:
- dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1.func);
- return -EINVAL;
+ if (hw_cfg->gpio1.valid) {
+ switch (hw_cfg->gpio1.func) {
+ case CS35L41_NOT_USED:
+ break;
+ case CS35l41_VSPK_SWITCH:
+ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
+ CS35L41_GPIO1_CTRL_MASK, 1 << CS35L41_GPIO1_CTRL_SHIFT);
+ break;
+ case CS35l41_SYNC:
+ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
+ CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT);
+ break;
+ default:
+ dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n",
+ hw_cfg->gpio1.func);
+ return -EINVAL;
+ }
}

- switch (hw_cfg->gpio2.func) {
- case CS35L41_NOT_USED:
- break;
- case CS35L41_INTERRUPT:
- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
- CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT);
- break;
- default:
- dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2.func);
- return -EINVAL;
+ if (hw_cfg->gpio2.valid) {
+ switch (hw_cfg->gpio2.func) {
+ case CS35L41_NOT_USED:
+ break;
+ case CS35L41_INTERRUPT:
+ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
+ CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT);
+ break;
+ default:
+ dev_err(cs35l41->dev, "Invalid GPIO2 function %d\n", hw_cfg->gpio2.func);
+ return -EINVAL;
+ }
}

if (internal_boost) {
cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst;
- if (!(hw_cfg->bst_ind && hw_cfg->bst_cap && hw_cfg->bst_ipk))
- return -EINVAL;
ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap,
hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk);
if (ret)
@@ -334,28 +340,37 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
if (ret)
goto err;
hw_cfg->gpio1.func = values[cs35l41->index];
+ hw_cfg->gpio1.valid = true;

property = "cirrus,gpio2-func";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret)
goto err;
hw_cfg->gpio2.func = values[cs35l41->index];
+ hw_cfg->gpio2.valid = true;

property = "cirrus,boost-peak-milliamp";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret == 0)
hw_cfg->bst_ipk = values[cs35l41->index];
+ else
+ hw_cfg->bst_ipk = -1;

property = "cirrus,boost-ind-nanohenry";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret == 0)
hw_cfg->bst_ind = values[cs35l41->index];
+ else
+ hw_cfg->bst_ind = -1;

property = "cirrus,boost-cap-microfarad";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret == 0)
hw_cfg->bst_cap = values[cs35l41->index];
+ else
+ hw_cfg->bst_cap = -1;

+ hw_cfg->valid = true;
put_device(physdev);

return 0;
@@ -381,6 +396,7 @@ static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, i
cs35l41->index = id == 0x40 ? 0 : 1;
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
cs35l41->hw_cfg.vspk_always_on = true;
+ cs35l41->hw_cfg.valid = true;
put_device(physdev);

return 0;
diff --git a/sound/soc/codecs/cs35l41-lib.c b/sound/soc/codecs/cs35l41-lib.c
index e5a56bcbb223..905c648a8f49 100644
--- a/sound/soc/codecs/cs35l41-lib.c
+++ b/sound/soc/codecs/cs35l41-lib.c
@@ -992,10 +992,20 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in
case 101 ... 200:
bst_cbst_range = 3;
break;
- default: /* 201 uF and greater */
+ default:
+ if (boost_cap < 0) {
+ dev_err(dev, "Invalid boost capacitor value: %d nH\n", boost_cap);
+ return -EINVAL;
+ }
+ /* 201 uF and greater */
bst_cbst_range = 4;
}

+ if (boost_ipk < 1600 || boost_ipk > 4500) {
+ dev_err(dev, "Invalid boost inductor peak current: %d mA\n", boost_ipk);
+ return -EINVAL;
+ }
+
ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_COEFF,
CS35L41_BST_K1_MASK | CS35L41_BST_K2_MASK,
cs35l41_bst_k1_table[bst_lbst_val][bst_cbst_range]
@@ -1017,10 +1027,6 @@ int cs35l41_boost_config(struct device *dev, struct regmap *regmap, int boost_in
return ret;
}

- if (boost_ipk < 1600 || boost_ipk > 4500) {
- dev_err(dev, "Invalid boost inductor peak current: %d mA\n", boost_ipk);
- return -EINVAL;
- }
bst_ipk_scaled = ((boost_ipk - 1600) / 50) + 0x10;

ret = regmap_update_bits(regmap, CS35L41_BSTCVRT_PEAK_CUR, CS35L41_BST_IPK_MASK,
diff --git a/sound/soc/codecs/cs35l41.c b/sound/soc/codecs/cs35l41.c
index e76b93c15106..90dec80707ea 100644
--- a/sound/soc/codecs/cs35l41.c
+++ b/sound/soc/codecs/cs35l41.c
@@ -995,28 +995,24 @@ static int cs35l41_dai_set_sysclk(struct snd_soc_dai *dai,

static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
{
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
int ret;

- /* Set Platform Data */
- /* Required */
- if (cs35l41->hw_cfg.bst_ipk &&
- cs35l41->hw_cfg.bst_ind && cs35l41->hw_cfg.bst_cap) {
- ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_ind,
- cs35l41->hw_cfg.bst_cap, cs35l41->hw_cfg.bst_ipk);
- if (ret) {
- dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
- return ret;
- }
- } else {
- dev_err(cs35l41->dev, "Incomplete Boost component DT config\n");
+ if (!hw_cfg->valid)
return -EINVAL;
+
+ /* Required */
+ ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap,
+ hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk);
+ if (ret) {
+ dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
+ return ret;
}

/* Optional */
- if (cs35l41->hw_cfg.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK &&
- cs35l41->hw_cfg.dout_hiz >= 0)
+ if (hw_cfg->dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && hw_cfg->dout_hiz >= 0)
regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, CS35L41_ASP_DOUT_HIZ_MASK,
- cs35l41->hw_cfg.dout_hiz);
+ hw_cfg->dout_hiz);

return 0;
}
@@ -1037,16 +1033,28 @@ static int cs35l41_gpio_config(struct cs35l41_private *cs35l41)
gpio2->pol_inv << CS35L41_GPIO_POL_SHIFT |
!gpio2->out_en << CS35L41_GPIO_DIR_SHIFT);

- regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
- CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
- gpio1->func << CS35L41_GPIO1_CTRL_SHIFT |
- gpio2->func << CS35L41_GPIO2_CTRL_SHIFT);
+ if (gpio1->valid)
+ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
+ CS35L41_GPIO1_CTRL_MASK,
+ gpio1->func << CS35L41_GPIO1_CTRL_SHIFT);

- if ((gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_LOW | CS35L41_VALID_PDATA)) ||
- (gpio2->func == (CS35L41_GPIO2_INT_OPEN_DRAIN | CS35L41_VALID_PDATA)))
- irq_pol = IRQF_TRIGGER_LOW;
- else if (gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_HIGH | CS35L41_VALID_PDATA))
- irq_pol = IRQF_TRIGGER_HIGH;
+ if (gpio2->valid) {
+ regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
+ CS35L41_GPIO2_CTRL_MASK,
+ gpio2->func << CS35L41_GPIO2_CTRL_SHIFT);
+
+ switch (gpio2->func) {
+ case CS35L41_GPIO2_INT_PUSH_PULL_LOW:
+ case CS35L41_GPIO2_INT_OPEN_DRAIN:
+ irq_pol = IRQF_TRIGGER_LOW;
+ break;
+ case CS35L41_GPIO2_INT_PUSH_PULL_HIGH:
+ irq_pol = IRQF_TRIGGER_HIGH;
+ break;
+ default:
+ break;
+ }
+ }

return irq_pol;
}
@@ -1121,14 +1129,20 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf
ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
if (ret >= 0)
hw_cfg->bst_ipk = val;
+ else
+ hw_cfg->bst_ipk = -1;

ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
if (ret >= 0)
hw_cfg->bst_ind = val;
+ else
+ hw_cfg->bst_ind = -1;

ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
if (ret >= 0)
hw_cfg->bst_cap = val;
+ else
+ hw_cfg->bst_cap = -1;

ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
if (ret >= 0)
@@ -1140,15 +1154,21 @@ static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cf
gpio1->pol_inv = device_property_read_bool(dev, "cirrus,gpio1-polarity-invert");
gpio1->out_en = device_property_read_bool(dev, "cirrus,gpio1-output-enable");
ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", &val);
- if (ret >= 0)
- gpio1->func = val | CS35L41_VALID_PDATA;
+ if (ret >= 0) {
+ gpio1->func = val;
+ gpio1->valid = true;
+ }

/* GPIO2 Pin Config */
gpio2->pol_inv = device_property_read_bool(dev, "cirrus,gpio2-polarity-invert");
gpio2->out_en = device_property_read_bool(dev, "cirrus,gpio2-output-enable");
ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", &val);
- if (ret >= 0)
- gpio2->func = val | CS35L41_VALID_PDATA;
+ if (ret >= 0) {
+ gpio2->func = val;
+ gpio2->valid = true;
+ }
+
+ hw_cfg->valid = true;

return 0;
}
--
2.35.1

2022-03-25 18:44:12

by Lucas Tanure

[permalink] [raw]
Subject: [PATCH v5 11/16] ALSA: hda: cs35l41: Remove cs35l41_hda_reg_sequence struct

Remove cs35l41_hd_reg_sequence as it adds a layer of flexibility not needed.
As cs35l41_hda_(start/stop)_bst is a single register, it can be replaced by
regmap_update_bits with usleep_range to wait for the same 3000us that
reg_sequence had.

Signed-off-by: Lucas Tanure <[email protected]>
---
sound/pci/hda/cs35l41_hda.c | 79 ++++++++++++++++---------------------
sound/pci/hda/cs35l41_hda.h | 14 -------
2 files changed, 33 insertions(+), 60 deletions(-)

diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index 6e82ab9517f0..ece784662dbd 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -32,14 +32,6 @@ static const struct reg_sequence cs35l41_hda_mute[] = {
{ CS35L41_AMP_DIG_VOL_CTRL, 0x0000A678 }, // AMP_VOL_PCM Mute
};

-static const struct reg_sequence cs35l41_hda_start_bst[] = {
- { CS35L41_PWR_CTRL1, 0x00000001, 3000}, // set GLOBAL_EN = 1
-};
-
-static const struct reg_sequence cs35l41_hda_stop_bst[] = {
- { CS35L41_PWR_CTRL1, 0x00000000, 3000}, // set GLOBAL_EN = 0
-};
-
// only on amps where GPIO1 is used to control ext. VSPK switch
static const struct reg_sequence cs35l41_start_ext_vspk[] = {
{ 0x00000040, 0x00000055 },
@@ -109,31 +101,44 @@ static const struct reg_sequence cs35l41_reset_to_safe[] = {
{ 0x00000040, 0x00000033 },
};

-static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_no_bst = {
- .prepare = cs35l41_safe_to_active,
- .num_prepare = ARRAY_SIZE(cs35l41_safe_to_active),
- .cleanup = cs35l41_active_to_safe,
- .num_cleanup = ARRAY_SIZE(cs35l41_active_to_safe),
-};
+static int cs35l41_hda_global_enable(struct cs35l41_hda *cs35l41, int enable)
+{
+ int ret;

-static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_ext_bst = {
- .prepare = cs35l41_start_ext_vspk,
- .num_prepare = ARRAY_SIZE(cs35l41_start_ext_vspk),
- .cleanup = cs35l41_stop_ext_vspk,
- .num_cleanup = ARRAY_SIZE(cs35l41_stop_ext_vspk),
-};
+ switch (cs35l41->hw_cfg.bst_type) {
+ case CS35L41_INT_BOOST:
+ ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL1,
+ CS35L41_GLOBAL_EN_MASK,
+ enable << CS35L41_GLOBAL_EN_SHIFT);
+ usleep_range(3000, 3100);
+ break;
+ case CS35L41_EXT_BOOST:
+ if (enable)
+ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_start_ext_vspk,
+ ARRAY_SIZE(cs35l41_start_ext_vspk));
+ else
+ ret = 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)
+ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_safe_to_active,
+ ARRAY_SIZE(cs35l41_safe_to_active));
+ else
+ ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41_active_to_safe,
+ ARRAY_SIZE(cs35l41_active_to_safe));
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }

-static const struct cs35l41_hda_reg_sequence cs35l41_hda_reg_seq_int_bst = {
- .prepare = cs35l41_hda_start_bst,
- .num_prepare = ARRAY_SIZE(cs35l41_hda_start_bst),
- .cleanup = cs35l41_hda_stop_bst,
- .num_cleanup = ARRAY_SIZE(cs35l41_hda_stop_bst),
+ return ret;
};

static void cs35l41_hda_playback_hook(struct device *dev, int action)
{
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
- const struct cs35l41_hda_reg_sequence *reg_seq = cs35l41->reg_seq;
struct regmap *reg = cs35l41->regmap;
int ret = 0;

@@ -145,19 +150,15 @@ static void cs35l41_hda_playback_hook(struct device *dev, int action)
CS35L41_AMP_EN_MASK, 1 << CS35L41_AMP_EN_SHIFT);
break;
case HDA_GEN_PCM_ACT_PREPARE:
- if (reg_seq->prepare)
- ret = regmap_multi_reg_write(reg, reg_seq->prepare, reg_seq->num_prepare);
+ ret = cs35l41_hda_global_enable(cs35l41, 1);
break;
case HDA_GEN_PCM_ACT_CLEANUP:
regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
- if (reg_seq->cleanup)
- ret = regmap_multi_reg_write(reg, reg_seq->cleanup, reg_seq->num_cleanup);
+ ret = cs35l41_hda_global_enable(cs35l41, 0);
break;
case HDA_GEN_PCM_ACT_CLOSE:
regmap_update_bits(reg, CS35L41_PWR_CTRL2,
CS35L41_AMP_EN_MASK, 0 << CS35L41_AMP_EN_SHIFT);
- if (reg_seq->close)
- ret = regmap_multi_reg_write(reg, reg_seq->close, reg_seq->num_close);
break;
default:
ret = -EINVAL;
@@ -221,7 +222,6 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)

switch (hw_cfg->bst_type) {
case CS35L41_INT_BOOST:
- cs35l41->reg_seq = &cs35l41_hda_reg_seq_int_bst;
ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap,
hw_cfg->bst_ind, hw_cfg->bst_cap, hw_cfg->bst_ipk);
if (ret)
@@ -229,10 +229,6 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
break;
case CS35L41_EXT_BOOST:
case CS35L41_EXT_BOOST_NO_VSPK_SWITCH:
- if (hw_cfg->bst_type == CS35L41_EXT_BOOST)
- cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst;
- else
- cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst;
regmap_multi_reg_write(cs35l41->regmap, cs35l41_reset_to_safe,
ARRAY_SIZE(cs35l41_reset_to_safe));
ret = regmap_update_bits(cs35l41->regmap, CS35L41_PWR_CTRL2, CS35L41_BST_EN_MASK,
@@ -511,15 +507,6 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
if (ret)
goto err;

- if (cs35l41->reg_seq->probe) {
- ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe,
- cs35l41->reg_seq->num_probe);
- if (ret) {
- dev_err(cs35l41->dev, "Fail to apply probe reg patch: %d\n", ret);
- goto err;
- }
- }
-
ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops);
if (ret) {
dev_err(cs35l41->dev, "Register component failed: %d\n", ret);
diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h
index 17f10764f174..44d9204ffdf1 100644
--- a/sound/pci/hda/cs35l41_hda.h
+++ b/sound/pci/hda/cs35l41_hda.h
@@ -27,24 +27,10 @@ enum cs35l41_hda_gpio_function {
CS35l41_SYNC,
};

-struct cs35l41_hda_reg_sequence {
- const struct reg_sequence *probe;
- unsigned int num_probe;
- const struct reg_sequence *open;
- unsigned int num_open;
- const struct reg_sequence *prepare;
- unsigned int num_prepare;
- const struct reg_sequence *cleanup;
- unsigned int num_cleanup;
- const struct reg_sequence *close;
- unsigned int num_close;
-};
-
struct cs35l41_hda {
struct device *dev;
struct regmap *regmap;
struct gpio_desc *reset_gpio;
- const struct cs35l41_hda_reg_sequence *reg_seq;
struct cs35l41_hw_cfg hw_cfg;

int irq;
--
2.35.1