[v2,6/7] ASoC: cs43130: Allow driver to work without IRQ thread
Commit Message
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(-)
--
2.34.1
Comments
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.
@@ -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;
@@ -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;