summaryrefslogtreecommitdiff
path: root/sound/soc/codecs/cs35l41.c
diff options
context:
space:
mode:
authorLucas Tanure <tanureal@opensource.cirrus.com>2022-04-13 11:37:14 +0300
committerTakashi Iwai <tiwai@suse.de>2022-04-13 11:42:32 +0300
commit2603c974b45dbfeece80474ee32173756aac3ba1 (patch)
treee1b926fa5ab245c9087b9f41abb55273093d5a8c /sound/soc/codecs/cs35l41.c
parentf7f207375d4e6eb9acc78d312eed8806b37d101a (diff)
downloadlinux-2603c974b45dbfeece80474ee32173756aac3ba1.tar.xz
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 <tanureal@opensource.cirrus.com> Acked-by: Charles Keepax <ckeepax@opensource.cirrus.com> Link: https://lore.kernel.org/r/20220413083728.10730-3-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/soc/codecs/cs35l41.c')
-rw-r--r--sound/soc/codecs/cs35l41.c76
1 files changed, 48 insertions, 28 deletions
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;
}