Commit f7f20737 authored by Lucas Tanure's avatar Lucas Tanure Committed by Takashi Iwai

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: default avatarLucas Tanure <tanureal@opensource.cirrus.com>
Acked-by: default avatarCharles Keepax <ckeepax@opensource.cirrus.com>
Link: https://lore.kernel.org/r/20220413083728.10730-2-tanureal@opensource.cirrus.comSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent ce522ba9
...@@ -701,9 +701,6 @@ ...@@ -701,9 +701,6 @@
#define CS35L41_GPIO1_CTRL_SHIFT 16 #define CS35L41_GPIO1_CTRL_SHIFT 16
#define CS35L41_GPIO2_CTRL_MASK 0x07000000 #define CS35L41_GPIO2_CTRL_MASK 0x07000000
#define CS35L41_GPIO2_CTRL_SHIFT 24 #define CS35L41_GPIO2_CTRL_SHIFT 24
#define CS35L41_GPIO_CTRL_OPEN_INT 2
#define CS35L41_GPIO_CTRL_ACTV_LO 4
#define CS35L41_GPIO_CTRL_ACTV_HI 5
#define CS35L41_GPIO_POL_MASK 0x1000 #define CS35L41_GPIO_POL_MASK 0x1000
#define CS35L41_GPIO_POL_SHIFT 12 #define CS35L41_GPIO_POL_SHIFT 12
...@@ -735,19 +732,43 @@ enum cs35l41_clk_ids { ...@@ -735,19 +732,43 @@ enum cs35l41_clk_ids {
CS35L41_CLKID_MCLK = 4, CS35L41_CLKID_MCLK = 4,
}; };
struct cs35l41_irq_cfg { enum cs35l41_gpio1_func {
bool irq_pol_inv; CS35L41_GPIO1_HIZ,
bool irq_out_en; CS35L41_GPIO1_GPIO,
int irq_src_sel; CS35L41_GPIO1_MDSYNC,
CS35L41_GPIO1_MCLK,
CS35L41_GPIO1_PDM_CLK,
CS35L41_GPIO1_PDM_DATA,
}; };
struct cs35l41_platform_data { enum cs35l41_gpio2_func {
CS35L41_GPIO2_HIZ,
CS35L41_GPIO2_GPIO,
CS35L41_GPIO2_INT_OPEN_DRAIN,
CS35L41_GPIO2_MCLK,
CS35L41_GPIO2_INT_PUSH_PULL_LOW,
CS35L41_GPIO2_INT_PUSH_PULL_HIGH,
CS35L41_GPIO2_PDM_CLK,
CS35L41_GPIO2_PDM_DATA,
};
struct cs35l41_gpio_cfg {
bool pol_inv;
bool out_en;
unsigned int func;
};
struct cs35l41_hw_cfg {
int bst_ind; int bst_ind;
int bst_ipk; int bst_ipk;
int bst_cap; int bst_cap;
int dout_hiz; int dout_hiz;
struct cs35l41_irq_cfg irq_config1; struct cs35l41_gpio_cfg gpio1;
struct cs35l41_irq_cfg irq_config2; struct cs35l41_gpio_cfg gpio2;
unsigned int spk_pos;
/* Don't put the AMP in reset if VSPK can not be turned off */
bool vspk_always_on;
}; };
struct cs35l41_otp_packed_element_t { struct cs35l41_otp_packed_element_t {
......
...@@ -213,13 +213,13 @@ static const struct component_ops cs35l41_hda_comp_ops = { ...@@ -213,13 +213,13 @@ static const struct component_ops cs35l41_hda_comp_ops = {
.unbind = cs35l41_hda_unbind, .unbind = cs35l41_hda_unbind,
}; };
static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41)
const struct cs35l41_hda_hw_config *hw_cfg)
{ {
struct cs35l41_hw_cfg *hw_cfg = &cs35l41->hw_cfg;
bool internal_boost = false; bool internal_boost = false;
int ret; int ret;
if (!hw_cfg) { if (hw_cfg->vspk_always_on) {
cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst; cs35l41->reg_seq = &cs35l41_hda_reg_seq_no_bst;
return 0; return 0;
} }
...@@ -227,7 +227,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, ...@@ -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) if (hw_cfg->bst_ind || hw_cfg->bst_cap || hw_cfg->bst_ipk)
internal_boost = true; internal_boost = true;
switch (hw_cfg->gpio1_func) { switch (hw_cfg->gpio1.func) {
case CS35L41_NOT_USED: case CS35L41_NOT_USED:
break; break;
case CS35l41_VSPK_SWITCH: case CS35l41_VSPK_SWITCH:
...@@ -239,11 +239,11 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, ...@@ -239,11 +239,11 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT); CS35L41_GPIO1_CTRL_MASK, 2 << CS35L41_GPIO1_CTRL_SHIFT);
break; break;
default: 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; return -EINVAL;
} }
switch (hw_cfg->gpio2_func) { switch (hw_cfg->gpio2.func) {
case CS35L41_NOT_USED: case CS35L41_NOT_USED:
break; break;
case CS35L41_INTERRUPT: case CS35L41_INTERRUPT:
...@@ -251,7 +251,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, ...@@ -251,7 +251,7 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT); CS35L41_GPIO2_CTRL_MASK, 2 << CS35L41_GPIO2_CTRL_SHIFT);
break; break;
default: 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; return -EINVAL;
} }
...@@ -267,13 +267,12 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41, ...@@ -267,13 +267,12 @@ static int cs35l41_hda_apply_properties(struct cs35l41_hda *cs35l41,
cs35l41->reg_seq = &cs35l41_hda_reg_seq_ext_bst; 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, static int cs35l41_hda_read_acpi(struct cs35l41_hda *cs35l41, const char *hid, int id)
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]; u32 values[HDA_MAX_COMPONENTS];
struct acpi_device *adev; struct acpi_device *adev;
struct device *physdev; struct device *physdev;
...@@ -284,7 +283,7 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c ...@@ -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); adev = acpi_dev_get_first_match_dev(hid, NULL, -1);
if (!adev) { if (!adev) {
dev_err(cs35l41->dev, "Failed to find an ACPI device for %s\n", hid); 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)); 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 ...@@ -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, cs35l41->reset_gpio = fwnode_gpiod_get_index(&adev->fwnode, "reset", cs35l41->index,
GPIOD_OUT_LOW, "cs35l41-reset"); GPIOD_OUT_LOW, "cs35l41-reset");
hw_cfg = kzalloc(sizeof(*hw_cfg), GFP_KERNEL);
if (!hw_cfg) {
ret = -ENOMEM;
goto err;
}
property = "cirrus,speaker-position"; property = "cirrus,speaker-position";
ret = device_property_read_u32_array(physdev, property, values, nval); ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret) if (ret)
goto err_free; goto err;
hw_cfg->spk_pos = values[cs35l41->index]; hw_cfg->spk_pos = values[cs35l41->index];
property = "cirrus,gpio1-func"; property = "cirrus,gpio1-func";
ret = device_property_read_u32_array(physdev, property, values, nval); ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret) if (ret)
goto err_free; goto err;
hw_cfg->gpio1_func = values[cs35l41->index]; hw_cfg->gpio1.func = values[cs35l41->index];
property = "cirrus,gpio2-func"; property = "cirrus,gpio2-func";
ret = device_property_read_u32_array(physdev, property, values, nval); ret = device_property_read_u32_array(physdev, property, values, nval);
if (ret) if (ret)
goto err_free; goto err;
hw_cfg->gpio2_func = values[cs35l41->index]; hw_cfg->gpio2.func = values[cs35l41->index];
property = "cirrus,boost-peak-milliamp"; property = "cirrus,boost-peak-milliamp";
ret = device_property_read_u32_array(physdev, property, values, nval); 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 ...@@ -365,15 +358,13 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
put_device(physdev); put_device(physdev);
return hw_cfg; return 0;
err_free:
kfree(hw_cfg);
err: err:
put_device(physdev); put_device(physdev);
dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret); dev_err(cs35l41->dev, "Failed property %s: %d\n", property, ret);
return ERR_PTR(ret); return ret;
no_acpi_dsd: no_acpi_dsd:
/* /*
...@@ -384,22 +375,21 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c ...@@ -384,22 +375,21 @@ static struct cs35l41_hda_hw_config *cs35l41_hda_read_acpi(struct cs35l41_hda *c
* fwnode. * fwnode.
*/ */
if (strncmp(hid, "CLSA0100", 8) != 0) if (strncmp(hid, "CLSA0100", 8) != 0)
return ERR_PTR(-EINVAL); return -EINVAL;
/* check I2C address to assign the index */ /* check I2C address to assign the index */
cs35l41->index = id == 0x40 ? 0 : 1; cs35l41->index = id == 0x40 ? 0 : 1;
cs35l41->reset_gpio = gpiod_get_index(physdev, NULL, 0, GPIOD_OUT_HIGH); 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); put_device(physdev);
return NULL; return 0;
} }
int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq, int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
struct regmap *regmap) struct regmap *regmap)
{ {
unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status; unsigned int int_sts, regid, reg_revid, mtl_revid, chipid, int_status;
struct cs35l41_hda_hw_config *acpi_hw_cfg;
struct cs35l41_hda *cs35l41; struct cs35l41_hda *cs35l41;
int ret; int ret;
...@@ -415,9 +405,11 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i ...@@ -415,9 +405,11 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
cs35l41->regmap = regmap; cs35l41->regmap = regmap;
dev_set_drvdata(dev, cs35l41); dev_set_drvdata(dev, cs35l41);
acpi_hw_cfg = cs35l41_hda_read_acpi(cs35l41, device_name, id); ret = cs35l41_hda_read_acpi(cs35l41, device_name, id);
if (IS_ERR(acpi_hw_cfg)) if (ret) {
return PTR_ERR(acpi_hw_cfg); dev_err_probe(cs35l41->dev, ret, "Platform not supported %d\n", ret);
return ret;
}
if (IS_ERR(cs35l41->reset_gpio)) { if (IS_ERR(cs35l41->reset_gpio)) {
ret = PTR_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 ...@@ -490,11 +482,9 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
if (ret) if (ret)
goto err; goto err;
ret = cs35l41_hda_apply_properties(cs35l41, acpi_hw_cfg); ret = cs35l41_hda_apply_properties(cs35l41);
if (ret) if (ret)
goto err; goto err;
kfree(acpi_hw_cfg);
acpi_hw_cfg = NULL;
if (cs35l41->reg_seq->probe) { if (cs35l41->reg_seq->probe) {
ret = regmap_multi_reg_write(cs35l41->regmap, 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 ...@@ -516,8 +506,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
return 0; return 0;
err: err:
kfree(acpi_hw_cfg); if (!cs35l41->hw_cfg.vspk_always_on)
if (!cs35l41->vspk_always_on)
gpiod_set_value_cansleep(cs35l41->reset_gpio, 0); gpiod_set_value_cansleep(cs35l41->reset_gpio, 0);
gpiod_put(cs35l41->reset_gpio); gpiod_put(cs35l41->reset_gpio);
...@@ -531,7 +520,7 @@ void cs35l41_hda_remove(struct device *dev) ...@@ -531,7 +520,7 @@ void cs35l41_hda_remove(struct device *dev)
component_del(cs35l41->dev, &cs35l41_hda_comp_ops); 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_set_value_cansleep(cs35l41->reset_gpio, 0);
gpiod_put(cs35l41->reset_gpio); gpiod_put(cs35l41->reset_gpio);
} }
......
...@@ -40,26 +40,15 @@ struct cs35l41_hda_reg_sequence { ...@@ -40,26 +40,15 @@ struct cs35l41_hda_reg_sequence {
unsigned int num_close; 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 cs35l41_hda {
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
struct gpio_desc *reset_gpio; struct gpio_desc *reset_gpio;
const struct cs35l41_hda_reg_sequence *reg_seq; const struct cs35l41_hda_reg_sequence *reg_seq;
struct cs35l41_hw_cfg hw_cfg;
int irq; int irq;
int index; 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, int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int irq,
......
...@@ -34,7 +34,7 @@ static int cs35l41_i2c_probe(struct i2c_client *client, ...@@ -34,7 +34,7 @@ static int cs35l41_i2c_probe(struct i2c_client *client,
{ {
struct cs35l41_private *cs35l41; struct cs35l41_private *cs35l41;
struct device *dev = &client->dev; struct device *dev = &client->dev;
struct cs35l41_platform_data *pdata = dev_get_platdata(dev); struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(dev);
const struct regmap_config *regmap_config = &cs35l41_regmap_i2c; const struct regmap_config *regmap_config = &cs35l41_regmap_i2c;
int ret; int ret;
...@@ -54,7 +54,7 @@ static int cs35l41_i2c_probe(struct i2c_client *client, ...@@ -54,7 +54,7 @@ static int cs35l41_i2c_probe(struct i2c_client *client,
return ret; return ret;
} }
return cs35l41_probe(cs35l41, pdata); return cs35l41_probe(cs35l41, hw_cfg);
} }
static int cs35l41_i2c_remove(struct i2c_client *client) static int cs35l41_i2c_remove(struct i2c_client *client)
......
...@@ -30,7 +30,7 @@ MODULE_DEVICE_TABLE(spi, cs35l41_id_spi); ...@@ -30,7 +30,7 @@ MODULE_DEVICE_TABLE(spi, cs35l41_id_spi);
static int cs35l41_spi_probe(struct spi_device *spi) static int cs35l41_spi_probe(struct spi_device *spi)
{ {
const struct regmap_config *regmap_config = &cs35l41_regmap_spi; const struct regmap_config *regmap_config = &cs35l41_regmap_spi;
struct cs35l41_platform_data *pdata = dev_get_platdata(&spi->dev); struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev);
struct cs35l41_private *cs35l41; struct cs35l41_private *cs35l41;
int ret; int ret;
...@@ -52,7 +52,7 @@ static int cs35l41_spi_probe(struct spi_device *spi) ...@@ -52,7 +52,7 @@ static int cs35l41_spi_probe(struct spi_device *spi)
cs35l41->dev = &spi->dev; cs35l41->dev = &spi->dev;
cs35l41->irq = spi->irq; cs35l41->irq = spi->irq;
return cs35l41_probe(cs35l41, pdata); return cs35l41_probe(cs35l41, hw_cfg);
} }
static void cs35l41_spi_remove(struct spi_device *spi) static void cs35l41_spi_remove(struct spi_device *spi)
......
...@@ -999,10 +999,10 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) ...@@ -999,10 +999,10 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
/* Set Platform Data */ /* Set Platform Data */
/* Required */ /* Required */
if (cs35l41->pdata.bst_ipk && if (cs35l41->hw_cfg.bst_ipk &&
cs35l41->pdata.bst_ind && cs35l41->pdata.bst_cap) { cs35l41->hw_cfg.bst_ind && cs35l41->hw_cfg.bst_cap) {
ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->pdata.bst_ind, ret = cs35l41_boost_config(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_ind,
cs35l41->pdata.bst_cap, cs35l41->pdata.bst_ipk); cs35l41->hw_cfg.bst_cap, cs35l41->hw_cfg.bst_ipk);
if (ret) { if (ret) {
dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret); dev_err(cs35l41->dev, "Error in Boost DT config: %d\n", ret);
return ret; return ret;
...@@ -1013,43 +1013,39 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41) ...@@ -1013,43 +1013,39 @@ static int cs35l41_set_pdata(struct cs35l41_private *cs35l41)
} }
/* Optional */ /* Optional */
if (cs35l41->pdata.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK && if (cs35l41->hw_cfg.dout_hiz <= CS35L41_ASP_DOUT_HIZ_MASK &&
cs35l41->pdata.dout_hiz >= 0) cs35l41->hw_cfg.dout_hiz >= 0)
regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, regmap_update_bits(cs35l41->regmap, CS35L41_SP_HIZ_CTRL, CS35L41_ASP_DOUT_HIZ_MASK,
CS35L41_ASP_DOUT_HIZ_MASK, cs35l41->hw_cfg.dout_hiz);
cs35l41->pdata.dout_hiz);
return 0; return 0;
} }
static int cs35l41_irq_gpio_config(struct cs35l41_private *cs35l41) static int cs35l41_gpio_config(struct cs35l41_private *cs35l41)
{ {
struct cs35l41_irq_cfg *irq_gpio_cfg1 = &cs35l41->pdata.irq_config1; struct cs35l41_gpio_cfg *gpio1 = &cs35l41->hw_cfg.gpio1;
struct cs35l41_irq_cfg *irq_gpio_cfg2 = &cs35l41->pdata.irq_config2; struct cs35l41_gpio_cfg *gpio2 = &cs35l41->hw_cfg.gpio2;
int irq_pol = IRQF_TRIGGER_NONE; int irq_pol = IRQF_TRIGGER_NONE;
regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1, regmap_update_bits(cs35l41->regmap, CS35L41_GPIO1_CTRL1,
CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
irq_gpio_cfg1->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | gpio1->pol_inv << CS35L41_GPIO_POL_SHIFT |
!irq_gpio_cfg1->irq_out_en << CS35L41_GPIO_DIR_SHIFT); !gpio1->out_en << CS35L41_GPIO_DIR_SHIFT);
regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1, regmap_update_bits(cs35l41->regmap, CS35L41_GPIO2_CTRL1,
CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK, CS35L41_GPIO_POL_MASK | CS35L41_GPIO_DIR_MASK,
irq_gpio_cfg2->irq_pol_inv << CS35L41_GPIO_POL_SHIFT | gpio2->pol_inv << CS35L41_GPIO_POL_SHIFT |
!irq_gpio_cfg2->irq_out_en << CS35L41_GPIO_DIR_SHIFT); !gpio2->out_en << CS35L41_GPIO_DIR_SHIFT);
regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL, regmap_update_bits(cs35l41->regmap, CS35L41_GPIO_PAD_CONTROL,
CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK, CS35L41_GPIO1_CTRL_MASK | CS35L41_GPIO2_CTRL_MASK,
irq_gpio_cfg1->irq_src_sel << CS35L41_GPIO1_CTRL_SHIFT | gpio1->func << CS35L41_GPIO1_CTRL_SHIFT |
irq_gpio_cfg2->irq_src_sel << CS35L41_GPIO2_CTRL_SHIFT); gpio2->func << CS35L41_GPIO2_CTRL_SHIFT);
if ((irq_gpio_cfg2->irq_src_sel == if ((gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_LOW | CS35L41_VALID_PDATA)) ||
(CS35L41_GPIO_CTRL_ACTV_LO | CS35L41_VALID_PDATA)) || (gpio2->func == (CS35L41_GPIO2_INT_OPEN_DRAIN | CS35L41_VALID_PDATA)))
(irq_gpio_cfg2->irq_src_sel ==
(CS35L41_GPIO_CTRL_OPEN_INT | CS35L41_VALID_PDATA)))
irq_pol = IRQF_TRIGGER_LOW; irq_pol = IRQF_TRIGGER_LOW;
else if (irq_gpio_cfg2->irq_src_sel == else if (gpio2->func == (CS35L41_GPIO2_INT_PUSH_PULL_HIGH | CS35L41_VALID_PDATA))
(CS35L41_GPIO_CTRL_ACTV_HI | CS35L41_VALID_PDATA))
irq_pol = IRQF_TRIGGER_HIGH; irq_pol = IRQF_TRIGGER_HIGH;
return irq_pol; return irq_pol;
...@@ -1115,50 +1111,44 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = { ...@@ -1115,50 +1111,44 @@ static const struct snd_soc_component_driver soc_component_dev_cs35l41 = {
.set_sysclk = cs35l41_component_set_sysclk, .set_sysclk = cs35l41_component_set_sysclk,
}; };
static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_platform_data *pdata) static int cs35l41_handle_pdata(struct device *dev, struct cs35l41_hw_cfg *hw_cfg)
{ {
struct cs35l41_irq_cfg *irq_gpio1_config = &pdata->irq_config1; struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1;
struct cs35l41_irq_cfg *irq_gpio2_config = &pdata->irq_config2; struct cs35l41_gpio_cfg *gpio2 = &hw_cfg->gpio2;
unsigned int val; unsigned int val;
int ret; int ret;
ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val); ret = device_property_read_u32(dev, "cirrus,boost-peak-milliamp", &val);
if (ret >= 0) if (ret >= 0)
pdata->bst_ipk = val; hw_cfg->bst_ipk = val;
ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val); ret = device_property_read_u32(dev, "cirrus,boost-ind-nanohenry", &val);
if (ret >= 0) if (ret >= 0)
pdata->bst_ind = val; hw_cfg->bst_ind = val;
ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val); ret = device_property_read_u32(dev, "cirrus,boost-cap-microfarad", &val);
if (ret >= 0) if (ret >= 0)
pdata->bst_cap = val; hw_cfg->bst_cap = val;
ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val); ret = device_property_read_u32(dev, "cirrus,asp-sdout-hiz", &val);
if (ret >= 0) if (ret >= 0)
pdata->dout_hiz = val; hw_cfg->dout_hiz = val;
else else
pdata->dout_hiz = -1; hw_cfg->dout_hiz = -1;
/* GPIO1 Pin Config */ /* GPIO1 Pin Config */
irq_gpio1_config->irq_pol_inv = device_property_read_bool(dev, gpio1->pol_inv = device_property_read_bool(dev, "cirrus,gpio1-polarity-invert");
"cirrus,gpio1-polarity-invert"); gpio1->out_en = device_property_read_bool(dev, "cirrus,gpio1-output-enable");
irq_gpio1_config->irq_out_en = device_property_read_bool(dev, ret = device_property_read_u32(dev, "cirrus,gpio1-src-select", &val);
"cirrus,gpio1-output-enable");
ret = device_property_read_u32(dev, "cirrus,gpio1-src-select",
&val);
if (ret >= 0) if (ret >= 0)
irq_gpio1_config->irq_src_sel = val | CS35L41_VALID_PDATA; gpio1->func = val | CS35L41_VALID_PDATA;
/* GPIO2 Pin Config */ /* GPIO2 Pin Config */
irq_gpio2_config->irq_pol_inv = device_property_read_bool(dev, gpio2->pol_inv = device_property_read_bool(dev, "cirrus,gpio2-polarity-invert");
"cirrus,gpio2-polarity-invert"); gpio2->out_en = device_property_read_bool(dev, "cirrus,gpio2-output-enable");
irq_gpio2_config->irq_out_en = device_property_read_bool(dev, ret = device_property_read_u32(dev, "cirrus,gpio2-src-select", &val);
"cirrus,gpio2-output-enable");
ret = device_property_read_u32(dev, "cirrus,gpio2-src-select",
&val);
if (ret >= 0) if (ret >= 0)
irq_gpio2_config->irq_src_sel = val | CS35L41_VALID_PDATA; gpio2->func = val | CS35L41_VALID_PDATA;
return 0; return 0;
} }
...@@ -1248,17 +1238,16 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41) ...@@ -1248,17 +1238,16 @@ static int cs35l41_dsp_init(struct cs35l41_private *cs35l41)
return ret; return ret;
} }
int cs35l41_probe(struct cs35l41_private *cs35l41, int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg)
struct cs35l41_platform_data *pdata)
{ {
u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match; u32 regid, reg_revid, i, mtl_revid, int_status, chipid_match;
int irq_pol = 0; int irq_pol = 0;
int ret; int ret;
if (pdata) { if (hw_cfg) {
cs35l41->pdata = *pdata; cs35l41->hw_cfg = *hw_cfg;
} else { } else {
ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->pdata); ret = cs35l41_handle_pdata(cs35l41->dev, &cs35l41->hw_cfg);
if (ret != 0) if (ret != 0)
return ret; return ret;
} }
...@@ -1357,7 +1346,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, ...@@ -1357,7 +1346,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41,
cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap); cs35l41_test_key_lock(cs35l41->dev, cs35l41->regmap);
irq_pol = cs35l41_irq_gpio_config(cs35l41); irq_pol = cs35l41_gpio_config(cs35l41);
/* Set interrupt masks for critical errors */ /* Set interrupt masks for critical errors */
regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1,
......
...@@ -44,7 +44,7 @@ enum cs35l41_cspl_mbox_cmd { ...@@ -44,7 +44,7 @@ enum cs35l41_cspl_mbox_cmd {
struct cs35l41_private { struct cs35l41_private {
struct wm_adsp dsp; /* needs to be first member */ struct wm_adsp dsp; /* needs to be first member */
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct cs35l41_platform_data pdata; struct cs35l41_hw_cfg hw_cfg;
struct device *dev; struct device *dev;
struct regmap *regmap; struct regmap *regmap;
struct regulator_bulk_data supplies[CS35L41_NUM_SUPPLIES]; struct regulator_bulk_data supplies[CS35L41_NUM_SUPPLIES];
...@@ -53,8 +53,7 @@ struct cs35l41_private { ...@@ -53,8 +53,7 @@ struct cs35l41_private {
struct gpio_desc *reset_gpio; struct gpio_desc *reset_gpio;
}; };
int cs35l41_probe(struct cs35l41_private *cs35l41, int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg);
struct cs35l41_platform_data *pdata);
void cs35l41_remove(struct cs35l41_private *cs35l41); void cs35l41_remove(struct cs35l41_private *cs35l41);
#endif /*__CS35L41_H__*/ #endif /*__CS35L41_H__*/
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment