[PATCH v2 6/7] ASoC: cs43130: Allow driver to work without IRQ thread
This is to support systems without physical IRQ connection. The device only requires the IRQ for a couple of internal delays, this polling mechanism is a fallback when no IRQ is specified.
Signed-off-by: Maciej Strozek mstrozek@opensource.cirrus.com --- V1 -> V2: Add changelog message
sound/soc/codecs/cs43130.c | 56 +++++++++++++++++++++++++++++++------- sound/soc/codecs/cs43130.h | 1 + 2 files changed, 47 insertions(+), 10 deletions(-)
diff --git a/sound/soc/codecs/cs43130.c b/sound/soc/codecs/cs43130.c index fd39328579fb..1e7c32eedc7b 100644 --- a/sound/soc/codecs/cs43130.c +++ b/sound/soc/codecs/cs43130.c @@ -326,6 +326,43 @@ static int cs43130_set_pll(struct snd_soc_component *component, int pll_id, int return ret; }
+static int cs43130_wait_for_completion(struct cs43130_private *cs43130, struct completion *to_poll, + int time) +{ + int stickies, offset, flag; + int ret = 0; + + if (cs43130->has_irq_line) { + ret = wait_for_completion_timeout(to_poll, msecs_to_jiffies(time)); + } else { + if (to_poll == &cs43130->xtal_rdy) { + offset = 0; + flag = CS43130_XTAL_RDY_INT; + } else if (to_poll == &cs43130->pll_rdy) { + offset = 0; + flag = CS43130_PLL_RDY_INT; + } else if (to_poll == &cs43130->hpload_evt) { + offset = 3; + flag = CS43130_HPLOAD_NO_DC_INT | CS43130_HPLOAD_UNPLUG_INT | + CS43130_HPLOAD_OOR_INT | CS43130_HPLOAD_AC_INT | + CS43130_HPLOAD_DC_INT | CS43130_HPLOAD_ON_INT | + CS43130_HPLOAD_OFF_INT; + } else { + return 0; + } + + ret = regmap_read_poll_timeout(cs43130->regmap, CS43130_INT_STATUS_1 + offset, + stickies, (stickies & flag), + 1000, time * 1000); + + /* + * Return 0 for an timeout/error to be consistent with wait_for_completion_timeout + */ + ret = !ret; + } + return ret; +} + static int cs43130_change_clksrc(struct snd_soc_component *component, enum cs43130_mclk_src_sel src) { @@ -364,8 +401,7 @@ static int cs43130_change_clksrc(struct snd_soc_component *component, CS43130_XTAL_RDY_INT_MASK, 0); regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, CS43130_PDN_XTAL_MASK, 0); - ret = wait_for_completion_timeout(&cs43130->xtal_rdy, - msecs_to_jiffies(100)); + ret = cs43130_wait_for_completion(cs43130, &cs43130->xtal_rdy, 100); regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, CS43130_XTAL_RDY_INT_MASK, 1 << CS43130_XTAL_RDY_INT_SHIFT); @@ -400,8 +436,7 @@ static int cs43130_change_clksrc(struct snd_soc_component *component, CS43130_XTAL_RDY_INT_MASK, 0); regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, CS43130_PDN_XTAL_MASK, 0); - ret = wait_for_completion_timeout(&cs43130->xtal_rdy, - msecs_to_jiffies(100)); + ret = cs43130_wait_for_completion(cs43130, &cs43130->xtal_rdy, 100); regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, CS43130_XTAL_RDY_INT_MASK, 1 << CS43130_XTAL_RDY_INT_SHIFT); @@ -416,8 +451,7 @@ static int cs43130_change_clksrc(struct snd_soc_component *component, CS43130_PLL_RDY_INT_MASK, 0); regmap_update_bits(cs43130->regmap, CS43130_PWDN_CTL, CS43130_PDN_PLL_MASK, 0); - ret = wait_for_completion_timeout(&cs43130->pll_rdy, - msecs_to_jiffies(100)); + ret = cs43130_wait_for_completion(cs43130, &cs43130->pll_rdy, 100); regmap_update_bits(cs43130->regmap, CS43130_INT_MASK_1, CS43130_PLL_RDY_INT_MASK, 1 << CS43130_PLL_RDY_INT_SHIFT); @@ -2040,8 +2074,8 @@ static int cs43130_hpload_proc(struct cs43130_private *cs43130, regmap_multi_reg_write(cs43130->regmap, seq, seq_size);
- ret = wait_for_completion_timeout(&cs43130->hpload_evt, - msecs_to_jiffies(1000)); + ret = cs43130_wait_for_completion(cs43130, &cs43130->hpload_evt, 1000); + regmap_read(cs43130->regmap, CS43130_INT_MASK_4, &msk); if (!ret) { dev_err(cs43130->dev, "Timeout waiting for HPLOAD interrupt\n"); @@ -2545,8 +2579,10 @@ static int cs43130_i2c_probe(struct i2c_client *client) IRQF_ONESHOT | IRQF_TRIGGER_LOW, "cs43130", cs43130); if (ret != 0) { - dev_err(cs43130->dev, "Failed to request IRQ: %d\n", ret); - goto err; + dev_dbg(cs43130->dev, "Failed to request IRQ: %d, will poll instead\n", ret); + cs43130->has_irq_line = 0; + } else { + cs43130->has_irq_line = 1; }
cs43130->mclk_int_src = CS43130_MCLK_SRC_RCO; diff --git a/sound/soc/codecs/cs43130.h b/sound/soc/codecs/cs43130.h index d3f595bbd3ba..dbdb5b262f1b 100644 --- a/sound/soc/codecs/cs43130.h +++ b/sound/soc/codecs/cs43130.h @@ -508,6 +508,7 @@ struct cs43130_private { struct gpio_desc *reset_gpio; unsigned int dev_id; /* codec device ID */ int xtal_ibias; + bool has_irq_line;
/* shared by both DAIs */ struct mutex clk_mutex; -- 2.34.1
On Mon, Nov 20, 2023 at 10:41:53AM +0000, Maciej Strozek wrote:
This is to support systems without physical IRQ connection. The device only requires the IRQ for a couple of internal delays, this polling mechanism is a fallback when no IRQ is specified.
Your changelog here doesn't describe the change - is then intention here to remove the IRQ thread (and presumably open code?) or to make interrupts entirely optional?
I'm assuming there aren't six more patches in this series? The whole point in numbering patches is to order things, if you're only sending one patch you don't need numbering at all.
W dniu pon, 20.11.2023 o godzinie 12∶31 +0000, użytkownik Mark Brown napisał:
On Mon, Nov 20, 2023 at 10:41:53AM +0000, Maciej Strozek wrote:
This is to support systems without physical IRQ connection. The device only requires the IRQ for a couple of internal delays, this polling mechanism is a fallback when no IRQ is specified.
Your changelog here doesn't describe the change - is then intention here to remove the IRQ thread (and presumably open code?) or to make interrupts entirely optional?
I'm assuming there aren't six more patches in this series? The whole point in numbering patches is to order things, if you're only sending one patch you don't need numbering at all.
Apologies, I thought the word "fallback" would describe the intention of making an optional way for the driver to work in absence of IRQ rather than removing the IRQ thread. Will send an amended (and unnumbered) v3.
On Mon, Nov 20, 2023 at 01:51:33PM +0000, Maciej Strozek wrote:
W dniu pon, 20.11.2023 o godzinie 12∶31 +0000, użytkownik Mark Brown
On Mon, Nov 20, 2023 at 10:41:53AM +0000, Maciej Strozek wrote:
This is to support systems without physical IRQ connection. The device only requires the IRQ for a couple of internal delays, this polling mechanism is a fallback when no IRQ is specified.
Your changelog here doesn't describe the change - is then intention here to remove the IRQ thread (and presumably open code?) or to make interrupts entirely optional?
Apologies, I thought the word "fallback" would describe the intention of making an optional way for the driver to work in absence of IRQ rather than removing the IRQ thread. Will send an amended (and unnumbered) v3.
Your subject line says that the patch is changing things to work "without an IRQ thread" - the thread specifically. This conflicts with the additional text you've added in the body of the changelog which talks about removing the need for an interrupt entirely.
participants (2)
-
Maciej Strozek
-
Mark Brown