Commit 09d86dbf authored by Mark Brown's avatar Mark Brown

Improve CS35l41-based audio codec drivers

Merge series from Cristian Ciocaltea <cristian.ciocaltea@collabora.com>:

This patch series contains several fixes and improvements to drivers
based on the CS35l41 audio codec.

It has been verified on Valve's Steam Deck, except the HDA related patches.
parents 5b772c61 206b250c
......@@ -11,7 +11,6 @@
#define __CS35L41_H
#include <linux/regmap.h>
#include <linux/completion.h>
#include <linux/firmware/cirrus/cs_dsp.h>
#define CS35L41_FIRSTREG 0x00000000
......@@ -902,7 +901,8 @@ int cs35l41_exit_hibernate(struct device *dev, struct regmap *regmap);
int cs35l41_init_boost(struct device *dev, struct regmap *regmap,
struct cs35l41_hw_cfg *hw_cfg);
bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type);
int cs35l41_mdsync_up(struct regmap *regmap);
int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type,
int enable, struct completion *pll_lock, bool firmware_running);
int enable, bool firmware_running);
#endif /* __CS35L41_H */
......@@ -527,7 +527,7 @@ static void cs35l41_hda_play_done(struct device *dev)
dev_dbg(dev, "Play (Complete)\n");
cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1, NULL,
cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 1,
cs35l41->firmware_running);
if (cs35l41->firmware_running) {
regmap_multi_reg_write(reg, cs35l41_hda_unmute_dsp,
......@@ -546,7 +546,7 @@ static void cs35l41_hda_pause_start(struct device *dev)
dev_dbg(dev, "Pause (Start)\n");
regmap_multi_reg_write(reg, cs35l41_hda_mute, ARRAY_SIZE(cs35l41_hda_mute));
cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 0, NULL,
cs35l41_global_enable(dev, reg, cs35l41->hw_cfg.bst_type, 0,
cs35l41->firmware_running);
}
......@@ -1550,27 +1550,27 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
ret = regmap_read_poll_timeout(cs35l41->regmap, CS35L41_IRQ1_STATUS4, int_status,
int_status & CS35L41_OTP_BOOT_DONE, 1000, 100000);
if (ret) {
dev_err(cs35l41->dev, "Failed waiting for OTP_BOOT_DONE: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Failed waiting for OTP_BOOT_DONE\n");
goto err;
}
ret = regmap_read(cs35l41->regmap, CS35L41_IRQ1_STATUS3, &int_sts);
if (ret || (int_sts & CS35L41_OTP_BOOT_ERR)) {
dev_err(cs35l41->dev, "OTP Boot status %x error: %d\n",
int_sts & CS35L41_OTP_BOOT_ERR, ret);
dev_err_probe(cs35l41->dev, ret, "OTP Boot status %x error\n",
int_sts & CS35L41_OTP_BOOT_ERR);
ret = -EIO;
goto err;
}
ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
if (ret) {
dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Get Device ID failed\n");
goto err;
}
ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
if (ret) {
dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Get Revision ID failed\n");
goto err;
}
......@@ -1593,7 +1593,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap);
if (ret) {
dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "OTP Unpack failed\n");
goto err;
}
......@@ -1624,9 +1624,8 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
ret = component_add(cs35l41->dev, &cs35l41_hda_comp_ops);
if (ret) {
dev_err(cs35l41->dev, "Register component failed: %d\n", ret);
pm_runtime_disable(cs35l41->dev);
goto err;
dev_err_probe(cs35l41->dev, ret, "Register component failed\n");
goto err_pm;
}
dev_info(cs35l41->dev, "Cirrus Logic CS35L41 (%x), Revision: %02X\n", regid, reg_revid);
......@@ -1634,6 +1633,7 @@ int cs35l41_hda_probe(struct device *dev, const char *device_name, int id, int i
return 0;
err_pm:
pm_runtime_dont_use_autosuspend(cs35l41->dev);
pm_runtime_disable(cs35l41->dev);
pm_runtime_put_noidle(cs35l41->dev);
......@@ -1652,6 +1652,7 @@ void cs35l41_hda_remove(struct device *dev)
struct cs35l41_hda *cs35l41 = dev_get_drvdata(dev);
pm_runtime_get_sync(cs35l41->dev);
pm_runtime_dont_use_autosuspend(cs35l41->dev);
pm_runtime_disable(cs35l41->dev);
if (cs35l41->halo_initialized)
......
......@@ -35,7 +35,6 @@ static int cs35l41_i2c_probe(struct i2c_client *client)
struct device *dev = &client->dev;
struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(dev);
const struct regmap_config *regmap_config = &cs35l41_regmap_i2c;
int ret;
cs35l41 = devm_kzalloc(dev, sizeof(struct cs35l41_private), GFP_KERNEL);
......@@ -47,11 +46,9 @@ static int cs35l41_i2c_probe(struct i2c_client *client)
i2c_set_clientdata(client, cs35l41);
cs35l41->regmap = devm_regmap_init_i2c(client, regmap_config);
if (IS_ERR(cs35l41->regmap)) {
ret = PTR_ERR(cs35l41->regmap);
dev_err(cs35l41->dev, "Failed to allocate register map: %d\n", ret);
return ret;
}
if (IS_ERR(cs35l41->regmap))
return dev_err_probe(cs35l41->dev, PTR_ERR(cs35l41->regmap),
"Failed to allocate register map\n");
return cs35l41_probe(cs35l41, hw_cfg);
}
......@@ -83,7 +80,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match);
static struct i2c_driver cs35l41_i2c_driver = {
.driver = {
.name = "cs35l41",
.pm = &cs35l41_pm_ops,
.pm = pm_ptr(&cs35l41_pm_ops),
.of_match_table = of_match_ptr(cs35l41_of_match),
.acpi_match_table = ACPI_PTR(cs35l41_acpi_match),
},
......
......@@ -1192,8 +1192,28 @@ bool cs35l41_safe_reset(struct regmap *regmap, enum cs35l41_boost_type b_type)
}
EXPORT_SYMBOL_GPL(cs35l41_safe_reset);
/*
* Enabling the CS35L41_SHD_BOOST_ACTV and CS35L41_SHD_BOOST_PASS shared boosts
* does also require a call to cs35l41_mdsync_up(), but not before getting the
* PLL Lock signal.
*
* PLL Lock seems to be triggered soon after snd_pcm_start() is executed and
* SNDRV_PCM_TRIGGER_START command is processed, which happens (long) after the
* SND_SOC_DAPM_PRE_PMU event handler is invoked as part of snd_pcm_prepare().
*
* This event handler is where cs35l41_global_enable() is normally called from,
* but waiting for PLL Lock here will time out. Increasing the wait duration
* will not help, as the only consequence of it would be to add an unnecessary
* delay in the invocation of snd_pcm_start().
*
* Trying to move the wait in the SNDRV_PCM_TRIGGER_START callback is not a
* solution either, as the trigger is executed in an IRQ-off atomic context.
*
* The current approach is to invoke cs35l41_mdsync_up() right after receiving
* the PLL Lock interrupt, in the IRQ handler.
*/
int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l41_boost_type b_type,
int enable, struct completion *pll_lock, bool firmware_running)
int enable, bool firmware_running)
{
int ret;
unsigned int gpio1_func, pad_control, pwr_ctrl1, pwr_ctrl3, int_status, pup_pdn_mask;
......@@ -1203,11 +1223,6 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4
{CS35L41_GPIO_PAD_CONTROL, 0},
{CS35L41_PWR_CTRL1, 0, 3000},
};
struct reg_sequence cs35l41_mdsync_up_seq[] = {
{CS35L41_PWR_CTRL3, 0},
{CS35L41_PWR_CTRL1, 0x00000000, 3000},
{CS35L41_PWR_CTRL1, 0x00000001, 3000},
};
pup_pdn_mask = enable ? CS35L41_PUP_DONE_MASK : CS35L41_PDN_DONE_MASK;
......@@ -1241,24 +1256,12 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4
cs35l41_mdsync_down_seq[0].def = pwr_ctrl3;
cs35l41_mdsync_down_seq[1].def = pad_control;
cs35l41_mdsync_down_seq[2].def = pwr_ctrl1;
ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_down_seq,
ARRAY_SIZE(cs35l41_mdsync_down_seq));
if (!enable)
break;
if (!pll_lock)
return -EINVAL;
ret = wait_for_completion_timeout(pll_lock, msecs_to_jiffies(1000));
if (ret == 0) {
ret = -ETIMEDOUT;
} else {
regmap_read(regmap, CS35L41_PWR_CTRL3, &pwr_ctrl3);
pwr_ctrl3 |= CS35L41_SYNC_EN_MASK;
cs35l41_mdsync_up_seq[0].def = pwr_ctrl3;
ret = regmap_multi_reg_write(regmap, cs35l41_mdsync_up_seq,
ARRAY_SIZE(cs35l41_mdsync_up_seq));
}
/* Activation to be completed later via cs35l41_mdsync_up() */
if (ret || enable)
return ret;
ret = regmap_read_poll_timeout(regmap, CS35L41_IRQ1_STATUS1,
int_status, int_status & pup_pdn_mask,
......@@ -1266,7 +1269,7 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4
if (ret)
dev_err(dev, "Enable(%d) failed: %d\n", enable, ret);
// Clear PUP/PDN status
/* Clear PUP/PDN status */
regmap_write(regmap, CS35L41_IRQ1_STATUS1, pup_pdn_mask);
break;
case CS35L41_INT_BOOST:
......@@ -1348,6 +1351,17 @@ int cs35l41_global_enable(struct device *dev, struct regmap *regmap, enum cs35l4
}
EXPORT_SYMBOL_GPL(cs35l41_global_enable);
/*
* To be called after receiving the IRQ Lock interrupt, in order to complete
* any shared boost activation initiated by cs35l41_global_enable().
*/
int cs35l41_mdsync_up(struct regmap *regmap)
{
return regmap_update_bits(regmap, CS35L41_PWR_CTRL3,
CS35L41_SYNC_EN_MASK, CS35L41_SYNC_EN_MASK);
}
EXPORT_SYMBOL_GPL(cs35l41_mdsync_up);
int cs35l41_gpio_config(struct regmap *regmap, struct cs35l41_hw_cfg *hw_cfg)
{
struct cs35l41_gpio_cfg *gpio1 = &hw_cfg->gpio1;
......
......@@ -32,7 +32,6 @@ static int cs35l41_spi_probe(struct spi_device *spi)
const struct regmap_config *regmap_config = &cs35l41_regmap_spi;
struct cs35l41_hw_cfg *hw_cfg = dev_get_platdata(&spi->dev);
struct cs35l41_private *cs35l41;
int ret;
cs35l41 = devm_kzalloc(&spi->dev, sizeof(struct cs35l41_private), GFP_KERNEL);
if (!cs35l41)
......@@ -43,11 +42,9 @@ static int cs35l41_spi_probe(struct spi_device *spi)
spi_set_drvdata(spi, cs35l41);
cs35l41->regmap = devm_regmap_init_spi(spi, regmap_config);
if (IS_ERR(cs35l41->regmap)) {
ret = PTR_ERR(cs35l41->regmap);
dev_err(&spi->dev, "Failed to allocate register map: %d\n", ret);
return ret;
}
if (IS_ERR(cs35l41->regmap))
return dev_err_probe(cs35l41->dev, PTR_ERR(cs35l41->regmap),
"Failed to allocate register map\n");
cs35l41->dev = &spi->dev;
cs35l41->irq = spi->irq;
......@@ -83,7 +80,7 @@ MODULE_DEVICE_TABLE(acpi, cs35l41_acpi_match);
static struct spi_driver cs35l41_spi_driver = {
.driver = {
.name = "cs35l41",
.pm = &cs35l41_pm_ops,
.pm = pm_ptr(&cs35l41_pm_ops),
.of_match_table = of_match_ptr(cs35l41_of_match),
.acpi_match_table = ACPI_PTR(cs35l41_acpi_match),
},
......
......@@ -386,10 +386,18 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
struct cs35l41_private *cs35l41 = data;
unsigned int status[4] = { 0, 0, 0, 0 };
unsigned int masks[4] = { 0, 0, 0, 0 };
int ret = IRQ_NONE;
unsigned int i;
int ret;
pm_runtime_get_sync(cs35l41->dev);
ret = pm_runtime_resume_and_get(cs35l41->dev);
if (ret < 0) {
dev_err(cs35l41->dev,
"pm_runtime_resume_and_get failed in %s: %d\n",
__func__, ret);
return IRQ_NONE;
}
ret = IRQ_NONE;
for (i = 0; i < ARRAY_SIZE(status); i++) {
regmap_read(cs35l41->regmap,
......@@ -459,7 +467,19 @@ static irqreturn_t cs35l41_irq(int irq, void *data)
if (status[2] & CS35L41_PLL_LOCK) {
regmap_write(cs35l41->regmap, CS35L41_IRQ1_STATUS3, CS35L41_PLL_LOCK);
complete(&cs35l41->pll_lock);
if (cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_ACTV ||
cs35l41->hw_cfg.bst_type == CS35L41_SHD_BOOST_PASS) {
ret = cs35l41_mdsync_up(cs35l41->regmap);
if (ret)
dev_err(cs35l41->dev, "MDSYNC-up failed: %d\n", ret);
else
dev_dbg(cs35l41->dev, "MDSYNC-up done\n");
dev_dbg(cs35l41->dev, "PUP-done status: %d\n",
!!(status[0] & CS35L41_PUP_DONE_MASK));
}
ret = IRQ_HANDLED;
}
......@@ -500,11 +520,11 @@ static int cs35l41_main_amp_event(struct snd_soc_dapm_widget *w,
ARRAY_SIZE(cs35l41_pup_patch));
ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type,
1, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running);
1, cs35l41->dsp.cs_dsp.running);
break;
case SND_SOC_DAPM_POST_PMD:
ret = cs35l41_global_enable(cs35l41->dev, cs35l41->regmap, cs35l41->hw_cfg.bst_type,
0, &cs35l41->pll_lock, cs35l41->dsp.cs_dsp.running);
0, cs35l41->dsp.cs_dsp.running);
regmap_multi_reg_write_bypassed(cs35l41->regmap,
cs35l41_pdn_patch,
......@@ -802,10 +822,6 @@ static const struct snd_pcm_hw_constraint_list cs35l41_constraints = {
static int cs35l41_pcm_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct cs35l41_private *cs35l41 = snd_soc_component_get_drvdata(dai->component);
reinit_completion(&cs35l41->pll_lock);
if (substream->runtime)
return snd_pcm_hw_constraint_list(substream->runtime, 0,
SNDRV_PCM_HW_PARAM_RATE,
......@@ -1174,16 +1190,14 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
ret = devm_regulator_bulk_get(cs35l41->dev, CS35L41_NUM_SUPPLIES,
cs35l41->supplies);
if (ret != 0) {
dev_err(cs35l41->dev, "Failed to request core supplies: %d\n", ret);
return ret;
}
if (ret != 0)
return dev_err_probe(cs35l41->dev, ret,
"Failed to request core supplies\n");
ret = regulator_bulk_enable(CS35L41_NUM_SUPPLIES, cs35l41->supplies);
if (ret != 0) {
dev_err(cs35l41->dev, "Failed to enable core supplies: %d\n", ret);
return ret;
}
if (ret != 0)
return dev_err_probe(cs35l41->dev, ret,
"Failed to enable core supplies\n");
/* returning NULL can be an option if in stereo mode */
cs35l41->reset_gpio = devm_gpiod_get_optional(cs35l41->dev, "reset",
......@@ -1195,8 +1209,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
dev_info(cs35l41->dev,
"Reset line busy, assuming shared reset\n");
} else {
dev_err(cs35l41->dev,
"Failed to get reset GPIO: %d\n", ret);
dev_err_probe(cs35l41->dev, ret,
"Failed to get reset GPIO\n");
goto err;
}
}
......@@ -1212,8 +1226,8 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
int_status, int_status & CS35L41_OTP_BOOT_DONE,
1000, 100000);
if (ret) {
dev_err(cs35l41->dev,
"Failed waiting for OTP_BOOT_DONE: %d\n", ret);
dev_err_probe(cs35l41->dev, ret,
"Failed waiting for OTP_BOOT_DONE\n");
goto err;
}
......@@ -1226,13 +1240,13 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
ret = regmap_read(cs35l41->regmap, CS35L41_DEVID, &regid);
if (ret < 0) {
dev_err(cs35l41->dev, "Get Device ID failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Get Device ID failed\n");
goto err;
}
ret = regmap_read(cs35l41->regmap, CS35L41_REVID, &reg_revid);
if (ret < 0) {
dev_err(cs35l41->dev, "Get Revision ID failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Get Revision ID failed\n");
goto err;
}
......@@ -1257,7 +1271,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
ret = cs35l41_otp_unpack(cs35l41->dev, cs35l41->regmap);
if (ret < 0) {
dev_err(cs35l41->dev, "OTP Unpack failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "OTP Unpack failed\n");
goto err;
}
......@@ -1277,13 +1291,13 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
IRQF_ONESHOT | IRQF_SHARED | irq_pol,
"cs35l41", cs35l41);
if (ret != 0) {
dev_err(cs35l41->dev, "Failed to request IRQ: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Failed to request IRQ\n");
goto err;
}
ret = cs35l41_set_pdata(cs35l41);
if (ret < 0) {
dev_err(cs35l41->dev, "Set pdata failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Set pdata failed\n");
goto err;
}
......@@ -1295,8 +1309,6 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
if (ret < 0)
goto err;
init_completion(&cs35l41->pll_lock);
pm_runtime_set_autosuspend_delay(cs35l41->dev, 3000);
pm_runtime_use_autosuspend(cs35l41->dev);
pm_runtime_mark_last_busy(cs35l41->dev);
......@@ -1308,7 +1320,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
&soc_component_dev_cs35l41,
cs35l41_dai, ARRAY_SIZE(cs35l41_dai));
if (ret < 0) {
dev_err(cs35l41->dev, "Register codec failed: %d\n", ret);
dev_err_probe(cs35l41->dev, ret, "Register codec failed\n");
goto err_pm;
}
......@@ -1320,6 +1332,7 @@ int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *
return 0;
err_pm:
pm_runtime_dont_use_autosuspend(cs35l41->dev);
pm_runtime_disable(cs35l41->dev);
pm_runtime_put_noidle(cs35l41->dev);
......@@ -1336,6 +1349,7 @@ EXPORT_SYMBOL_GPL(cs35l41_probe);
void cs35l41_remove(struct cs35l41_private *cs35l41)
{
pm_runtime_get_sync(cs35l41->dev);
pm_runtime_dont_use_autosuspend(cs35l41->dev);
pm_runtime_disable(cs35l41->dev);
regmap_write(cs35l41->regmap, CS35L41_IRQ1_MASK1, 0xFFFFFFFF);
......@@ -1354,7 +1368,7 @@ void cs35l41_remove(struct cs35l41_private *cs35l41)
}
EXPORT_SYMBOL_GPL(cs35l41_remove);
static int __maybe_unused cs35l41_runtime_suspend(struct device *dev)
static int cs35l41_runtime_suspend(struct device *dev)
{
struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
......@@ -1371,7 +1385,7 @@ static int __maybe_unused cs35l41_runtime_suspend(struct device *dev)
return 0;
}
static int __maybe_unused cs35l41_runtime_resume(struct device *dev)
static int cs35l41_runtime_resume(struct device *dev)
{
struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
int ret;
......@@ -1400,7 +1414,7 @@ static int __maybe_unused cs35l41_runtime_resume(struct device *dev)
return 0;
}
static int __maybe_unused cs35l41_sys_suspend(struct device *dev)
static int cs35l41_sys_suspend(struct device *dev)
{
struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
......@@ -1410,7 +1424,7 @@ static int __maybe_unused cs35l41_sys_suspend(struct device *dev)
return 0;
}
static int __maybe_unused cs35l41_sys_suspend_noirq(struct device *dev)
static int cs35l41_sys_suspend_noirq(struct device *dev)
{
struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
......@@ -1420,7 +1434,7 @@ static int __maybe_unused cs35l41_sys_suspend_noirq(struct device *dev)
return 0;
}
static int __maybe_unused cs35l41_sys_resume_noirq(struct device *dev)
static int cs35l41_sys_resume_noirq(struct device *dev)
{
struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
......@@ -1430,7 +1444,7 @@ static int __maybe_unused cs35l41_sys_resume_noirq(struct device *dev)
return 0;
}
static int __maybe_unused cs35l41_sys_resume(struct device *dev)
static int cs35l41_sys_resume(struct device *dev)
{
struct cs35l41_private *cs35l41 = dev_get_drvdata(dev);
......@@ -1440,13 +1454,12 @@ static int __maybe_unused cs35l41_sys_resume(struct device *dev)
return 0;
}
const struct dev_pm_ops cs35l41_pm_ops = {
SET_RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL)
EXPORT_GPL_DEV_PM_OPS(cs35l41_pm_ops) = {
RUNTIME_PM_OPS(cs35l41_runtime_suspend, cs35l41_runtime_resume, NULL)
SET_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend, cs35l41_sys_resume)
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend_noirq, cs35l41_sys_resume_noirq)
SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend, cs35l41_sys_resume)
NOIRQ_SYSTEM_SLEEP_PM_OPS(cs35l41_sys_suspend_noirq, cs35l41_sys_resume_noirq)
};
EXPORT_SYMBOL_GPL(cs35l41_pm_ops);
MODULE_DESCRIPTION("ASoC CS35L41 driver");
MODULE_AUTHOR("David Rhodes, Cirrus Logic Inc, <david.rhodes@cirrus.com>");
......
......@@ -33,7 +33,6 @@ struct cs35l41_private {
int irq;
/* GPIO for /RST */
struct gpio_desc *reset_gpio;
struct completion pll_lock;
};
int cs35l41_probe(struct cs35l41_private *cs35l41, const struct cs35l41_hw_cfg *hw_cfg);
......
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