aboutsummaryrefslogtreecommitdiff
path: root/sound/pci
diff options
context:
space:
mode:
authorLucas Tanure2022-04-13 09:37:13 +0100
committerTakashi Iwai2022-04-13 10:42:32 +0200
commitf7f207375d4e6eb9acc78d312eed8806b37d101a (patch)
treeb8b76fd3e874a0f164346aae1feac6a671ee9fa3 /sound/pci
parentce522ba9ef7e2d9fb22a39eb3371c0c64e2a433e (diff)
ALSA: cs35l41: Unify hardware configuration
Both ASoC and HDA require to configure the GPIOs and Boost, so create a single shared struct for hardware configuration. 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-2-tanureal@opensource.cirrus.com Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/cs35l41_hda.c69
-rw-r--r--sound/pci/hda/cs35l41_hda.h13
2 files changed, 30 insertions, 52 deletions
diff --git a/sound/pci/hda/cs35l41_hda.c b/sound/pci/hda/cs35l41_hda.c
index 718595380868..b79d6ad4b4f5 100644
--- a/sound/pci/hda/cs35l41_hda.c
+++ b/sound/pci/hda/cs35l41_hda.c
@@ -213,13 +213,13 @@ static const struct component_ops cs35l41_hda_comp_ops = {
.unbind = cs35l41_hda_unbind,
};
-static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
- const struct cs35l41_hda_hw_config *hw_cfg)
+static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
{
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
bool internal_boost = false;
int ret;
- if (!hw_cfg) {
+ if (hw_cfg->vspk_always_on) {
cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst;
return 0;
}
@@ -227,7 +227,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk)
internal_boost = true;
- switch (hw_cfg->gpio1_func) {
+ switch (hw_cfg->gpio1.func) {
case CS35L41_NOT_USED:
break;
case CS35l41_VSPK_SWITCH:
@@ -239,11 +239,11 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
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);
+ dev_err(cs35l41->dev, "Invalid function %d for GPIO1\n", hw_cfg->gpio1.func);
return -EINVAL;
}
- switch (hw_cfg->gpio2_func) {
+ switch (hw_cfg->gpio2.func) {
case CS35L41_NOT_USED:
break;
case CS35L41_INTERRUPT:
@@ -251,7 +251,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
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);
+ dev_err(cs35l41->dev, "Invalid function %d for GPIO2\n", hw_cfg->gpio2.func);
return -EINVAL;
}
@@ -267,13 +267,12 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst;
}
- return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, (unsigned int *)&hw_cfg->spk_pos);
+ return cs35l41_hda_channel_map(cs35l41->dev, 0, NULL, 1, &hw_cfg->spk_pos);
}
-static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41,
- const char *hid, int id)
+static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
{
- struct cs35l41_hda_hw_config *hw_cfg;
+ struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
u32 values[HDA_MAX_COMPONENTS];
struct acpi_device *adev;
struct device *physdev;
@@ -284,7 +283,7 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
if (!adev) {
dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid);
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
}
physdev = get_device(acpi_get_first_physical_node(adev));
@@ -324,29 +323,23 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index,
GPIOD_OUT_LOW, "cs35l41-reset");
- hw_cfg = kzalloc(sizeof(*hw_cfg), GFP_KERNEL);
- if (!hw_cfg) {
- ret = -ENOMEM;
- goto err;
- }
-
property = "cirrus,speaker-position";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret)
- goto err_free;
+ goto err;
hw_cfg->spk_pos = values[cs35l41->index];
property = "cirrus,gpio1-func";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret)
- goto err_free;
- hw_cfg->gpio1_func = values[cs35l41->index];
+ goto err;
+ hw_cfg->gpio1.func = values[cs35l41->index];
property = "cirrus,gpio2-func";
ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret)
- goto err_free;
- hw_cfg->gpio2_func = values[cs35l41->index];
+ goto err;
+ hw_cfg->gpio2.func = values[cs35l41->index];
property = "cirrus,boost-peak-milliamp";
ret = device_property_read_u32_array(physdev, property, values, nval);
@@ -365,15 +358,13 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
put_device(physdev);
- return hw_cfg;
+ return 0;
-err_free:
- kfree(hw_cfg);
err:
put_device(physdev);
dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
- return ERR_PTR(ret);
+ return ret;
no_acpi_dsd:
/*
@@ -384,22 +375,21 @@ no_acpi_dsd:
* fwnode.
*/
if (strncmp(hid, "CLSA0100", 8) != 0)
- return ERR_PTR(-EINVAL);
+ return -EINVAL;
/* check I2C address to assign the index */
cs35l41->index = id == 0x40 ? 0 : 1;
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH);
- cs35l41->vspk_always_on = true;
+ cs35l41->hw_cfg.vspk_always_on = true;
put_device(physdev);
- return NULL;
+ return 0;
}
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
struct regmap *regmap)
{
unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status;
- struct cs35l41_hda_hw_config *acpi_hw_cfg;
struct cs35l41_hda *cs35l41;
int ret;
@@ -415,9 +405,11 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
cs35l41->regmap = regmap;
dev_set_drvdata(dev, cs35l41);
- acpi_hw_cfg = cs35l41_hda_read_acpi(cs35l41, device_name, id);
- if (IS_ERR(acpi_hw_cfg))
- return PTR_ERR(acpi_hw_cfg);
+ ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);
+ if (ret) {
+ dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret);
+ return ret;
+ }
if (IS_ERR(cs35l41->reset_gpio)) {
ret = PTR_ERR(cs35l41->reset_gpio);
@@ -490,11 +482,9 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
if (ret)
goto err;
- ret = cs35l41_hda_apply_properties(cs35l41, acpi_hw_cfg);
+ ret = cs35l41_hda_apply_properties(cs35l41);
if (ret)
goto err;
- kfree(acpi_hw_cfg);
- acpi_hw_cfg = NULL;
if (cs35l41->reg_seq->probe) {
ret = regmap_multi_reg_write(cs35l41->regmap, cs35l41->reg_seq->probe,
@@ -516,8 +506,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
return 0;
err:
- kfree(acpi_hw_cfg);
- if (!cs35l41->vspk_always_on)
+ if (!cs35l41->hw_cfg.vspk_always_on)
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
gpiod_put(cs35l41->reset_gpio);
@@ -531,7 +520,7 @@ void cs35l41_hda_remove(struct device *dev)
component_del(cs35l41->dev, &cs35l41_hda_comp_ops);
- if (!cs35l41->vspk_always_on)
+ if (!cs35l41->hw_cfg.vspk_always_on)
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
gpiod_put(cs35l41->reset_gpio);
}
diff --git a/sound/pci/hda/cs35l41_hda.h b/sound/pci/hda/cs35l41_hda.h
index 74951001501c..17f10764f174 100644
--- a/sound/pci/hda/cs35l41_hda.h
+++ b/sound/pci/hda/cs35l41_hda.h
@@ -40,26 +40,15 @@ struct cs35l41_hda_reg_sequence {
unsigned int num_close;
};
-struct cs35l41_hda_hw_config {
- unsigned int spk_pos;
- unsigned int gpio1_func;
- unsigned int gpio2_func;
- int bst_ind;
- int bst_ipk;
- int bst_cap;
-};
-
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;
int index;
-
- /* Don't put the AMP in reset of VSPK can not be turned off */
- bool vspk_always_on;
};
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,