diff options
author | Lucas Tanure <tanureal@opensource.cirrus.com> | 2022-04-13 11:37:14 +0300 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2022-04-13 11:42:32 +0300 |
commit | 2603c974b45dbfeece80474ee32173756aac3ba1 (patch) | |
tree | e1b926fa5ab245c9087b9f41abb55273093d5a8c /sound/soc/codecs/cs35l41.c | |
parent | f7f207375d4e6eb9acc78d312eed8806b37d101a (diff) | |
download | linux-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.c | 76 |
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; } |