[PATCH] ASoC: core: init delayed_work for codec-codec links

2013-07-31 Thread Richard Fitzgerald
If soc_probe_link_dais() finds a codec-codec link it
skips creating a compress or pcm stream and links the
DAIs together. But it must also init the delayed_work
otherwise shutting down the DAI chain will fault when
calling flush_delayed_work_sync() on the linked DAI.

Pointing it to a dummy work callback is cleaner than taking
special cases in the code to bypass the flush_delayed_work_sync().

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/soc-core.c |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4489c5b..bbe136c 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -199,6 +199,10 @@ static ssize_t pmdown_time_set(struct device *dev,
return count;
 }
 
+static void dummy_delayed_work(struct work_struct *work)
+{
+}
+
 static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
 
 #ifdef CONFIG_DEBUG_FS
@@ -1428,6 +1432,8 @@ static int soc_probe_link_dais(struct snd_soc_card *card, 
int num, int order)
return ret;
}
} else {
+   INIT_DELAYED_WORK(&rtd->delayed_work, 
dummy_delayed_work);
+
/* link the DAI widgets */
play_w = codec_dai->playback_widget;
capture_w = cpu_dai->capture_widget;
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ASoC: core: init delayed_work for codec-codec links

2013-08-01 Thread Richard Fitzgerald
On Wed, Jul 31, 2013 at 02:25:22PM +0100, Mark Brown wrote:
> On Wed, Jul 31, 2013 at 02:16:44PM +0100, Richard Fitzgerald wrote:
> 
> > Pointing it to a dummy work callback is cleaner than taking
> > special cases in the code to bypass the flush_delayed_work_sync().
> 
> Why is this better than pointing at the normal work that you'd expect to
> be used there?

By 'normal work' do you mean the close_delayed_work() used for
standard PCM DAIs?
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH] ASoC: core: init delayed_work for codec-codec links

2013-08-01 Thread Richard Fitzgerald
On Thu, Aug 01, 2013 at 04:23:56PM +0100, Mark Brown wrote:
> On Thu, Aug 01, 2013 at 04:13:52PM +0100, Richard Fitzgerald wrote:
> > On Wed, Jul 31, 2013 at 02:25:22PM +0100, Mark Brown wrote:
> 
> > > Why is this better than pointing at the normal work that you'd expect to
> > > be used there?
> 
> > By 'normal work' do you mean the close_delayed_work() used for
> > standard PCM DAIs?
> 
> Yes - making up this empty work doesn't seem like a robust approach.

Yeah, I think the problem is more one of bad naming. I should define that
function as the delayed work for codec-2-codec links, it just happens
that we don't currently have to do anything for them. The only thing
the pcm close_delayed_work() does is to send a SND_SOC_DAPM_STREAM_STOP
but for c2c links we never send a start anyway.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] ASoC: core: init delayed_work for codec-codec links

2013-08-02 Thread Richard Fitzgerald
We must init the delayed_work for codec-codec links
otherwise shutting down the DAI chain will fault when
calling flush_delayed_work_sync() on the linked DAI.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/soc-core.c |   11 +++
 1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4489c5b..e649efe 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -199,6 +199,14 @@ static ssize_t pmdown_time_set(struct device *dev,
return count;
 }
 
+static void codec2codec_close_delayed_work(struct work_struct *work)
+{
+   /* No action required.
+* C2C links only represent a hardware connection and currently
+* we assume that we don't have to explicitly start or stop them
+*/
+}
+
 static DEVICE_ATTR(pmdown_time, 0644, pmdown_time_show, pmdown_time_set);
 
 #ifdef CONFIG_DEBUG_FS
@@ -1428,6 +1436,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, 
int num, int order)
return ret;
}
} else {
+   INIT_DELAYED_WORK(&rtd->delayed_work,
+   codec2codec_close_delayed_work);
+
/* link the DAI widgets */
play_w = codec_dai->playback_widget;
capture_w = cpu_dai->capture_widget;
-- 
1.7.2.5
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [alsa-devel] [PATCH v3] ASoC: core: init delayed_work for codec-codec links

2013-08-02 Thread Richard Fitzgerald
We must init the delayed_work for codec-codec links
otherwise shutting down the DAI chain will fault when
calling flush_delayed_work_sync() on the linked DAI.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/soc-core.c |7 +++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4489c5b..450dbf4 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -530,6 +530,10 @@ static int soc_ac97_dev_register(struct snd_soc_codec 
*codec)
 }
 #endif
 
+static void codec2codec_close_delayed_work(struct work_struct *work)
+{
+}
+
 #ifdef CONFIG_PM_SLEEP
 /* powers down audio subsystem for suspend */
 int snd_soc_suspend(struct device *dev)
@@ -1428,6 +1432,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, 
int num, int order)
return ret;
}
} else {
+   INIT_DELAYED_WORK(&rtd->delayed_work,
+   codec2codec_close_delayed_work);
+
/* link the DAI widgets */
play_w = codec_dai->playback_widget;
capture_w = cpu_dai->capture_widget;
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [alsa-devel] [PATCH v4] ASoC: core: init delayed_work for codec-codec links

2013-08-05 Thread Richard Fitzgerald
We must init the delayed_work for codec-codec links
otherwise shutting down the DAI chain will fault when
calling flush_delayed_work_sync() on the linked DAI.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/soc-core.c |   12 
 1 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 4489c5b..c57d5f1 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -530,6 +530,15 @@ static int soc_ac97_dev_register(struct snd_soc_codec 
*codec)
 }
 #endif
 
+static void codec2codec_close_delayed_work(struct work_struct *work)
+{
+   /* Currently nothing to do for c2c links
+* Since c2c links are internal nodes in the DAPM graph and
+* don't interface with the outside world or application layer
+* we don't have to do any special handling on close.
+*/
+}
+
 #ifdef CONFIG_PM_SLEEP
 /* powers down audio subsystem for suspend */
 int snd_soc_suspend(struct device *dev)
@@ -1428,6 +1437,9 @@ static int soc_probe_link_dais(struct snd_soc_card *card, 
int num, int order)
return ret;
}
} else {
+   INIT_DELAYED_WORK(&rtd->delayed_work,
+   codec2codec_close_delayed_work);
+
/* link the DAI widgets */
play_w = codec_dai->playback_widget;
capture_w = cpu_dai->capture_widget;
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 2/2] of: Add array read functions with min/max size limits

2016-09-08 Thread Richard Fitzgerald
On Thu, 2016-09-08 at 09:46 -0500, Rob Herring wrote:
> On Tue, Sep 6, 2016 at 10:02 AM, Richard Fitzgerald
>  wrote:
> > Add a new set of array reading functions that take a minimum and
> > maximum size limit and will fail if the property size is not within
> > the size limits. This makes it more convenient for drivers that
> > use variable-size DT arrays which must be bounded at both ends -
> > data must be at least N entries but must not overflow the array
> > it is being copied into. It is also more efficient than making this
> > functionality out of existing public functions and avoids duplication.
> >
> > The existing array functions have been left in the API, since there
> > are a very large number of clients of those functions and their
> > existing functionality is still useful. This avoids turning a small
> > API improvement into a major kernel rework.
> 
> Thanks for doing this.
> 
> > Signed-off-by: Richard Fitzgerald 
> > ---
> >  drivers/of/base.c  | 206 
> > ++---
> >  include/linux/of.h |  16 +
> >  2 files changed, 180 insertions(+), 42 deletions(-)
> >
> > diff --git a/drivers/of/base.c b/drivers/of/base.c
> > index b853737..cbad5cf 100644
> > --- a/drivers/of/base.c
> > +++ b/drivers/of/base.c
> > @@ -1209,6 +1209,47 @@ int of_property_read_u32_index(const struct 
> > device_node *np,
> >  EXPORT_SYMBOL_GPL(of_property_read_u32_index);
> >
> >  /**
> > + * of_property_read_variable_u8_array - Find and read an array of u8 from a
> > + * property, with bounds on the minimum and maximum array size.
> > + *
> > + * @np:device node from which the property value is to be 
> > read.
> > + * @propname:  name of the property to be searched.
> > + * @out_values:pointer to return value, modified only if return 
> > value is 0.
> > + * @sz_min:minimum number of array elements to read
> > + * @sz_max:maximum number of array elements to read
> > + *
> > + * Search for a property in a device node and read 8-bit value(s) from
> > + * it. Returns 0 on success, -EINVAL if the property does not exist,
> > + * -ENODATA if property does not have a value, and -EOVERFLOW if the
> > + * property data is smaller than sz_min or longer than sz_max.
> > + *
> > + * dts entry of array should be like:
> > + * property = /bits/ 8 <0x50 0x60 0x70>;
> > + *
> > + * The out_values is modified only if a valid u8 value can be decoded.
> > + */
> > +int of_property_read_variable_u8_array(const struct device_node *np,
> > +   const char *propname, u8 
> > *out_values,
> > +   size_t sz_min, size_t sz_max)
> > +{
> > +   size_t sz;
> > +   const u8 *val = of_find_property_value_of_size(np, propname,
> > +   (sz_min * 
> > sizeof(*out_values)),
> > +   (sz_max * 
> > sizeof(*out_values)),
> > +   &sz);
> > +
> > +   if (IS_ERR(val))
> > +   return PTR_ERR(val);
> > +
> > +   sz /= sizeof(*out_values);
> > +
> > +   while (sz--)
> > +   *out_values++ = *val++;
> > +   return 0;
> 
> I think this needs to return the actual number of elements filled.

You're right.

> 
> > +}
> > +EXPORT_SYMBOL_GPL(of_property_read_variable_u8_array);
> > +
> > +/**
> >   * of_property_read_u8_array - Find and read an array of u8 from a 
> > property.
> >   *
> >   * @np:device node from which the property value is to be 
> > read.
> > @@ -1229,21 +1270,53 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
> >  int of_property_read_u8_array(const struct device_node *np,
> > const char *propname, u8 *out_values, size_t sz)
> >  {
> > -   const u8 *val = of_find_property_value_of_size(np, propname,
> > -   (sz * sizeof(*out_values)),
> > -   0,
> > -   NULL);
> > -
> > -   if (IS_ERR(val))
> > -   return PTR_ERR(val);
> > -
> > -   while (sz--)
> > -   *out_values++ = *val++;
> > -   return 0;
> > +   return of_property_read_variable_u8_array(np, propname, out_values,
> > + sz, 0);
> 
> This should be min and max both set to sz.

Passing 0 as max preserves the existing behaviour of these functions of
only requiring the array to be at least sz long, but not caring if it's
longer.

> 
> All these can be made a static inline and then we don't need the
> declaration and the dummy empty function. Changing the return value
> here will complicate things as this function should maintain the
> existing return values (i.e. 0 for success).
> 
> Similar comments for the other flavors.
> 
> Rob

I'll push a new version of these patches.





Re: [PATCH 2/2] of: Add array read functions with min/max size limits

2016-09-08 Thread Richard Fitzgerald
On Thu, 2016-09-08 at 10:38 -0500, Rob Herring wrote:
> On Thu, Sep 8, 2016 at 10:34 AM, Richard Fitzgerald
>  wrote:
> > On Thu, 2016-09-08 at 09:46 -0500, Rob Herring wrote:
> >> On Tue, Sep 6, 2016 at 10:02 AM, Richard Fitzgerald
> >>  wrote:
> >> > Add a new set of array reading functions that take a minimum and
> >> > maximum size limit and will fail if the property size is not within
> >> > the size limits. This makes it more convenient for drivers that
> >> > use variable-size DT arrays which must be bounded at both ends -
> >> > data must be at least N entries but must not overflow the array
> >> > it is being copied into. It is also more efficient than making this
> >> > functionality out of existing public functions and avoids duplication.
> >> >
> >> > The existing array functions have been left in the API, since there
> >> > are a very large number of clients of those functions and their
> >> > existing functionality is still useful. This avoids turning a small
> >> > API improvement into a major kernel rework.
> 
> [...]
> 
> >> > @@ -1229,21 +1270,53 @@ EXPORT_SYMBOL_GPL(of_property_read_u32_index);
> >> >  int of_property_read_u8_array(const struct device_node *np,
> >> > const char *propname, u8 *out_values, size_t sz)
> >> >  {
> >> > -   const u8 *val = of_find_property_value_of_size(np, propname,
> >> > -   (sz * 
> >> > sizeof(*out_values)),
> >> > -   0,
> >> > -   NULL);
> >> > -
> >> > -   if (IS_ERR(val))
> >> > -   return PTR_ERR(val);
> >> > -
> >> > -   while (sz--)
> >> > -   *out_values++ = *val++;
> >> > -   return 0;
> >> > +   return of_property_read_variable_u8_array(np, propname, 
> >> > out_values,
> >> > + sz, 0);
> >>
> >> This should be min and max both set to sz.
> >
> > Passing 0 as max preserves the existing behaviour of these functions of
> > only requiring the array to be at least sz long, but not caring if it's
> > longer.
> 
> Yes, I was just writing to say that after reading patch 1 more carefully.
> 

Although at the same time I was realizing that actually my code is
broken for that and somehow I missed validating it in my testing.
The new functions validate the min and max against the DT entry size and
copy the actual number of elements. The old functions effectively
validate only the min and return that number of elements.

I'm just considering whether it's worth fixing my new functions to keep
the intention that max=0 duplicates the old behaviour, or not bother and
just keep the old functions.

> Rob




Re: [PATCH v3] mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config

2016-09-13 Thread Richard Fitzgerald
On Mon, 2016-09-12 at 11:53 -0500, Rob Herring wrote:
> On Mon, Sep 05, 2016 at 12:56:25PM +0100, Richard Fitzgerald wrote:
> > This patch adds DT settings for the max_channels_clocked, spk_fmt and
> > spk_mute pdata.
> > 
> > Signed-off-by: Richard Fitzgerald 
> > ---
> >  Documentation/devicetree/bindings/mfd/arizona.txt | 18 ++
> >  drivers/mfd/arizona-core.c| 30 
> > +++
> >  2 files changed, 48 insertions(+)
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
> > b/Documentation/devicetree/bindings/mfd/arizona.txt
> > index a6e2ea41..8f2e282 100644
> > --- a/Documentation/devicetree/bindings/mfd/arizona.txt
> > +++ b/Documentation/devicetree/bindings/mfd/arizona.txt
> > @@ -85,6 +85,24 @@ Optional properties:
> >  present, the number of values should be less than or equal to the
> >  number of inputs, unspecified inputs will use the chip default.
> >  
> > +  - wlf,max-channels-clocked : The maximum number of channels to be 
> > clocked on
> > +each AIF, useful for I2S systems with multiple data lines being 
> > mastered.
> > +Specify one cell for each AIF to be configured, specify zero for AIFs 
> > that
> > +should be handled normally.
> > +If present, number of cells must be less than or equal to the number of
> > +AIFs. If less than the number of AIFs, for cells that have not been
> > +specified the corresponding AIFs will be treated as default setting.
> > +
> > +  - wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and 
> > OUT6).
> > +See the datasheet for values.
> > +The second cell is ignored for codecs that do not have OUT6 (wm5102, 
> > wm8997,
> > +  wm8998, wm1814)
> > +
> > +  - wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 
> > and OUT6).
> > +See the datasheet for values.
> > +The second cell is ignored for codecs that do not have OUT6 (wm5102, 
> > wm8997,
> > +wm8998, wm1814)
> > +
> >- DCVDD-supply, MICVDD-supply : Power supplies, only need to be 
> > specified if
> >  they are being externally supplied. As covered in
> >  Documentation/devicetree/bindings/regulator/regulator.txt
> > diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
> > index fa267fa..c621c46 100644
> > --- a/drivers/mfd/arizona-core.c
> > +++ b/drivers/mfd/arizona-core.c
> > @@ -813,6 +813,7 @@ static int arizona_of_get_core_pdata(struct arizona 
> > *arizona)
> > struct property *prop;
> > const __be32 *cur;
> > u32 val;
> > +   u32 pdm_val[ARIZONA_MAX_PDM_SPK];
> > int ret, i;
> > int count = 0;
> >  
> > @@ -869,6 +870,35 @@ static int arizona_of_get_core_pdata(struct arizona 
> > *arizona)
> > count++;
> > }
> >  
> > +   count = 0;
> > +   of_property_for_each_u32(arizona->dev->of_node,
> > +"wlf,max-channels-clocked",
> > +prop, cur, val) {
> > +   if (count == ARRAY_SIZE(pdata->max_channels_clocked))
> > +   break;
> > +
> > +   pdata->max_channels_clocked[count] = val;
> > +   count++;
> > +   }
> > +
> > +   ret = of_property_read_u32_array(arizona->dev->of_node,
> > +"wlf,spk-fmt",
> > +pdm_val,
> > +ARRAY_SIZE(pdm_val));
> 
> Why are you using this intermediate buffer?
> 

Because targets are not u32

> > +
> > +   if (ret >= 0)
> > +   for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
> > +   pdata->spk_fmt[count] = pdm_val[count];
> > +
> > +   ret = of_property_read_u32_array(arizona->dev->of_node,
> > +"wlf,spk-mute",
> > +pdm_val,
> > +ARRAY_SIZE(pdm_val));
> > +
> > +   if (ret >= 0)
> > +   for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
> 
> s/spk_fmt/spk_mute/
> 

Damn!, I read and re-read and re-re-read that code so many times to make
sure I had the right names

> > +   pdata->spk_mute[count] = pdm_val[count];
> > +
> > return 0;
> >  }
> >  
> > -- 
> > 1.9.1
> > 




[PATCH v4] mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config

2016-09-13 Thread Richard Fitzgerald
This patch adds DT settings for the max_channels_clocked, spk_fmt and
spk_mute pdata.

Signed-off-by: Richard Fitzgerald 
---
 Documentation/devicetree/bindings/mfd/arizona.txt | 18 ++
 drivers/mfd/arizona-core.c| 30 +++
 2 files changed, 48 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
b/Documentation/devicetree/bindings/mfd/arizona.txt
index a6e2ea41..8f2e282 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -85,6 +85,24 @@ Optional properties:
 present, the number of values should be less than or equal to the
 number of inputs, unspecified inputs will use the chip default.
 
+  - wlf,max-channels-clocked : The maximum number of channels to be clocked on
+each AIF, useful for I2S systems with multiple data lines being mastered.
+Specify one cell for each AIF to be configured, specify zero for AIFs that
+should be handled normally.
+If present, number of cells must be less than or equal to the number of
+AIFs. If less than the number of AIFs, for cells that have not been
+specified the corresponding AIFs will be treated as default setting.
+
+  - wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and 
OUT6).
+See the datasheet for values.
+The second cell is ignored for codecs that do not have OUT6 (wm5102, 
wm8997,
+  wm8998, wm1814)
+
+  - wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and 
OUT6).
+See the datasheet for values.
+The second cell is ignored for codecs that do not have OUT6 (wm5102, 
wm8997,
+wm8998, wm1814)
+
   - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
 they are being externally supplied. As covered in
 Documentation/devicetree/bindings/regulator/regulator.txt
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index b95ff2d..3687e5f 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -760,6 +760,7 @@ static int arizona_of_get_core_pdata(struct arizona 
*arizona)
struct property *prop;
const __be32 *cur;
u32 val;
+   u32 pdm_val[ARIZONA_MAX_PDM_SPK];
int ret, i;
int count = 0;
 
@@ -816,6 +817,35 @@ static int arizona_of_get_core_pdata(struct arizona 
*arizona)
count++;
}
 
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node,
+"wlf,max-channels-clocked",
+prop, cur, val) {
+   if (count == ARRAY_SIZE(pdata->max_channels_clocked))
+   break;
+
+   pdata->max_channels_clocked[count] = val;
+   count++;
+   }
+
+   ret = of_property_read_u32_array(arizona->dev->of_node,
+"wlf,spk-fmt",
+pdm_val,
+ARRAY_SIZE(pdm_val));
+
+   if (ret >= 0)
+   for (count = 0; count < ARRAY_SIZE(pdata->spk_fmt); ++count)
+   pdata->spk_fmt[count] = pdm_val[count];
+
+   ret = of_property_read_u32_array(arizona->dev->of_node,
+"wlf,spk-mute",
+pdm_val,
+ARRAY_SIZE(pdm_val));
+
+   if (ret >= 0)
+   for (count = 0; count < ARRAY_SIZE(pdata->spk_mute); ++count)
+   pdata->spk_mute[count] = pdm_val[count];
+
return 0;
 }
 
-- 
1.9.1



[PATCH v2] mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config

2016-08-31 Thread Richard Fitzgerald
This patch adds DT settings for the max_channels_clocked, spk_fmt and
spk_mute pdata.

Signed-off-by: Richard Fitzgerald 
---
 Documentation/devicetree/bindings/mfd/arizona.txt | 11 
 drivers/mfd/arizona-core.c| 31 +++
 2 files changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
b/Documentation/devicetree/bindings/mfd/arizona.txt
index a6e2ea41..6eaf006 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -85,6 +85,17 @@ Optional properties:
 present, the number of values should be less than or equal to the
 number of inputs, unspecified inputs will use the chip default.
 
+  - wlf,max-channels-clocked : The maximum number of channels to be clocked on
+each AIF, useful for I2S systems with multiple data lines being mastered.
+Specify one cell for each AIF, specify zero for AIFs that should be handled
+normally.
+
+  - wlf,spk-fmt : PDM speaker data format, must contain 2 cells (OUT5 and 
OUT6).
+See the datasheet for values.
+
+  - wlf,spk-mute : PDM speaker mute setting, must contain 2 cells (OUT5 and 
OUT6).
+See the datasheet for values.
+
   - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
 they are being externally supplied. As covered in
 Documentation/devicetree/bindings/regulator/regulator.txt
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index b95ff2d..36a9633 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -816,6 +816,37 @@ static int arizona_of_get_core_pdata(struct arizona 
*arizona)
count++;
}
 
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node,
+"wlf,max-channels-clocked",
+prop, cur, val) {
+   if (count == ARRAY_SIZE(pdata->max_channels_clocked))
+   break;
+
+   pdata->max_channels_clocked[count] = val;
+   count++;
+   }
+
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node, "wlf,spk-fmt", prop,
+cur, val) {
+   if (count == ARRAY_SIZE(pdata->spk_fmt))
+   break;
+
+   pdata->spk_fmt[count] = val;
+   count++;
+   }
+
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node, "wlf,spk-mute", prop,
+cur, val) {
+   if (count == ARRAY_SIZE(pdata->spk_mute))
+   break;
+
+   pdata->spk_mute[count] = val;
+   count++;
+   }
+
return 0;
 }
 
-- 
1.9.1



Re: [PATCH v2] mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config

2016-09-02 Thread Richard Fitzgerald
On Fri, 2016-09-02 at 10:34 -0500, Rob Herring wrote:
> On Wed, Aug 31, 2016 at 10:25:43AM +0100, Richard Fitzgerald wrote:
> > This patch adds DT settings for the max_channels_clocked, spk_fmt and
> > spk_mute pdata.
> > 
> > Signed-off-by: Richard Fitzgerald 
> > ---
> >  Documentation/devicetree/bindings/mfd/arizona.txt | 11 
> 
> Binding looks fine, but...
> 
> >  drivers/mfd/arizona-core.c| 31 
> > +++
> >  2 files changed, 42 insertions(+)
> 
> > diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
> > index b95ff2d..36a9633 100644
> > --- a/drivers/mfd/arizona-core.c
> > +++ b/drivers/mfd/arizona-core.c
> > @@ -816,6 +816,37 @@ static int arizona_of_get_core_pdata(struct arizona 
> > *arizona)
> > count++;
> > }
> >  
> > +   count = 0;
> > +   of_property_for_each_u32(arizona->dev->of_node,
> > +"wlf,max-channels-clocked",
> > +prop, cur, val) {
> > +   if (count == ARRAY_SIZE(pdata->max_channels_clocked))
> > +   break;
> > +
> > +   pdata->max_channels_clocked[count] = val;
> > +   count++;
> > +   }
> 
> of_property_read_u32_array doesn't work for you?

No, it doesn't, because it doesn't read a variable-sized array.

> 
> > +
> > +   count = 0;
> > +   of_property_for_each_u32(arizona->dev->of_node, "wlf,spk-fmt", prop,
> > +cur, val) {
> > +   if (count == ARRAY_SIZE(pdata->spk_fmt))
> > +   break;
> > +
> > +   pdata->spk_fmt[count] = val;
> > +   count++;
> > +   }
> > +
> > +   count = 0;
> > +   of_property_for_each_u32(arizona->dev->of_node, "wlf,spk-mute", prop,
> > +cur, val) {
> > +   if (count == ARRAY_SIZE(pdata->spk_mute))
> > +   break;
> > +
> > +   pdata->spk_mute[count] = val;
> > +   count++;
> > +   }
> > +
> > return 0;
> >  }
> >  
> > -- 
> > 1.9.1
> > 
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree" in
> > the body of a message to majord...@vger.kernel.org
> > More majordomo info at  http://vger.kernel.org/majordomo-info.html




[PATCH] mfd: arizona: Add DT options for max_channels_clocked and PDM speaker config

2016-08-25 Thread Richard Fitzgerald
This patch adds DT settings for the max_channels_clocked, spk_fmt and
spk_mute pdata.

Signed-off-by: Richard Fitzgerald 
---
 Documentation/devicetree/bindings/mfd/arizona.txt | 11 
 drivers/mfd/arizona-core.c| 31 +++
 2 files changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
b/Documentation/devicetree/bindings/mfd/arizona.txt
index a6e2ea41..6eaf006 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -85,6 +85,17 @@ Optional properties:
 present, the number of values should be less than or equal to the
 number of inputs, unspecified inputs will use the chip default.
 
+  - wlf,max-channels-clocked : The maximum number of channels to be clocked on
+each AIF, useful for I2S systems with multiple data lines being mastered.
+Specify one cell for each AIF, specify zero for AIFs that should be handled
+normally.
+
+  - wlf,spk_fmt : PDM speaker data format, must contain 2 cells (OUT5 and 
OUT6).
+See the datasheet for values.
+
+  - wlf,spk_mute : PDM speaker mute setting, must contain 2 cells (OUT5 and 
OUT6).
+See the datasheet for values.
+
   - DCVDD-supply, MICVDD-supply : Power supplies, only need to be specified if
 they are being externally supplied. As covered in
 Documentation/devicetree/bindings/regulator/regulator.txt
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index b95ff2d..36a9633 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -816,6 +816,37 @@ static int arizona_of_get_core_pdata(struct arizona 
*arizona)
count++;
}
 
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node,
+"wlf,max-channels-clocked",
+prop, cur, val) {
+   if (count == ARRAY_SIZE(pdata->max_channels_clocked))
+   break;
+
+   pdata->max_channels_clocked[count] = val;
+   count++;
+   }
+
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node, "wlf,spk-fmt", prop,
+cur, val) {
+   if (count == ARRAY_SIZE(pdata->spk_fmt))
+   break;
+
+   pdata->spk_fmt[count] = val;
+   count++;
+   }
+
+   count = 0;
+   of_property_for_each_u32(arizona->dev->of_node, "wlf,spk-mute", prop,
+cur, val) {
+   if (count == ARRAY_SIZE(pdata->spk_mute))
+   break;
+
+   pdata->spk_mute[count] = val;
+   count++;
+   }
+
return 0;
 }
 
-- 
1.9.1



[PATCH] ASoC: arizona: Wait for resume before enabling FLL

2016-08-25 Thread Richard Fitzgerald
When enabling an FLL use pm_runtime_get_sync() instead of
pm_runtime_get() to ensure that all the register settings
have been written out and the codec is powered-up before
we write the enable bit.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/arizona.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/arizona.c b/sound/soc/codecs/arizona.c
index ecfdbfc..8b8f2d2 100644
--- a/sound/soc/codecs/arizona.c
+++ b/sound/soc/codecs/arizona.c
@@ -2268,7 +2268,7 @@ static int arizona_enable_fll(struct arizona_fll *fll)
 ARIZONA_FLL1_SYNC_BW);
 
if (!already_enabled)
-   pm_runtime_get(arizona->dev);
+   pm_runtime_get_sync(arizona->dev);
 
regmap_update_bits_async(arizona->regmap, fll->base + 1,
 ARIZONA_FLL1_ENA, ARIZONA_FLL1_ENA);
-- 
1.9.1



[PATCH] ASoC: wm_adsp: Fix typo in algorithm list warning message

2017-05-26 Thread Richard Fitzgerald
The list terminator is 0xbedead but the message warning if it
wasn't found was showing that 0xbeadead was expected.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/wm_adsp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 5aff83b..65c059b5 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -1888,7 +1888,7 @@ static void *wm_adsp_read_algs(struct wm_adsp *dsp, 
size_t n_algs,
}
 
if (be32_to_cpu(val) != 0xbedead)
-   adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n",
+   adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n",
  pos + len, be32_to_cpu(val));
 
alg = kzalloc(len * 2, GFP_KERNEL | GFP_DMA);
-- 
1.9.1



[PATCH 2/3] gpio: arizona: Support Cirrus Logic CS47L24 and WM1831

2015-10-19 Thread Richard Fitzgerald
The CS47L24 and WM1831 codecs only have two GPIO lines, but are
otherwise similar to the WM8280.

Signed-off-by: Richard Fitzgerald 
---
 drivers/gpio/gpio-arizona.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c
index ca00273..624ea54 100644
--- a/drivers/gpio/gpio-arizona.c
+++ b/drivers/gpio/gpio-arizona.c
@@ -122,6 +122,10 @@ static int arizona_gpio_probe(struct platform_device *pdev)
case WM1814:
arizona_gpio->gpio_chip.ngpio = 5;
break;
+   case WM1831:
+   case CS47L24:
+   arizona_gpio->gpio_chip.ngpio = 2;
+   break;
default:
dev_err(&pdev->dev, "Unknown chip variant %d\n",
arizona->type);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 3/3] ASoC: cs47l24: Add driver for Cirrus Logic CS47L24 and WM1831 codecs

2015-10-19 Thread Richard Fitzgerald
This patch adds support for the Cirrus Logic CS47L24 and WM1831 codecs.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/Kconfig   |8 +
 sound/soc/codecs/Makefile  |2 +
 sound/soc/codecs/cs47l24.c | 1148 
 sound/soc/codecs/cs47l24.h |   23 +
 4 files changed, 1181 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l24.c
 create mode 100644 sound/soc/codecs/cs47l24.h

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index cfdafc4..4d229d0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -134,6 +134,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM5100 if I2C
select SND_SOC_WM5102 if MFD_WM5102
select SND_SOC_WM5110 if MFD_WM5110
+   select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_WM8350 if MFD_WM8350
select SND_SOC_WM8400 if MFD_WM8400
select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -197,10 +198,12 @@ config SND_SOC_ARIZONA
tristate
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
+   default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM8997=y
default y if SND_SOC_WM8998=y
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
+   default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM8997=m
default m if SND_SOC_WM8998=m
 
@@ -213,9 +216,11 @@ config SND_SOC_WM_ADSP
tristate
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
+   default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM2200=y
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
+   default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM2200=m
 
 config SND_SOC_AB8500_CODEC
@@ -733,6 +738,9 @@ config SND_SOC_WM5102
 config SND_SOC_WM5110
tristate
 
+config SND_SOC_CS47L24
+   tristate "TEST cs47l24"
+
 config SND_SOC_WM8350
tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f632fc4..45877b8 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -138,6 +138,7 @@ snd-soc-wm2200-objs := wm2200.o
 snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
 snd-soc-wm5102-objs := wm5102.o
 snd-soc-wm5110-objs := wm5110.o
+snd-soc-cs47l24-objs := cs47l24.o
 snd-soc-wm8350-objs := wm8350.o
 snd-soc-wm8400-objs := wm8400.o
 snd-soc-wm8510-objs := wm8510.o
@@ -329,6 +330,7 @@ obj-$(CONFIG_SND_SOC_WM2200)+= snd-soc-wm2200.o
 obj-$(CONFIG_SND_SOC_WM5100)   += snd-soc-wm5100.o
 obj-$(CONFIG_SND_SOC_WM5102)   += snd-soc-wm5102.o
 obj-$(CONFIG_SND_SOC_WM5110)   += snd-soc-wm5110.o
+obj-$(CONFIG_SND_SOC_CS47L24)  += snd-soc-cs47l24.o
 obj-$(CONFIG_SND_SOC_WM8350)   += snd-soc-wm8350.o
 obj-$(CONFIG_SND_SOC_WM8400)   += snd-soc-wm8400.o
 obj-$(CONFIG_SND_SOC_WM8510)   += snd-soc-wm8510.o
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
new file mode 100644
index 000..dc5ae7f
--- /dev/null
+++ b/sound/soc/codecs/cs47l24.c
@@ -0,0 +1,1148 @@
+/*
+ * cs47l24.h  --  ALSA SoC Audio driver for Cirrus Logic CS47L24
+ *
+ * Copyright 2015 Cirrus Logic Inc.
+ *
+ * Author: Richard Fitzgerald 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "arizona.h"
+#include "wm_adsp.h"
+#include "cs47l24.h"
+
+struct cs47l24_priv {
+   struct arizona_priv core;
+   struct arizona_fll fll[2];
+};
+
+static const struct wm_adsp_region cs47l24_dsp2_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x20 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x28 },
+   { .type = WMFW_ADSP2_XM, .base = 0x29 },
+   { .type = WMFW_ADSP2_YM, .base = 0x2a8000 },
+};
+
+static const struct wm_adsp_region cs47l24_dsp3_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x30 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x38 },
+   { .type = WMFW_ADSP2_XM, .base = 0x39 },
+   { .type = WMFW_ADSP2_YM, .base = 0x3a8000 },
+};
+
+static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
+   cs47l24_dsp2_regions,
+   cs47l24_dsp3_regions,
+};
+
+static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
+static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
+static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);
+static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
+
+#define CS47L24_NG_SRC(name, base) \
+   SOC_SINGLE(name " NG HPOUT1L Switch",  base,  0, 1, 0), \
+   SOC_SINGLE(name " NG HPOUT1R Switch",  base,  1, 1, 0), \
+   SOC_SINGLE(name " NG SPKOUT Switch",  base,  6, 1, 0)
+
+static const

[PATCH 1/3] mfd: arizona: Support Cirrus Logic CS47L24 and WM1831

2015-10-19 Thread Richard Fitzgerald
This patch adds the regmap configuration tables and
core MFD handling for the CS47L24 and WM1831 codecs.

Note that compared to the other Arizona codecs, these devices
do not have an LDO1 or micsupp regulators, extcon driver, or
the DCVDD isolation control.

Signed-off-by: Richard Fitzgerald 
---
 Documentation/devicetree/bindings/mfd/arizona.txt |4 +-
 drivers/mfd/Kconfig   |   19 +-
 drivers/mfd/Makefile  |3 +
 drivers/mfd/arizona-core.c|   72 +-
 drivers/mfd/arizona-irq.c |   40 +-
 drivers/mfd/arizona-spi.c |7 +
 drivers/mfd/arizona.h |4 +
 drivers/mfd/cs47l24-tables.c  | 1629 +
 include/linux/mfd/arizona/core.h  |3 +
 9 files changed, 1756 insertions(+), 25 deletions(-)
 create mode 100644 drivers/mfd/cs47l24-tables.c

diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
b/Documentation/devicetree/bindings/mfd/arizona.txt
index a8fee60..73f28fa 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -1,4 +1,4 @@
-Wolfson Arizona class audio SoCs
+Cirrus Logic/Wolfson Microelectronics Arizona class audio SoCs
 
 These devices are audio SoCs with extensive digital capabilites and a range
 of analogue I/O.
@@ -12,6 +12,8 @@ Required properties:
 "wlf,wm8997"
 "wlf,wm8998"
 "wlf,wm1814"
+"wlf,wm1831"
+"cirrus,cs47l24"
 
   - reg : I2C slave address when connected using I2C, chip select number when
 using SPI.
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4d92df6..d25bbb3 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1370,24 +1370,24 @@ config MFD_ARIZONA
bool
 
 config MFD_ARIZONA_I2C
-   tristate "Wolfson Microelectronics Arizona platform with I2C"
+   tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with 
I2C"
select MFD_ARIZONA
select MFD_CORE
select REGMAP_I2C
depends on I2C
help
- Support for the Wolfson Microelectronics Arizona platform audio SoC
- core functionality controlled via I2C.
+ Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
+ audio SoC core functionality controlled via I2C.
 
 config MFD_ARIZONA_SPI
-   tristate "Wolfson Microelectronics Arizona platform with SPI"
+   tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with 
SPI"
select MFD_ARIZONA
select MFD_CORE
select REGMAP_SPI
depends on SPI_MASTER
help
- Support for the Wolfson Microelectronics Arizona platform audio SoC
- core functionality controlled via I2C.
+ Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
+ audio SoC core functionality controlled via I2C.
 
 config MFD_WM5102
bool "Wolfson Microelectronics WM5102"
@@ -1414,6 +1414,13 @@ config MFD_WM8998
help
  Support for Wolfson Microelectronics WM8998 low power audio SoC
 
+config MFD_CS47L24
+   bool "Cirrus Logic CS47L24 and WM1831"
+   depends on MFD_ARIZONA
+   help
+ Support for Cirrus Logic CS47L24 and WM1831 low power audio SoC
+
+
 config MFD_WM8400
bool "Wolfson Microelectronics WM8400"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a8b76b8..3fa1df4 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -51,6 +51,9 @@ endif
 ifeq ($(CONFIG_MFD_WM8998),y)
 obj-$(CONFIG_MFD_ARIZONA)  += wm8998-tables.o
 endif
+ifeq ($(CONFIG_MFD_CS47L24),y)
+obj-$(CONFIG_MFD_ARIZONA)  += cs47l24-tables.o
+endif
 obj-$(CONFIG_MFD_WM8400)   += wm8400-core.o
 wm831x-objs:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 wm831x-objs+= wm831x-auxadc.o
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 4e49210..0bbbc0d 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev)
goto err;
}
break;
+   case WM1831:
+   case CS47L24:
+   ret = arizona_wait_for_boot(arizona);
+   if (ret != 0)
+   goto err;
+   break;
default:
ret = arizona_wait_for_boot(arizona);
if (ret != 0)
@@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev)
}
}
break;
+   case WM1831:
+   case CS47L24:
+   break;
default:
jd_active = arizona_is_jac

[PATCH 0/3] Add support for Cirrus Logic CS47L24 and WM1831 codecs

2015-10-19 Thread Richard Fitzgerald
mfd patch based on Lee Jones's for-next
gpio patch based on Linus Walleij's for-next
ASoC patch based on Mark Brown's for-next

Lee/Mark - can one of you take all three patches (with maintainer acks) so
that the patch set is kept together?

Richard Fitzgerald (3):
  mfd: arizona: Support Cirrus Logic CS47L24 and WM1831
  gpio: arizona: Support Cirrus Logic CS47L24 and WM1831
  ASoC: cs47l24: Add driver for Cirrus Logic CS47L24 and WM1831 codecs

 Documentation/devicetree/bindings/mfd/arizona.txt |4 +-
 drivers/gpio/gpio-arizona.c   |4 +
 drivers/mfd/Kconfig   |   19 +-
 drivers/mfd/Makefile  |3 +
 drivers/mfd/arizona-core.c|   72 +-
 drivers/mfd/arizona-irq.c |   40 +-
 drivers/mfd/arizona-spi.c |7 +
 drivers/mfd/arizona.h |4 +
 drivers/mfd/cs47l24-tables.c  | 1629 +
 include/linux/mfd/arizona/core.h  |3 +
 sound/soc/codecs/Kconfig  |8 +
 sound/soc/codecs/Makefile |2 +
 sound/soc/codecs/cs47l24.c| 1147 +++
 sound/soc/codecs/cs47l24.h|   23 +
 14 files changed, 2940 insertions(+), 25 deletions(-)
 create mode 100644 drivers/mfd/cs47l24-tables.c
 create mode 100644 sound/soc/codecs/cs47l24.c
 create mode 100644 sound/soc/codecs/cs47l24.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 1/3] mfd: arizona: Support Cirrus Logic CS47L24 and WM1831

2015-10-19 Thread Richard Fitzgerald
This patch adds the regmap configuration tables and
core MFD handling for the CS47L24 and WM1831 codecs.

Note that compared to the other Arizona codecs, these devices
do not have an LDO1 or micsupp regulators, extcon driver, or
the DCVDD isolation control.

Signed-off-by: Richard Fitzgerald 
---
 Documentation/devicetree/bindings/mfd/arizona.txt |4 +-
 drivers/mfd/Kconfig   |   19 +-
 drivers/mfd/Makefile  |3 +
 drivers/mfd/arizona-core.c|   74 +-
 drivers/mfd/arizona-irq.c |   40 +-
 drivers/mfd/arizona-spi.c |7 +
 drivers/mfd/arizona.h |4 +
 drivers/mfd/cs47l24-tables.c  | 1629 +
 include/linux/mfd/arizona/core.h  |3 +
 9 files changed, 1757 insertions(+), 26 deletions(-)
 create mode 100644 drivers/mfd/cs47l24-tables.c

diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
b/Documentation/devicetree/bindings/mfd/arizona.txt
index a8fee60..73f28fa 100644
--- a/Documentation/devicetree/bindings/mfd/arizona.txt
+++ b/Documentation/devicetree/bindings/mfd/arizona.txt
@@ -1,4 +1,4 @@
-Wolfson Arizona class audio SoCs
+Cirrus Logic/Wolfson Microelectronics Arizona class audio SoCs
 
 These devices are audio SoCs with extensive digital capabilites and a range
 of analogue I/O.
@@ -12,6 +12,8 @@ Required properties:
 "wlf,wm8997"
 "wlf,wm8998"
 "wlf,wm1814"
+"wlf,wm1831"
+"cirrus,cs47l24"
 
   - reg : I2C slave address when connected using I2C, chip select number when
 using SPI.
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 4d92df6..d25bbb3 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -1370,24 +1370,24 @@ config MFD_ARIZONA
bool
 
 config MFD_ARIZONA_I2C
-   tristate "Wolfson Microelectronics Arizona platform with I2C"
+   tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with 
I2C"
select MFD_ARIZONA
select MFD_CORE
select REGMAP_I2C
depends on I2C
help
- Support for the Wolfson Microelectronics Arizona platform audio SoC
- core functionality controlled via I2C.
+ Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
+ audio SoC core functionality controlled via I2C.
 
 config MFD_ARIZONA_SPI
-   tristate "Wolfson Microelectronics Arizona platform with SPI"
+   tristate "Cirrus Logic/Wolfson Microelectronics Arizona platform with 
SPI"
select MFD_ARIZONA
select MFD_CORE
select REGMAP_SPI
depends on SPI_MASTER
help
- Support for the Wolfson Microelectronics Arizona platform audio SoC
- core functionality controlled via I2C.
+ Support for the Cirrus Logic/Wolfson Microelectronics Arizona platform
+ audio SoC core functionality controlled via I2C.
 
 config MFD_WM5102
bool "Wolfson Microelectronics WM5102"
@@ -1414,6 +1414,13 @@ config MFD_WM8998
help
  Support for Wolfson Microelectronics WM8998 low power audio SoC
 
+config MFD_CS47L24
+   bool "Cirrus Logic CS47L24 and WM1831"
+   depends on MFD_ARIZONA
+   help
+ Support for Cirrus Logic CS47L24 and WM1831 low power audio SoC
+
+
 config MFD_WM8400
bool "Wolfson Microelectronics WM8400"
select MFD_CORE
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index a8b76b8..3fa1df4 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -51,6 +51,9 @@ endif
 ifeq ($(CONFIG_MFD_WM8998),y)
 obj-$(CONFIG_MFD_ARIZONA)  += wm8998-tables.o
 endif
+ifeq ($(CONFIG_MFD_CS47L24),y)
+obj-$(CONFIG_MFD_ARIZONA)  += cs47l24-tables.o
+endif
 obj-$(CONFIG_MFD_WM8400)   += wm8400-core.o
 wm831x-objs:= wm831x-core.o wm831x-irq.o wm831x-otp.o
 wm831x-objs+= wm831x-auxadc.o
diff --git a/drivers/mfd/arizona-core.c b/drivers/mfd/arizona-core.c
index 4e49210..52d9fac 100644
--- a/drivers/mfd/arizona-core.c
+++ b/drivers/mfd/arizona-core.c
@@ -598,6 +598,12 @@ static int arizona_runtime_resume(struct device *dev)
goto err;
}
break;
+   case WM1831:
+   case CS47L24:
+   ret = arizona_wait_for_boot(arizona);
+   if (ret != 0)
+   goto err;
+   break;
default:
ret = arizona_wait_for_boot(arizona);
if (ret != 0)
@@ -682,6 +688,9 @@ static int arizona_runtime_suspend(struct device *dev)
}
}
break;
+   case WM1831:
+   case CS47L24:
+   break;
default:
jd_active = arizona_is_jac

[PATCH v2 3/3] ASoC: cs47l24: Add driver for Cirrus Logic CS47L24 and WM1831 codecs

2015-10-19 Thread Richard Fitzgerald
This patch adds support for the Cirrus Logic CS47L24 and WM1831 codecs.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/Kconfig   |8 +
 sound/soc/codecs/Makefile  |2 +
 sound/soc/codecs/cs47l24.c | 1148 
 sound/soc/codecs/cs47l24.h |   23 +
 4 files changed, 1181 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l24.c
 create mode 100644 sound/soc/codecs/cs47l24.h

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index cfdafc4..4d229d0 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -134,6 +134,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_WM5100 if I2C
select SND_SOC_WM5102 if MFD_WM5102
select SND_SOC_WM5110 if MFD_WM5110
+   select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_WM8350 if MFD_WM8350
select SND_SOC_WM8400 if MFD_WM8400
select SND_SOC_WM8510 if SND_SOC_I2C_AND_SPI
@@ -197,10 +198,12 @@ config SND_SOC_ARIZONA
tristate
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
+   default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM8997=y
default y if SND_SOC_WM8998=y
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
+   default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM8997=m
default m if SND_SOC_WM8998=m
 
@@ -213,9 +216,11 @@ config SND_SOC_WM_ADSP
tristate
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
+   default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM2200=y
default m if SND_SOC_WM5102=m
default m if SND_SOC_WM5110=m
+   default m if SND_SOC_CS47L24=m
default m if SND_SOC_WM2200=m
 
 config SND_SOC_AB8500_CODEC
@@ -733,6 +738,9 @@ config SND_SOC_WM5102
 config SND_SOC_WM5110
tristate
 
+config SND_SOC_CS47L24
+   tristate "TEST cs47l24"
+
 config SND_SOC_WM8350
tristate
 
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index f632fc4..45877b8 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -138,6 +138,7 @@ snd-soc-wm2200-objs := wm2200.o
 snd-soc-wm5100-objs := wm5100.o wm5100-tables.o
 snd-soc-wm5102-objs := wm5102.o
 snd-soc-wm5110-objs := wm5110.o
+snd-soc-cs47l24-objs := cs47l24.o
 snd-soc-wm8350-objs := wm8350.o
 snd-soc-wm8400-objs := wm8400.o
 snd-soc-wm8510-objs := wm8510.o
@@ -329,6 +330,7 @@ obj-$(CONFIG_SND_SOC_WM2200)+= snd-soc-wm2200.o
 obj-$(CONFIG_SND_SOC_WM5100)   += snd-soc-wm5100.o
 obj-$(CONFIG_SND_SOC_WM5102)   += snd-soc-wm5102.o
 obj-$(CONFIG_SND_SOC_WM5110)   += snd-soc-wm5110.o
+obj-$(CONFIG_SND_SOC_CS47L24)  += snd-soc-cs47l24.o
 obj-$(CONFIG_SND_SOC_WM8350)   += snd-soc-wm8350.o
 obj-$(CONFIG_SND_SOC_WM8400)   += snd-soc-wm8400.o
 obj-$(CONFIG_SND_SOC_WM8510)   += snd-soc-wm8510.o
diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
new file mode 100644
index 000..dc5ae7f
--- /dev/null
+++ b/sound/soc/codecs/cs47l24.c
@@ -0,0 +1,1148 @@
+/*
+ * cs47l24.h  --  ALSA SoC Audio driver for Cirrus Logic CS47L24
+ *
+ * Copyright 2015 Cirrus Logic Inc.
+ *
+ * Author: Richard Fitzgerald 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "arizona.h"
+#include "wm_adsp.h"
+#include "cs47l24.h"
+
+struct cs47l24_priv {
+   struct arizona_priv core;
+   struct arizona_fll fll[2];
+};
+
+static const struct wm_adsp_region cs47l24_dsp2_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x20 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x28 },
+   { .type = WMFW_ADSP2_XM, .base = 0x29 },
+   { .type = WMFW_ADSP2_YM, .base = 0x2a8000 },
+};
+
+static const struct wm_adsp_region cs47l24_dsp3_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x30 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x38 },
+   { .type = WMFW_ADSP2_XM, .base = 0x39 },
+   { .type = WMFW_ADSP2_YM, .base = 0x3a8000 },
+};
+
+static const struct wm_adsp_region *cs47l24_dsp_regions[] = {
+   cs47l24_dsp2_regions,
+   cs47l24_dsp3_regions,
+};
+
+static DECLARE_TLV_DB_SCALE(eq_tlv, -1200, 100, 0);
+static DECLARE_TLV_DB_SCALE(digital_tlv, -6400, 50, 0);
+static DECLARE_TLV_DB_SCALE(noise_tlv, -13200, 600, 0);
+static DECLARE_TLV_DB_SCALE(ng_tlv, -10200, 600, 0);
+
+#define CS47L24_NG_SRC(name, base) \
+   SOC_SINGLE(name " NG HPOUT1L Switch",  base,  0, 1, 0), \
+   SOC_SINGLE(name " NG HPOUT1R Switch",  base,  1, 1, 0), \
+   SOC_SINGLE(name " NG SPKOUT Switch",  base,  6, 1, 0)
+
+static const

[PATCH v2 2/3] gpio: arizona: Support Cirrus Logic CS47L24 and WM1831

2015-10-19 Thread Richard Fitzgerald
The CS47L24 and WM1831 codecs only have two GPIO lines, but are
otherwise similar to the WM8280.

Signed-off-by: Richard Fitzgerald 
---
 drivers/gpio/gpio-arizona.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpio/gpio-arizona.c b/drivers/gpio/gpio-arizona.c
index ca00273..624ea54 100644
--- a/drivers/gpio/gpio-arizona.c
+++ b/drivers/gpio/gpio-arizona.c
@@ -122,6 +122,10 @@ static int arizona_gpio_probe(struct platform_device *pdev)
case WM1814:
arizona_gpio->gpio_chip.ngpio = 5;
break;
+   case WM1831:
+   case CS47L24:
+   arizona_gpio->gpio_chip.ngpio = 2;
+   break;
default:
dev_err(&pdev->dev, "Unknown chip variant %d\n",
arizona->type);
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2 0/3] Add support for Cirrus Logic CS47L24 and WM1831 codecs

2015-10-19 Thread Richard Fitzgerald
mfd patch based on Lee Jones's for-next
gpio patch based on Linus Walleij's for-next
ASoC patch based on Mark Brown's for-next

Lee/Mark - can one of you take all three patches (with maintainer acks) so
that the patch set is kept together?

Richard Fitzgerald (3):
  mfd: arizona: Support Cirrus Logic CS47L24 and WM1831
  gpio: arizona: Support Cirrus Logic CS47L24 and WM1831
  ASoC: cs47l24: Add driver for Cirrus Logic CS47L24 and WM1831 codecs

 Documentation/devicetree/bindings/mfd/arizona.txt |4 +-
 drivers/gpio/gpio-arizona.c   |4 +
 drivers/mfd/Kconfig   |   19 +-
 drivers/mfd/Makefile  |3 +
 drivers/mfd/arizona-core.c|   74 +-
 drivers/mfd/arizona-irq.c |   40 +-
 drivers/mfd/arizona-spi.c |7 +
 drivers/mfd/arizona.h |4 +
 drivers/mfd/cs47l24-tables.c  | 1629 +
 include/linux/mfd/arizona/core.h  |3 +
 sound/soc/codecs/Kconfig  |8 +
 sound/soc/codecs/Makefile |2 +
 sound/soc/codecs/cs47l24.c| 1148 +++
 sound/soc/codecs/cs47l24.h|   23 +
 14 files changed, 2942 insertions(+), 26 deletions(-)
 create mode 100644 drivers/mfd/cs47l24-tables.c
 create mode 100644 sound/soc/codecs/cs47l24.c
 create mode 100644 sound/soc/codecs/cs47l24.h

-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [alsa-devel] [PATCH v2 0/3] Add support for Cirrus Logic CS47L24 and WM1831 codecs

2015-10-19 Thread Richard Fitzgerald
On Mon, 2015-10-19 at 07:52 -0700, Caleb Crome wrote:
> (Accidentally sent HTML format last time, so re-sending...)
> 
> Does anybody have support written for the CS53L30 4 channel ADC ?
> 
> 
> Thanks,
>  -Caleb
> 

You'd be more likely to get a reply to that if you started a new thread
that included in the email title the part number of the device you are
interested in. It not reasonable to assume that someone who knows about
the CS53L30 would expect to find a discussion of it under a thread about
a different device.

> On Mon, Oct 19, 2015 at 7:13 AM, Richard Fitzgerald
>  wrote:
> > mfd patch based on Lee Jones's for-next
> > gpio patch based on Linus Walleij's for-next
> > ASoC patch based on Mark Brown's for-next
> >
> > Lee/Mark - can one of you take all three patches (with maintainer acks) so
> > that the patch set is kept together?
> >
> > Richard Fitzgerald (3):
> >   mfd: arizona: Support Cirrus Logic CS47L24 and WM1831
> >   gpio: arizona: Support Cirrus Logic CS47L24 and WM1831
> >   ASoC: cs47l24: Add driver for Cirrus Logic CS47L24 and WM1831 codecs
> >
> >  Documentation/devicetree/bindings/mfd/arizona.txt |4 +-
> >  drivers/gpio/gpio-arizona.c   |4 +
> >  drivers/mfd/Kconfig   |   19 +-
> >  drivers/mfd/Makefile  |3 +
> >  drivers/mfd/arizona-core.c|   74 +-
> >  drivers/mfd/arizona-irq.c |   40 +-
> >  drivers/mfd/arizona-spi.c |7 +
> >  drivers/mfd/arizona.h |4 +
> >  drivers/mfd/cs47l24-tables.c  | 1629 
> > +
> >  include/linux/mfd/arizona/core.h  |3 +
> >  sound/soc/codecs/Kconfig  |8 +
> >  sound/soc/codecs/Makefile |2 +
> >  sound/soc/codecs/cs47l24.c| 1148 +++
> >  sound/soc/codecs/cs47l24.h|   23 +
> >  14 files changed, 2942 insertions(+), 26 deletions(-)
> >  create mode 100644 drivers/mfd/cs47l24-tables.c
> >  create mode 100644 sound/soc/codecs/cs47l24.c
> >  create mode 100644 sound/soc/codecs/cs47l24.h
> >
> > --
> > 1.9.1
> >
> > ___
> > Alsa-devel mailing list
> > alsa-de...@alsa-project.org
> > http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v8] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-06 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
IMPORTANT:
This patch has a build dependency on patches from the mfd for-next tree:

16b27467f46c mfd: madera: Add common support for Cirrus Logic Madera codecs
97c2b5cba204 mfd: madera: Add register definitions for Cirrus Logic Madera 
codecs
---
 MAINTAINERS  |   2 +
 drivers/irqchip/Kconfig  |   3 +
 drivers/irqchip/Makefile |   1 +
 drivers/irqchip/irq-madera.c | 257 +++
 include/linux/irqchip/irq-madera-pdata.h |  24 +++
 include/linux/irqchip/irq-madera.h   | 144 +
 6 files changed, 431 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera-pdata.h
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b52bb772b57e..5712fa1f2b78 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3524,8 +3524,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index d564d21245c5..45e171c623b3 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 15f268f646bf..608a136c6af3 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -87,3 +87,4 @@ obj-$(CONFIG_MESON_IRQ_GPIO)  += irq-meson-gpio.o
 obj-$(CONFIG_GOLDFISH_PIC) += irq-goldfish-pic.o
 obj-$(CONFIG_NDS32)+= irq-ativic32.o
 obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..4104056fd38a
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_

[PATCH 2/2] mfd: madera: Don't use regmap_read_poll_timeout to poll for BOOT_DONE

2018-08-07 Thread Richard Fitzgerald
While polling for BOOT_DONE the chip could NAK a read because it is
still booting, which would terminate the regmap_read_poll_timeout()
with an error.

Instead implement a polling loop that ignores read errors so we
always poll until the chip signals boot or the loop times out.

Signed-off-by: Richard Fitzgerald 
---
 drivers/mfd/madera-core.c | 38 --
 1 file changed, 24 insertions(+), 14 deletions(-)

diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
index 8cfea969b060..bc5545c53ee5 100644
--- a/drivers/mfd/madera-core.c
+++ b/drivers/mfd/madera-core.c
@@ -132,33 +132,43 @@ const char *madera_name_from_type(enum madera_type type)
 }
 EXPORT_SYMBOL_GPL(madera_name_from_type);
 
-#define MADERA_BOOT_POLL_MAX_INTERVAL_US  5000
-#define MADERA_BOOT_POLL_TIMEOUT_US 25000
+#define MADERA_BOOT_POLL_INTERVAL_USEC 5000
+#define MADERA_BOOT_POLL_TIMEOUT_USEC  25000
 
 static int madera_wait_for_boot(struct madera *madera)
 {
-   unsigned int val;
-   int ret;
+   ktime_t timeout;
+   unsigned int val = 0;
+   int ret = 0;
 
/*
 * We can't use an interrupt as we need to runtime resume to do so,
 * so we poll the status bit. This won't race with the interrupt
 * handler because it will be blocked on runtime resume.
+* The chip could NAK a read request while it is booting so ignore
+* errors from regmap_read.
 */
-   ret = regmap_read_poll_timeout(madera->regmap,
-  MADERA_IRQ1_RAW_STATUS_1,
-  val,
-  (val & MADERA_BOOT_DONE_STS1),
-  MADERA_BOOT_POLL_MAX_INTERVAL_US,
-  MADERA_BOOT_POLL_TIMEOUT_US);
-
-   if (ret)
-   dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret);
+   regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
+   if (val & MADERA_BOOT_DONE_STS1)
+   goto done;
+
+   timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
+   do {
+   usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
+MADERA_BOOT_POLL_INTERVAL_USEC);
+   regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
+   if (val & MADERA_BOOT_DONE_STS1)
+   goto done;
+   } while (ktime_compare(ktime_get(), timeout) <= 0);
+
+   dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
+   ret = -ETIMEDOUT;
 
/*
 * BOOT_DONE defaults to unmasked on boot so we must ack it.
-* Do this unconditionally to avoid interrupt storms.
+* Do this even after a timeout to avoid interrupt storms.
 */
+done:
regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
 MADERA_BOOT_DONE_EINT1);
 
-- 
2.11.0



[PATCH 1/2] mfd: madera: Add register definitions for accessory detect

2018-08-07 Thread Richard Fitzgerald
Add some register definitions for accessory detection, used
by the extcon driver.

Signed-off-by: Richard Fitzgerald 
---
 include/linux/mfd/madera/registers.h | 51 
 1 file changed, 51 insertions(+)

diff --git a/include/linux/mfd/madera/registers.h 
b/include/linux/mfd/madera/registers.h
index a6b7c4222c5e..977e06101711 100644
--- a/include/linux/mfd/madera/registers.h
+++ b/include/linux/mfd/madera/registers.h
@@ -1219,9 +1219,11 @@
 #define MADERA_IRQ1_STATUS_33  0x1820
 #define MADERA_IRQ1_MASK_1 0x1840
 #define MADERA_IRQ1_MASK_2 0x1841
+#define MADERA_IRQ1_MASK_6 0x1845
 #define MADERA_IRQ1_MASK_330x1860
 #define MADERA_IRQ1_RAW_STATUS_1   0x1880
 #define MADERA_IRQ1_RAW_STATUS_2   0x1881
+#define MADERA_IRQ1_RAW_STATUS_7   0x1886
 #define MADERA_IRQ1_RAW_STATUS_15  0x188E
 #define MADERA_IRQ1_RAW_STATUS_33  0x18A0
 #define MADERA_INTERRUPT_DEBOUNCE_70x1A06
@@ -1664,6 +1666,42 @@
 #define MADERA_MICB2A_ENA_SHIFT 0
 #define MADERA_MICB2A_ENA_WIDTH 1
 
+/* (0x0225) - HP Ctrl 1L */
+#define MADERA_RMV_SHRT_HP1L   0x4000
+#define MADERA_RMV_SHRT_HP1L_MASK  0x4000
+#define MADERA_RMV_SHRT_HP1L_SHIFT 14
+#define MADERA_RMV_SHRT_HP1L_WIDTH  1
+#define MADERA_HP1L_FLWR   0x0004
+#define MADERA_HP1L_FLWR_MASK  0x0004
+#define MADERA_HP1L_FLWR_SHIFT  2
+#define MADERA_HP1L_FLWR_WIDTH  1
+#define MADERA_HP1L_SHRTI  0x0002
+#define MADERA_HP1L_SHRTI_MASK 0x0002
+#define MADERA_HP1L_SHRTI_SHIFT 1
+#define MADERA_HP1L_SHRTI_WIDTH 1
+#define MADERA_HP1L_SHRTO  0x0001
+#define MADERA_HP1L_SHRTO_MASK 0x0001
+#define MADERA_HP1L_SHRTO_SHIFT 0
+#define MADERA_HP1L_SHRTO_WIDTH 1
+
+/* (0x0226) - HP Ctrl 1R */
+#define MADERA_RMV_SHRT_HP1R   0x4000
+#define MADERA_RMV_SHRT_HP1R_MASK  0x4000
+#define MADERA_RMV_SHRT_HP1R_SHIFT 14
+#define MADERA_RMV_SHRT_HP1R_WIDTH  1
+#define MADERA_HP1R_FLWR   0x0004
+#define MADERA_HP1R_FLWR_MASK  0x0004
+#define MADERA_HP1R_FLWR_SHIFT  2
+#define MADERA_HP1R_FLWR_WIDTH  1
+#define MADERA_HP1R_SHRTI  0x0002
+#define MADERA_HP1R_SHRTI_MASK 0x0002
+#define MADERA_HP1R_SHRTI_SHIFT 1
+#define MADERA_HP1R_SHRTI_WIDTH 1
+#define MADERA_HP1R_SHRTO  0x0001
+#define MADERA_HP1R_SHRTO_MASK 0x0001
+#define MADERA_HP1R_SHRTO_SHIFT 0
+#define MADERA_HP1R_SHRTO_WIDTH 1
+
 /* (0x0293)  Accessory_Detect_Mode_1 */
 #define MADERA_ACCDET_SRC  0x2000
 #define MADERA_ACCDET_SRC_MASK 0x2000
@@ -3766,6 +3804,19 @@
 #define MADERA_DSP1_BUS_ERR_EINT1_SHIFT 0
 #define MADERA_DSP1_BUS_ERR_EINT1_WIDTH 1
 
+/* (0x1845)  IRQ1_Mask_6 */
+#define MADERA_IM_MICDET2_EINT10x0200
+#define MADERA_IM_MICDET2_EINT1_MASK   0x0200
+#define MADERA_IM_MICDET2_EINT1_SHIFT   9
+#define MADERA_IM_MICDET2_EINT1_WIDTH   1
+#define MADERA_IM_MICDET1_EINT10x0100
+#define MADERA_IM_MICDET1_EINT1_MASK   0x0100
+#define MADERA_IM_MICDET1_EINT1_SHIFT   8
+#define MADERA_IM_MICDET1_EINT1_WIDTH   1
+#define MADERA_IM_HPDET_EINT1  0x0001
+#define MADERA_IM_HPDET_EINT1_MASK 0x0001
+#define MADERA_IM_HPDET_EINT1_SHIFT 0
+#define MADERA_IM_HPDET_EINT1_WIDTH 1
 /* (0x184E)  IRQ1_Mask_15 */
 #define MADERA_IM_SPK_OVERHEAT_WARN_EINT1  0x0004
 #define MADERA_IM_SPK_OVERHEAT_WARN_EINT1_MASK 0x0004
-- 
2.11.0



[PATCH 2/3] pinctrl: madera: Return ENOTSUPP for unsupported pin attributes

2018-08-07 Thread Richard Fitzgerald
The pin_config_[get|set] functions should return ENOTSUPP if
the requested attribute isn't supported.

Signed-off-by: Richard Fitzgerald 
---
 drivers/pinctrl/cirrus/pinctrl-madera-core.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/pinctrl/cirrus/pinctrl-madera-core.c 
b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
index 4f9b7e3b7cf2..4ba56ca5a9be 100644
--- a/drivers/pinctrl/cirrus/pinctrl-madera-core.c
+++ b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
@@ -801,7 +801,7 @@ static int madera_pin_conf_get(struct pinctrl_dev *pctldev, 
unsigned int pin,
result = 1;
break;
default:
-   break;
+   return -ENOTSUPP;
}
 
*config = pinconf_to_config_packed(param, result);
@@ -905,7 +905,7 @@ static int madera_pin_conf_set(struct pinctrl_dev *pctldev, 
unsigned int pin,
conf[1] &= ~MADERA_GP1_DIR;
break;
default:
-   break;
+   return -ENOTSUPP;
}
 
++configs;
-- 
2.11.0



[PATCH 1/3] pinctrl: madera: Set is_generic

2018-08-07 Thread Richard Fitzgerald
We are using the generic pin configuration interface so
we can set is_generic.

Signed-off-by: Richard Fitzgerald 
---
 drivers/pinctrl/cirrus/pinctrl-madera-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/cirrus/pinctrl-madera-core.c 
b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
index ece41fb2848f..4f9b7e3b7cf2 100644
--- a/drivers/pinctrl/cirrus/pinctrl-madera-core.c
+++ b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
@@ -971,10 +971,10 @@ static int madera_pin_conf_group_set(struct pinctrl_dev 
*pctldev,
 }
 
 static const struct pinconf_ops madera_pin_conf_ops = {
+   .is_generic = true,
.pin_config_get = madera_pin_conf_get,
.pin_config_set = madera_pin_conf_set,
.pin_config_group_set = madera_pin_conf_group_set,
-
 };
 
 static struct pinctrl_desc madera_pin_desc = {
-- 
2.11.0



[PATCH 3/3] pinctrl: madera: Fix missing space in debugfs output

2018-08-07 Thread Richard Fitzgerald
The SCHMITT tag was being dumped without a separating space.

Signed-off-by: Richard Fitzgerald 
---
 drivers/pinctrl/cirrus/pinctrl-madera-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/cirrus/pinctrl-madera-core.c 
b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
index 4ba56ca5a9be..979df109e187 100644
--- a/drivers/pinctrl/cirrus/pinctrl-madera-core.c
+++ b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
@@ -550,7 +550,7 @@ static void __maybe_unused madera_pin_dbg_show(struct 
pinctrl_dev *pctldev,
seq_printf(s, " DRV=%umA", madera_pin_unmake_drv_str(priv, conf[1]));
 
if (conf[0] & MADERA_GP1_IP_CFG_MASK)
-   seq_puts(s, "SCHMITT");
+   seq_puts(s, " SCHMITT");
 }
 
 
-- 
2.11.0



[PATCH v2] mfd: madera: Don't use regmap_read_poll_timeout to poll for BOOT_DONE

2018-08-27 Thread Richard Fitzgerald
While polling for BOOT_DONE the chip could NAK a read because it is
still booting, which would terminate the regmap_read_poll_timeout()
with an error.

Instead implement a polling loop that ignores read errors so we
always poll until the chip signals boot or the loop times out.

Signed-off-by: Richard Fitzgerald 
---
 drivers/mfd/madera-core.c | 33 -
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
index 8cfea969b060..440030cecbbd 100644
--- a/drivers/mfd/madera-core.c
+++ b/drivers/mfd/madera-core.c
@@ -132,32 +132,39 @@ const char *madera_name_from_type(enum madera_type type)
 }
 EXPORT_SYMBOL_GPL(madera_name_from_type);
 
-#define MADERA_BOOT_POLL_MAX_INTERVAL_US  5000
-#define MADERA_BOOT_POLL_TIMEOUT_US 25000
+#define MADERA_BOOT_POLL_INTERVAL_USEC 5000
+#define MADERA_BOOT_POLL_TIMEOUT_USEC  25000
 
 static int madera_wait_for_boot(struct madera *madera)
 {
+   ktime_t timeout;
unsigned int val;
-   int ret;
+   int ret = 0;
 
/*
 * We can't use an interrupt as we need to runtime resume to do so,
 * so we poll the status bit. This won't race with the interrupt
 * handler because it will be blocked on runtime resume.
+* The chip could NAK a read request while it is booting so ignore
+* errors from regmap_read.
 */
-   ret = regmap_read_poll_timeout(madera->regmap,
-  MADERA_IRQ1_RAW_STATUS_1,
-  val,
-  (val & MADERA_BOOT_DONE_STS1),
-  MADERA_BOOT_POLL_MAX_INTERVAL_US,
-  MADERA_BOOT_POLL_TIMEOUT_US);
-
-   if (ret)
-   dev_err(madera->dev, "Polling BOOT_DONE_STS failed: %d\n", ret);
+   timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
+   regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
+   while (!(val & MADERA_BOOT_DONE_STS1) &&
+  !ktime_after(ktime_get(), timeout)) {
+   usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
+MADERA_BOOT_POLL_INTERVAL_USEC);
+   regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
+   };
+
+   if (!(val & MADERA_BOOT_DONE_STS1)) {
+   dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
+   ret = -ETIMEDOUT;
+   }
 
/*
 * BOOT_DONE defaults to unmasked on boot so we must ack it.
-* Do this unconditionally to avoid interrupt storms.
+* Do this even after a timeout to avoid interrupt storms.
 */
regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
 MADERA_BOOT_DONE_EINT1);
-- 
2.11.0



[PATCH v9 1/2] mfd: madera: Add irqchip data pointer into struct madera

2018-08-27 Thread Richard Fitzgerald
Put the pointer to struct regmap_irq_chip_data into the parent
mfd structure so that the child irqchip driver does not need
a trivial private structure to store only this pointer. As
the irqchip child driver already has a pointer to the parent
struct madera it can use that to store the pointer. This also
means that the irqchip driver does not need a double-indirection
from its local struct to get at the parent struct madera.

Signed-off-by: Richard Fitzgerald 
---
 include/linux/mfd/madera/core.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h
index c332681848ef..fe69c0f4398f 100644
--- a/include/linux/mfd/madera/core.h
+++ b/include/linux/mfd/madera/core.h
@@ -148,6 +148,7 @@ struct snd_soc_dapm_context;
  * @internal_dcvdd:true if DCVDD is supplied from the internal LDO1
  * @pdata: our pdata
  * @irq_dev:   the irqchip child driver device
+ * @irq_data:  pointer to irqchip data for the child irqchip driver
  * @irq:   host irq number from SPI or I2C configuration
  * @out_clamp: indicates output clamp state for each analogue output
  * @out_shorted:   indicates short circuit state for each analogue output
@@ -175,6 +176,7 @@ struct madera {
struct madera_pdata pdata;
 
struct device *irq_dev;
+   struct regmap_irq_chip_data *irq_data;
int irq;
 
unsigned int num_micbias;
-- 
2.11.0



[PATCH v9 2/2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-27 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 244 +
 include/linux/irqchip/irq-madera.h | 135 
 5 files changed, 385 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a5b256b25905..d20b81fcbc53 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3594,8 +3594,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 383e7b70221d..0afe6bdd2074 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index fbd1ec8070ef..97838212d8e4 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -88,3 +88,4 @@ obj-$(CONFIG_GOLDFISH_PIC)+= irq-goldfish-pic.o
 obj-$(CONFIG_NDS32)+= irq-ativic32.o
 obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
 obj-$(CONFIG_SIFIVE_PLIC)  += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..414fd9b574d9
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_DET,MADERA_IRQ1_STATUS_9),
+
+   MADERA_IRQ(DSP_I

[PATCH] mfd: madera: Remove unused forward reference

2018-08-28 Thread Richard Fitzgerald
The madera_irqchip_pdata struct was replaced by the irq_flags
member of struct madera_pdata so the forward reference is
obsolete.

Signed-off-by: Richard Fitzgerald 
---
 include/linux/mfd/madera/pdata.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/include/linux/mfd/madera/pdata.h b/include/linux/mfd/madera/pdata.h
index 0b311f39c8f4..8dc852402dbb 100644
--- a/include/linux/mfd/madera/pdata.h
+++ b/include/linux/mfd/madera/pdata.h
@@ -24,7 +24,6 @@
 
 struct gpio_desc;
 struct pinctrl_map;
-struct madera_irqchip_pdata;
 struct madera_codec_pdata;
 
 /**
-- 
2.11.0



[PATCH] pinctrl: madera: Fix possible NULL pointer with pdata config

2018-08-28 Thread Richard Fitzgerald
If we are being configured via pdata we don't necessarily have
any gpio mappings being configured that way so pdata->gpio_config
could be NULL.

Signed-off-by: Richard Fitzgerald 
---
 drivers/pinctrl/cirrus/pinctrl-madera-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/pinctrl/cirrus/pinctrl-madera-core.c 
b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
index ece41fb2848f..c4f4d904e4a6 100644
--- a/drivers/pinctrl/cirrus/pinctrl-madera-core.c
+++ b/drivers/pinctrl/cirrus/pinctrl-madera-core.c
@@ -1040,7 +1040,7 @@ static int madera_pin_probe(struct platform_device *pdev)
}
 
/* if the configuration is provided through pdata, apply it */
-   if (pdata) {
+   if (pdata && pdata->gpio_configs) {
ret = pinctrl_register_mappings(pdata->gpio_configs,
pdata->n_gpio_configs);
if (ret) {
-- 
2.11.0



Re: [PATCH v9 2/2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-28 Thread Richard Fitzgerald

On 27/08/18 17:26, Richard Fitzgerald wrote:

The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
  MAINTAINERS|   2 +
  drivers/irqchip/Kconfig|   3 +
  drivers/irqchip/Makefile   |   1 +
  drivers/irqchip/irq-madera.c   | 244 +
  include/linux/irqchip/irq-madera.h | 135 
  5 files changed, 385 insertions(+)
  create mode 100644 drivers/irqchip/irq-madera.c
  create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a5b256b25905..d20b81fcbc53 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3594,8 +3594,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
  S:Supported
  F:Documentation/devicetree/bindings/mfd/madera.txt
  F:Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
  F:include/linux/mfd/madera/*
  F:drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
  F:drivers/mfd/madera*
  F:drivers/mfd/cs47l*
  F:drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 383e7b70221d..0afe6bdd2074 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
  
+config MADERA_IRQ

+   tristate
+
  config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index fbd1ec8070ef..97838212d8e4 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -88,3 +88,4 @@ obj-$(CONFIG_GOLDFISH_PIC)+= irq-goldfish-pic.o
  obj-$(CONFIG_NDS32)   += irq-ativic32.o
  obj-$(CONFIG_QCOM_PDC)+= qcom-pdc.o
  obj-$(CONFIG_SIFIVE_PLIC) += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..414fd9b574d9
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_

[PATCH v10 1/2] mfd: madera: Add irqchip data pointer into struct madera

2018-08-28 Thread Richard Fitzgerald
Put the pointer to struct regmap_irq_chip_data into the parent
mfd structure so that the child irqchip driver does not need
a trivial private structure to store only this pointer. As
the irqchip child driver already has a pointer to the parent
struct madera it can use that to store the pointer. This also
means that the irqchip driver does not need a double-indirection
from its local struct to get at the parent struct madera.

Signed-off-by: Richard Fitzgerald 
---
 include/linux/mfd/madera/core.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h
index c332681848ef..fe69c0f4398f 100644
--- a/include/linux/mfd/madera/core.h
+++ b/include/linux/mfd/madera/core.h
@@ -148,6 +148,7 @@ struct snd_soc_dapm_context;
  * @internal_dcvdd:true if DCVDD is supplied from the internal LDO1
  * @pdata: our pdata
  * @irq_dev:   the irqchip child driver device
+ * @irq_data:  pointer to irqchip data for the child irqchip driver
  * @irq:   host irq number from SPI or I2C configuration
  * @out_clamp: indicates output clamp state for each analogue output
  * @out_shorted:   indicates short circuit state for each analogue output
@@ -175,6 +176,7 @@ struct madera {
struct madera_pdata pdata;
 
struct device *irq_dev;
+   struct regmap_irq_chip_data *irq_data;
int irq;
 
unsigned int num_micbias;
-- 
2.11.0



[PATCH v10 2/2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-28 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 244 +
 include/linux/irqchip/irq-madera.h | 135 
 5 files changed, 385 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a5b256b25905..d20b81fcbc53 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3594,8 +3594,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 383e7b70221d..0afe6bdd2074 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index fbd1ec8070ef..97838212d8e4 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -88,3 +88,4 @@ obj-$(CONFIG_GOLDFISH_PIC)+= irq-goldfish-pic.o
 obj-$(CONFIG_NDS32)+= irq-ativic32.o
 obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
 obj-$(CONFIG_SIFIVE_PLIC)  += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..b21d60659af9
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_DET,MADERA_IRQ1_STATUS_9),
+
+   MADERA_IRQ(DSP_I

Re: [PATCH] MAINTAINERS: Move entry for Cirrus Logic Madera codecs

2018-08-28 Thread Richard Fitzgerald

On 28/08/18 14:33, Geert Uytterhoeven wrote:

To preserve alphabetical sort order.

Fixes: 97c2b5cba2044f1c ("mfd: madera: Add register definitions for Cirrus Logic 
Madera codecs")
Signed-off-by: Geert Uytterhoeven 
---
  MAINTAINERS | 32 
  1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 9ad052aeac39be98..4b0ce55dd7c2413d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3557,6 +3557,22 @@ L:   net...@vger.kernel.org
  S:Maintained
  F:drivers/net/ethernet/cirrus/ep93xx_eth.c
  
+CIRRUS LOGIC MADERA CODEC DRIVERS

+M: Charles Keepax 
+M:     Richard Fitzgerald 
+L: alsa-de...@alsa-project.org (moderated for non-subscribers)
+L: patc...@opensource.cirrus.com
+T: git https://github.com/CirrusLogic/linux-drivers.git
+W: https://github.com/CirrusLogic/linux-drivers/wiki
+S: Supported
+F: Documentation/devicetree/bindings/mfd/madera.txt
+F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/mfd/madera/*
+F: drivers/gpio/gpio-madera*
+F: drivers/mfd/madera*
+F: drivers/mfd/cs47l*
+F: drivers/pinctrl/cirrus/*
+
  CISCO FCOE HBA DRIVER
  M:Satish Kharat 
  M:Sesidhar Baddela 
@@ -3584,22 +3600,6 @@ M:   Christian Benvenuti 
  S:Supported
  F:drivers/infiniband/hw/usnic/
  
-CIRRUS LOGIC MADERA CODEC DRIVERS

-M: Charles Keepax 
-M:     Richard Fitzgerald 
-L: alsa-de...@alsa-project.org (moderated for non-subscribers)
-L: patc...@opensource.cirrus.com
-T: git https://github.com/CirrusLogic/linux-drivers.git
-W: https://github.com/CirrusLogic/linux-drivers/wiki
-S: Supported
-F: Documentation/devicetree/bindings/mfd/madera.txt
-F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
-F: include/linux/mfd/madera/*
-F: drivers/gpio/gpio-madera*
-F: drivers/mfd/madera*
-F: drivers/mfd/cs47l*
-F: drivers/pinctrl/cirrus/*
-
  CLANG-FORMAT FILE
  M:Miguel Ojeda 
  S:Maintained



Reviewed-by: Richard Fitzgerald 

A maintainer for MAINTAINERS would help avoid these problems, which will
tend to happen when changes to the file go through many trees.



Re: [PATCH v10 2/2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-30 Thread Richard Fitzgerald

On 30/08/18 11:31, Thomas Gleixner wrote:

On Tue, 28 Aug 2018, Richard Fitzgerald wrote:

@@ -0,0 +1,244 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.


You have the SPDX identifier above, which makes this boilerplate
superfluous.



Our legal people want it left here.
They are ok with the SPDX reference, but they want to keep an
explicit statement of the license that was intended.


+#ifdef CONFIG_PM_SLEEP
+static int madera_suspend_noirq(struct device *dev)
+{
+   struct madera *madera = dev_get_drvdata(dev->parent);
+
+   dev_dbg(madera->irq_dev, "No IRQ suspend, reenabling IRQ\n");
+
+   enable_irq(madera->irq);
+
+   return 0;
+}
+
+static int madera_suspend(struct device *dev)
+{
+   struct madera *madera = dev_get_drvdata(dev->parent);
+
+   dev_dbg(madera->irq_dev, "Suspend, disabling IRQ\n");
+
+   disable_irq(madera->irq);
+
+   return 0;
+}


This really wants a comment why you are disabling it first and reenabling
it afterwards. I have no idea why you are doing this and it doesn't make
much sense from the S/R perspective either.


+   /*
+* Read the flags from the interrupt controller if not specified
+* by pdata
+*/
+   irq_flags = madera->pdata.irq_flags;
+   if (!irq_flags) {
+   irq_data = irq_get_irq_data(madera->irq);
+   if (!irq_data) {
+   dev_err(&pdev->dev, "Invalid IRQ: %d\n", madera->irq);
+   return -EINVAL;
+   }
+
+   irq_flags = irqd_get_trigger_type(irq_data);
+
+   /* Codec defaults to trigger low, use this if no flags given */
+   if (irq_flags == IRQ_TYPE_NONE)
+   irq_flags = IRQF_TRIGGER_LOW;
+   }
+
+   if (irq_flags & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+   dev_err(&pdev->dev, "Host interrupt not level-triggered\n");
+   return -EINVAL;
+   }
+
+   if (irq_flags & IRQF_TRIGGER_HIGH) {
+   ret = regmap_update_bits(madera->regmap, MADERA_IRQ1_CTRL,
+MADERA_IRQ_POL_MASK, 0);
+   if (ret) {
+   dev_err(&pdev->dev,
+   "Failed to set IRQ polarity: %d\n", ret);
+   return ret;
+   }
+   }


This looks wrong. Why are you only updating the polarity for trigger HIGH?


diff --git a/include/linux/irqchip/irq-madera.h 
b/include/linux/irqchip/irq-madera.h
new file mode 100644
index ..5aeb7e6adc82
--- /dev/null
+++ b/include/linux/irqchip/irq-madera.h
@@ -0,0 +1,135 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2016-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.


See above.

Thanks,

tglx





[PATCH v11 2/2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-30 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 259 +
 include/linux/irqchip/irq-madera.h | 135 +++
 5 files changed, 400 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index a5b256b25905..d20b81fcbc53 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3594,8 +3594,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 383e7b70221d..0afe6bdd2074 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index fbd1ec8070ef..97838212d8e4 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -88,3 +88,4 @@ obj-$(CONFIG_GOLDFISH_PIC)+= irq-goldfish-pic.o
 obj-$(CONFIG_NDS32)+= irq-ativic32.o
 obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
 obj-$(CONFIG_SIFIVE_PLIC)  += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..f8944d107400
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,259 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_DET,MADERA_IRQ1_STATUS_9),
+
+   MADERA_IRQ(DSP_I

[PATCH v11 1/2] mfd: madera: Add irqchip data pointer into struct madera

2018-08-30 Thread Richard Fitzgerald
Put the pointer to struct regmap_irq_chip_data into the parent
mfd structure so that the child irqchip driver does not need
a trivial private structure to store only this pointer. As
the irqchip child driver already has a pointer to the parent
struct madera it can use that to store the pointer. This also
means that the irqchip driver does not need a double-indirection
from its local struct to get at the parent struct madera.

Signed-off-by: Richard Fitzgerald 
---
 include/linux/mfd/madera/core.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h
index c332681848ef..fe69c0f4398f 100644
--- a/include/linux/mfd/madera/core.h
+++ b/include/linux/mfd/madera/core.h
@@ -148,6 +148,7 @@ struct snd_soc_dapm_context;
  * @internal_dcvdd:true if DCVDD is supplied from the internal LDO1
  * @pdata: our pdata
  * @irq_dev:   the irqchip child driver device
+ * @irq_data:  pointer to irqchip data for the child irqchip driver
  * @irq:   host irq number from SPI or I2C configuration
  * @out_clamp: indicates output clamp state for each analogue output
  * @out_shorted:   indicates short circuit state for each analogue output
@@ -175,6 +176,7 @@ struct madera {
struct madera_pdata pdata;
 
struct device *irq_dev;
+   struct regmap_irq_chip_data *irq_data;
int irq;
 
unsigned int num_micbias;
-- 
2.11.0



Re: [PATCH v8] irqchip: Add driver for Cirrus Logic Madera codecs

2018-08-08 Thread Richard Fitzgerald

On 08/08/18 11:27, Marc Zyngier wrote:

On 06/08/18 17:04, Richard Fitzgerald wrote:

The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
IMPORTANT:
This patch has a build dependency on patches from the mfd for-next tree:

16b27467f46c mfd: madera: Add common support for Cirrus Logic Madera codecs
97c2b5cba204 mfd: madera: Add register definitions for Cirrus Logic Madera 
codecs
---
  MAINTAINERS  |   2 +
  drivers/irqchip/Kconfig  |   3 +
  drivers/irqchip/Makefile |   1 +
  drivers/irqchip/irq-madera.c | 257 +++
  include/linux/irqchip/irq-madera-pdata.h |  24 +++
  include/linux/irqchip/irq-madera.h   | 144 +
  6 files changed, 431 insertions(+)
  create mode 100644 drivers/irqchip/irq-madera.c
  create mode 100644 include/linux/irqchip/irq-madera-pdata.h
  create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index b52bb772b57e..5712fa1f2b78 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3524,8 +3524,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
  S:Supported
  F:Documentation/devicetree/bindings/mfd/madera.txt
  F:Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
  F:include/linux/mfd/madera/*
  F:drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
  F:drivers/mfd/madera*
  F:drivers/mfd/cs47l*
  F:drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index d564d21245c5..45e171c623b3 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
  
+config MADERA_IRQ

+   tristate
+
  config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 15f268f646bf..608a136c6af3 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -87,3 +87,4 @@ obj-$(CONFIG_MESON_IRQ_GPIO)  += irq-meson-gpio.o
  obj-$(CONFIG_GOLDFISH_PIC)+= irq-goldfish-pic.o
  obj-$(CONFIG_NDS32)   += irq-ativic32.o
  obj-$(CONFIG_QCOM_PDC)+= qcom-pdc.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..4104056fd38a
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,257 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_F

[PATCH 1/2] ASoC: wm_adsp: Declare firmware controls from codec driver

2018-08-08 Thread Richard Fitzgerald
To allow for more flexibility in naming of DSP-type cores
move the creation of the firmware controls to the codec
drivers instead of having a hardcoded list in wm_adsp.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/cs47l24.c |  3 +++
 sound/soc/codecs/wm2200.c  | 10 --
 sound/soc/codecs/wm5102.c  |  2 ++
 sound/soc/codecs/wm5110.c  |  5 +
 sound/soc/codecs/wm_adsp.c | 35 +--
 sound/soc/codecs/wm_adsp.h | 10 +-
 6 files changed, 32 insertions(+), 33 deletions(-)

diff --git a/sound/soc/codecs/cs47l24.c b/sound/soc/codecs/cs47l24.c
index 0da52ead91e0..45e50fe3bf25 100644
--- a/sound/soc/codecs/cs47l24.c
+++ b/sound/soc/codecs/cs47l24.c
@@ -235,6 +235,9 @@ ARIZONA_MIXER_CONTROLS("AIF2TX6", 
ARIZONA_AIF2TX6MIX_INPUT_1_SOURCE),
 
 ARIZONA_MIXER_CONTROLS("AIF3TX1", ARIZONA_AIF3TX1MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("AIF3TX2", ARIZONA_AIF3TX2MIX_INPUT_1_SOURCE),
+
+WM_ADSP_FW_CONTROL("DSP2", 1),
+WM_ADSP_FW_CONTROL("DSP3", 2),
 };
 
 ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c
index 3663b9fd4d65..deff65161504 100644
--- a/sound/soc/codecs/wm2200.c
+++ b/sound/soc/codecs/wm2200.c
@@ -1180,6 +1180,9 @@ SOC_DOUBLE_R_TLV("OUT2 Digital Volume", 
WM2200_DAC_DIGITAL_VOLUME_2L,
 SOC_DOUBLE("OUT2 Switch", WM2200_PDM_1, WM2200_SPK1L_MUTE_SHIFT,
   WM2200_SPK1R_MUTE_SHIFT, 1, 1),
 SOC_ENUM("RxANC Src", wm2200_rxanc_input_sel),
+
+WM_ADSP_FW_CONTROL("DSP1", 0),
+WM_ADSP_FW_CONTROL("DSP2", 1),
 };
 
 WM2200_MIXER_ENUMS(OUT1L, WM2200_OUT1LMIX_INPUT_1_SOURCE);
@@ -1553,15 +1556,10 @@ static const struct snd_soc_dapm_route 
wm2200_dapm_routes[] = {
 static int wm2200_probe(struct snd_soc_component *component)
 {
struct wm2200_priv *wm2200 = snd_soc_component_get_drvdata(component);
-   int ret;
 
wm2200->component = component;
 
-   ret = snd_soc_add_component_controls(component, wm_adsp_fw_controls, 2);
-   if (ret != 0)
-   return ret;
-
-   return ret;
+   return 0;
 }
 
 static int wm2200_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c
index a01a0c0e01eb..7e817e1877c2 100644
--- a/sound/soc/codecs/wm5102.c
+++ b/sound/soc/codecs/wm5102.c
@@ -985,6 +985,8 @@ ARIZONA_MIXER_CONTROLS("SLIMTX5", 
ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
+
+WM_ADSP_FW_CONTROL("DSP1", 0),
 };
 
 ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c
index 00c735c585d9..b0789a03d699 100644
--- a/sound/soc/codecs/wm5110.c
+++ b/sound/soc/codecs/wm5110.c
@@ -927,6 +927,11 @@ ARIZONA_MIXER_CONTROLS("SLIMTX5", 
ARIZONA_SLIMTX5MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SLIMTX6", ARIZONA_SLIMTX6MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SLIMTX7", ARIZONA_SLIMTX7MIX_INPUT_1_SOURCE),
 ARIZONA_MIXER_CONTROLS("SLIMTX8", ARIZONA_SLIMTX8MIX_INPUT_1_SOURCE),
+
+WM_ADSP_FW_CONTROL("DSP1", 0),
+WM_ADSP_FW_CONTROL("DSP2", 1),
+WM_ADSP_FW_CONTROL("DSP3", 2),
+WM_ADSP_FW_CONTROL("DSP4", 3),
 };
 
 ARIZONA_MIXER_ENUMS(EQ1, ARIZONA_EQ1MIX_INPUT_1_SOURCE);
diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index ae131376cea1..1c12c78dbcce 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -684,8 +684,8 @@ static inline void wm_adsp_debugfs_clear(struct wm_adsp 
*dsp)
 }
 #endif
 
-static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
 {
struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
@@ -695,9 +695,10 @@ static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
 
return 0;
 }
+EXPORT_SYMBOL_GPL(wm_adsp_fw_get);
 
-static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
+int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
+  struct snd_ctl_elem_value *ucontrol)
 {
struct snd_soc_component *component = 
snd_soc_kcontrol_component(kcontrol);
struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
@@ -721,8 +722,9 @@ static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
 
return ret;
 }
+EXPORT_SYMBOL_GPL(wm_adsp_fw_put);
 
-static c

[PATCH 2/2] ASoC: wm_adsp: Make DSP name configurable by codec driver

2018-08-08 Thread Richard Fitzgerald
Instead of harcoding that a core must always be called "DSPn"
add a name member to struct wm_adsp so that the owning codec
driver can provide a custom name. This allows for re-use of
the wm_adsp driver with parts where the processing cores are
named differently.

If no name is provided the default DSPn name is used.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/wm_adsp.c | 69 --
 sound/soc/codecs/wm_adsp.h |  2 ++
 2 files changed, 50 insertions(+), 21 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 1c12c78dbcce..f61656070225 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -10,6 +10,7 @@
  * published by the Free Software Foundation.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -35,15 +36,15 @@
 #include "wm_adsp.h"
 
 #define adsp_crit(_dsp, fmt, ...) \
-   dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+   dev_crit(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
 #define adsp_err(_dsp, fmt, ...) \
-   dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+   dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
 #define adsp_warn(_dsp, fmt, ...) \
-   dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+   dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
 #define adsp_info(_dsp, fmt, ...) \
-   dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+   dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
 #define adsp_dbg(_dsp, fmt, ...) \
-   dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
+   dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__)
 
 #define ADSP1_CONTROL_1   0x00
 #define ADSP1_CONTROL_2   0x02
@@ -608,7 +609,6 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
  struct snd_soc_component *component)
 {
struct dentry *root = NULL;
-   char *root_name;
int i;
 
if (!component->debugfs_root) {
@@ -616,13 +616,7 @@ static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
goto err;
}
 
-   root_name = kmalloc(PAGE_SIZE, GFP_KERNEL);
-   if (!root_name)
-   goto err;
-
-   snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num);
-   root = debugfs_create_dir(root_name, component->debugfs_root);
-   kfree(root_name);
+   root = debugfs_create_dir(dsp->name, component->debugfs_root);
 
if (!root)
goto err;
@@ -1315,12 +1309,12 @@ static int wm_adsp_create_control(struct wm_adsp *dsp,
switch (dsp->fw_ver) {
case 0:
case 1:
-   snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x",
-dsp->num, region_name, alg_region->alg);
+   snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "%s %s %x",
+dsp->name, region_name, alg_region->alg);
break;
default:
ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN,
-   "DSP%d%c %.12s %x", dsp->num, *region_name,
+   "%s%c %.12s %x", dsp->name, *region_name,
wm_adsp_fw_text[dsp->fw], alg_region->alg);
 
/* Truncate the subname from the start if it is too long */
@@ -1648,7 +1642,7 @@ static int wm_adsp_load(struct wm_adsp *dsp)
if (file == NULL)
return -ENOMEM;
 
-   snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num,
+   snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name,
 wm_adsp_fw[dsp->fw].file);
file[PAGE_SIZE - 1] = '\0';
 
@@ -2226,7 +2220,7 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
if (file == NULL)
return -ENOMEM;
 
-   snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num,
+   snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name,
 wm_adsp_fw[dsp->fw].file);
file[PAGE_SIZE - 1] = '\0';
 
@@ -2398,8 +2392,38 @@ static int wm_adsp_load_coeff(struct wm_adsp *dsp)
return ret;
 }
 
+static int wm_adsp_create_name(struct wm_adsp *dsp)
+{
+   char *p;
+
+   if (!dsp->name) {
+   dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d",
+  dsp->num);
+   if (!dsp->name)
+   return -ENOMEM;
+   }
+
+   if (!dsp->fwf_name) {
+

[PATCH v7 09/17] irqchip: Add driver for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
 MAINTAINERS  |   2 +
 drivers/irqchip/Kconfig  |   3 +
 drivers/irqchip/Makefile |   1 +
 drivers/irqchip/irq-madera.c | 301 +++
 include/linux/irqchip/irq-madera-pdata.h |  23 +++
 include/linux/irqchip/irq-madera.h   |  98 ++
 6 files changed, 428 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera-pdata.h
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index aa7f3a9dfa77..6e79d651639b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3496,7 +3496,9 @@ T:git 
https://github.com/CirrusLogic/linux-drivers.git
 W: https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index c70476b34a53..d128c902b670 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -144,6 +144,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   bool
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index d2df34a54d38..4aa3fbdb7929 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_ARCH_S3C24XX)+= irq-s3c24xx.o
 obj-$(CONFIG_DW_APB_ICTL)  += irq-dw-apb-ictl.o
 obj-$(CONFIG_METAG)+= irq-metag-ext.o
 obj-$(CONFIG_METAG_PERFCOUNTER_IRQS)   += irq-metag.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
 obj-$(CONFIG_CLPS711X_IRQCHIP) += irq-clps711x.o
 obj-$(CONFIG_OMPIC)+= irq-ompic.o
 obj-$(CONFIG_OR1K_PIC) += irq-or1k-pic.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..d80c459cddd7
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,301 @@
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+struct madera_irq_priv {
+   struct device   *dev;
+   int irq;
+   struct regmap_irq_chip_data *irq_data;
+   struct madera   *madera;
+};
+
+#define MADERA_IRQ(_irq, _reg)  \
+   [MADERA_IRQ_ ## _irq] = { .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2, \
+   .mask = MADERA_ ## _irq ## _EINT1 }
+
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATU

[PATCH v7 04/17] mfd: madera: Register map tables for Cirrus Logic CS47L35

2018-01-15 Thread Richard Fitzgerald
Regmap configuration tables for Cirrus Logic CS47L35 codecs.

Signed-off-by: Piotr Stankiewicz 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
Acked-for-MFD-by: Lee Jones 
---
 drivers/mfd/Kconfig  |7 +
 drivers/mfd/Makefile |3 +
 drivers/mfd/cs47l35-tables.c | 1610 ++
 3 files changed, 1620 insertions(+)
 create mode 100644 drivers/mfd/cs47l35-tables.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 8ea298bdcf58..97151f3340bd 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -259,6 +259,13 @@ config MFD_MADERA_SPI
  Support for the Cirrus Logic Madera platform audio SoC
  core functionality controlled via SPI.
 
+config MFD_CS47L35
+   bool "Cirrus Logic CS47L35"
+   select PINCTRL_CS47L35
+   depends on MFD_MADERA
+   help
+ Support for Cirrus Logic CS47L35 Smart Codec
+
 config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 1349e23e2be1..abc2de60aa35 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -74,6 +74,9 @@ obj-$(CONFIG_MFD_WM8994)  += wm8994.o
 obj-$(CONFIG_MFD_WM97xx)   += wm97xx-core.o
 
 obj-$(CONFIG_MFD_MADERA)   += madera-core.o
+ifeq ($(CONFIG_MFD_CS47L35),y)
+obj-$(CONFIG_MFD_MADERA)   += cs47l35-tables.o
+endif
 obj-$(CONFIG_MFD_MADERA_I2C)   += madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)   += madera-spi.o
 
diff --git a/drivers/mfd/cs47l35-tables.c b/drivers/mfd/cs47l35-tables.c
new file mode 100644
index ..fdaf6de3c8aa
--- /dev/null
+++ b/drivers/mfd/cs47l35-tables.c
@@ -0,0 +1,1610 @@
+/*
+ * Regmap tables for CS47L35 codec
+ *
+ * Copyright 2015-2016 Cirrus Logic
+ *
+ * Author: Piotr Stankiewicz 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+
+static const struct reg_sequence cs47l35_reva_16_patch[] = {
+   { 0x460, 0x0c40 },
+   { 0x461, 0xcd1a },
+   { 0x462, 0x0c40 },
+   { 0x463, 0xb53b },
+   { 0x464, 0x0c40 },
+   { 0x465, 0x7503 },
+   { 0x466, 0x0c40 },
+   { 0x467, 0x4a41 },
+   { 0x468, 0x0041 },
+   { 0x469, 0x3491 },
+   { 0x46a, 0x0841 },
+   { 0x46b, 0x1f50 },
+   { 0x46c, 0x0446 },
+   { 0x46d, 0x14ed },
+   { 0x46e, 0x0446 },
+   { 0x46f, 0x1455 },
+   { 0x470, 0x04c6 },
+   { 0x471, 0x1220 },
+   { 0x472, 0x04c6 },
+   { 0x473, 0x040f },
+   { 0x474, 0x04ce },
+   { 0x475, 0x0339 },
+   { 0x476, 0x05df },
+   { 0x477, 0x028f },
+   { 0x478, 0x05df },
+   { 0x479, 0x0209 },
+   { 0x47a, 0x05df },
+   { 0x47b, 0x00cf },
+   { 0x47c, 0x05df },
+   { 0x47d, 0x0001 },
+   { 0x47e, 0x07ff },
+};
+
+int cs47l35_patch(struct madera *madera)
+{
+   int ret;
+
+   ret = regmap_register_patch(madera->regmap, cs47l35_reva_16_patch,
+   ARRAY_SIZE(cs47l35_reva_16_patch));
+   if (ret < 0)
+   dev_err(madera->dev, "Error applying patch: %d\n", ret);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(cs47l35_patch);
+
+static const struct reg_default cs47l35_reg_default[] = {
+   { 0x0020, 0x }, /* R32 (0x20) - Tone Generator 1 */
+   { 0x0021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
+   { 0x0022, 0x }, /* R34 (0x22) - Tone Generator 3 */
+   { 0x0023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
+   { 0x0024, 0x }, /* R36 (0x24) - Tone Generator 5 */
+   { 0x0030, 0x }, /* R48 (0x30) - PWM Drive 1 */
+   { 0x0031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
+   { 0x0032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
+   { 0x0061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
+   { 0x0062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
+   { 0x0063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
+   { 0x0064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4*/
+   { 0x0066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence 
Select 1*/
+   { 0x0067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence 
Select 2*/
+   { 0x0090, 0x }, /* R144 (0x90) - Haptics Control 1 */
+   { 0x0091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
+   { 0x0092, 0x }, /* R146 (0x92) - Haptics phase 1 intensity */
+   { 0x0093, 0x }, /* R147 (0x93) - Haptics phase 1 duration */
+   { 0x0094, 0x }, /* R148 (0x94) - Haptics phase 2 intensity */
+   { 0x0095, 0x }, /* R149 (0x95) - Haptics phase 2 duration */
+   { 0x0

[PATCH v7 00/17] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs

2018-01-15 Thread Richard Fitzgerald
IMPORTANT: These patches have to be submitted as an atomic block because of
build interdependencies so you'll need to agree who is going to take them
all through a branch.

The Cirrus Logic CS47L35, CS47L85, CS47L90/91 codecs are complex audio SoC
devices. In addition to the core audio capability they have onboard GPIO,
regulators, DSPs and interrupt controller and a large register map space
accessed over SPI or I2C. This family of codecs is based around common IP
blocks and they are managed by a set of common drivers referred to as "Madera".

Patches still waiting for review/ack:
#7-8 regulator
#9 irqchip
#14-17 ASoC

Richard Fitzgerald (17):
  mfd: madera: Add register definitions for Cirrus Logic Madera codecs
  mfd: madera: Add DT bindings for Cirrus Logic Madera codecs
  mfd: madera: Add common support for Cirrus Logic Madera codecs
  mfd: madera: Register map tables for Cirrus Logic CS47L35
  mfd: madera: Register map tables for Cirrus Logic CS47L85
  mfd: madera: Register map tables for Cirrus Logic CS47L90/91
  regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs
  regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs
  irqchip: Add driver for Cirrus Logic Madera codecs
  pinctrl: madera: Add DT bindings for Cirrus Logic Madera codecs
  pinctrl: madera: Add driver for Cirrus Logic Madera codecs
  gpio: madera: Support Cirrus Logic Madera class codecs
  ASoC: madera: Add DT bindings for Cirrus Logic Madera codecs
  ASoC: madera: Add common support for Cirrus Logic Madera codecs
  ASoC: cs47l35: Add codec driver for Cirrus Logic CS47L35
  ASoC: cs47l85: Add codec driver for Cirrus Logic CS47L85
  ASoC: cs47l90: Add codec driver for Cirrus Logic CS47L90

 Documentation/devicetree/bindings/mfd/madera.txt   |  102 +
 .../bindings/pinctrl/cirrus,madera-pinctrl.txt |   99 +
 .../bindings/regulator/arizona-regulator.txt   |3 +-
 Documentation/devicetree/bindings/sound/madera.txt |   67 +
 MAINTAINERS|   23 +
 drivers/gpio/Kconfig   |6 +
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-madera.c |  196 +
 drivers/irqchip/Kconfig|3 +
 drivers/irqchip/Makefile   |1 +
 drivers/irqchip/irq-madera.c   |  301 ++
 drivers/mfd/Kconfig|   48 +
 drivers/mfd/Makefile   |   13 +
 drivers/mfd/cs47l35-tables.c   | 1610 +++
 drivers/mfd/cs47l85-tables.c   | 3010 +
 drivers/mfd/cs47l90-tables.c   | 2675 
 drivers/mfd/madera-core.c  |  599 +++
 drivers/mfd/madera-i2c.c   |  140 +
 drivers/mfd/madera-spi.c   |  139 +
 drivers/mfd/madera.h   |   44 +
 drivers/pinctrl/Kconfig|1 +
 drivers/pinctrl/Makefile   |1 +
 drivers/pinctrl/cirrus/Kconfig |   15 +
 drivers/pinctrl/cirrus/Makefile|   11 +
 drivers/pinctrl/cirrus/pinctrl-cs47l35.c   |   46 +
 drivers/pinctrl/cirrus/pinctrl-cs47l85.c   |   60 +
 drivers/pinctrl/cirrus/pinctrl-cs47l90.c   |   58 +
 drivers/pinctrl/cirrus/pinctrl-madera.c| 1074 +
 drivers/pinctrl/cirrus/pinctrl-madera.h|   40 +
 drivers/regulator/Kconfig  |   15 +-
 drivers/regulator/arizona-ldo1.c   |   82 +-
 drivers/regulator/arizona-micsupp.c|   71 +-
 include/dt-bindings/sound/madera.h |   27 +
 include/linux/irqchip/irq-madera-pdata.h   |   23 +
 include/linux/irqchip/irq-madera.h |   98 +
 include/linux/mfd/madera/core.h|  196 +
 include/linux/mfd/madera/pdata.h   |   61 +
 include/linux/mfd/madera/registers.h   | 3916 +
 include/sound/madera-pdata.h   |   61 +
 sound/soc/codecs/Kconfig   |   23 +
 sound/soc/codecs/Makefile  |8 +
 sound/soc/codecs/cs47l35.c | 1671 
 sound/soc/codecs/cs47l85.c | 2677 
 sound/soc/codecs/cs47l90.c | 2651 
 sound/soc/codecs/madera.c  | 4439 
 sound/soc/codecs/madera.h  |  470 +++
 46 files changed, 26865 insertions(+), 10 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 create mode 100644 Documentation/devicetree/bindings/sound/madera.txt
 create mode 100644 drivers/gpio/gpio-madera.c
 create mode

[PATCH v7 03/17] mfd: madera: Add common support for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
This adds the generic core support for Cirrus Logic "Madera" class codecs.
These are complex audio codec SoCs with a variety of digital and analogue
I/O, onboard audio processing and DSPs, and other features.

These codecs are all based off a common set of hardware IP so can be
supported by a core of common code (with a few minor device-to-device
variations).

Signed-off-by: Charles Keepax 
Signed-off-by: Nikesh Oswal 
Signed-off-by: Richard Fitzgerald 
Acked-for-MFD-by: Lee Jones 
---
 MAINTAINERS  |   3 +
 drivers/mfd/Kconfig  |  27 ++
 drivers/mfd/Makefile |   4 +
 drivers/mfd/madera-core.c| 599 +++
 drivers/mfd/madera-i2c.c | 140 +
 drivers/mfd/madera-spi.c | 139 +
 drivers/mfd/madera.h |  44 +++
 include/linux/mfd/madera/core.h  | 196 +
 include/linux/mfd/madera/pdata.h |  61 
 9 files changed, 1213 insertions(+)
 create mode 100644 drivers/mfd/madera-core.c
 create mode 100644 drivers/mfd/madera-i2c.c
 create mode 100644 drivers/mfd/madera-spi.c
 create mode 100644 drivers/mfd/madera.h
 create mode 100644 include/linux/mfd/madera/core.h
 create mode 100644 include/linux/mfd/madera/pdata.h

diff --git a/MAINTAINERS b/MAINTAINERS
index d150555c328a..aa7f3a9dfa77 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3495,7 +3495,10 @@ L:   patc...@opensource.wolfsonmicro.com
 T: git https://github.com/CirrusLogic/linux-drivers.git
 W: https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
+F: Documentation/devicetree/bindings/mfd/madera.txt
 F: include/linux/mfd/madera/*
+F: drivers/mfd/madera*
+F: drivers/mfd/cs47l*
 
 CLEANCACHE API
 M: Konrad Rzeszutek Wilk 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..8ea298bdcf58 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -232,6 +232,33 @@ config MFD_CROS_EC_CHARDEV
   If you have a supported Chromebook, choose Y or M here.
   The module will be called cros_ec_dev.
 
+config MFD_MADERA
+   bool
+   select MFD_CORE
+   select REGMAP
+   select REGMAP_IRQ
+   select MADERA_IRQ
+
+config MFD_MADERA_I2C
+   bool "Cirrus Logic Madera codecs with I2C"
+   select MFD_MADERA
+   select REGMAP_I2C
+   select PINCTRL
+   depends on I2C
+   help
+ Support for the Cirrus Logic Madera platform audio SoC
+ core functionality controlled via I2C.
+
+config MFD_MADERA_SPI
+   bool "Cirrus Logic Madera codecs with SPI"
+   select MFD_MADERA
+   select REGMAP_SPI
+   select PINCTRL
+   depends on SPI_MASTER
+   help
+ Support for the Cirrus Logic Madera platform audio SoC
+ core functionality controlled via SPI.
+
 config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index d9d2cf0d32ef..1349e23e2be1 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -73,6 +73,10 @@ wm8994-objs  := wm8994-core.o wm8994-irq.o 
wm8994-regmap.o
 obj-$(CONFIG_MFD_WM8994)   += wm8994.o
 obj-$(CONFIG_MFD_WM97xx)   += wm97xx-core.o
 
+obj-$(CONFIG_MFD_MADERA)   += madera-core.o
+obj-$(CONFIG_MFD_MADERA_I2C)   += madera-i2c.o
+obj-$(CONFIG_MFD_MADERA_SPI)   += madera-spi.o
+
 obj-$(CONFIG_TPS6105X) += tps6105x.o
 obj-$(CONFIG_TPS65010) += tps65010.o
 obj-$(CONFIG_TPS6507X) += tps6507x.o
diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
new file mode 100644
index ..de1208b2f587
--- /dev/null
+++ b/drivers/mfd/madera-core.c
@@ -0,0 +1,599 @@
+/*
+ * Core MFD support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * Author: Richard Fitzgerald 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+
+#define CS47L35_SILICON_ID 0x6360
+#define CS47L85_SILICON_ID 0x6338
+#define CS47L90_SILICON_ID 0x6364
+
+#define MADERA_32KZ_MCLK2  1
+
+static const char * const madera_core_supplies[] = {
+   "AVDD",
+   "DBVDD1",
+};
+
+static const struct mfd_cell madera_ldo1_devs[] = {
+   { .name = "madera-ldo1" },
+};
+
+static const char * const cs47l35_supplies[] = {
+   "MICVDD",
+   "DBVDD2",
+   "CPVDD1",
+   "CPVDD2",
+   "SPKVDD",
+};
+
+static const struct mfd_cell cs47l35_devs[] = {
+   { .name = "madera-pinctrl"

[PATCH v7 02/17] mfd: madera: Add DT bindings for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
Specification of the bindings for the parent MFD driver component
of the Cirrus Logic Madera codec drivers.

Note that although the interrupt controller and GPIO are child
drivers their required bindings are trivial, mandatory, and exist
within the parent MFD node so are documented here.

Signed-off-by: Richard Fitzgerald 
Acked-by: Rob Herring 
Acked-for-MFD-by: Lee Jones 

---
 Documentation/devicetree/bindings/mfd/madera.txt | 102 +++
 1 file changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt

diff --git a/Documentation/devicetree/bindings/mfd/madera.txt 
b/Documentation/devicetree/bindings/mfd/madera.txt
new file mode 100644
index ..db3266088386
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/madera.txt
@@ -0,0 +1,102 @@
+Cirrus Logic Madera class audio codecs Multi-Functional Device
+
+These devices are audio SoCs with extensive digital capabilities and a range
+of analogue I/O.
+
+See also the child driver bindings in:
+bindings/pinctrl/cirrus,madera-pinctrl.txt
+bindings/regulator/arizona-regulator.txt
+bindings/sound/madera.txt
+
+Required properties:
+
+  - compatible : One of the following chip-specific strings:
+"cirrus,cs47l35"
+"cirrus,cs47l85"
+"cirrus,cs47l90"
+"cirrus,cs47l91"
+"cirrus,wm1840"
+
+  - reg : I2C slave address when connected using I2C, chip select number when
+using SPI.
+
+  - DCVDD-supply : Power supply for the device as defined in
+bindings/regulator/regulator.txt
+Mandatory on CS47L35, CS47L90, CS47L91
+Optional on CS47L85, WM1840
+
+  - AVDD-supply, DBVDD1-supply, DBVDD2-supply, CPVDD1-supply, CPVDD2-supply :
+Power supplies for the device
+
+  - DBVDD3-supply, DBVDD4-supply : Power supplies for the device
+(CS47L85, CS47L90, CS47L91, WM1840)
+
+  - SPKVDDL-supply, SPKVDDR-supply : Power supplies for the device
+(CS47L85, WM1840)
+
+  - SPKVDD-supply : Power supply for the device
+(CS47L35)
+
+  - interrupt-controller : Indicates that this device is an interrupt 
controller
+
+  - #interrupt-cells: the number of cells to describe an IRQ, must be 2.
+The first cell is the IRQ number.
+The second cell is the flags, encoded as the trigger masks from
+bindings/interrupt-controller/interrupts.txt
+
+  - gpio-controller : Indicates this device is a GPIO controller.
+
+  - #gpio-cells : Must be 2. The first cell is the pin number. The second cell
+is reserved for future use and must be zero
+
+  - interrupt-parent : The parent interrupt controller.
+
+  - interrupts : The interrupt line the /IRQ signal for the device is
+connected to.
+
+Optional properties:
+
+  - MICVDD-supply : Power supply, only need to be specified if
+powered externally
+
+  - reset-gpios : One entry specifying the GPIO controlling /RESET.
+As defined in bindings/gpio.txt.
+Although optional, it is strongly recommended to use a hardware reset
+
+  - MICBIASx : Initial data for the MICBIAS regulators, as covered in
+Documentation/devicetree/bindings/regulator/regulator.txt.
+One for each MICBIAS generator (MICBIAS1, MICBIAS2, ...)
+(all codecs)
+
+One for each output pin (MICBIAS1A, MIBCIAS1B, MICBIAS2A, ...)
+(all except CS47L85, WM1840)
+
+The following following additional property is supported for the generator
+nodes:
+  - cirrus,ext-cap : Set to 1 if the MICBIAS has external decoupling
+capacitors attached.
+
+Optional child nodes:
+micvdd : Node containing initialization data for the micvdd regulator
+See bindings/regulator/arizona-regulator.txt
+
+ldo1 : Node containing initialization data for the LDO1 regulator
+See bindings/regulator/arizona-regulator.txt
+(cs47l85, wm1840)
+
+Example:
+
+cs47l85@0 {
+   compatible = "cirrus,cs47l85";
+   reg = <0>;
+
+   reset-gpios = <&gpio 0>;
+
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   interrupts = <&host_irq1>;
+   interrupt-parent = <&gic>;
+
+   gpio-controller;
+   #gpio-cells = <2>;
+};
-- 
2.11.0



[PATCH v7 17/17] ASoC: cs47l90: Add codec driver for Cirrus Logic CS47L90

2018-01-15 Thread Richard Fitzgerald
Adds the codec driver for the CS47L90 SmartCodec. This is a
multi-functional codec based on the Cirrus Logic Madera platform.

Signed-off-by: Nikesh Oswal 
Signed-off-by: Charles Keepax 
Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/Kconfig   |6 +
 sound/soc/codecs/Makefile  |2 +
 sound/soc/codecs/cs47l90.c | 2651 
 3 files changed, 2659 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l90.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 5e431d50529a..5a72f47418ce 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -65,6 +65,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS47L35 if MFD_CS47L35
select SND_SOC_CS47L85 if MFD_CS47L85
+   select SND_SOC_CS47L90 if MFD_CS47L90
select SND_SOC_CS53L30 if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
@@ -516,6 +517,9 @@ config SND_SOC_CS47L35
 config SND_SOC_CS47L85
tristate
 
+config SND_SOC_CS47L90
+   tristate
+
 # Cirrus Logic Quad-Channel ADC
 config SND_SOC_CS53L30
tristate "Cirrus Logic CS53L30 CODEC"
@@ -609,8 +613,10 @@ config SND_SOC_MADERA
tristate
default y if SND_SOC_CS47L35=y
default y if SND_SOC_CS47L85=y
+   default y if SND_SOC_CS47L90=y
default m if SND_SOC_CS47L35=m
default m if SND_SOC_CS47L85=m
+   default m if SND_SOC_CS47L90=m
 
 config SND_SOC_MAX98088
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index d7596a68cc11..51171c8ffc08 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -59,6 +59,7 @@ snd-soc-cs4349-objs := cs4349.o
 snd-soc-cs47l24-objs := cs47l24.o
 snd-soc-cs47l35-objs := cs47l35.o
 snd-soc-cs47l85-objs := cs47l85.o
+snd-soc-cs47l90-objs := cs47l90.o
 snd-soc-cs53l30-objs := cs53l30.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
@@ -307,6 +308,7 @@ obj-$(CONFIG_SND_SOC_CS4349)+= snd-soc-cs4349.o
 obj-$(CONFIG_SND_SOC_CS47L24)  += snd-soc-cs47l24.o
 obj-$(CONFIG_SND_SOC_CS47L35)  += snd-soc-cs47l35.o
 obj-$(CONFIG_SND_SOC_CS47L85)  += snd-soc-cs47l85.o
+obj-$(CONFIG_SND_SOC_CS47L90)  += snd-soc-cs47l90.o
 obj-$(CONFIG_SND_SOC_CS53L30)  += snd-soc-cs53l30.o
 obj-$(CONFIG_SND_SOC_CX20442)  += snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)   += snd-soc-da7210.o
diff --git a/sound/soc/codecs/cs47l90.c b/sound/soc/codecs/cs47l90.c
new file mode 100644
index ..a4d0319403bc
--- /dev/null
+++ b/sound/soc/codecs/cs47l90.c
@@ -0,0 +1,2651 @@
+/*
+ * cs47l90.c  --  ALSA SoC Audio driver for CS47L90 codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * Author: Nikesh Oswal 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+#include "wm_adsp.h"
+
+#define CS47L90_NUM_ADSP   7
+#define CS47L90_MONO_OUTPUTS   3
+
+struct cs47l90 {
+   struct madera_priv core;
+   struct madera_fll fll[3];
+};
+
+static const struct wm_adsp_region cs47l90_dsp1_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x08 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x0e },
+   { .type = WMFW_ADSP2_XM, .base = 0x0a },
+   { .type = WMFW_ADSP2_YM, .base = 0x0c },
+};
+
+static const struct wm_adsp_region cs47l90_dsp2_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x10 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x16 },
+   { .type = WMFW_ADSP2_XM, .base = 0x12 },
+   { .type = WMFW_ADSP2_YM, .base = 0x14 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp3_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x18 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x1e },
+   { .type = WMFW_ADSP2_XM, .base = 0x1a },
+   { .type = WMFW_ADSP2_YM, .base = 0x1c },
+};
+
+static const struct wm_adsp_region cs47l90_dsp4_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x20 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x26 },
+   { .type = WMFW_ADSP2_XM, .base = 0x22 },
+   { .type = WMFW_ADSP2_YM, .base = 0x24 },
+};
+
+static const struct wm_adsp_region cs47l90_dsp5_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x28 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x2e },
+   { .type = WMFW_ADSP2_XM, .base = 0x2a },
+   { .type = WMFW_ADSP2_YM, .base = 0x2c },
+};
+
+static const struct wm_adsp_region cs47l90_dsp6_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x30 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x36 },
+   { .type = W

[PATCH v7 14/17] ASoC: madera: Add common support for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs are a family of related codecs with
extensive digital and analogue I/O, digital mixing and routing,
signal processing and programmable DSPs.

This patch adds common support code shared by all Madera codecs.

Signed-off-by: Charles Keepax 
Signed-off-by: Nariman Poushin 
Signed-off-by: Nikesh Oswal 
Signed-off-by: Piotr Stankiewicz 
Signed-off-by: Ajit Pandey 
Signed-off-by: Richard Fitzgerald 
---
 MAINTAINERS  |4 +
 include/sound/madera-pdata.h |   61 +
 sound/soc/codecs/Kconfig |5 +
 sound/soc/codecs/Makefile|2 +
 sound/soc/codecs/madera.c| 4439 ++
 sound/soc/codecs/madera.h|  470 +
 6 files changed, 4981 insertions(+)
 create mode 100644 include/sound/madera-pdata.h
 create mode 100644 sound/soc/codecs/madera.c
 create mode 100644 sound/soc/codecs/madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 49f1ca1698ab..f53ae362814b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3497,14 +3497,18 @@ W:  
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: Documentation/devicetree/bindings/sound/madera.txt
 F: include/dt-bindings/sound/madera*
 F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
+F: include/sound/madera*
 F: drivers/gpio/gpio-madera*
 F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
+F: sound/soc/codecs/cs47l*
+F: sound/soc/codecs/madera*
 
 CLEANCACHE API
 M: Konrad Rzeszutek Wilk 
diff --git a/include/sound/madera-pdata.h b/include/sound/madera-pdata.h
new file mode 100644
index ..47f6b44e53f8
--- /dev/null
+++ b/include/sound/madera-pdata.h
@@ -0,0 +1,61 @@
+/*
+ * Platform data for Madera codec driver
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef MADERA_CODEC_PDATA_H
+#define MADERA_CODEC_PDATA_H
+
+#include 
+
+#define MADERA_MAX_INPUT   6
+#define MADERA_MAX_MUXED_CHANNELS  4
+#define MADERA_MAX_OUTPUT  6
+#define MADERA_MAX_AIF 4
+#define MADERA_MAX_PDM_SPK 2
+#define MADERA_MAX_DSP 7
+
+/**
+ * struct madera_codec_pdata
+ *
+ * @max_channels_clocked: Maximum number of channels that I2S clocks will be
+ *   generated for. Useful when clock master for systems
+ *   where the I2S bus has multiple data lines.
+ * @dmic_ref:Indicates how the MICBIAS pins have been externally
+ *   connected to DMICs on each input. A value of 0
+ *   indicates MICVDD and is the default. Other values are:
+ *   For CS47L35 one of the CS47L35_DMIC_REF_xxx values
+ *   For all other codecs one of the MADERA_DMIC_REF_xxx
+ *   Also see the datasheet for a description of the
+ *   INn_DMIC_SUP field.
+ * @inmode:  Mode for the ADC inputs. One of the MADERA_INMODE_xxx
+ *   values. Two-dimensional array
+ *   [input_number][channel number], with four slots per
+ *   input in the order
+ *   [n][0]=INnAL [n][1]=INnAR [n][2]=INnBL [n][3]=INnBR
+ * @out_mono:For each output set the value to TRUE to indicate that
+ *   the output is mono. [0]=OUT1, [1]=OUT2, ...
+ * @pdm_fmt: PDM speaker data format. See the PDM_SPKn_FMT field in
+ *   the datasheet for a description of this value.
+ * @pdm_mute:PDM mute format. See the PDM_SPKn_CTRL_1 register
+ *   in the datasheet for a description of this value.
+ */
+struct madera_codec_pdata {
+   u32 max_channels_clocked[MADERA_MAX_AIF];
+
+   u32 dmic_ref[MADERA_MAX_INPUT];
+
+   u32 inmode[MADERA_MAX_INPUT][MADERA_MAX_MUXED_CHANNELS];
+
+   bool out_mono[MADERA_MAX_OUTPUT];
+
+   u32 pdm_fmt[MADERA_MAX_PDM_SPK];
+   u32 pdm_mute[MADERA_MAX_PDM_SPK];
+};
+
+#endif
diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 2b331f7266ab..77a5dc072b47 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -256,10 +256,12 @@ config SND_SOC_WM_HUBS
 config SND_SOC_WM_ADSP
tristate
select SND_SOC_COMPRESS
+   default y if SND_SOC_MADERA=y
default y if SND_SOC_CS47L24=y
default y if SND_SOC_WM5102=y
default y if SND_SOC_WM5110=y
default y if SND_SOC_WM2200=y
+   default m if SND_SOC_MADERA=m
default m if SND_SOC_CS47L24=m
default

[PATCH v7 16/17] ASoC: cs47l85: Add codec driver for Cirrus Logic CS47L85

2018-01-15 Thread Richard Fitzgerald
Adds the codec driver for the CS47L85 SmartCodec. This is a
multi-functional codec based on the Cirrus Logic Madera platform.

Signed-off-by: Nariman Poushin 
Signed-off-by: Charles Keepax 
Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/Kconfig   |6 +
 sound/soc/codecs/Makefile  |2 +
 sound/soc/codecs/cs47l85.c | 2677 
 3 files changed, 2685 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l85.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index d3ccec56f6a1..5e431d50529a 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -64,6 +64,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L24 if MFD_CS47L24
select SND_SOC_CS47L35 if MFD_CS47L35
+   select SND_SOC_CS47L85 if MFD_CS47L85
select SND_SOC_CS53L30 if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
@@ -512,6 +513,9 @@ config SND_SOC_CS47L24
 config SND_SOC_CS47L35
tristate
 
+config SND_SOC_CS47L85
+   tristate
+
 # Cirrus Logic Quad-Channel ADC
 config SND_SOC_CS53L30
tristate "Cirrus Logic CS53L30 CODEC"
@@ -604,7 +608,9 @@ config SND_SOC_LM49453
 config SND_SOC_MADERA
tristate
default y if SND_SOC_CS47L35=y
+   default y if SND_SOC_CS47L85=y
default m if SND_SOC_CS47L35=m
+   default m if SND_SOC_CS47L85=m
 
 config SND_SOC_MAX98088
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index 6438b878a850..d7596a68cc11 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -58,6 +58,7 @@ snd-soc-cs43130-objs := cs43130.o
 snd-soc-cs4349-objs := cs4349.o
 snd-soc-cs47l24-objs := cs47l24.o
 snd-soc-cs47l35-objs := cs47l35.o
+snd-soc-cs47l85-objs := cs47l85.o
 snd-soc-cs53l30-objs := cs53l30.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
@@ -305,6 +306,7 @@ obj-$(CONFIG_SND_SOC_CS43130)   += snd-soc-cs43130.o
 obj-$(CONFIG_SND_SOC_CS4349)   += snd-soc-cs4349.o
 obj-$(CONFIG_SND_SOC_CS47L24)  += snd-soc-cs47l24.o
 obj-$(CONFIG_SND_SOC_CS47L35)  += snd-soc-cs47l35.o
+obj-$(CONFIG_SND_SOC_CS47L85)  += snd-soc-cs47l85.o
 obj-$(CONFIG_SND_SOC_CS53L30)  += snd-soc-cs53l30.o
 obj-$(CONFIG_SND_SOC_CX20442)  += snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)   += snd-soc-da7210.o
diff --git a/sound/soc/codecs/cs47l85.c b/sound/soc/codecs/cs47l85.c
new file mode 100644
index ..4a4a7501744d
--- /dev/null
+++ b/sound/soc/codecs/cs47l85.c
@@ -0,0 +1,2677 @@
+/*
+ * cs47l85.c  --  ALSA SoC Audio driver for CS47L85 codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+#include "wm_adsp.h"
+
+#define CS47L85_NUM_ADSP   7
+#define CS47L85_MONO_OUTPUTS   4
+
+struct cs47l85 {
+   struct madera_priv core;
+   struct madera_fll fll[3];
+};
+
+static const struct wm_adsp_region cs47l85_dsp1_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x08 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x0e },
+   { .type = WMFW_ADSP2_XM, .base = 0x0a },
+   { .type = WMFW_ADSP2_YM, .base = 0x0c },
+};
+
+static const struct wm_adsp_region cs47l85_dsp2_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x10 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x16 },
+   { .type = WMFW_ADSP2_XM, .base = 0x12 },
+   { .type = WMFW_ADSP2_YM, .base = 0x14 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp3_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x18 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x1e },
+   { .type = WMFW_ADSP2_XM, .base = 0x1a },
+   { .type = WMFW_ADSP2_YM, .base = 0x1c },
+};
+
+static const struct wm_adsp_region cs47l85_dsp4_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x20 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x26 },
+   { .type = WMFW_ADSP2_XM, .base = 0x22 },
+   { .type = WMFW_ADSP2_YM, .base = 0x24 },
+};
+
+static const struct wm_adsp_region cs47l85_dsp5_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x28 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x2e },
+   { .type = WMFW_ADSP2_XM, .base = 0x2a },
+   { .type = WMFW_ADSP2_YM, .base = 0x2c },
+};
+
+static const struct wm_adsp_region cs47l85_dsp6_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x30 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x36 },
+   { .type = WMFW_ADSP2_XM, .base = 0x32 },
+   { .type = WMFW_ADSP2_YM, .base = 0x34

[PATCH v7 06/17] mfd: madera: Register map tables for Cirrus Logic CS47L90/91

2018-01-15 Thread Richard Fitzgerald
Regmap configuration tables for Cirrus Logic CS47L90 and CS47L91 codecs.

Signed-off-by: Nikesh Oswal 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
Acked-for-MFD-by: Lee Jones 
---
 drivers/mfd/Kconfig  |7 +
 drivers/mfd/Makefile |3 +
 drivers/mfd/cs47l90-tables.c | 2675 ++
 3 files changed, 2685 insertions(+)
 create mode 100644 drivers/mfd/cs47l90-tables.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f167add2792d..33f4da0670a3 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -273,6 +273,13 @@ config MFD_CS47L85
help
  Support for Cirrus Logic CS47L85 Smart Codec
 
+config MFD_CS47L90
+   bool "Cirrus Logic CS47L90/91"
+   select PINCTRL_CS47L90
+   depends on MFD_MADERA
+   help
+ Support for Cirrus Logic CS47L90 and CS47L91 Smart Codecs
+
 config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 43750bf5edbf..3ba9ce8da0ec 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -80,6 +80,9 @@ endif
 ifeq ($(CONFIG_MFD_CS47L85),y)
 obj-$(CONFIG_MFD_MADERA)   += cs47l85-tables.o
 endif
+ifeq ($(CONFIG_MFD_CS47L90),y)
+obj-$(CONFIG_MFD_MADERA)   += cs47l90-tables.o
+endif
 obj-$(CONFIG_MFD_MADERA_I2C)   += madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)   += madera-spi.o
 
diff --git a/drivers/mfd/cs47l90-tables.c b/drivers/mfd/cs47l90-tables.c
new file mode 100644
index ..1ab02f799eba
--- /dev/null
+++ b/drivers/mfd/cs47l90-tables.c
@@ -0,0 +1,2675 @@
+/*
+ * Regmap tables for CS47L90 codec
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * Author: Nikesh Oswal 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+
+static const struct reg_sequence cs47l90_reva_16_patch[] = {
+   { 0x8A,   0x },
+   { 0x8A,   0x },
+   { 0x4CF,  0x0700 },
+   { 0x171,  0x0003 },
+   { 0x101,  0x0444 },
+   { 0x159,  0x0002 },
+   { 0x120,  0x0444 },
+   { 0x1D1,  0x0004 },
+   { 0x1E0,  0xC084 },
+   { 0x159,  0x },
+   { 0x120,  0x0404 },
+   { 0x101,  0x0404 },
+   { 0x171,  0x0002 },
+   { 0x17A,  0x2906 },
+   { 0x19A,  0x2906 },
+   { 0x441,  0xC750 },
+   { 0x340,  0x0001 },
+   { 0x112,  0x0405 },
+   { 0x124,  0x0C49 },
+   { 0x1300, 0x050E },
+   { 0x1302, 0x0101 },
+   { 0x1380, 0x0425 },
+   { 0x1381, 0xF6D8 },
+   { 0x1382, 0x0632 },
+   { 0x1383, 0xFEC8 },
+   { 0x1390, 0x042F },
+   { 0x1391, 0xF6CA },
+   { 0x1392, 0x0637 },
+   { 0x1393, 0xFEC8 },
+   { 0x281,  0x },
+   { 0x282,  0x },
+   { 0x4EA,  0x0100 },
+   { 0x8A,   0x },
+   { 0x8A,   0x },
+};
+
+int cs47l90_patch(struct madera *madera)
+{
+   int ret;
+
+   ret = regmap_register_patch(madera->regmap,
+   cs47l90_reva_16_patch,
+   ARRAY_SIZE(cs47l90_reva_16_patch));
+   if (ret < 0) {
+   dev_err(madera->dev,
+   "Error in applying 16-bit patch: %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(cs47l90_patch);
+
+static const struct reg_default cs47l90_reg_default[] = {
+   { 0x0020, 0x }, /* R32 (0x20) - Tone Generator 1 */
+   { 0x0021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
+   { 0x0022, 0x }, /* R34 (0x22) - Tone Generator 3 */
+   { 0x0023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
+   { 0x0024, 0x }, /* R36 (0x24) - Tone Generator 5 */
+   { 0x0030, 0x }, /* R48 (0x30) - PWM Drive 1 */
+   { 0x0031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
+   { 0x0032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
+   { 0x0061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
+   { 0x0062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
+   { 0x0063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
+   { 0x0064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4 
*/
+   { 0x0066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence 
Select 1 */
+   { 0x0067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence 
Select 2 */
+   { 0x0090, 0x }, /* R144 (0x90) - Haptics Control 1 */
+   { 0x0091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
+   { 0x0092, 0x }, /* R146 (0x92) - Haptics phase 1 intensity */
+   { 0x0093, 0x }, /* R147 (0x93) - Haptics phase 1 duration */
+   { 0x0

[PATCH v7 08/17] regulator: arizona-ldo1: Add support for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
This adds a new driver identity "madera-ldo1" and probe function
so that this driver can be used to control the LDO1 regulator on
some Cirrus Logic Madera codecs.

Signed-off-by: Richard Fitzgerald 
---
 drivers/regulator/Kconfig|  8 ++--
 drivers/regulator/arizona-ldo1.c | 82 +++-
 2 files changed, 85 insertions(+), 5 deletions(-)

diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index eed360626274..51a772e2b685 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -126,12 +126,12 @@ config REGULATOR_AB8500
  signal AB8500 PMIC
 
 config REGULATOR_ARIZONA_LDO1
-   tristate "Wolfson Arizona class devices LDO1"
-   depends on MFD_ARIZONA
+   tristate "Cirrus Madera and Wolfson Arizona class devices LDO1"
+   depends on MFD_ARIZONA || MFD_MADERA
depends on SND_SOC
help
- Support for the LDO1 regulators found on Wolfson Arizona class
- devices.
+ Support for the LDO1 regulators found on Cirrus Logic Madera codecs
+ and Wolfson Arizona codecs.
 
 config REGULATOR_ARIZONA_MICSUPP
tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
diff --git a/drivers/regulator/arizona-ldo1.c b/drivers/regulator/arizona-ldo1.c
index 96fddfff5dc4..c64625e76124 100644
--- a/drivers/regulator/arizona-ldo1.c
+++ b/drivers/regulator/arizona-ldo1.c
@@ -31,6 +31,10 @@
 #include 
 #include 
 
+#include 
+#include 
+#include 
+
 struct arizona_ldo1 {
struct regulator_dev *regulator;
struct regmap *regmap;
@@ -188,6 +192,31 @@ static const struct regulator_init_data 
arizona_ldo1_wm5110 = {
.num_consumer_supplies = 1,
 };
 
+static const struct regulator_desc madera_ldo1 = {
+   .name = "LDO1",
+   .supply_name = "LDOVDD",
+   .type = REGULATOR_VOLTAGE,
+   .ops = &arizona_ldo1_ops,
+
+   .vsel_reg = MADERA_LDO1_CONTROL_1,
+   .vsel_mask = MADERA_LDO1_VSEL_MASK,
+   .min_uV = 90,
+   .uV_step = 25000,
+   .n_voltages = 13,
+   .enable_time = 3000,
+
+   .owner = THIS_MODULE,
+};
+
+static const struct regulator_init_data madera_ldo1_default = {
+   .constraints = {
+   .min_uV = 120,
+   .max_uV = 120,
+   .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+   },
+   .num_consumer_supplies = 1,
+};
+
 static int arizona_ldo1_of_get_pdata(struct arizona_ldo1_pdata *pdata,
 struct regulator_config *config,
 const struct regulator_desc *desc,
@@ -341,6 +370,32 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
return ret;
 }
 
+static int madera_ldo1_probe(struct platform_device *pdev)
+{
+   struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+   struct arizona_ldo1 *ldo1;
+   bool external_dcvdd;
+   int ret;
+
+   ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
+   if (!ldo1)
+   return -ENOMEM;
+
+   ldo1->regmap = madera->regmap;
+
+   ldo1->init_data = madera_ldo1_default;
+
+   ret = arizona_ldo1_common_init(pdev, ldo1, &arizona_ldo1,
+  &madera->pdata.ldo1,
+  &external_dcvdd);
+   if (ret)
+   return ret;
+
+   madera->internal_dcvdd = !external_dcvdd;
+
+   return 0;
+}
+
 static struct platform_driver arizona_ldo1_driver = {
.probe = arizona_ldo1_probe,
.driver = {
@@ -348,10 +403,35 @@ static struct platform_driver arizona_ldo1_driver = {
},
 };
 
-module_platform_driver(arizona_ldo1_driver);
+static struct platform_driver madera_ldo1_driver = {
+   .probe = madera_ldo1_probe,
+   .driver = {
+   .name   = "madera-ldo1",
+   },
+};
+
+static struct platform_driver * const madera_ldo1_drivers[] = {
+   &arizona_ldo1_driver,
+   &madera_ldo1_driver,
+};
+
+static int __init arizona_ldo1_init(void)
+{
+   return platform_register_drivers(madera_ldo1_drivers,
+ARRAY_SIZE(madera_ldo1_drivers));
+}
+module_init(arizona_ldo1_init);
+
+static void __exit madera_ldo1_exit(void)
+{
+   platform_unregister_drivers(madera_ldo1_drivers,
+   ARRAY_SIZE(madera_ldo1_drivers));
+}
+module_exit(madera_ldo1_exit);
 
 /* Module information */
 MODULE_AUTHOR("Mark Brown ");
 MODULE_DESCRIPTION("Arizona LDO1 driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:arizona-ldo1");
+MODULE_ALIAS("platform:madera-ldo1");
-- 
2.11.0



[PATCH v7 15/17] ASoC: cs47l35: Add codec driver for Cirrus Logic CS47L35

2018-01-15 Thread Richard Fitzgerald
Adds the codec driver for the CS47L35 SmartCodec. This is a
multi-functional codec based on the Cirrus Logic Madera platform.

Signed-off-by: Piotr Stankiewicz 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
 sound/soc/codecs/Kconfig   |6 +
 sound/soc/codecs/Makefile  |2 +
 sound/soc/codecs/cs47l35.c | 1671 
 3 files changed, 1679 insertions(+)
 create mode 100644 sound/soc/codecs/cs47l35.c

diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
index 77a5dc072b47..d3ccec56f6a1 100644
--- a/sound/soc/codecs/Kconfig
+++ b/sound/soc/codecs/Kconfig
@@ -63,6 +63,7 @@ config SND_SOC_ALL_CODECS
select SND_SOC_CS43130 if I2C
select SND_SOC_CS4349 if I2C
select SND_SOC_CS47L24 if MFD_CS47L24
+   select SND_SOC_CS47L35 if MFD_CS47L35
select SND_SOC_CS53L30 if I2C
select SND_SOC_CX20442 if TTY
select SND_SOC_DA7210 if SND_SOC_I2C_AND_SPI
@@ -508,6 +509,9 @@ config SND_SOC_CS4349
 config SND_SOC_CS47L24
tristate
 
+config SND_SOC_CS47L35
+   tristate
+
 # Cirrus Logic Quad-Channel ADC
 config SND_SOC_CS53L30
tristate "Cirrus Logic CS53L30 CODEC"
@@ -599,6 +603,8 @@ config SND_SOC_LM49453
 
 config SND_SOC_MADERA
tristate
+   default y if SND_SOC_CS47L35=y
+   default m if SND_SOC_CS47L35=m
 
 config SND_SOC_MAX98088
tristate
diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
index deb3641970e5..6438b878a850 100644
--- a/sound/soc/codecs/Makefile
+++ b/sound/soc/codecs/Makefile
@@ -57,6 +57,7 @@ snd-soc-cs42xx8-i2c-objs := cs42xx8-i2c.o
 snd-soc-cs43130-objs := cs43130.o
 snd-soc-cs4349-objs := cs4349.o
 snd-soc-cs47l24-objs := cs47l24.o
+snd-soc-cs47l35-objs := cs47l35.o
 snd-soc-cs53l30-objs := cs53l30.o
 snd-soc-cx20442-objs := cx20442.o
 snd-soc-da7210-objs := da7210.o
@@ -303,6 +304,7 @@ obj-$(CONFIG_SND_SOC_CS42XX8_I2C) += snd-soc-cs42xx8-i2c.o
 obj-$(CONFIG_SND_SOC_CS43130)   += snd-soc-cs43130.o
 obj-$(CONFIG_SND_SOC_CS4349)   += snd-soc-cs4349.o
 obj-$(CONFIG_SND_SOC_CS47L24)  += snd-soc-cs47l24.o
+obj-$(CONFIG_SND_SOC_CS47L35)  += snd-soc-cs47l35.o
 obj-$(CONFIG_SND_SOC_CS53L30)  += snd-soc-cs53l30.o
 obj-$(CONFIG_SND_SOC_CX20442)  += snd-soc-cx20442.o
 obj-$(CONFIG_SND_SOC_DA7210)   += snd-soc-da7210.o
diff --git a/sound/soc/codecs/cs47l35.c b/sound/soc/codecs/cs47l35.c
new file mode 100644
index ..c75998c4cb0c
--- /dev/null
+++ b/sound/soc/codecs/cs47l35.c
@@ -0,0 +1,1671 @@
+/*
+ * cs47l35.c  --  ALSA SoC Audio driver for CS47L35 codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+#include "madera.h"
+#include "wm_adsp.h"
+
+#define CS47L35_NUM_ADSP   3
+#define CS47L35_MONO_OUTPUTS   1
+
+struct cs47l35 {
+   struct madera_priv core;
+   struct madera_fll fll;
+};
+
+static const struct wm_adsp_region cs47l35_dsp1_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x08 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x0e },
+   { .type = WMFW_ADSP2_XM, .base = 0x0a },
+   { .type = WMFW_ADSP2_YM, .base = 0x0c },
+};
+
+static const struct wm_adsp_region cs47l35_dsp2_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x10 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x16 },
+   { .type = WMFW_ADSP2_XM, .base = 0x12 },
+   { .type = WMFW_ADSP2_YM, .base = 0x14 },
+};
+
+static const struct wm_adsp_region cs47l35_dsp3_regions[] = {
+   { .type = WMFW_ADSP2_PM, .base = 0x18 },
+   { .type = WMFW_ADSP2_ZM, .base = 0x1e },
+   { .type = WMFW_ADSP2_XM, .base = 0x1a },
+   { .type = WMFW_ADSP2_YM, .base = 0x1c },
+};
+
+static const struct wm_adsp_region *cs47l35_dsp_regions[] = {
+   cs47l35_dsp1_regions,
+   cs47l35_dsp2_regions,
+   cs47l35_dsp3_regions,
+};
+
+static const int wm_adsp2_control_bases[] = {
+   MADERA_DSP1_CONFIG_1,
+   MADERA_DSP2_CONFIG_1,
+   MADERA_DSP3_CONFIG_1,
+};
+
+static const char * const cs47l35_outdemux_texts[] = {
+   "HPOUT",
+   "EPOUT",
+};
+
+static SOC_ENUM_SINGLE_DECL(cs47l35_outdemux_enum, SND_SOC_NOPM, 0,
+   cs47l35_outdemux_texts);
+
+static const struct snd_kcontrol_new cs47l35_outdemux =
+   SOC_DAPM_ENUM_EXT("HPOUT1 Demux", cs47l35_outdemux_enum,
+ snd_soc_dapm_get_enum_double, madera_out1_demux_put);
+
+static int cs47l35_adsp_power_ev(struct snd_soc_dapm_widget *w,
+struct snd_kcontrol *kcontrol,
+

[PATCH v7 10/17] pinctrl: madera: Add DT bindings for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
This is the binding description of the pinctrl driver for Cirru Logic
Madera codecs. The binding uses the generic pinctrl binding so  the main
purpose here is to describe the device-specific names for groups and
functions.

Signed-off-by: Richard Fitzgerald 
Acked-by: Rob Herring 
---
 .../bindings/pinctrl/cirrus,madera-pinctrl.txt | 99 ++
 1 file changed, 99 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt

diff --git 
a/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
new file mode 100644
index ..b0e36cf0d289
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
@@ -0,0 +1,99 @@
+Cirrus Logic Madera class audio codecs pinctrl driver
+
+The Cirrus Logic Madera codecs provide a number of GPIO functions for
+interfacing to external hardware and to provide logic outputs to other devices.
+Certain groups of GPIO pins also have an alternate function, normally as an
+audio interface.
+
+The set of available GPIOs, functions and alternate function groups differs
+between codecs so refer to the datasheet for the codec for further information
+on what is supported on that device.
+
+The properties for this driver exist within the parent MFD driver node.
+
+See also
+  the core bindings for the parent MFD driver:
+Documentation/devicetree/bindings/mfd/madera.txt
+
+  the generic pinmix bindings:
+Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+
+Required properties of parent mfd node:
+  - pinctrl-names : must be "default"
+  - pinctrl-0 : a phandle to the node containing the subnodes containing 
default
+  configurations
+
+Required subnodes:
+  One subnode is required to contain the default settings. It contains an
+  arbitrary number of configuration subnodes, one for each group or pin
+  configuration you want to apply as a default.
+
+Required properties of configuration subnodes:
+  - groups : name of one pin group to configure. One of:
+   aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+   dmic4, dmic5, dmic6,
+   gpio1, gpio2, ..., gpio40
+The gpioN groups select the single pin of this name for configuration
+
+Optional properties of configuration subnodes:
+  Any configuration option not explicitly listed in the dts will be left at
+  chip default setting.
+
+  - function : name of function to assign to this group. One of:
+   aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+   dmic3, dmic4, dmic5, dmic6,
+   io, dsp-gpio, irq1, irq2,
+   fll1-clk, fll1-lock, fll2-clk, fll2-lock, fll3-clk, fll3-lock,
+   fllao-clk, fllao-lock,
+   opclk, opclk-async, pwm1, pwm2, spdif,
+   asrc1-in1-lock, asrc1-in2-lock, asrc2-in1-lock, asrc2-in2-lock,
+   spkl-short-circuit, spkr-short-circuit, spk-shutdown,
+   spk-overheat-shutdown, spk-overheat-warn,
+   timer1-sts, timer2-sts, timer3-sts, timer4-sts, timer5-sts, timer6-sts,
+   timer7-sts, timer8-sts,
+   log1-fifo-ne, log2-fifo-ne, log3-fifo-ne, log4-fifo-ne, log5-fifo-ne,
+   log6-fifo-ne, log7-fifo-ne, log8-fifo-ne,
+
+  - bias-disable : disable pull-up and pull-down
+  - bias-bus-hold : enable buskeeper
+  - bias-pull-up : output is pulled-up
+  - bias-pull-down : output is pulled-down
+  - drive-push-pull : CMOS output
+  - drive-open-drain : open-drain output
+  - drive-strength : drive strength in mA. Valid values are 4 or 8
+  - input-schmitt-enable : enable schmitt-trigger mode
+  - input-schmitt-disable : disable schmitt-trigger mode
+  - input-debounce : A value of 0 disables debounce, a value !=0 enables
+   debounce
+  - output-low : set the pin to output mode with low level
+  - output-high : set the pin to output mode with high level
+
+Example:
+
+cs47l85@0 {
+   compatible = "cirrus,cs47l85";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&cs47l85_defaults>;
+
+   cs47l85_defaults: cs47l85-gpio-defaults {
+   aif1 {
+   groups = "aif1";
+   function = "aif1";
+   bias-bus-hold;
+   };
+
+   aif2 {
+   groups = "aif2";
+   function = "aif2";
+   bias-bus-hold;
+   };
+
+   opclk {
+   groups = "gpio1";
+   function = "opclk";
+   bias-pull-up;
+   drive-strength = <8>;
+   };
+   };
+};
-- 
2.11.0



[PATCH v7 13/17] ASoC: madera: Add DT bindings for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs are a family of related codecs with
extensive digital and analogue I/O, digital mixing and routing,
signal processing and programmable DSPs.

Signed-off-by: Richard Fitzgerald 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/sound/madera.txt | 67 ++
 MAINTAINERS|  1 +
 include/dt-bindings/sound/madera.h | 27 +
 3 files changed, 95 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/madera.txt
 create mode 100644 include/dt-bindings/sound/madera.h

diff --git a/Documentation/devicetree/bindings/sound/madera.txt 
b/Documentation/devicetree/bindings/sound/madera.txt
new file mode 100644
index ..1114fcf1aa4c
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/madera.txt
@@ -0,0 +1,67 @@
+Cirrus Logic Madera class audio codecs
+
+This describes audio configuration bindings for these codecs.
+
+See also the core bindings for the parent MFD driver:
+See Documentation/devicetree/bindings/mfd/madera.txt
+
+and defines for values used in these bindings:
+include/dt-bindings/sound/madera.h
+
+These properties are all contained in the parent MFD node.
+
+Optional properties:
+  - cirrus,dmic-ref : Indicates how the MICBIAS pins have been externally
+connected to DMICs on each input, one cell per input.
+
+A value of 0 indicates MICVDD and is the default, other values depend on 
the
+codec:
+For CS47L35 one of the CS47L35_DMIC_REF_xxx values
+For all other codecs one of the MADERA_DMIC_REF_xxx values
+Also see the datasheet for a description of the INn_DMIC_SUP field.
+
+  - cirrus,inmode : A list of input mode settings for each input. A maximum of
+16 cells, with four cells per input in the order INnAL, INnAR INnBL INnBR.
+For non-muxed inputs the first two cells for that input set the mode for
+the left and right channel and the second two cells must be 0.
+For muxed inputs the first two cells for that input set the mode of the
+left and right A inputs and the second two cells set the mode of the left
+and right B inputs.
+Valid mode values are one of the MADERA_INMODE_xxx. If the array is shorter
+than the number of inputs the unspecified inputs default to
+MADERA_INMODE_DIFF.
+
+  - cirrus,out-mono : Mono bit for each output, must contain six cells if
+specified. A non-zero value indicates the corresponding output is mono.
+
+  - cirrus,max-channels-clocked : Maximum number of channels that I2S clocks
+will be generated for. Useful when clock master for systems where the I2S
+bus has multiple data lines.
+One cell for each AIF, use a value of zero for AIFs that should be handled
+normally.
+
+  - cirrus,pdm-fmt : PDM speaker data format, must contain 2 cells
+(OUT5 and OUT6). See the PDM_SPKn_FMT field in the datasheet for a
+description of this value.
+The second cell is ignored for codecs that do not have OUT6.
+
+  - cirrus,pdm-mute : PDM mute format, must contain 2 cells
+(OUT5 and OUT6). See the PDM_SPKn_CTRL_1 register in the datasheet for a
+description of this value.
+The second cell is ignored for codecs that do not have OUT6.
+
+Example:
+
+cs47l35@0 {
+   compatible = "cirrus,cs47l35";
+
+   cirrus,dmic-ref = <0 0 CS47L35_DMIC_REF_MICBIAS1B 0>;
+   cirrus,inmode = <
+   MADERA_INMODE_DMIC MADERA_INMODE_DMIC /* IN1A digital */
+   MADERA_INMODE_SE   MADERA_INMODE_SE   /* IN1B single-ended */
+   MADERA_INMODE_DIFF MADERA_INMODE_DIFF /* IN2 differential */
+   0 0 /* not used on this codec */
+   >;
+   cirrus,out-mono = <0 0 0 0 0 0>;
+   cirrus,max-channels-clocked = <2 0 0>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index b179fee1bba7..49f1ca1698ab 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3497,6 +3497,7 @@ W:
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/dt-bindings/sound/madera*
 F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
diff --git a/include/dt-bindings/sound/madera.h 
b/include/dt-bindings/sound/madera.h
new file mode 100644
index ..5c05b7a9bab8
--- /dev/null
+++ b/include/dt-bindings/sound/madera.h
@@ -0,0 +1,27 @@
+/*
+ * Device Tree defines for Madera codecs
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef DT_BINDINGS_SOUND_MADERA_H
+#define DT_BINDINGS_SOUND_MADERA_H
+
+#define MADERA_INMODE_DIFF 0
+#define MADERA_INMODE_SE  

[PATCH v7 11/17] pinctrl: madera: Add driver for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
These codecs have a variable number of I/O lines each of which
is individually selectable to a wide range of possible functions.

The functionality is slightly different from the traditional muxed
GPIO since most of the functions can be mapped to any pin (and even
the same function to multiple pins). Most pins have a dedicated
"alternate" function that is only available on that pin. The
alternate functions are usually a group of signals, though it is
not always necessary to enable the full group, depending on the
alternate function and how it is to be used. The mapping between
alternate functions and GPIO pins varies between codecs depending
on the number of alternate functions and available pins.

Note on the Kconfig options:
The formula "default y if..." is used for PINCTRL_MADERA so that its
select options will be processed, allowing us to group selects for
pinctrl into the pinctrl Kconfig where they logically belong instead
of accumulating under the parent MFD Kconfig.

Signed-off-by: Richard Fitzgerald 
Reviewed-by: Linus Walleij 
---
 MAINTAINERS  |2 +
 drivers/pinctrl/Kconfig  |1 +
 drivers/pinctrl/Makefile |1 +
 drivers/pinctrl/cirrus/Kconfig   |   15 +
 drivers/pinctrl/cirrus/Makefile  |   11 +
 drivers/pinctrl/cirrus/pinctrl-cs47l35.c |   46 ++
 drivers/pinctrl/cirrus/pinctrl-cs47l85.c |   60 ++
 drivers/pinctrl/cirrus/pinctrl-cs47l90.c |   58 ++
 drivers/pinctrl/cirrus/pinctrl-madera.c  | 1074 ++
 drivers/pinctrl/cirrus/pinctrl-madera.h  |   40 ++
 10 files changed, 1308 insertions(+)
 create mode 100644 drivers/pinctrl/cirrus/Kconfig
 create mode 100644 drivers/pinctrl/cirrus/Makefile
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l35.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l85.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l90.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6e79d651639b..d9c0b9a9e6b0 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3496,11 +3496,13 @@ T:  git 
https://github.com/CirrusLogic/linux-drivers.git
 W: https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
+F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
+F: drivers/pinctrl/cirrus/*
 
 CLEANCACHE API
 M: Konrad Rzeszutek Wilk 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 1dd445116432..7175c4b0dd12 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -379,6 +379,7 @@ source "drivers/pinctrl/vt8500/Kconfig"
 source "drivers/pinctrl/mediatek/Kconfig"
 source "drivers/pinctrl/zte/Kconfig"
 source "drivers/pinctrl/meson/Kconfig"
+source "drivers/pinctrl/cirrus/Kconfig"
 
 config PINCTRL_XWAY
bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 2341228eb718..149ee512ac5a 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -67,3 +67,4 @@ obj-$(CONFIG_PINCTRL_UNIPHIER)+= uniphier/
 obj-$(CONFIG_ARCH_VT8500)  += vt8500/
 obj-y  += mediatek/
 obj-$(CONFIG_PINCTRL_ZX)   += zte/
+obj-y  += cirrus/
diff --git a/drivers/pinctrl/cirrus/Kconfig b/drivers/pinctrl/cirrus/Kconfig
new file mode 100644
index ..093527eaf2eb
--- /dev/null
+++ b/drivers/pinctrl/cirrus/Kconfig
@@ -0,0 +1,15 @@
+config PINCTRL_MADERA
+   bool
+   select PINMUX
+   select GENERIC_PINCONF
+   default y if MFD_MADERA=y
+
+config PINCTRL_CS47L35
+   bool
+
+config PINCTRL_CS47L85
+   bool
+
+config PINCTRL_CS47L90
+   bool
+
diff --git a/drivers/pinctrl/cirrus/Makefile b/drivers/pinctrl/cirrus/Makefile
new file mode 100644
index ..b34473c5c53f
--- /dev/null
+++ b/drivers/pinctrl/cirrus/Makefile
@@ -0,0 +1,11 @@
+# Cirrus Logic pinctrl drivers
+obj-$(CONFIG_PINCTRL_MADERA)   += pinctrl-madera.o
+ifeq ($(CONFIG_PINCTRL_CS47L35),y)
+obj-$(CONFIG_PINCTRL_MADERA)   += pinctrl-cs47l35.o
+endif
+ifeq ($(CONFIG_PINCTRL_CS47L85),y)
+obj-$(CONFIG_PINCTRL_MADERA)   += pinctrl-cs47l85.o
+endif
+ifeq ($(CONFIG_PINCTRL_CS47L90),y)
+obj-$(CONFIG_PINCTRL_MADERA)   += pinctrl-cs47l90.o
+endif
diff --git a/drivers/pinctrl/cirrus/pinctrl-cs47l35.c 
b/drivers/pinctrl/cirrus/pinctrl-cs47l35.c
new file mode 100644
index ..edf444a4ac87
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-cs47l35.c
@@ -0,0 +1,46 @@
+/*
+ * Pinctrl for Cirrus Logic CS47L35
+ *
+ * Copyright 2016-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it 

[PATCH v7 07/17] regulator: arizona-micsupp: Add support for Cirrus Logic Madera codecs

2018-01-15 Thread Richard Fitzgerald
This adds a new driver identity "madera-micsupp" and probe function
so that this driver can be used to control the micsupp regulator on
Cirrus Logic Madera codecs.

Signed-off-by: Richard Fitzgerald 
Acked-by: Rob Herring 
---
 .../bindings/regulator/arizona-regulator.txt   |  3 +-
 drivers/regulator/Kconfig  |  7 ++-
 drivers/regulator/arizona-micsupp.c| 71 +-
 3 files changed, 76 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt 
b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
index 443564d7784f..91b00f9f06d5 100644
--- a/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
+++ b/Documentation/devicetree/bindings/regulator/arizona-regulator.txt
@@ -5,7 +5,8 @@ of analogue I/O.
 
 This document lists regulator specific bindings, see the primary binding
 document:
-  ../mfd/arizona.txt
+  For Wolfson Arizona codecs: ../mfd/arizona.txt
+  For Cirrus Logic Madera codecs: ../mfd/madera.txt
 
 Optional properties:
   - wlf,ldoena : GPIO specifier for the GPIO controlling LDOENA
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index b27417ca188a..eed360626274 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -134,11 +134,12 @@ config REGULATOR_ARIZONA_LDO1
  devices.
 
 config REGULATOR_ARIZONA_MICSUPP
-   tristate "Wolfson Arizona class devices MICSUPP"
-   depends on MFD_ARIZONA
+   tristate "Cirrus Madera and Wolfson Arizona class devices MICSUPP"
+   depends on MFD_ARIZONA || MFD_MADERA
depends on SND_SOC
help
- Support for the MICSUPP regulators found on Wolfson Arizona class
+ Support for the MICSUPP regulators found on Cirrus Logic Madera codecs
+ and Wolfson Arizona codecs
  devices.
 
 config REGULATOR_AS3711
diff --git a/drivers/regulator/arizona-micsupp.c 
b/drivers/regulator/arizona-micsupp.c
index 120de94caf02..36bf73c15e2d 100644
--- a/drivers/regulator/arizona-micsupp.c
+++ b/drivers/regulator/arizona-micsupp.c
@@ -30,6 +30,10 @@
 #include 
 #include 
 
+#include 
+#include 
+#include 
+
 #include 
 
 struct arizona_micsupp {
@@ -205,6 +209,28 @@ static const struct regulator_init_data 
arizona_micsupp_ext_default = {
.num_consumer_supplies = 1,
 };
 
+static const struct regulator_desc madera_micsupp = {
+   .name = "MICVDD",
+   .supply_name = "CPVDD1",
+   .type = REGULATOR_VOLTAGE,
+   .n_voltages = 40,
+   .ops = &arizona_micsupp_ops,
+
+   .vsel_reg = MADERA_LDO2_CONTROL_1,
+   .vsel_mask = MADERA_LDO2_VSEL_MASK,
+   .enable_reg = MADERA_MIC_CHARGE_PUMP_1,
+   .enable_mask = MADERA_CPMIC_ENA,
+   .bypass_reg = MADERA_MIC_CHARGE_PUMP_1,
+   .bypass_mask = MADERA_CPMIC_BYPASS,
+
+   .linear_ranges = arizona_micsupp_ext_ranges,
+   .n_linear_ranges = ARRAY_SIZE(arizona_micsupp_ext_ranges),
+
+   .enable_time = 3000,
+
+   .owner = THIS_MODULE,
+};
+
 static int arizona_micsupp_of_get_pdata(struct arizona_micsupp_pdata *pdata,
struct regulator_config *config,
const struct regulator_desc *desc)
@@ -321,6 +347,24 @@ static int arizona_micsupp_probe(struct platform_device 
*pdev)
   &arizona->pdata.micvdd);
 }
 
+static int madera_micsupp_probe(struct platform_device *pdev)
+{
+   struct madera *madera = dev_get_drvdata(pdev->dev.parent);
+   struct arizona_micsupp *micsupp;
+
+   micsupp = devm_kzalloc(&pdev->dev, sizeof(*micsupp), GFP_KERNEL);
+   if (!micsupp)
+   return -ENOMEM;
+
+   micsupp->regmap = madera->regmap;
+   micsupp->dapm = &madera->dapm;
+   micsupp->dev = madera->dev;
+   micsupp->init_data = arizona_micsupp_ext_default;
+
+   return arizona_micsupp_common_init(pdev, micsupp, &madera_micsupp,
+  &madera->pdata.micvdd);
+}
+
 static struct platform_driver arizona_micsupp_driver = {
.probe = arizona_micsupp_probe,
.driver = {
@@ -328,10 +372,35 @@ static struct platform_driver arizona_micsupp_driver = {
},
 };
 
-module_platform_driver(arizona_micsupp_driver);
+static struct platform_driver madera_micsupp_driver = {
+   .probe = madera_micsupp_probe,
+   .driver = {
+   .name   = "madera-micsupp",
+   },
+};
+
+static struct platform_driver * const arizona_micsupp_drivers[] = {
+   &arizona_micsupp_driver,
+   &madera_micsupp_driver,
+};
+
+static int __init arizona_micsupp_init(void)
+{
+   return platform_register_drivers(arizona_micsupp_drivers,
+ARRAY_SIZE(arizona_micsupp_drivers));
+

[PATCH v7 12/17] gpio: madera: Support Cirrus Logic Madera class codecs

2018-01-15 Thread Richard Fitzgerald
This adds support for the GPIOs on Cirrus Logic Madera class codecs.
Any pins not used for special functions (see the pinctrl driver) can be
used as general single-bit input or output lines. The number of available
GPIOs varies between codecs.

Signed-off-by: Nariman Poushin 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
Acked-by: Linus Walleij 
---
 MAINTAINERS|   1 +
 drivers/gpio/Kconfig   |   6 ++
 drivers/gpio/Makefile  |   1 +
 drivers/gpio/gpio-madera.c | 196 +
 4 files changed, 204 insertions(+)
 create mode 100644 drivers/gpio/gpio-madera.c

diff --git a/MAINTAINERS b/MAINTAINERS
index d9c0b9a9e6b0..b179fee1bba7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3499,6 +3499,7 @@ F:Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
+F: drivers/gpio/gpio-madera*
 F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8dbb2280538d..1b9abae4cbac 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1003,6 +1003,12 @@ config GPIO_LP87565
  This driver can also be built as a module. If so, the module will be
  called gpio-lp87565.
 
+config GPIO_MADERA
+   bool "Cirrus Logic Madera class codecs"
+   depends on PINCTRL_MADERA
+   help
+ Support for GPIOs on Cirrus Logic Madera class codecs.
+
 config GPIO_MAX77620
tristate "GPIO support for PMIC MAX77620 and MAX20024"
depends on MFD_MAX77620
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index cccb0d40846c..bb3b8c4ca507 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -69,6 +69,7 @@ obj-$(CONFIG_ARCH_LPC32XX)+= gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LP873X)  += gpio-lp873x.o
 obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
+obj-$(CONFIG_GPIO_MADERA)  += gpio-madera.o
 obj-$(CONFIG_GPIO_MAX3191X)+= gpio-max3191x.o
 obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
diff --git a/drivers/gpio/gpio-madera.c b/drivers/gpio/gpio-madera.c
new file mode 100644
index ..e45905d59238
--- /dev/null
+++ b/drivers/gpio/gpio-madera.c
@@ -0,0 +1,196 @@
+/*
+ * GPIO support for Cirrus Logic Madera codecs
+ *
+ * Copyright 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct madera_gpio {
+   struct madera *madera;
+   struct gpio_chip gpio_chip;
+};
+
+static int madera_gpio_get_direction(struct gpio_chip *chip,
+unsigned int offset)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+   unsigned int val;
+   int ret;
+
+   ret = regmap_read(madera->regmap,
+ MADERA_GPIO1_CTRL_2 + (2 * offset), &val);
+   if (ret < 0)
+   return ret;
+
+   return (val & MADERA_GP1_DIR_MASK) >> MADERA_GP1_DIR_SHIFT;
+}
+
+static int madera_gpio_direction_in(struct gpio_chip *chip, unsigned int 
offset)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+
+   return regmap_update_bits(madera->regmap,
+ MADERA_GPIO1_CTRL_2 + (2 * offset),
+ MADERA_GP1_DIR_MASK, MADERA_GP1_DIR);
+}
+
+static int madera_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+   unsigned int val;
+   int ret;
+
+   ret = regmap_read(madera->regmap,
+ MADERA_GPIO1_CTRL_1 + (2 * offset), &val);
+   if (ret < 0)
+   return ret;
+
+   return !!(val & MADERA_GP1_LVL_MASK);
+}
+
+static int madera_gpio_direction_out(struct gpio_chip *chip,
+unsigned int offset, int value)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+   unsigned int regval;
+   int ret;
+
+   if (value)
+   regval = MADERA_GP1_LVL;
+   else
+   regval = 0;
+
+   ret = regmap_update_bits(madera->regmap,
+MADERA_GPIO1_CTRL_2 + (2 * offset),
+MADERA_GP1_DIR_MAS

Re: [REGRESSION][BISECTED] i.MX6 pinctrl hogs stopped working

2018-04-10 Thread Richard Fitzgerald

On 04/04/18 06:33, Mika Penttilä wrote:

Hi!

Reverting this made the hogs on a i.MX6 board work again. :


commit b89405b6102fcc3746f43697b826028caa94c823
Author: Richard Fitzgerald 
Date:   Wed Feb 28 15:53:06 2018 +

 pinctrl: devicetree: Fix dt_to_map_one_config handling of hogs



--Mika



I think you should check whether the bug is with the i.MX6 driver
relying on the previous buggy behaviour of pinctrl. I haven't got
i.MX6 hardware to test myself.

The bug I fixed in that patch was that when pinctrl is probing a
pinctrl driver it would try to apply all the pinctrl settings
listed in a dt node to the pinctrl driver it is probing instead
of the pinctrl drivers they actually refer to. This was a bug
introduced by an earlier patch (which unfortunately I forgot to
include a fixes line reference to)

  pinctrl: core: Use delayed work for hogs

So if a pinctrl driver "A" had a dependency on another pinctrl
driver "B" those dependencies wouldn't be properly created because
all the "B" pinctrl DT entries would be attempted against "A"
instead of "B". This caused failures if a pinctrl driver had a
dependency on another pinctrl driver, of if creating a pinctrl
driver that is a child of an MFD and that MFD has dependencies
on another pinctrl driver.



[PATCH v9 7/9] pinctrl: madera: Add DT bindings for Cirrus Logic Madera codecs

2018-03-13 Thread Richard Fitzgerald
This is the binding description of the pinctrl driver for Cirrus Logic
Madera codecs. The binding uses the generic pinctrl binding so  the main
purpose here is to describe the device-specific names for groups and
functions.

Signed-off-by: Richard Fitzgerald 
Acked-by: Rob Herring 
---
 .../bindings/pinctrl/cirrus,madera-pinctrl.txt | 99 ++
 1 file changed, 99 insertions(+)
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt

diff --git 
a/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt 
b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
new file mode 100644
index ..b0e36cf0d289
--- /dev/null
+++ b/Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
@@ -0,0 +1,99 @@
+Cirrus Logic Madera class audio codecs pinctrl driver
+
+The Cirrus Logic Madera codecs provide a number of GPIO functions for
+interfacing to external hardware and to provide logic outputs to other devices.
+Certain groups of GPIO pins also have an alternate function, normally as an
+audio interface.
+
+The set of available GPIOs, functions and alternate function groups differs
+between codecs so refer to the datasheet for the codec for further information
+on what is supported on that device.
+
+The properties for this driver exist within the parent MFD driver node.
+
+See also
+  the core bindings for the parent MFD driver:
+Documentation/devicetree/bindings/mfd/madera.txt
+
+  the generic pinmix bindings:
+Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt
+
+Required properties of parent mfd node:
+  - pinctrl-names : must be "default"
+  - pinctrl-0 : a phandle to the node containing the subnodes containing 
default
+  configurations
+
+Required subnodes:
+  One subnode is required to contain the default settings. It contains an
+  arbitrary number of configuration subnodes, one for each group or pin
+  configuration you want to apply as a default.
+
+Required properties of configuration subnodes:
+  - groups : name of one pin group to configure. One of:
+   aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+   dmic4, dmic5, dmic6,
+   gpio1, gpio2, ..., gpio40
+The gpioN groups select the single pin of this name for configuration
+
+Optional properties of configuration subnodes:
+  Any configuration option not explicitly listed in the dts will be left at
+  chip default setting.
+
+  - function : name of function to assign to this group. One of:
+   aif1, aif2, aif3, aif4, mif1, mif2, mif3, pdmspk1, pdmspk2,
+   dmic3, dmic4, dmic5, dmic6,
+   io, dsp-gpio, irq1, irq2,
+   fll1-clk, fll1-lock, fll2-clk, fll2-lock, fll3-clk, fll3-lock,
+   fllao-clk, fllao-lock,
+   opclk, opclk-async, pwm1, pwm2, spdif,
+   asrc1-in1-lock, asrc1-in2-lock, asrc2-in1-lock, asrc2-in2-lock,
+   spkl-short-circuit, spkr-short-circuit, spk-shutdown,
+   spk-overheat-shutdown, spk-overheat-warn,
+   timer1-sts, timer2-sts, timer3-sts, timer4-sts, timer5-sts, timer6-sts,
+   timer7-sts, timer8-sts,
+   log1-fifo-ne, log2-fifo-ne, log3-fifo-ne, log4-fifo-ne, log5-fifo-ne,
+   log6-fifo-ne, log7-fifo-ne, log8-fifo-ne,
+
+  - bias-disable : disable pull-up and pull-down
+  - bias-bus-hold : enable buskeeper
+  - bias-pull-up : output is pulled-up
+  - bias-pull-down : output is pulled-down
+  - drive-push-pull : CMOS output
+  - drive-open-drain : open-drain output
+  - drive-strength : drive strength in mA. Valid values are 4 or 8
+  - input-schmitt-enable : enable schmitt-trigger mode
+  - input-schmitt-disable : disable schmitt-trigger mode
+  - input-debounce : A value of 0 disables debounce, a value !=0 enables
+   debounce
+  - output-low : set the pin to output mode with low level
+  - output-high : set the pin to output mode with high level
+
+Example:
+
+cs47l85@0 {
+   compatible = "cirrus,cs47l85";
+
+   pinctrl-names = "default";
+   pinctrl-0 = <&cs47l85_defaults>;
+
+   cs47l85_defaults: cs47l85-gpio-defaults {
+   aif1 {
+   groups = "aif1";
+   function = "aif1";
+   bias-bus-hold;
+   };
+
+   aif2 {
+   groups = "aif2";
+   function = "aif2";
+   bias-bus-hold;
+   };
+
+   opclk {
+   groups = "gpio1";
+   function = "opclk";
+   bias-pull-up;
+   drive-strength = <8>;
+   };
+   };
+};
-- 
2.11.0



[PATCH v9 4/9] mfd: madera: Register map tables for Cirrus Logic CS47L35

2018-03-13 Thread Richard Fitzgerald
Regmap configuration tables for Cirrus Logic CS47L35 codecs.

Signed-off-by: Piotr Stankiewicz 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
Acked-for-MFD-by: Lee Jones 
---
 drivers/mfd/Kconfig  |7 +
 drivers/mfd/Makefile |3 +
 drivers/mfd/cs47l35-tables.c | 1609 ++
 3 files changed, 1619 insertions(+)
 create mode 100644 drivers/mfd/cs47l35-tables.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index f5ca392f8bc2..da595d71671d 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -261,6 +261,13 @@ config MFD_MADERA_SPI
  Support for the Cirrus Logic Madera platform audio SoC
  core functionality controlled via SPI.
 
+config MFD_CS47L35
+   bool "Cirrus Logic CS47L35"
+   select PINCTRL_CS47L35
+   depends on MFD_MADERA
+   help
+ Support for Cirrus Logic CS47L35 Smart Codec
+
 config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index db9ee6d24d91..0ab6b09daf2a 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -73,6 +73,9 @@ obj-$(CONFIG_MFD_WM8994)  += wm8994.o
 obj-$(CONFIG_MFD_WM97xx)   += wm97xx-core.o
 
 madera-objs:= madera-core.o
+ifeq ($(CONFIG_MFD_CS47L35),y)
+madera-objs+= cs47l35-tables.o
+endif
 obj-$(CONFIG_MFD_MADERA)   += madera.o
 obj-$(CONFIG_MFD_MADERA_I2C)   += madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)   += madera-spi.o
diff --git a/drivers/mfd/cs47l35-tables.c b/drivers/mfd/cs47l35-tables.c
new file mode 100644
index ..604c9dd14df5
--- /dev/null
+++ b/drivers/mfd/cs47l35-tables.c
@@ -0,0 +1,1609 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Regmap tables for CS47L35 codec
+ *
+ * Copyright (C) 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+
+static const struct reg_sequence cs47l35_reva_16_patch[] = {
+   { 0x460, 0x0c40 },
+   { 0x461, 0xcd1a },
+   { 0x462, 0x0c40 },
+   { 0x463, 0xb53b },
+   { 0x464, 0x0c40 },
+   { 0x465, 0x7503 },
+   { 0x466, 0x0c40 },
+   { 0x467, 0x4a41 },
+   { 0x468, 0x0041 },
+   { 0x469, 0x3491 },
+   { 0x46a, 0x0841 },
+   { 0x46b, 0x1f50 },
+   { 0x46c, 0x0446 },
+   { 0x46d, 0x14ed },
+   { 0x46e, 0x0446 },
+   { 0x46f, 0x1455 },
+   { 0x470, 0x04c6 },
+   { 0x471, 0x1220 },
+   { 0x472, 0x04c6 },
+   { 0x473, 0x040f },
+   { 0x474, 0x04ce },
+   { 0x475, 0x0339 },
+   { 0x476, 0x05df },
+   { 0x477, 0x028f },
+   { 0x478, 0x05df },
+   { 0x479, 0x0209 },
+   { 0x47a, 0x05df },
+   { 0x47b, 0x00cf },
+   { 0x47c, 0x05df },
+   { 0x47d, 0x0001 },
+   { 0x47e, 0x07ff },
+};
+
+int cs47l35_patch(struct madera *madera)
+{
+   int ret;
+
+   ret = regmap_register_patch(madera->regmap, cs47l35_reva_16_patch,
+   ARRAY_SIZE(cs47l35_reva_16_patch));
+   if (ret < 0)
+   dev_err(madera->dev, "Error applying patch: %d\n", ret);
+
+   return ret;
+}
+EXPORT_SYMBOL_GPL(cs47l35_patch);
+
+static const struct reg_default cs47l35_reg_default[] = {
+   { 0x0020, 0x }, /* R32 (0x20) - Tone Generator 1 */
+   { 0x0021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
+   { 0x0022, 0x }, /* R34 (0x22) - Tone Generator 3 */
+   { 0x0023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
+   { 0x0024, 0x }, /* R36 (0x24) - Tone Generator 5 */
+   { 0x0030, 0x }, /* R48 (0x30) - PWM Drive 1 */
+   { 0x0031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
+   { 0x0032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
+   { 0x0061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
+   { 0x0062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
+   { 0x0063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
+   { 0x0064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4*/
+   { 0x0066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence 
Select 1*/
+   { 0x0067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence 
Select 2*/
+   { 0x0090, 0x }, /* R144 (0x90) - Haptics Control 1 */
+   { 0x0091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
+   { 0x0092, 0x }, /* R146 (0x92) - Haptics phase 1 intensity */
+   { 0x0093, 0x }, /* R147 (0x93) - Haptics phase 1 duration */
+   { 0x0094, 0x }, /* R148 (0x94) - Haptics phase 2 intensity */
+   { 0x0095, 0x }, /* R149 (0x95) -

[PATCH v9 3/9] mfd: madera: Add common support for Cirrus Logic Madera codecs

2018-03-13 Thread Richard Fitzgerald
This adds the generic core support for Cirrus Logic "Madera" class codecs.
These are complex audio codec SoCs with a variety of digital and analogue
I/O, onboard audio processing and DSPs, and other features.

These codecs are all based off a common set of hardware IP so can be
supported by a core of common code (with a few minor device-to-device
variations).

Signed-off-by: Charles Keepax 
Signed-off-by: Nikesh Oswal 
Signed-off-by: Richard Fitzgerald 
---
There have been various smallish changes since Lee acked this patch so I have
decided to err on the side of caution and remove the Ack in case Lee might have
some comments about the current state of the code.

Cumulative changes since Lee acked it:
- changed to use gpiod for all reset code - affects 
madera_[enable|disable]_hard_reset,
  madera_get_reset_gpio, madera_dev_init
- use of_device_get_match_data in the spi and i2c probes
- use __maybe_unused on the pm runtime functions instead of a #ifdef
- don't put comma after {} list terminators
- commented why we don't use the devm version of mfd_add_devices
- don't use regulator_get_exclusive, it fails in the legitimate case of having 
the same
  regulator supply multiple chip supplies
- the core driver can now be built as a module
- minor Kconfig change to make the SPI/I2C submodules depend on the core module
as this gives a more user-friendly menuconfig
- changed the irqchip and codec pdata to be a pointer to remove the build 
dependency
so we can submit this patch without the irqchip and codec driver patches
- SPDX license headers
---
 MAINTAINERS  |   3 +
 drivers/mfd/Kconfig  |  29 ++
 drivers/mfd/Makefile |   5 +
 drivers/mfd/madera-core.c| 600 +++
 drivers/mfd/madera-i2c.c | 139 +
 drivers/mfd/madera-spi.c | 138 +
 drivers/mfd/madera.h |  44 +++
 include/linux/mfd/madera/core.h  | 187 
 include/linux/mfd/madera/pdata.h |  63 
 9 files changed, 1208 insertions(+)
 create mode 100644 drivers/mfd/madera-core.c
 create mode 100644 drivers/mfd/madera-i2c.c
 create mode 100644 drivers/mfd/madera-spi.c
 create mode 100644 drivers/mfd/madera.h
 create mode 100644 include/linux/mfd/madera/core.h
 create mode 100644 include/linux/mfd/madera/pdata.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 40d78683a53f..f7ea1a47496c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3498,7 +3498,10 @@ L:   patc...@opensource.cirrus.com
 T: git https://github.com/CirrusLogic/linux-drivers.git
 W: https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
+F: Documentation/devicetree/bindings/mfd/madera.txt
 F: include/linux/mfd/madera/*
+F: drivers/mfd/madera*
+F: drivers/mfd/cs47l*
 
 CLEANCACHE API
 M: Konrad Rzeszutek Wilk 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b860eb5aa194..f5ca392f8bc2 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -232,6 +232,35 @@ config MFD_CROS_EC_CHARDEV
   If you have a supported Chromebook, choose Y or M here.
   The module will be called cros_ec_dev.
 
+config MFD_MADERA
+   tristate "Cirrus Logic Madera codecs"
+   select MFD_CORE
+   select REGMAP
+   select REGMAP_IRQ
+   select MADERA_IRQ
+   select PINCTRL
+   select PINCTRL_MADERA
+   help
+ Support for the Cirrus Logic Madera platform audio codecs
+
+config MFD_MADERA_I2C
+   tristate "Cirrus Logic Madera codecs with I2C"
+   depends on MFD_MADERA
+   depends on I2C
+   select REGMAP_I2C
+   help
+ Support for the Cirrus Logic Madera platform audio SoC
+ core functionality controlled via I2C.
+
+config MFD_MADERA_SPI
+   tristate "Cirrus Logic Madera codecs with SPI"
+   depends on MFD_MADERA
+   depends on SPI_MASTER
+   select REGMAP_SPI
+   help
+ Support for the Cirrus Logic Madera platform audio SoC
+ core functionality controlled via SPI.
+
 config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index e9fd20dba18d..db9ee6d24d91 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -72,6 +72,11 @@ wm8994-objs  := wm8994-core.o wm8994-irq.o 
wm8994-regmap.o
 obj-$(CONFIG_MFD_WM8994)   += wm8994.o
 obj-$(CONFIG_MFD_WM97xx)   += wm97xx-core.o
 
+madera-objs:= madera-core.o
+obj-$(CONFIG_MFD_MADERA)   += madera.o
+obj-$(CONFIG_MFD_MADERA_I2C)   += madera-i2c.o
+obj-$(CONFIG_MFD_MADERA_SPI)   += madera-spi.o
+
 obj-$(CONFIG_TPS6105X) += tps6105x.o
 obj-$(CONFIG_TPS65010) += tps65010.o
 obj-$(CONFIG_TPS6507X) += tps6507x.o
diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
new file mode 100644
index ..fde4aae41608
--- /de

[PATCH v9 2/9] mfd: madera: Add DT bindings for Cirrus Logic Madera codecs

2018-03-13 Thread Richard Fitzgerald
Specification of the bindings for the parent MFD driver component
of the Cirrus Logic Madera codec drivers.

Note that although the interrupt controller and GPIO are child
drivers their required bindings are trivial, mandatory, and exist
within the parent MFD node so are documented here.

Signed-off-by: Richard Fitzgerald 
Acked-by: Rob Herring 
Acked-for-MFD-by: Lee Jones 
---
 Documentation/devicetree/bindings/mfd/madera.txt | 102 +++
 1 file changed, 102 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt

diff --git a/Documentation/devicetree/bindings/mfd/madera.txt 
b/Documentation/devicetree/bindings/mfd/madera.txt
new file mode 100644
index ..db3266088386
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/madera.txt
@@ -0,0 +1,102 @@
+Cirrus Logic Madera class audio codecs Multi-Functional Device
+
+These devices are audio SoCs with extensive digital capabilities and a range
+of analogue I/O.
+
+See also the child driver bindings in:
+bindings/pinctrl/cirrus,madera-pinctrl.txt
+bindings/regulator/arizona-regulator.txt
+bindings/sound/madera.txt
+
+Required properties:
+
+  - compatible : One of the following chip-specific strings:
+"cirrus,cs47l35"
+"cirrus,cs47l85"
+"cirrus,cs47l90"
+"cirrus,cs47l91"
+"cirrus,wm1840"
+
+  - reg : I2C slave address when connected using I2C, chip select number when
+using SPI.
+
+  - DCVDD-supply : Power supply for the device as defined in
+bindings/regulator/regulator.txt
+Mandatory on CS47L35, CS47L90, CS47L91
+Optional on CS47L85, WM1840
+
+  - AVDD-supply, DBVDD1-supply, DBVDD2-supply, CPVDD1-supply, CPVDD2-supply :
+Power supplies for the device
+
+  - DBVDD3-supply, DBVDD4-supply : Power supplies for the device
+(CS47L85, CS47L90, CS47L91, WM1840)
+
+  - SPKVDDL-supply, SPKVDDR-supply : Power supplies for the device
+(CS47L85, WM1840)
+
+  - SPKVDD-supply : Power supply for the device
+(CS47L35)
+
+  - interrupt-controller : Indicates that this device is an interrupt 
controller
+
+  - #interrupt-cells: the number of cells to describe an IRQ, must be 2.
+The first cell is the IRQ number.
+The second cell is the flags, encoded as the trigger masks from
+bindings/interrupt-controller/interrupts.txt
+
+  - gpio-controller : Indicates this device is a GPIO controller.
+
+  - #gpio-cells : Must be 2. The first cell is the pin number. The second cell
+is reserved for future use and must be zero
+
+  - interrupt-parent : The parent interrupt controller.
+
+  - interrupts : The interrupt line the /IRQ signal for the device is
+connected to.
+
+Optional properties:
+
+  - MICVDD-supply : Power supply, only need to be specified if
+powered externally
+
+  - reset-gpios : One entry specifying the GPIO controlling /RESET.
+As defined in bindings/gpio.txt.
+Although optional, it is strongly recommended to use a hardware reset
+
+  - MICBIASx : Initial data for the MICBIAS regulators, as covered in
+Documentation/devicetree/bindings/regulator/regulator.txt.
+One for each MICBIAS generator (MICBIAS1, MICBIAS2, ...)
+(all codecs)
+
+One for each output pin (MICBIAS1A, MIBCIAS1B, MICBIAS2A, ...)
+(all except CS47L85, WM1840)
+
+The following following additional property is supported for the generator
+nodes:
+  - cirrus,ext-cap : Set to 1 if the MICBIAS has external decoupling
+capacitors attached.
+
+Optional child nodes:
+micvdd : Node containing initialization data for the micvdd regulator
+See bindings/regulator/arizona-regulator.txt
+
+ldo1 : Node containing initialization data for the LDO1 regulator
+See bindings/regulator/arizona-regulator.txt
+(cs47l85, wm1840)
+
+Example:
+
+cs47l85@0 {
+   compatible = "cirrus,cs47l85";
+   reg = <0>;
+
+   reset-gpios = <&gpio 0>;
+
+   interrupt-controller;
+   #interrupt-cells = <2>;
+   interrupts = <&host_irq1>;
+   interrupt-parent = <&gic>;
+
+   gpio-controller;
+   #gpio-cells = <2>;
+};
-- 
2.11.0



[PATCH v9 6/9] mfd: madera: Register map tables for Cirrus Logic CS47L90/91

2018-03-13 Thread Richard Fitzgerald
Regmap configuration tables for Cirrus Logic CS47L90 and CS47L91 codecs.

Signed-off-by: Nikesh Oswal 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
Acked-for-MFD-by: Lee Jones 
---
 drivers/mfd/Kconfig  |7 +
 drivers/mfd/Makefile |3 +
 drivers/mfd/cs47l90-tables.c | 2674 ++
 3 files changed, 2684 insertions(+)
 create mode 100644 drivers/mfd/cs47l90-tables.c

diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 92d555ca21e2..2db1c1c48700 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -275,6 +275,13 @@ config MFD_CS47L85
help
  Support for Cirrus Logic CS47L85 Smart Codec
 
+config MFD_CS47L90
+   bool "Cirrus Logic CS47L90/91"
+   select PINCTRL_CS47L90
+   depends on MFD_MADERA
+   help
+ Support for Cirrus Logic CS47L90 and CS47L91 Smart Codecs
+
 config MFD_ASIC3
bool "Compaq ASIC3"
depends on GPIOLIB && ARM
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index c503b13f0b0b..de11fb168699 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -79,6 +79,9 @@ endif
 ifeq ($(CONFIG_MFD_CS47L85),y)
 madera-objs+= cs47l85-tables.o
 endif
+ifeq ($(CONFIG_MFD_CS47L90),y)
+madera-objs+= cs47l90-tables.o
+endif
 obj-$(CONFIG_MFD_MADERA)   += madera.o
 obj-$(CONFIG_MFD_MADERA_I2C)   += madera-i2c.o
 obj-$(CONFIG_MFD_MADERA_SPI)   += madera-spi.o
diff --git a/drivers/mfd/cs47l90-tables.c b/drivers/mfd/cs47l90-tables.c
new file mode 100644
index ..77207d98f0cc
--- /dev/null
+++ b/drivers/mfd/cs47l90-tables.c
@@ -0,0 +1,2674 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Regmap tables for CS47L90 codec
+ *
+ * Copyright (C) 2015-2017 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+
+#include 
+#include 
+
+#include "madera.h"
+
+static const struct reg_sequence cs47l90_reva_16_patch[] = {
+   { 0x8A,   0x },
+   { 0x8A,   0x },
+   { 0x4CF,  0x0700 },
+   { 0x171,  0x0003 },
+   { 0x101,  0x0444 },
+   { 0x159,  0x0002 },
+   { 0x120,  0x0444 },
+   { 0x1D1,  0x0004 },
+   { 0x1E0,  0xC084 },
+   { 0x159,  0x },
+   { 0x120,  0x0404 },
+   { 0x101,  0x0404 },
+   { 0x171,  0x0002 },
+   { 0x17A,  0x2906 },
+   { 0x19A,  0x2906 },
+   { 0x441,  0xC750 },
+   { 0x340,  0x0001 },
+   { 0x112,  0x0405 },
+   { 0x124,  0x0C49 },
+   { 0x1300, 0x050E },
+   { 0x1302, 0x0101 },
+   { 0x1380, 0x0425 },
+   { 0x1381, 0xF6D8 },
+   { 0x1382, 0x0632 },
+   { 0x1383, 0xFEC8 },
+   { 0x1390, 0x042F },
+   { 0x1391, 0xF6CA },
+   { 0x1392, 0x0637 },
+   { 0x1393, 0xFEC8 },
+   { 0x281,  0x },
+   { 0x282,  0x },
+   { 0x4EA,  0x0100 },
+   { 0x8A,   0x },
+   { 0x8A,   0x },
+};
+
+int cs47l90_patch(struct madera *madera)
+{
+   int ret;
+
+   ret = regmap_register_patch(madera->regmap,
+   cs47l90_reva_16_patch,
+   ARRAY_SIZE(cs47l90_reva_16_patch));
+   if (ret < 0) {
+   dev_err(madera->dev,
+   "Error in applying 16-bit patch: %d\n", ret);
+   return ret;
+   }
+
+   return 0;
+}
+EXPORT_SYMBOL_GPL(cs47l90_patch);
+
+static const struct reg_default cs47l90_reg_default[] = {
+   { 0x0020, 0x }, /* R32 (0x20) - Tone Generator 1 */
+   { 0x0021, 0x1000 }, /* R33 (0x21) - Tone Generator 2 */
+   { 0x0022, 0x }, /* R34 (0x22) - Tone Generator 3 */
+   { 0x0023, 0x1000 }, /* R35 (0x23) - Tone Generator 4 */
+   { 0x0024, 0x }, /* R36 (0x24) - Tone Generator 5 */
+   { 0x0030, 0x }, /* R48 (0x30) - PWM Drive 1 */
+   { 0x0031, 0x0100 }, /* R49 (0x31) - PWM Drive 2 */
+   { 0x0032, 0x0100 }, /* R50 (0x32) - PWM Drive 3 */
+   { 0x0061, 0x01ff }, /* R97 (0x61) - Sample Rate Sequence Select 1 */
+   { 0x0062, 0x01ff }, /* R98 (0x62) - Sample Rate Sequence Select 2 */
+   { 0x0063, 0x01ff }, /* R99 (0x63) - Sample Rate Sequence Select 3 */
+   { 0x0064, 0x01ff }, /* R100 (0x64) - Sample Rate Sequence Select 4 
*/
+   { 0x0066, 0x01ff }, /* R102 (0x66) - Always On Triggers Sequence 
Select 1 */
+   { 0x0067, 0x01ff }, /* R103 (0x67) - Always On Triggers Sequence 
Select 2 */
+   { 0x0090, 0x }, /* R144 (0x90) - Haptics Control 1 */
+   { 0x0091, 0x7fff }, /* R145 (0x91) - Haptics Control 2 */
+   { 0x0092, 0x }, /* R146 (0x92) - Haptics phase 1 intensity */
+   { 0x0093, 0x }, /* R147 (0x93) -

[PATCH v9 8/9] pinctrl: madera: Add driver for Cirrus Logic Madera codecs

2018-03-13 Thread Richard Fitzgerald
These codecs have a variable number of I/O lines each of which
is individually selectable to a wide range of possible functions.

The functionality is slightly different from the traditional muxed
GPIO since most of the functions can be mapped to any pin (and even
the same function to multiple pins). Most pins have a dedicated
"alternate" function that is only available on that pin. The
alternate functions are usually a group of signals, though it is
not always necessary to enable the full group, depending on the
alternate function and how it is to be used. The mapping between
alternate functions and GPIO pins varies between codecs depending
on the number of alternate functions and available pins.

Signed-off-by: Richard Fitzgerald 
Reviewed-by: Linus Walleij 
---
There are some minor changes since LinusW last reviewed this patch but as
they are trivial I have carried forward Linus's Reviewed-by:
- SPDX license headers
- can now build it as a module
- avoided a minor checkpatch warning about an unnecessary else {} in
madera_get_group_name()
---
 MAINTAINERS  |2 +
 drivers/pinctrl/Kconfig  |1 +
 drivers/pinctrl/Makefile |1 +
 drivers/pinctrl/cirrus/Kconfig   |   15 +
 drivers/pinctrl/cirrus/Makefile  |   13 +
 drivers/pinctrl/cirrus/pinctrl-cs47l35.c |   45 ++
 drivers/pinctrl/cirrus/pinctrl-cs47l85.c |   59 ++
 drivers/pinctrl/cirrus/pinctrl-cs47l90.c |   57 ++
 drivers/pinctrl/cirrus/pinctrl-madera-core.c | 1074 ++
 drivers/pinctrl/cirrus/pinctrl-madera.h  |   41 +
 10 files changed, 1308 insertions(+)
 create mode 100644 drivers/pinctrl/cirrus/Kconfig
 create mode 100644 drivers/pinctrl/cirrus/Makefile
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l35.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l85.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l90.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera-core.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f7ea1a47496c..2983c5de73c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3499,9 +3499,11 @@ T:   git 
https://github.com/CirrusLogic/linux-drivers.git
 W: https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
+F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F: include/linux/mfd/madera/*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
+F: drivers/pinctrl/cirrus/*
 
 CLEANCACHE API
 M: Konrad Rzeszutek Wilk 
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index f5ef8201c09f..f98f1de312a2 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -378,6 +378,7 @@ source "drivers/pinctrl/vt8500/Kconfig"
 source "drivers/pinctrl/mediatek/Kconfig"
 source "drivers/pinctrl/zte/Kconfig"
 source "drivers/pinctrl/meson/Kconfig"
+source "drivers/pinctrl/cirrus/Kconfig"
 
 config PINCTRL_XWAY
bool
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 6255546735ff..86e18aeaff17 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -66,3 +66,4 @@ obj-$(CONFIG_PINCTRL_UNIPHIER)+= uniphier/
 obj-$(CONFIG_ARCH_VT8500)  += vt8500/
 obj-y  += mediatek/
 obj-$(CONFIG_PINCTRL_ZX)   += zte/
+obj-y  += cirrus/
diff --git a/drivers/pinctrl/cirrus/Kconfig b/drivers/pinctrl/cirrus/Kconfig
new file mode 100644
index ..a86e354bb62a
--- /dev/null
+++ b/drivers/pinctrl/cirrus/Kconfig
@@ -0,0 +1,15 @@
+# This is all selected by the Madera MFD driver Kconfig options
+config PINCTRL_MADERA
+   tristate
+   select PINMUX
+   select GENERIC_PINCONF
+
+config PINCTRL_CS47L35
+   bool
+
+config PINCTRL_CS47L85
+   bool
+
+config PINCTRL_CS47L90
+   bool
+
diff --git a/drivers/pinctrl/cirrus/Makefile b/drivers/pinctrl/cirrus/Makefile
new file mode 100644
index ..6e4938cde9e3
--- /dev/null
+++ b/drivers/pinctrl/cirrus/Makefile
@@ -0,0 +1,13 @@
+# Cirrus Logic pinctrl drivers
+pinctrl-madera-objs:= pinctrl-madera-core.o
+ifeq ($(CONFIG_PINCTRL_CS47L35),y)
+pinctrl-madera-objs+= pinctrl-cs47l35.o
+endif
+ifeq ($(CONFIG_PINCTRL_CS47L85),y)
+pinctrl-madera-objs+= pinctrl-cs47l85.o
+endif
+ifeq ($(CONFIG_PINCTRL_CS47L90),y)
+pinctrl-madera-objs+= pinctrl-cs47l90.o
+endif
+
+obj-$(CONFIG_PINCTRL_MADERA)   += pinctrl-madera.o
diff --git a/drivers/pinctrl/cirrus/pinctrl-cs47l35.c 
b/drivers/pinctrl/cirrus/pinctrl-cs47l35.c
new file mode 100644
index ..06b59160783d
--- /dev/null
+++ b/drivers/pinctrl/cirrus/pinctrl-cs47l35.c
@@ -0,0 +1,45 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Pinctrl for Cirrus Logic CS47L35
+ *
+ * 

[PATCH v9 9/9] gpio: madera: Support Cirrus Logic Madera class codecs

2018-03-13 Thread Richard Fitzgerald
This adds support for the GPIOs on Cirrus Logic Madera class codecs.
Any pins not used for special functions (see the pinctrl driver) can be
used as general single-bit input or output lines. The number of available
GPIOs varies between codecs.

Note that this is part of a composite MFD for these codecs and can only
be used with the corresponding MFD and other child drivers on those
silicon. The GPIO block on these codecs does not exist indepedently of
the rest of the MFD.

Signed-off-by: Nariman Poushin 
Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
Acked-by: Linus Walleij 
---
Changes since V7:
As the changes are all small and mostly coding style, I've carried forward 
Linus's
previous ack.

- SPDX license headers
- can now build as a module
- fixed some coding style issues raised by Andy Shevchenko and Linus Walleij
- commented why we are calling gpiochip_add_pin_range()
- commented why there is a struct gpio_chip inside struct madera_gpio
---
 MAINTAINERS|   1 +
 drivers/gpio/Kconfig   |   6 ++
 drivers/gpio/Makefile  |   1 +
 drivers/gpio/gpio-madera.c | 206 +
 4 files changed, 214 insertions(+)
 create mode 100644 drivers/gpio/gpio-madera.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 2983c5de73c1..a8a2d9a3c0d1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3501,6 +3501,7 @@ S:Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 F: include/linux/mfd/madera/*
+F: drivers/gpio/gpio-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 6b1ee11295d5..b3b63388ac55 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -1020,6 +1020,12 @@ config GPIO_LP87565
  This driver can also be built as a module. If so, the module will be
  called gpio-lp87565.
 
+config GPIO_MADERA
+   tristate "Cirrus Logic Madera class codecs"
+   depends on PINCTRL_MADERA
+   help
+ Support for GPIOs on Cirrus Logic Madera class codecs.
+
 config GPIO_MAX77620
tristate "GPIO support for PMIC MAX77620 and MAX20024"
depends on MFD_MAX77620
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 5c1f087c65aa..5c98390ea576 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -71,6 +71,7 @@ obj-$(CONFIG_ARCH_LPC32XX)+= gpio-lpc32xx.o
 obj-$(CONFIG_GPIO_LP873X)  += gpio-lp873x.o
 obj-$(CONFIG_GPIO_LP87565) += gpio-lp87565.o
 obj-$(CONFIG_GPIO_LYNXPOINT)   += gpio-lynxpoint.o
+obj-$(CONFIG_GPIO_MADERA)  += gpio-madera.o
 obj-$(CONFIG_GPIO_MAX3191X)+= gpio-max3191x.o
 obj-$(CONFIG_GPIO_MAX730X) += gpio-max730x.o
 obj-$(CONFIG_GPIO_MAX7300) += gpio-max7300.o
diff --git a/drivers/gpio/gpio-madera.c b/drivers/gpio/gpio-madera.c
new file mode 100644
index ..7ba68d1a0932
--- /dev/null
+++ b/drivers/gpio/gpio-madera.c
@@ -0,0 +1,206 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * GPIO support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2.
+ */
+
+#include 
+#include 
+#include 
+#include 
+
+#include 
+#include 
+#include 
+
+struct madera_gpio {
+   struct madera *madera;
+   /* storage space for the gpio_chip we're using */
+   struct gpio_chip gpio_chip;
+};
+
+static int madera_gpio_get_direction(struct gpio_chip *chip,
+unsigned int offset)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+   unsigned int reg_offset = 2 * offset;
+   unsigned int val;
+   int ret;
+
+   ret = regmap_read(madera->regmap, MADERA_GPIO1_CTRL_2 + reg_offset,
+ &val);
+   if (ret < 0)
+   return ret;
+
+   return !!(val & MADERA_GP1_DIR_MASK);
+}
+
+static int madera_gpio_direction_in(struct gpio_chip *chip, unsigned int 
offset)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+   unsigned int reg_offset = 2 * offset;
+
+   return regmap_update_bits(madera->regmap,
+ MADERA_GPIO1_CTRL_2 + reg_offset,
+ MADERA_GP1_DIR_MASK, MADERA_GP1_DIR);
+}
+
+static int madera_gpio_get(struct gpio_chip *chip, unsigned int offset)
+{
+   struct madera_gpio *madera_gpio = gpiochip_get_data(chip);
+   struct madera *madera = madera_gpio->madera;
+   unsigned int reg_offset = 2 * offset;
+   unsigned int val;
+   int ret;
+
+   ret =

[PATCH v9 0/9] Add support for Cirrus Logic CS47L35/L85/L90/L91 codecs

2018-03-13 Thread Richard Fitzgerald
NOTE: Compared to older versions of this chain I have removed patches at the
end of the chain that were being ignored until the earlier patches had been
merged - an impossible circular dependency. There were too many moving targets
to keep the whole chain up-to-date and so patches that were already acked were
getting stale. The subset of patches here are all acked or close-to-acked, and
can be built and used as they are to produce a working pinctrl and gpio.

The Cirrus Logic CS47L35, CS47L85, CS47L90/91 codecs are complex audio SoC
devices. In addition to the core audio capability they have onboard GPIO,
regulators, DSPs and interrupt controller and a large register map space
accessed over SPI or I2C. This family of codecs is based around common IP
blocks and they are managed by a set of common drivers referred to as "Madera".

Richard Fitzgerald (9):
  mfd: madera: Add register definitions for Cirrus Logic Madera codecs
  mfd: madera: Add DT bindings for Cirrus Logic Madera codecs
  mfd: madera: Add common support for Cirrus Logic Madera codecs
  mfd: madera: Register map tables for Cirrus Logic CS47L35
  mfd: madera: Register map tables for Cirrus Logic CS47L85
  mfd: madera: Register map tables for Cirrus Logic CS47L90/91
  pinctrl: madera: Add DT bindings for Cirrus Logic Madera codecs
  pinctrl: madera: Add driver for Cirrus Logic Madera codecs
  gpio: madera: Support Cirrus Logic Madera class codecs

 Documentation/devicetree/bindings/mfd/madera.txt   |  102 +
 .../bindings/pinctrl/cirrus,madera-pinctrl.txt |   99 +
 MAINTAINERS|   16 +
 drivers/gpio/Kconfig   |6 +
 drivers/gpio/Makefile  |1 +
 drivers/gpio/gpio-madera.c |  206 +
 drivers/mfd/Kconfig|   50 +
 drivers/mfd/Makefile   |   14 +
 drivers/mfd/cs47l35-tables.c   | 1609 
 drivers/mfd/cs47l85-tables.c   | 3009 +++
 drivers/mfd/cs47l90-tables.c   | 2674 +
 drivers/mfd/madera-core.c  |  600 +++
 drivers/mfd/madera-i2c.c   |  139 +
 drivers/mfd/madera-spi.c   |  138 +
 drivers/mfd/madera.h   |   44 +
 drivers/pinctrl/Kconfig|1 +
 drivers/pinctrl/Makefile   |1 +
 drivers/pinctrl/cirrus/Kconfig |   15 +
 drivers/pinctrl/cirrus/Makefile|   13 +
 drivers/pinctrl/cirrus/pinctrl-cs47l35.c   |   45 +
 drivers/pinctrl/cirrus/pinctrl-cs47l85.c   |   59 +
 drivers/pinctrl/cirrus/pinctrl-cs47l90.c   |   57 +
 drivers/pinctrl/cirrus/pinctrl-madera-core.c   | 1074 ++
 drivers/pinctrl/cirrus/pinctrl-madera.h|   41 +
 include/linux/mfd/madera/core.h|  187 +
 include/linux/mfd/madera/pdata.h   |   63 +
 include/linux/mfd/madera/registers.h   | 3917 
 27 files changed, 14180 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/madera.txt
 create mode 100644 
Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
 create mode 100644 drivers/gpio/gpio-madera.c
 create mode 100644 drivers/mfd/cs47l35-tables.c
 create mode 100644 drivers/mfd/cs47l85-tables.c
 create mode 100644 drivers/mfd/cs47l90-tables.c
 create mode 100644 drivers/mfd/madera-core.c
 create mode 100644 drivers/mfd/madera-i2c.c
 create mode 100644 drivers/mfd/madera-spi.c
 create mode 100644 drivers/mfd/madera.h
 create mode 100644 drivers/pinctrl/cirrus/Kconfig
 create mode 100644 drivers/pinctrl/cirrus/Makefile
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l35.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l85.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-cs47l90.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera-core.c
 create mode 100644 drivers/pinctrl/cirrus/pinctrl-madera.h
 create mode 100644 include/linux/mfd/madera/core.h
 create mode 100644 include/linux/mfd/madera/pdata.h
 create mode 100644 include/linux/mfd/madera/registers.h

-- 
2.11.0



Re: Applied "regulator: wm8994: Pass descriptor instead of GPIO number" to the regulator tree

2018-11-20 Thread Richard Fitzgerald

On 20/11/18 15:56, Marek Szyprowski wrote:

Hi Charles,

On 2018-11-20 16:36, Charles Keepax wrote:

On Tue, Nov 20, 2018 at 03:32:15PM +, Charles Keepax wrote:

On Tue, Nov 20, 2018 at 03:58:59PM +0100, Marek Szyprowski wrote:

On 2018-11-20 15:47, Charles Keepax wrote:

On Tue, Nov 20, 2018 at 02:43:32PM +0100, Marek Szyprowski wrote:

On 2018-05-17 18:41, Mark Brown wrote:

Subject: [PATCH] regulator: wm8994: Pass descriptor instead of GPIO number

This patch causes following kernel warning on Samsung Exynos4412 based
Trats2 board:

wm8994 4-001a: Failed to get supply 'DBVDD1': -517
wm8994 4-001a: Failed to get supplies: -517

This is really weird, because the error in your log relates to
DBVDD1 which is an independent regulator supplied by a separate
regulator. I am really having some difficulty seeing how the
patch interfers. It is definitely that patch which causes the
issue, like you revert it and things work again?

Wait does the board still boot just you have an extra probe defer
now? Or does it actually fail?


The board boots fine. The only new thing is the mentioned warning, which
I would

like to have fixed.


Best regards



-517 is EPROBE_DEFER. This isn't something  that needs "fixing" unless the
driver is never able to probe.

If the wm8994 eventually probes ok after retries it's not a problem,
it's normal kernel behaviour.

If the wm8994 driver never manages to probe successfully it should mean that
the driver which supplies DBVDD1 isn't available.


Re: Applied "regulator: wm8994: Pass descriptor instead of GPIO number" to the regulator tree

2018-11-20 Thread Richard Fitzgerald

On 20/11/18 16:34, Marek Szyprowski wrote:

Hi Richard,

On 2018-11-20 17:16, Richard Fitzgerald wrote:

On 20/11/18 15:56, Marek Szyprowski wrote:

Hi Charles,

On 2018-11-20 16:36, Charles Keepax wrote:

On Tue, Nov 20, 2018 at 03:32:15PM +, Charles Keepax wrote:

On Tue, Nov 20, 2018 at 03:58:59PM +0100, Marek Szyprowski wrote:

On 2018-11-20 15:47, Charles Keepax wrote:

On Tue, Nov 20, 2018 at 02:43:32PM +0100, Marek Szyprowski wrote:

On 2018-05-17 18:41, Mark Brown wrote:

Subject: [PATCH] regulator: wm8994: Pass descriptor instead of
GPIO number

This patch causes following kernel warning on Samsung Exynos4412
based
Trats2 board:

wm8994 4-001a: Failed to get supply 'DBVDD1': -517
wm8994 4-001a: Failed to get supplies: -517

This is really weird, because the error in your log relates to
DBVDD1 which is an independent regulator supplied by a separate
regulator. I am really having some difficulty seeing how the
patch interfers. It is definitely that patch which causes the
issue, like you revert it and things work again?

Wait does the board still boot just you have an extra probe defer
now? Or does it actually fail?


The board boots fine. The only new thing is the mentioned warning, which
I would

like to have fixed.


Best regards



-517 is EPROBE_DEFER. This isn't something  that needs "fixing" unless
the
driver is never able to probe.

If the wm8994 eventually probes ok after retries it's not a problem,
it's normal kernel behaviour.

If the wm8994 driver never manages to probe successfully it should
mean that
the driver which supplies DBVDD1 isn't available.


Deferred probe was there already. This patch however introduced the
warning from gpiolib and I would like to have it fixed somehow. In both


I don't follow what it is you want, are you asking that it shouldn't probe
defer, or that it shouldn't log the reason why it deferred?


cases (with this patch and before it) the wm8994 driver probes okay -
when the required regulators are finally available.


Sounds like all is ok and working as expected.
If this is causing you a problem you'll need to provide more explanation of
what problem you have so we can understand.



Best regards





Re: Applied "regulator: wm8994: Pass descriptor instead of GPIO number" to the regulator tree

2018-11-20 Thread Richard Fitzgerald

On 20/11/18 17:01, Mark Brown wrote:

On Tue, Nov 20, 2018 at 04:57:16PM +, Richard Fitzgerald wrote:

On 20/11/18 16:34, Marek Szyprowski wrote:



Deferred probe was there already. This patch however introduced the
warning from gpiolib and I would like to have it fixed somehow. In both



I don't follow what it is you want, are you asking that it shouldn't probe
defer, or that it shouldn't log the reason why it deferred?


He's complaining that gpiolib and/or the driver's usage of it shouldn't
be generating a backtrace in normal operation.


Ah, I didn't see that. I seem to have not received the start of this thread and
the subsequent discussion only includes the -517 warnings not a mention of
a backtrace.


[PATCH 2/2] ASoC: wm_adsp: Factor out common init code

2018-11-12 Thread Richard Fitzgerald
Factor out the duplicated initialization statements from
wm_adsp1_init() and wm_adsp2_init() into new function
wm_adsp_common_init().

The entire content of wm_adsp1_init() is the common code
but it is convenient to retain this exported function
to hide what we currently treat as common init (which might
change in the future) and also make clear the difference
between an ADSP1 entry point and common code.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/wm_adsp.c | 14 --
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 66501b8dc46f..1dd291cebe67 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -2419,7 +2419,7 @@ static int wm_adsp_create_name(struct wm_adsp *dsp)
return 0;
 }
 
-int wm_adsp1_init(struct wm_adsp *dsp)
+static int wm_adsp_common_init(struct wm_adsp *dsp)
 {
int ret;
 
@@ -2428,11 +2428,17 @@ int wm_adsp1_init(struct wm_adsp *dsp)
return ret;
 
INIT_LIST_HEAD(&dsp->alg_regions);
+   INIT_LIST_HEAD(&dsp->ctl_list);
 
mutex_init(&dsp->pwr_lock);
 
return 0;
 }
+
+int wm_adsp1_init(struct wm_adsp *dsp)
+{
+   return wm_adsp_common_init(dsp);
+}
 EXPORT_SYMBOL_GPL(wm_adsp1_init);
 
 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
@@ -2917,7 +2923,7 @@ int wm_adsp2_init(struct wm_adsp *dsp)
 {
int ret;
 
-   ret = wm_adsp_create_name(dsp);
+   ret = wm_adsp_common_init(dsp);
if (ret)
return ret;
 
@@ -2939,12 +2945,8 @@ int wm_adsp2_init(struct wm_adsp *dsp)
break;
}
 
-   INIT_LIST_HEAD(&dsp->alg_regions);
-   INIT_LIST_HEAD(&dsp->ctl_list);
INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work);
 
-   mutex_init(&dsp->pwr_lock);
-
return 0;
 }
 EXPORT_SYMBOL_GPL(wm_adsp2_init);
-- 
2.11.0



[PATCH 1/2] ASoC: wm_adsp: Fix dma-unsafe read of scratch registers

2018-11-12 Thread Richard Fitzgerald
Stack memory isn't DMA-safe so it isn't safe to use either
regmap_raw_read or regmap_bulk_read to read into stack memory.

The two functions to read the scratch registers were using
stack memory and regmap_raw_read. It's not worth allocating
memory just for this trivial read, and it isn't time-critical.
A simple regmap_read for each register is sufficient.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/wm_adsp.c | 37 -
 1 file changed, 20 insertions(+), 17 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index a53dc174bbf0..66501b8dc46f 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -765,38 +765,41 @@ static unsigned int wm_adsp_region_to_reg(struct 
wm_adsp_region const *mem,
 
 static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
 {
-   u16 scratch[4];
+   unsigned int scratch[4];
+   unsigned int addr = dsp->base + ADSP2_SCRATCH0;
+   unsigned int i;
int ret;
 
-   ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2_SCRATCH0,
-   scratch, sizeof(scratch));
-   if (ret) {
-   adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
-   return;
+   for (i = 0; i < ARRAY_SIZE(scratch); ++i) {
+   ret = regmap_read(dsp->regmap, addr + i, &scratch[i]);
+   if (ret) {
+   adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret);
+   return;
+   }
}
 
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
-be16_to_cpu(scratch[0]),
-be16_to_cpu(scratch[1]),
-be16_to_cpu(scratch[2]),
-be16_to_cpu(scratch[3]));
+scratch[0], scratch[1], scratch[2], scratch[3]);
 }
 
 static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp)
 {
-   u32 scratch[2];
+   unsigned int scratch[2];
int ret;
 
-   ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
- scratch, sizeof(scratch));
-
+   ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1,
+ &scratch[0]);
if (ret) {
-   adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret);
+   adsp_err(dsp, "Failed to read SCRATCH0_1: %d\n", ret);
return;
}
 
-   scratch[0] = be32_to_cpu(scratch[0]);
-   scratch[1] = be32_to_cpu(scratch[1]);
+   ret = regmap_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH2_3,
+ &scratch[1]);
+   if (ret) {
+   adsp_err(dsp, "Failed to read SCRATCH2_3: %d\n", ret);
+   return;
+   }
 
adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
 scratch[0] & 0x,
-- 
2.11.0



[PATCH v13 RESEND2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-11-12 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
The MFD dependency is now in Linus's tree so this patch should apply
to the irq tree without breaking it.
---
 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 256 +
 include/linux/irqchip/irq-madera.h | 132 +++
 5 files changed, 394 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f4855974f325..9060061f15f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3604,8 +3604,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 51a5ef0e96ed..a7252da28305 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 794c13d3ac3d..3dcea8a6e5de 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -91,3 +91,4 @@ obj-$(CONFIG_QCOM_PDC)+= qcom-pdc.o
 obj-$(CONFIG_CSKY_MPINTC)  += irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)+= irq-csky-apb-intc.o
 obj-$(CONFIG_SIFIVE_PLIC)  += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..e9256dee1a45
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_DET,MADERA_IRQ1_STATUS_9),
+
+   MADERA_IRQ(

[PATCH] mfd: madera: Add shared data for accessory detection

2018-11-12 Thread Richard Fitzgerald
Add variables to struct madera that will be shared by the
extcon and audio codec drivers to synchronize output state
during accessory detection. Also add a mutex to protect
the DAPM pointer.

Signed-off-by: Richard Fitzgerald 
---
 drivers/mfd/madera-core.c   | 3 +++
 include/linux/mfd/madera/core.h | 7 +++
 2 files changed, 10 insertions(+)

diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
index 440030cecbbd..5b58a8aea902 100644
--- a/drivers/mfd/madera-core.c
+++ b/drivers/mfd/madera-core.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -357,6 +358,8 @@ int madera_dev_init(struct madera *madera)
 
dev_set_drvdata(madera->dev, madera);
BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
+   mutex_init(&madera->dapm_ptr_lock);
+
madera_set_micbias_info(madera);
 
/*
diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h
index fe69c0f4398f..4d5d51a9c8a6 100644
--- a/include/linux/mfd/madera/core.h
+++ b/include/linux/mfd/madera/core.h
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,6 +38,8 @@ enum madera_type {
 
 #define MADERA_MAX_MICBIAS 4
 
+#define MADERA_MAX_HP_OUTPUT   3
+
 /* Notifier events */
 #define MADERA_NOTIFY_VOICE_TRIGGER0x1
 #define MADERA_NOTIFY_HPDET0x2
@@ -183,6 +186,10 @@ struct madera {
unsigned int num_childbias[MADERA_MAX_MICBIAS];
 
struct snd_soc_dapm_context *dapm;
+   struct mutex dapm_ptr_lock;
+   unsigned int hp_ena;
+   bool out_clamp[MADERA_MAX_HP_OUTPUT];
+   bool out_shorted[MADERA_MAX_HP_OUTPUT];
 
struct blocking_notifier_head notifier;
 };
-- 
2.11.0



Re: [PATCH] gpiolib: Defer on non-DT find_chip_by_name() failure

2018-07-06 Thread Richard Fitzgerald

On 05/07/18 21:56, Janusz Krzysztofik wrote:

On Thursday, July 5, 2018 7:50:37 AM CEST Lee Jones wrote:

On Wed, 04 Jul 2018, Janusz Krzysztofik wrote:

On Tuesday, July 3, 2018 7:31:41 PM CEST Boris Brezillon wrote:

Hi Janusz,

On Tue,  3 Jul 2018 19:26:35 +0200

Janusz Krzysztofik  wrote:

Avoid replication of error code conversion in non-DT GPIO consumers'
code by returning -EPROBE_DEFER from gpiod_find() in case a chip
identified by its label in a registered lookup table is not ready.

See https://lkml.org/lkml/2018/5/30/176 for example case.

Signed-off-by: Janusz Krzysztofik 
---
If accepted, please add

Suggested-by: Boris Brezillon 

if Boris doesn't mind.

Thanks,
Janusz

  drivers/gpio/gpiolib.c | 13 ++---
  1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c
index e11a3bb03820..15dc77c80328 100644
--- a/drivers/gpio/gpiolib.c
+++ b/drivers/gpio/gpiolib.c
@@ -3639,9 +3639,16 @@ static struct gpio_desc *gpiod_find(struct
device
*dev, const char *con_id,>

chip = find_chip_by_name(p->chip_label);

if (!chip) {

-   dev_err(dev, "cannot find GPIO chip %s\n",
-   p->chip_label);
-   return ERR_PTR(-ENODEV);
+   /*
+* As the lookup table indicates a chip with
+* p->chip_label should exist, assume it may
+* still appear latar and let the interested


^ later


+* consumer be probed again or let the Deferred
+* Probe infrastructure handle the error.
+*/
+   dev_warn(dev, "cannot find GPIO chip %s, deferring\n",
+p->chip_label);
+   return ERR_PTR(-EPROBE_DEFER);

}

if (chip->ngpio <= p->chip_hwnum) {


Looks good otherwise. Let's hope we're not breaking implementations
testing for -ENODEV...


I've reviewed them all and found two which I think may be affected:
- drivers/mfd/arizona-core.c,
- drivers/i2c/busses/i2c-imx.c.
As far as I can understand the code, both depend on error != -EPROBE_DEFER
in order to continue in degraded mode. I'm adding their maintainers to
the loop.

 From a quick glance, the -EPROBE_DEFER handing in Arizona Core appears
to be correct.  Would you mind explaining what your concerns are in
more detail please?


Hi

That's more about handling -ENODEV rather than -EPROBE_DEFER.

Before the change, if GPIO chip supposed to provide "reset" pin was not ready
during  arizona_dev_init(), devm_gpiod_get() returned -ENODEV and device was
initialized in degraded mode, i.e., with no control over the "reset" pin.
After the change, gpiod_get() will return -EPROBE_DEFER in such case and
arizona_dev_init() won't succeed in case the GPIO chip doesn't appear later
for some reason.

Thanks,
Januszz




The intention is that if the DT node is missing, the Arizona driver can run
using only soft reset, though there are limitations in that mode.
This should return -ENOENT so that the Arizona driver will continue without
a GPIO.

If the DT defines a GPIO it is effectively saying that this GPIO is required so
it is valid for the Arizona driver never to come up if the GPIO it is defined to
depend on doesn't come up.


[PATCH] mfd: madera: Remove spurious semicolon in while loop

2018-12-14 Thread Richard Fitzgerald
Coccinelle warning of a spurious semicolon on the closing brace
of a while loop.

Signed-off-by: Richard Fitzgerald 
---
 drivers/mfd/madera-core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/mfd/madera-core.c b/drivers/mfd/madera-core.c
index 5b58a8aea902..2a77988d0462 100644
--- a/drivers/mfd/madera-core.c
+++ b/drivers/mfd/madera-core.c
@@ -154,11 +154,11 @@ static int madera_wait_for_boot(struct madera *madera)
while (!(val & MADERA_BOOT_DONE_STS1) &&
   !ktime_after(ktime_get(), timeout)) {
usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
 MADERA_BOOT_POLL_INTERVAL_USEC);
regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
-   };
+   }
 
if (!(val & MADERA_BOOT_DONE_STS1)) {
dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
ret = -ETIMEDOUT;
}
-- 
2.11.0



[PATCH v13 RESEND2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-12-14 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
The MFD dependency is now in Linus's tree so this patch should apply
to the irq tree without breaking it.
---
 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 256 +
 include/linux/irqchip/irq-madera.h | 132 +++
 5 files changed, 394 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index f4855974f325..9060061f15f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3604,8 +3604,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 51a5ef0e96ed..a7252da28305 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index 794c13d3ac3d..3dcea8a6e5de 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -91,3 +91,4 @@ obj-$(CONFIG_QCOM_PDC)+= qcom-pdc.o
 obj-$(CONFIG_CSKY_MPINTC)  += irq-csky-mpintc.o
 obj-$(CONFIG_CSKY_APB_INTC)+= irq-csky-apb-intc.o
 obj-$(CONFIG_SIFIVE_PLIC)  += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..e9256dee1a45
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_DET,MADERA_IRQ1_STATUS_9),
+
+   MADERA_IRQ(

Re: [PATCH] irqchip: madera: Drop GPIO includes

2019-01-04 Thread Richard Fitzgerald

On 03/01/19 10:26, Linus Walleij wrote:

This irqchip does not use anything GPIO-related so drop
the GPIO includes.



An older version did some stuff with GPIOs but when that code was removed
this include obviously was forgotten.


Cc: Richard Fitzgerald 
Signed-off-by: Linus Walleij 
---
  drivers/irqchip/irq-madera.c | 2 --
  1 file changed, 2 deletions(-)

diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
index e9256dee1a45..8b81271c823c 100644
--- a/drivers/irqchip/irq-madera.c
+++ b/drivers/irqchip/irq-madera.c
@@ -7,7 +7,6 @@
   */
  
  #include 

-#include 
  #include 
  #include 
  #include 
@@ -16,7 +15,6 @@
  #include 
  #include 
  #include 
-#include 
  #include 
  #include 
  #include 



Acked-by: Richard Fitzgerald 


Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-10-29 Thread Richard Fitzgerald

On 29/10/18 11:04, Lee Jones wrote:

On Fri, 26 Oct 2018, Mark Brown wrote:

On Fri, Oct 26, 2018 at 09:00:51AM +0100, Lee Jones wrote:

On Thu, 25 Oct 2018, Richard Fitzgerald wrote:



Largely the point. How long do you think it would take to populate the
cache if you had to read thousands of registers over I2C? Boot time matters.
Deferring it until it's touched can create various unpredictable and
annoying behaviour later, for example if a lot of cache entries are
written while the chip is asleep and the initial values weren't known
then a suspend/resume cannot filter out writes that are setting the
register to its default (which regmap does to avoid unnecessary bus traffic).
So the resume could have a large amount of unnecessary overhead writing
registers to a value they already have or reading the initial values of
those registers.



One more register read when initially writing to a register and one
more when resuming doesn't sound like a vast amount of over-head.


Especially on resume extra register I/O really adds up - people really
care how long their system takes to come back from suspend, and how
quickly individual devices come back.  For devices that are on slow
buses like I2C this means that every register operation counts.  Boot
can be similarly pressured of course, though it's a less frequent issue
for these devices.


Not sure what you think I was suggesting above.  If the default values
are actually non-zero that's fine - we'll either leave them as they
are (if they are never changed, in which case Regmap doesn't even need
to know about them), document only those (non-zero) ones or wait until
they are read for the first time, then populate the cache.


You can't assume that the device is in power on reset state unless the
driver reset it itself which may or may not be a good idea or even
possible, sometimes it's what you want but at other times even if it's
possible it can cause user visible disruption during the boot process
which is undesirable.


Setting up the cache manually also sounds like a vector for potential
failure.  At least if you were to cache dynamically on first write
(either on start-up or after sleep) then the actual value will be
cached, rather than what a piece of C code says it should be.


Even where there's no problem getting the hardware into a clean state it
can rapidly get very, very expensive to do this with larger register
sets on slow buses, and at the framework level we can't assume that
readback support is even present on the device (the earliest versions of
cache support were written to support such devices).  Some of the
userspaces that regmap devices get used with end up wanting to apply a
bunch of configuration at startup, if we can cut down on the amount of
I/O that's involved in doing that it can help them quite a bit.  You
also get userspaces that want to enumerate device state at startup,
that's a bit easier to change in userspace but it's not an unreasonable
thing to want to do and can also get very I/O heavy.

There is some potential for errors to be introduced but equally these
tables can be both generated and verified mechanically, tasks that are
particularly straightforward for the device vendors to do.  There are
also potential risks in doing this at runtime if we didn't get the
device reset, if we don't accurately mark the volatile registers as
volatile or if there's otherwise bugs in the code.


Precisely my point.  Lochnagar is a small device yet it's required to
submit hundreds of lines of Regmap tables.  Imagine what that would
look like for a large device.


There's no *requirement* to provide the data even if you're using the
cache (and the cache support is entirely optional), there's just costs
to not providing it in terms of what features you can get from the
regmap API and the performance of the system.  Not every device is going
to be bothered by those costs, many devices don't provide all of the
data they could.


So what do we do in the case where, due to the size of the device, the
amount of lines required by these tables go from crazy to grotesque?


I'm not clear to me that Lochnagar will particularly benefit from
providing the cache defaults but it sounds like you've raised concerns
about other devices which would, and it seems clear that the readability
information is very useful for this device if there's registers that
it's unsafe to try to read from.


Any reduction in lines would be a good thing.  Charles, could you
please define what specific benefits you gain from providing providing
the pre-cache data please?  With a particular emphasis on whether the
trade-off is justified.



Why so much concern over the number of source lines of a data table?
If we were talking about removing lines of executable code to make it
more efficient - yes, that's a good thing.
Worrying about the numb

Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-10-29 Thread Richard Fitzgerald

On 29/10/18 11:04, Lee Jones wrote:

On Fri, 26 Oct 2018, Mark Brown wrote:

On Fri, Oct 26, 2018 at 09:00:51AM +0100, Lee Jones wrote:

On Thu, 25 Oct 2018, Richard Fitzgerald wrote:



Largely the point. How long do you think it would take to populate the
cache if you had to read thousands of registers over I2C? Boot time matters.
Deferring it until it's touched can create various unpredictable and
annoying behaviour later, for example if a lot of cache entries are
written while the chip is asleep and the initial values weren't known
then a suspend/resume cannot filter out writes that are setting the
register to its default (which regmap does to avoid unnecessary bus traffic).
So the resume could have a large amount of unnecessary overhead writing
registers to a value they already have or reading the initial values of
those registers.



One more register read when initially writing to a register and one
more when resuming doesn't sound like a vast amount of over-head.


Especially on resume extra register I/O really adds up - people really
care how long their system takes to come back from suspend, and how
quickly individual devices come back.  For devices that are on slow
buses like I2C this means that every register operation counts.  Boot
can be similarly pressured of course, though it's a less frequent issue
for these devices.


Not sure what you think I was suggesting above.  If the default values
are actually non-zero that's fine - we'll either leave them as they
are (if they are never changed, in which case Regmap doesn't even need
to know about them), document only those (non-zero) ones or wait until
they are read for the first time, then populate the cache.


You can't assume that the device is in power on reset state unless the
driver reset it itself which may or may not be a good idea or even
possible, sometimes it's what you want but at other times even if it's
possible it can cause user visible disruption during the boot process
which is undesirable.


Setting up the cache manually also sounds like a vector for potential
failure.  At least if you were to cache dynamically on first write
(either on start-up or after sleep) then the actual value will be
cached, rather than what a piece of C code says it should be.


Even where there's no problem getting the hardware into a clean state it
can rapidly get very, very expensive to do this with larger register
sets on slow buses, and at the framework level we can't assume that
readback support is even present on the device (the earliest versions of
cache support were written to support such devices).  Some of the
userspaces that regmap devices get used with end up wanting to apply a
bunch of configuration at startup, if we can cut down on the amount of
I/O that's involved in doing that it can help them quite a bit.  You
also get userspaces that want to enumerate device state at startup,
that's a bit easier to change in userspace but it's not an unreasonable
thing to want to do and can also get very I/O heavy.

There is some potential for errors to be introduced but equally these
tables can be both generated and verified mechanically, tasks that are
particularly straightforward for the device vendors to do.  There are
also potential risks in doing this at runtime if we didn't get the
device reset, if we don't accurately mark the volatile registers as
volatile or if there's otherwise bugs in the code.


Precisely my point.  Lochnagar is a small device yet it's required to
submit hundreds of lines of Regmap tables.  Imagine what that would
look like for a large device.


There's no *requirement* to provide the data even if you're using the
cache (and the cache support is entirely optional), there's just costs
to not providing it in terms of what features you can get from the
regmap API and the performance of the system.  Not every device is going
to be bothered by those costs, many devices don't provide all of the
data they could.


So what do we do in the case where, due to the size of the device, the
amount of lines required by these tables go from crazy to grotesque?


I'm not clear to me that Lochnagar will particularly benefit from
providing the cache defaults but it sounds like you've raised concerns
about other devices which would, and it seems clear that the readability
information is very useful for this device if there's registers that
it's unsafe to try to read from.


Any reduction in lines would be a good thing.  Charles, could you
please define what specific benefits you gain from providing providing
the pre-cache data please?  With a particular emphasis on whether the
trade-off is justified.


Even if it is absolutely critical that you have to supply these to
Regmap up-front, instead of on first use/read, why can't you just
supply the oddball non-zero ones?


That doesn't work, we need to kn

[PATCH v13 RESEND 0/2] irqchip support for Cirrus Logic Madera codecs

2018-10-16 Thread Richard Fitzgerald
This adds the support for the interrupt controller on the Cirrus Logic
Madera codecs. The irqchip patch has dependencies on the MFD tree.

Lee - can you take both these through the MFD tree? The irqchip patch
has dependencies on headers in MFD that aren't upstream yet so
submitting it to the irqchip tree breaks that tree.

Richard Fitzgerald (2):
  mfd: madera: Add irqchip data pointer into struct madera
  irqchip: Add driver for Cirrus Logic Madera codecs

 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 256 +
 include/linux/irqchip/irq-madera.h | 132 +++
 include/linux/mfd/madera/core.h|   2 +
 6 files changed, 396 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

-- 
2.11.0



[PATCH v13 RESEND 2/2] irqchip: Add driver for Cirrus Logic Madera codecs

2018-10-16 Thread Richard Fitzgerald
The Cirrus Logic Madera codecs (Cirrus Logic CS47L35/85/90/91 and WM1840)
are highly complex devices containing up to 7 programmable DSPs and many
other internal sources of interrupts plus a number of GPIOs that can be
used as interrupt inputs. The large number (>150) of internal interrupt
sources are managed by an on-board interrupt controller.

This driver provides the handling for the interrupt controller. As the
codec is accessed via regmap, we can make use of the generic IRQ
functionality from regmap to do most of the work. Only around half of
the possible interrupt source are currently of interest from the driver
so only this subset is defined. Others can be added in future if needed.

The KConfig options are not user-configurable because this driver is
mandatory so is automatically included when the parent MFD driver is
selected.

Signed-off-by: Richard Fitzgerald 
Signed-off-by: Charles Keepax 
---
Can this patch go through the MFD tree? It has dependencies on headers
from MFD that aren't upstream yet.
---
 MAINTAINERS|   2 +
 drivers/irqchip/Kconfig|   3 +
 drivers/irqchip/Makefile   |   1 +
 drivers/irqchip/irq-madera.c   | 256 +
 include/linux/irqchip/irq-madera.h | 132 +++
 5 files changed, 394 insertions(+)
 create mode 100644 drivers/irqchip/irq-madera.c
 create mode 100644 include/linux/irqchip/irq-madera.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 187b8a164083..c55e8bc485dc 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3594,8 +3594,10 @@ W:   
https://github.com/CirrusLogic/linux-drivers/wiki
 S: Supported
 F: Documentation/devicetree/bindings/mfd/madera.txt
 F: Documentation/devicetree/bindings/pinctrl/cirrus,madera-pinctrl.txt
+F: include/linux/irqchip/irq-madera*
 F: include/linux/mfd/madera/*
 F: drivers/gpio/gpio-madera*
+F: drivers/irqchip/irq-madera*
 F: drivers/mfd/madera*
 F: drivers/mfd/cs47l*
 F: drivers/pinctrl/cirrus/*
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig
index 96451b581452..43d953cbcfd7 100644
--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -150,6 +150,9 @@ config IMGPDC_IRQ
select GENERIC_IRQ_CHIP
select IRQ_DOMAIN
 
+config MADERA_IRQ
+   tristate
+
 config IRQ_MIPS_CPU
bool
select GENERIC_IRQ_CHIP
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile
index b822199445ff..f839c4f2ed39 100644
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -89,3 +89,4 @@ obj-$(CONFIG_GOLDFISH_PIC)+= irq-goldfish-pic.o
 obj-$(CONFIG_NDS32)+= irq-ativic32.o
 obj-$(CONFIG_QCOM_PDC) += qcom-pdc.o
 obj-$(CONFIG_SIFIVE_PLIC)  += irq-sifive-plic.o
+obj-$(CONFIG_MADERA_IRQ)   += irq-madera.o
diff --git a/drivers/irqchip/irq-madera.c b/drivers/irqchip/irq-madera.c
new file mode 100644
index ..e9256dee1a45
--- /dev/null
+++ b/drivers/irqchip/irq-madera.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt support for Cirrus Logic Madera codecs
+ *
+ * Copyright (C) 2015-2018 Cirrus Logic, Inc. and
+ * Cirrus Logic International Semiconductor Ltd.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#define MADERA_IRQ(_irq, _reg) \
+   [MADERA_IRQ_ ## _irq] = {   \
+   .reg_offset = (_reg) - MADERA_IRQ1_STATUS_2,\
+   .mask = MADERA_ ## _irq ## _EINT1   \
+   }
+
+/* Mappings are the same for all Madera codecs */
+static const struct regmap_irq madera_irqs[MADERA_NUM_IRQ] = {
+   MADERA_IRQ(FLL1_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL2_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLL3_LOCK,   MADERA_IRQ1_STATUS_2),
+   MADERA_IRQ(FLLAO_LOCK,  MADERA_IRQ1_STATUS_2),
+
+   MADERA_IRQ(MICDET1, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(MICDET2, MADERA_IRQ1_STATUS_6),
+   MADERA_IRQ(HPDET,   MADERA_IRQ1_STATUS_6),
+
+   MADERA_IRQ(MICD_CLAMP_RISE, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(MICD_CLAMP_FALL, MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_RISE,MADERA_IRQ1_STATUS_7),
+   MADERA_IRQ(JD1_FALL,MADERA_IRQ1_STATUS_7),
+
+   MADERA_IRQ(ASRC2_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC2_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN1_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(ASRC1_IN2_LOCK,  MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC2_SIG_DET,MADERA_IRQ1_STATUS_9),
+   MADERA_IRQ(DRC1_SIG_DET,MADERA_IRQ1_STATUS_9),
+
+   MADERA_IRQ(

[PATCH v13 RESEND 1/2] mfd: madera: Add irqchip data pointer into struct madera

2018-10-16 Thread Richard Fitzgerald
Put the pointer to struct regmap_irq_chip_data into the parent
mfd structure so that the child irqchip driver does not need
a trivial private structure to store only this pointer. As
the irqchip child driver already has a pointer to the parent
struct madera it can use that to store the pointer. This also
means that the irqchip driver does not need a double-indirection
from its local struct to get at the parent struct madera.

Signed-off-by: Richard Fitzgerald 
---
 include/linux/mfd/madera/core.h | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/include/linux/mfd/madera/core.h b/include/linux/mfd/madera/core.h
index c332681848ef..fe69c0f4398f 100644
--- a/include/linux/mfd/madera/core.h
+++ b/include/linux/mfd/madera/core.h
@@ -148,6 +148,7 @@ struct snd_soc_dapm_context;
  * @internal_dcvdd:true if DCVDD is supplied from the internal LDO1
  * @pdata: our pdata
  * @irq_dev:   the irqchip child driver device
+ * @irq_data:  pointer to irqchip data for the child irqchip driver
  * @irq:   host irq number from SPI or I2C configuration
  * @out_clamp: indicates output clamp state for each analogue output
  * @out_shorted:   indicates short circuit state for each analogue output
@@ -175,6 +176,7 @@ struct madera {
struct madera_pdata pdata;
 
struct device *irq_dev;
+   struct regmap_irq_chip_data *irq_data;
int irq;
 
unsigned int num_micbias;
-- 
2.11.0



Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-11-01 Thread Richard Fitzgerald

On 01/11/18 10:28, Charles Keepax wrote:

On Mon, Oct 29, 2018 at 11:04:39AM +, Lee Jones wrote:

On Fri, 26 Oct 2018, Mark Brown wrote:

On Fri, Oct 26, 2018 at 09:00:51AM +0100, Lee Jones wrote:

On Thu, 25 Oct 2018, Richard Fitzgerald wrote:


I have re-ordered some of the quotes here for the benefit
of clarity. I will start with the Lochnagar focused bits
and then cover some of the more general regmap discussion.
Apologies for the wall of text towards the end but it seemed
wise to explore some of the why for parts of the current regmap
implementation and some of the implications for changing it.


I think from the perspective of Richard and Charles who are just trying
to get their driver merged this is something of an abstract distinction.
If the driver were merged and this discussion were happening separately
their perspective would most likely be different.


Charles has already mentioned that he'd take a look at the current
*use* (not changing the API, but the way in which Lochnagar
*uses/consumes* it).  Actions which would be most welcomed.


I kind of said this above but just to be clear this driver seems to me
like an idiomatic user of the regmap API as it is today.  My guess is
that we could probably loose the defaults tables and not suffer too much
but equally well they don't hurt from a regmap point of view.


Perhaps Charles could elaborate on whether this is possible or not?


So on this front I have had a look through and we can drop the
defaults tables for Lochnagar, although as I shall cover later
Lochnagar is the exceptional case with respect to our normal
devices.


Utilising range support here would certainly help IMHO.



I am rather hesitant to switch to the range API. Whilst it is
significantly more clear in certain situations, such as say
mapping out the memory for a DSP, where there exist large
amorphis blobs of identical function registers. I am really
not convinced it really suits something like the register map
that controls Lochnagar. You have an intertwinned mix of
various purpose registers, each with a clearly defined name
and potentially with quite fine grained properties.

Certainly when working with the driver I want to be able to
fairly quickly see what registers are marked as by name. The
callbacks are very simple and I don't need to look up where
register are in the regmap to be able check their attributes.
But perhaps I have just got too used to seeing these callbacks,
things do have a way of becoming normal after being exposed to
them for a while.

What I will try for the next spin is to try to use as much:

   case REG1...REG2:

As I can without totally sacrificing grepability/clarity and
hopefully that will get us to a compromise we can all live
with at least for now. Lochnagar is a fairly small part so it
feels like this should be doable.


+   ret = devm_of_platform_populate(dev);
+   if (ret < 0) {
+   dev_err(dev, "Failed to populate child
nodes:
%d\n", ret);
+   return ret;
+   }


Please do not mix OF and MFD device registration
strategies.

Pick one and register all devices through your chosen
method.


Hmmm we use this to do things like register some fixed
regulators
and clocks that don't need any control but do need to be
associated
with the device. I could do that through the MFD although it
is in
direct conflict with the feedback on the clock patches I
received
to move the fixed clocks into devicetree rather than
registering
them manually (see v2 of the patch chain).


The I suggest moving everything to DT.


So pulling this out from earlier discussions in this thread,
it seems I can happily move all the child device registration
into device tree. I will also try this for the next version of
the patch, unless anyone wants to object? But it does change
the DT binding quite a lot as the individual sub drivers now
each require their own node rather than one single unified
Lochnagar node.



We went through this discussion with the Madera MFD patches. I had
originally implemented it using DT to register the child drivers and
it was nice in some ways each driver having its own node. But Mark
and Rob didn't like it so I went back to non-DT child registration with
all sharing the parent MFD node. It would be nice if we could stick to
one way of doing it so that Cirrus drivers don't flip-flop between
different styles of DT binding.

With the Madera MFD, since it now uses non-DT registration of children
if there was a reason we need to be able to register DT-defined children
(and there are potential uses like adding platform-specific virtual
regulators that are treated as a child) the bindings are now fixed so we
would end up having a mixed non-DT and DT registration.





Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-11-01 Thread Richard Fitzgerald

On 01/11/18 10:28, Charles Keepax wrote:

On Mon, Oct 29, 2018 at 11:04:39AM +, Lee Jones wrote:

On Fri, 26 Oct 2018, Mark Brown wrote:

On Fri, Oct 26, 2018 at 09:00:51AM +0100, Lee Jones wrote:

On Thu, 25 Oct 2018, Richard Fitzgerald wrote:







Precisely my point.  Lochnagar is a small device yet it's required to
submit hundreds of lines of Regmap tables.  Imagine what that would
look like for a large device.


There's no *requirement* to provide the data even if you're using the
cache (and the cache support is entirely optional), there's just costs
to not providing it in terms of what features you can get from the
regmap API and the performance of the system.  Not every device is going
to be bothered by those costs, many devices don't provide all of the
data they could.


So what do we do in the case where, due to the size of the device, the
amount of lines required by these tables go from crazy to grotesque?



Ultimately, I guess I have always just viewed it as just data
tables. Its a lot of lines of source but its not complicated,
and complexity has really always been the thing I try to avoid.



Again my question is why does it matter how many lines of source the tables
take? Unlike actual code, reducing the number of lines in a table doesn't
mean its more efficient. The tables aren't even particularly large when
compiled, a few kilobytes for CS47L90, which the users of that codec don't
care about compared to speed.

I can give a size comparison based on the Madera patches. When built as
modules for 32-bit ARM, the pinctrl driver for the (very simple) GPIOs on
those codecs builds to 22kB. All the regmap tables for the CS47L90
(the largest codec), including the defaults and all the readable/volatile
functions, builds to 23kB, and the smaller (but still quite big) CS47L35
to 16kB. So we're talking <= a trivial pinctrl driver even for a big
complex device like a CS47L90 with >1350 registers. For another comparison
the bulk of the CS47L90 object is the audio driver, which is ~2.2MB. So
the regmap tables are < 0.1%.


Even if it is absolutely critical that you have to supply these to
Regmap up-front, instead of on first use/read, why can't you just
supply the oddball non-zero ones?


That doesn't work, we need to know both if the register has a default
value and what that value is - there's no great value in only supplying
the defaults for registers with non-zero values.


All registers have a default value.  Why can't we assume that if a
register is writable and a default value was omitted then the default
is zero?


Defaults basically serve two purposes in regmap:

  1) Initialise the register cache.

 There are basically three ways you could handle this
 (at least that I can think of) and regmap supports all
 three. Obviously each with their own pros and cons:

  1.1) Table of default values
   + Fast boot time
   - Uses some additional memory
  1.2) Read all the registers from the device on boot
   + Uses less memory
   - Potentially very slow boot time
  1.3) Only read values as you touch registers
   + Uses less memory
   + Usually no significant impact on boot time
   - Can't do read or read/write/modify operations on
 previously untouched registers whilst chip is off

 1.3 does probably make sense here for Lochnagar since we
 don't currently power things down. However, it is worth
 noting that such an approach is extremely challenging for many
 devices. For example the CODECs generally have all sorts of
 actual user-facing interface that needs to be accessible
 regardless of if the CODEC is powered up or down and powering it
 up to access registers would end up being either horrific on
 power consumption and/or horrific in terms of code complexity.

 1.1 and 1.2 are basically a straight trade off. Generally
 for our devices we talking loads of registers and
 potentially connected over I2C. Our customers care deeply
 about device boot time, Android has specs for such things
 and often it is tight for a system to make those specs.
 Conversly, generally the products we integrate into have
 a fairly large amount of memory. As such this is a no
 brainer of a choice for most of our devices.

  2) Determine what registers should be synchronised on a cache
 sync.

 A cache sync is usually done when pulling a device out of
 low power mode to reapply the currently desired register
 settings. As discussed in 1) we don't currently do cache
 syncs on Lochnagar, but this would affect most of our
 parts. Again I can see three approaches to synchronising
 the cache:

  2.1) Sync out registers that arn't at their default value
   + Only syncs register that are actually needed
   - Requires a table of defaults 

Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-10-25 Thread Richard Fitzgerald

On 25/10/18 09:26, Charles Keepax wrote:

On Thu, Oct 25, 2018 at 08:44:59AM +0100, Lee Jones wrote:

On Mon, 08 Oct 2018, Charles Keepax wrote:

From: Charles Keepax 
+static const struct reg_default lochnagar1_reg_defaults[] = {
+   { LOCHNAGAR1_CDC_AIF1_SEL,0x00 },
+   { LOCHNAGAR1_CDC_AIF2_SEL,0x00 },

...

+   { LOCHNAGAR1_LED1,0x00 },
+   { LOCHNAGAR1_LED2,0x00 },
+   { LOCHNAGAR1_I2C_CTRL,0x01 },
+};


Why do you need to specify each register value?



The way regmap operates it needs to know the starting value of
each register. It will use this to initialise the cache and to
determine if writes need to actually update the hardware on
cache_syncs after devices have been powered back up.


+static const struct reg_sequence lochnagar1_patch[] = {
+   { 0x40, 0x0083 },
+   { 0x46, 0x0001 },
+   { 0x47, 0x0018 },
+   { 0x50, 0x },
+};


I'm really not a fan of these so call 'patches'.

Can't you set the registers up proper way?



I will see if we could move any out of here or define any of the
registers but as we have discussed before it is not always possible.



Also patches generally come out of hardware tuning/qualification/tools
as this list of address,value. So it's easy for people to dump an update
into the driver as a trivial copy-paste but more work if they have to
reverse-engineer the patch list from hardware/datasheet into what each
line "means" and then find the relevant lines of code to change. It's also
much easier to answer the question "Have these hardware patches been
applied to the driver?" if we have them in the original documented format.
It just makes people's lives more difficult if they have to search around
the code to try to find something that looks like the originally specified
patch list. We don't use them just as a lazy way to setup some registers.


+static bool lochnagar2_readable_register(struct device *dev, unsigned int reg)
+{
+   switch (reg) {
+   case LOCHNAGAR_SOFTWARE_RESET:
+   case LOCHNAGAR_FIRMWARE_ID1:
+   case LOCHNAGAR_FIRMWARE_ID2:

...

+   case LOCHNAGAR2_MICVDD_CTRL2:
+   case LOCHNAGAR2_VDDCORE_CDC_CTRL1:
+   case LOCHNAGAR2_VDDCORE_CDC_CTRL2:
+   case LOCHNAGAR2_SOUNDCARD_AIF_CTRL:
+   return true;
+   default:
+   return false;
+   }
+}
+
+static bool lochnagar2_volatile_register(struct device *dev, unsigned int reg)
+{
+   switch (reg) {
+   case LOCHNAGAR2_GPIO_CHANNEL1:
+   case LOCHNAGAR2_GPIO_CHANNEL2:
+   case LOCHNAGAR2_GPIO_CHANNEL3:

...

+   case LOCHNAGAR2_GPIO_CHANNEL13:
+   case LOCHNAGAR2_GPIO_CHANNEL14:
+   case LOCHNAGAR2_GPIO_CHANNEL15:
+   case LOCHNAGAR2_GPIO_CHANNEL16:
+   case LOCHNAGAR2_ANALOGUE_PATH_CTRL1:
+   return true;
+   default:
+   return false;
+   }
+}


This is getting silly now.  Can't you use ranges?



I can if you feel strongly about it? But it does make the drivers
much more error prone and significantly more annoying to work
with. I find it is really common to be checking that a register
is handled correctly through the regmap callbacks and it is nice
to just be able to grep for that. Obviously this won't work for
all devices/regmaps as well since many will not have consecutive
addresses on registers, for example having multi-byte registers
that are byte addressed.

How far would you like me to take this as well? Is it just the
numeric registers you want ranges for ie.

LOCHNAGAR2_GPIO_CHANNEL1...LOCHNAGAR_GPIO_CHANNEL16

Or is it all consecutive registers even if they are unrelated
(exmaple is probably not accurate as I haven't checked the
addresses):

LOCHNAGAR2_GPIO_CHANNEL1...LOCHNAGAR2_ANALOGURE_PATH_CTRL1

I don't mind the first at all but the second is getting really
horrible in my opinion.


+static const struct reg_default lochnagar2_reg_defaults[] = {
+   { LOCHNAGAR2_CDC_AIF1_CTRL, 0x },
+   { LOCHNAGAR2_CDC_AIF2_CTRL, 0x },
+   { LOCHNAGAR2_CDC_AIF3_CTRL, 0x },
+   { LOCHNAGAR2_DSP_AIF1_CTRL, 0x },

...

+   { LOCHNAGAR2_MINICARD_RESETS,   0x },
+   { LOCHNAGAR2_ANALOGUE_PATH_CTRL2,   0x },
+   { LOCHNAGAR2_COMMS_CTRL4,   0x0001 },
+   { LOCHNAGAR2_SPDIF_CTRL,0x0008 },
+   { LOCHNAGAR2_POWER_CTRL,0x0001 },
+   { LOCHNAGAR2_SOUNDCARD_AIF_CTRL,0x },
+};


OMG!  Vile, vile vile!



I really feel this isn't the driver you are objecting to as such
but the way regmap operates and also we seem to always have the same
discussions around regmap every time we push a driver. Is there
any way me, you and Mark could hash this out and find out a way to
handle regmaps that is acceptable to you? I don't suppose you are
in Edinburgh at the moment for ELCE?



I suppose if Mark was willing to promote the regmap drivers to be a
top-level subsystem that could contain the r

Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-10-25 Thread Richard Fitzgerald

On 25/10/18 12:42, Lee Jones wrote:

On Thu, 25 Oct 2018, Richard Fitzgerald wrote:

On 25/10/18 09:26, Charles Keepax wrote:

On Thu, Oct 25, 2018 at 08:44:59AM +0100, Lee Jones wrote:

On Mon, 08 Oct 2018, Charles Keepax wrote:

From: Charles Keepax 
+static const struct reg_default lochnagar1_reg_defaults[] = {
+   { LOCHNAGAR1_CDC_AIF1_SEL,0x00 },
+   { LOCHNAGAR1_CDC_AIF2_SEL,0x00 },

...

+   { LOCHNAGAR1_LED1,0x00 },
+   { LOCHNAGAR1_LED2,0x00 },
+   { LOCHNAGAR1_I2C_CTRL,0x01 },
+};


Why do you need to specify each register value?


The way regmap operates it needs to know the starting value of
each register. It will use this to initialise the cache and to
determine if writes need to actually update the hardware on
cache_syncs after devices have been powered back up.


That sounds crazy to me.  Some devices have thousands of registers.


Largely the point. How long do you think it would take to populate the
cache if you had to read thousands of registers over I2C? Boot time matters.
Deferring it until it's touched can create various unpredictable and
annoying behaviour later, for example if a lot of cache entries are
written while the chip is asleep and the initial values weren't known
then a suspend/resume cannot filter out writes that are setting the
register to its default (which regmap does to avoid unnecessary bus traffic).
So the resume could have a large amount of unnecessary overhead writing
registers to a value they already have or reading the initial values of
those registers.


At a line per register, that's thousands of lines of code/cruft.
Especially seeing as most (sane?) register layouts I've seen default
to zero.


Not a valid generalization. And it's not a question of sanity, the purpose
of the register and the overhead to setup a use-case also matter.
There are many reasons why the default of a register might not be zero.
Take a look at drivers/mfd/wm5110-tables.c, a lot of the registers don't
have a default of zero (and that's only the registers accessed by the driver.)
It's particularly true of registers that affect things like voltage and
current sources, zero might be a very inappropriate default - even dangerous.
Also enable bits, if some things must power-up enabled and others don't, unless
you want a chip that has a confusing mix of inverted and non-inverted enable
bits. Another side to this is to reduce the number of writes to enable _typical_
behaviour - if an IP block has say 100 registers and you have to write all of
them to make it work that's a lot of overhead compared to them defaulting to
typical values used 99.9% of the time and you only need to write one or two
registers to use it.

  Then default values can be changed at the leisure of the

s/w.


Potentially with a lot of overhead, especially on those chips with thousands
of registers to set to useful non-zero values before you can use it.

Lochnagar doesn't have that many registers but convention and consistency also
comes into play. Regmap is used in a particular way and it helps people a lot
if every driver using it follows the convention.



Even if it is absolutely critical that you have to supply these to
Regmap up-front, instead of on first use/read, why can't you just
supply the oddball non-zero ones?



If you aren't happy with the regmap subsystem you could send some
patches to change it to what you would be happy with (and patch the ~1300
drivers that use it)

Like any kernel subsystem it has an API that we have to obey to be able to
use it.


+static const struct reg_sequence lochnagar1_patch[] = {
+   { 0x40, 0x0083 },
+   { 0x46, 0x0001 },
+   { 0x47, 0x0018 },
+   { 0x50, 0x },
+};


I'm really not a fan of these so call 'patches'.

Can't you set the registers up proper way?



I will see if we could move any out of here or define any of the
registers but as we have discussed before it is not always possible.



Also patches generally come out of hardware tuning/qualification/tools
as this list of address,value. So it's easy for people to dump an update
into the driver as a trivial copy-paste but more work if they have to
reverse-engineer the patch list from hardware/datasheet into what each
line "means" and then find the relevant lines of code to change. It's also
much easier to answer the question "Have these hardware patches been
applied to the driver?" if we have them in the original documented format.
It just makes people's lives more difficult if they have to search around
the code to try to find something that looks like the originally specified
patch list. We don't use them just as a lazy way to setup some registers.


I understand why they normally exist (sometimes people are just lazy
too) (Mark: BTW chicken-bits sound delicious!).  They're just ugly
from an Open Source PoV

Re: [PATCH v2 2/5] mfd: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-10-25 Thread Richard Fitzgerald

On 25/10/18 14:20, Charles Keepax wrote:

On Thu, Oct 25, 2018 at 01:49:05PM +0100, Charles Keepax wrote:

On Thu, Oct 25, 2018 at 12:42:05PM +0100, Lee Jones wrote:

On Thu, 25 Oct 2018, Richard Fitzgerald wrote:

On 25/10/18 09:26, Charles Keepax wrote:

On Thu, Oct 25, 2018 at 08:44:59AM +0100, Lee Jones wrote:

On Mon, 08 Oct 2018, Charles Keepax wrote:

From: Charles Keepax 

I really feel this isn't the driver you are objecting to as such
but the way regmap operates and also we seem to always have the same
discussions around regmap every time we push a driver.


Absolutely.  I didn't like it before.  I like it even less now.



I guess the question from my side becomes do you want to block
this driver pending on major refactoring to regmap? I will have a
think about what I can do but its going to affect a LOT of drivers.



Actually one more thought, perhaps as a halfway for now i could
look into removing the readables


Be careful with that, there are some addresses that are illegal to
access. What does regmap debugfs do if you don't have a readables
list? Just reading a debugfs shouldn't be able to kill the hardware.
You might need to add a precious list which is more error prone
than listing the valid readables we are using.

 and defaults. We lose some things

like error checking that we are reading real registers but as
this driver doesnt currently do cache syncs we might be able to
get away with this for now.

Unless anyone strenuously objects i will have a look at the
options there. As well as looking at wider refactoring but aiming
further out.

Thanks,
Charles





Re: [PATCH v3 4/5] regulator: lochnagar: Add support for the Cirrus Logic Lochnagar

2018-10-19 Thread Richard Fitzgerald

On 19/10/18 12:26, Mark Brown wrote:

On Fri, Oct 19, 2018 at 10:50:02AM +0100, Charles Keepax wrote:

Please do not submit new versions of already applied patches, please
submit incremental updates to the existing code.  Modifying existing
commits creates problems for other users building on top of those
commits so it's best practice to only change pubished git commits if
absolutely essential.


+++ b/drivers/regulator/lochnagar-regulator.c
@@ -0,0 +1,255 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Lochnagar regulator driver


Please don't mix C and C++ comments like this in the same block, just
have it be a C++ block so it looks consistent.



Most SPDX headers on C files that I've looked at have it this way with a
C++ style comment above a C-style comment, though some don't. license-rules.rst
doesn't define how or if a SPDX comment line should be merged with the following
file header comment. I've had a bunch of patches in different subsystems all
accepted with this mixed format (copied from existing files). Doing the same as
existing files sounds reasonable but often isn't in the Linux kernel. It's a
common problem/barrier to kernel programming that existing code isn't a guide
and there isn't a consistent style across the kernel so one never really knows
what the coding style is until you've pushed a patch and annoyed a maintainer.
And then you adopt that style on your next patch and annoy different maintainer.

Maybe someone should update license-rules.rst to make a definite statement of 
the
style instead of leaving it to become another style that varies across the 
kernel
and between files.


[PATCH 1/2] ASoC: wm_adsp: Rename memory fields in wm_adsp_buffer

2018-10-19 Thread Richard Fitzgerald
The wm_adsp_buffer struct is the control header of a circular
buffer used to transfer data from the firmware over the
control interface to an ALSA compressed stream.

The original names of the fields pointing to the data buffer
were based on ADSP2V2 memory layout where they correspond to
{XM, XM, YM}. But this circular buffer could be used on other
types of DSP core that have different memory region types.
Also the names and description of the size fields were not
very clear. The field names and descriptions have been changed
to be generic and not imply any particular memory types.

This patch updates the wm_adsp driver to the new field names.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/wm_adsp.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index f61656070225..7ae10c632614 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -311,12 +311,12 @@ struct wm_adsp_alg_xm_struct {
 };
 
 struct wm_adsp_buffer {
-   __be32 X_buf_base;  /* XM base addr of first X area */
-   __be32 X_buf_size;  /* Size of 1st X area in words */
-   __be32 X_buf_base2; /* XM base addr of 2nd X area */
-   __be32 X_buf_brk;   /* Total X size in words */
-   __be32 Y_buf_base;  /* YM base addr of Y area */
-   __be32 wrap;/* Total size X and Y in words */
+   __be32 buf1_base;   /* Base addr of first buffer area */
+   __be32 buf1_size;   /* Size of buf1 area in DSP words */
+   __be32 buf2_base;   /* Base addr of 2nd buffer area */
+   __be32 buf1_buf2_size;  /* Size of buf1+buf2 in DSP words */
+   __be32 buf3_base;   /* Base addr of buf3 area */
+   __be32 buf_total_size;  /* Size of buf1+buf2+buf3 in DSP words 
*/
__be32 high_water_mark; /* Point at which IRQ is asserted */
__be32 irq_count;   /* bits 1-31 count IRQ assertions */
__be32 irq_ack; /* acked IRQ count, bit 0 enables IRQ */
@@ -393,18 +393,18 @@ struct wm_adsp_buffer_region_def {
 static const struct wm_adsp_buffer_region_def default_regions[] = {
{
.mem_type = WMFW_ADSP2_XM,
-   .base_offset = HOST_BUFFER_FIELD(X_buf_base),
-   .size_offset = HOST_BUFFER_FIELD(X_buf_size),
+   .base_offset = HOST_BUFFER_FIELD(buf1_base),
+   .size_offset = HOST_BUFFER_FIELD(buf1_size),
},
{
.mem_type = WMFW_ADSP2_XM,
-   .base_offset = HOST_BUFFER_FIELD(X_buf_base2),
-   .size_offset = HOST_BUFFER_FIELD(X_buf_brk),
+   .base_offset = HOST_BUFFER_FIELD(buf2_base),
+   .size_offset = HOST_BUFFER_FIELD(buf1_buf2_size),
},
{
.mem_type = WMFW_ADSP2_YM,
-   .base_offset = HOST_BUFFER_FIELD(Y_buf_base),
-   .size_offset = HOST_BUFFER_FIELD(wrap),
+   .base_offset = HOST_BUFFER_FIELD(buf3_base),
+   .size_offset = HOST_BUFFER_FIELD(buf_total_size),
},
 };
 
-- 
2.11.0



[PATCH 2/2] ASoC: wm_adsp: Log addresses as 8 digits in wm_adsp_buffer_populate

2018-10-19 Thread Richard Fitzgerald
Increase the address value width in the debug log from 4 digits to
8 digits to allow for DSP cores with larger memory address ranges.

Signed-off-by: Richard Fitzgerald 
---
 sound/soc/codecs/wm_adsp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/codecs/wm_adsp.c b/sound/soc/codecs/wm_adsp.c
index 7ae10c632614..a53dc174bbf0 100644
--- a/sound/soc/codecs/wm_adsp.c
+++ b/sound/soc/codecs/wm_adsp.c
@@ -3345,7 +3345,7 @@ static int wm_adsp_buffer_populate(struct 
wm_adsp_compr_buf *buf)
region->cumulative_size = offset;
 
adsp_dbg(buf->dsp,
-"region=%d type=%d base=%04x off=%04x size=%04x\n",
+"region=%d type=%d base=%08x off=%08x size=%08x\n",
 i, region->mem_type, region->base_addr,
 region->offset, region->cumulative_size);
}
-- 
2.11.0



Re: [PATCH 6/8] extcon: arizona: Add support for WM8998 and WM1814

2015-04-22 Thread Richard Fitzgerald
On Wed, Apr 22, 2015 at 02:53:42PM +0900, Chanwoo Choi wrote:
> Hi Richard,
> 
> > @@ -1176,6 +1182,11 @@ static int arizona_extcon_probe(struct 
> > platform_device *pdev)
> > break;
> > }
> > break;
> > +   case WM8998:
> > +   case WM1814:
> > +   info->micd_clamp = true;
> > +   info->hpdet_ip = 2;
> 
> What is meaning of '2'? I prefer to use the definition for '2'.
> 

'2' is the version number of the hpdet ip block in silicon. We're already using
it as a raw number '0', '1' or '2' all over extcon-arizona.c so changing it here
would mean making other patches to the file that aren't really part of adding
WM8998 support, so I'd prefer not to change that as a side-effect of adding 
WM8998.


> Except for upper one comment, looks good to me.
> 
> Thanks,
> Chanwoo Choi
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [alsa-devel] [PATCH 6/8] extcon: arizona: Add support for WM8998 and WM1814

2015-04-23 Thread Richard Fitzgerald
On Wed, Apr 22, 2015 at 07:20:09PM +0900, Chanwoo Choi wrote:
> On 04/22/2015 06:19 PM, Richard Fitzgerald wrote:
> > On Wed, Apr 22, 2015 at 02:53:42PM +0900, Chanwoo Choi wrote:
> >> Hi Richard,
> >>
> >>> @@ -1176,6 +1182,11 @@ static int arizona_extcon_probe(struct 
> >>> platform_device *pdev)
> >>>   break;
> >>>   }
> >>>   break;
> >>> + case WM8998:
> >>> + case WM1814:
> >>> + info->micd_clamp = true;
> >>> + info->hpdet_ip = 2;
> >>
> >> What is meaning of '2'? I prefer to use the definition for '2'.
> >>
> > 
> > '2' is the version number of the hpdet ip block in silicon. We're already 
> > using
> > it as a raw number '0', '1' or '2' all over extcon-arizona.c so changing it 
> > here
> > would mean making other patches to the file that aren't really part of 
> > adding
> > WM8998 support, so I'd prefer not to change that as a side-effect of adding 
> > WM8998.
> 
> I think that just you can define following definitions and use 
> HPDET_IP_VER_V2 instead of '2'.
> 
>   #define HPDET_IP_VER_V0 0
>   #define HPDET_IP_VER_V1 1
>   #define HPDET_IP_VER_V2 2
> 

Can we deal with that as a separate patch from this series? Like I said,
the code already uses '0' '1' and '2' for the existing codecs so making a
change to use #define means patching the code for the other codecs. That
is not part of adding WM8998 support and I don't like patches that make
unexpected extra side-effect changes that are not relevant to the actual
functionality being added by the patch. It's specially annoying when
cherry-picking or reverting those patches if they included some extra
code change.

If we can get this series submitted I can look at making a later patch
to improve readbility, but since this really is just a version number I
think it would be enough to rename the variable to hpdet_ip_version rather
than effectively doing #define TWO 2


> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 7/8] ASoC: wm8998: Initial WM8998 codec driver

2015-04-23 Thread Richard Fitzgerald
On Wed, Apr 22, 2015 at 12:00:30PM +0100, Mark Brown wrote:
> On Tue, Apr 21, 2015 at 01:33:55PM +0100, Richard Fitzgerald wrote:
> 
> > +static int wm8998_in1mux_ev(struct snd_soc_dapm_widget *w,
> > +   struct snd_kcontrol *kcontrol,
> > +   int event)
> > +{
> > +   struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
> > +   struct arizona *arizona = dev_get_drvdata(codec->dev->parent);
> > +   unsigned int left_mux, right_mux, in1mode, old;
> > +
> > +   switch (event) {
> > +   case SND_SOC_DAPM_PRE_PMU:
> > +   /* Validate the mux configuration */
> > +   left_mux = snd_soc_read(codec, ARIZONA_ADC_DIGITAL_VOLUME_1L) &
> > + ARIZONA_IN1L_SRC_MASK;
> > +   right_mux = snd_soc_read(codec, ARIZONA_ADC_DIGITAL_VOLUME_1R) &
> > + ARIZONA_IN1R_SRC_MASK;
> > +
> > +   /* Only IN1A can be digital, IN1B is always analogue */
> > +   in1mode = (arizona->pdata.inmode[0] & 2)
> > +   << (ARIZONA_IN1_MODE_SHIFT - 1);
> > +
> > +   if (in1mode != 0) {
> > +   /* if IN1A is digital, the only valid mux configs
> > +* are both channels A or both channels B.
> > +*/
> > +   if (left_mux != right_mux) {
> > +   dev_err(arizona->dev,
> > +   "IN1=DMIC and IN1L Mux != IN1R Mux");
> > +   return -EINVAL;
> > +   }
> 
> This (or at least some of it) seems like something we should be doing by
> registering different widgets and routing at device probe time.

I'm not sure this is really a routing or widget problem. Problem is that
if the muxed inputs are analogue we need to provide separate ALSA controls
for the left and right mux because it is allowed to use them as two
independant mono channels with separate muxing. But if they are
configured as digital the mux controls are ganged so must be set the
same. I don't feel good about registering a single mux control if its
digital and two if its analogue because that means the codec's control
list depends on a pdata option. I could implement the control pair
so that if the input is digital changing one control always changes
the other so they will always be forced to the same setting. Any
better options?

> 
> > +   old = snd_soc_read(codec, ARIZONA_IN1L_CONTROL) &
> > +   ARIZONA_IN1_MODE_MASK;
> 
> > +   if (old != in1mode)
> > +   snd_soc_update_bits(codec, ARIZONA_IN1L_CONTROL,
> > +   ARIZONA_IN1_MODE_MASK, in1mode);
> 
> Why bother with the read into old here?  Suppressing redundant updates
> is part of the point of snd_soc_update_bits().

Agreed, probably a legacy of an earlier implementation that's now redundant.


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [alsa-devel] [PATCH 8/8] Documentation: Add WM8998/WM1814 device tree bindings

2015-04-23 Thread Richard Fitzgerald
On Thu, Apr 23, 2015 at 02:05:18AM +, Austin, Brian wrote:
> 
> 
> > On Apr 21, 2015, at 07:38, Richard Fitzgerald 
> >  wrote:
> > 
> > Signed-off-by: Richard Fitzgerald 
> > ---
> > Documentation/devicetree/bindings/mfd/arizona.txt |3 +++
> > 1 files changed, 3 insertions(+), 0 deletions(-)
> > 
> > diff --git a/Documentation/devicetree/bindings/mfd/arizona.txt 
> > b/Documentation/devicetree/bindings/mfd/arizona.txt
> > index 7665aa9..a3cb34b 100644
> > --- a/Documentation/devicetree/bindings/mfd/arizona.txt
> > +++ b/Documentation/devicetree/bindings/mfd/arizona.txt
> > @@ -10,6 +10,9 @@ Required properties:
> > "wlf,wm5110"
> > "wlf,wm8280"
> > "wlf,wm8997"
> > +"wlf,WM8998"
> > +"wlf,wm1814"
> > +
> Is there a reason for caps on the 8998? 
> 
> -Brian 

Yes, it's called "lack of attention to detail". Will be fixed in the respin.

> ___
> Alsa-devel mailing list
> alsa-de...@alsa-project.org
> http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


Re: [PATCH 3/8] mfd: arizona: Add support for WM8998 and WM1814

2015-04-27 Thread Richard Fitzgerald
On Wed, Apr 22, 2015 at 12:08:08PM +0100, Mark Brown wrote:
> On Tue, Apr 21, 2015 at 01:33:51PM +0100, Richard Fitzgerald wrote:
> 
> > +   switch (arizona->type) {
> > +   case WM8998:
> > +   case WM1814:
> > +   /* Some bits are shifted on WM8998,
> > +* rearrange to match the standard bit layout
> > +*/
> > +   val[0] = ((val[0] & 0x60e0) >> 1) |
> > +((val[0] & 0x1e00) >> 2) |
> > +(val[0] & 0x000f);
> > +   break;
> 
> Are you sure this approach is going to scale (and avoid confusion)?

It's a total one-off for the WM8998/WM1814, no other codecs have
this shifted-bit-position problem. This shouldn't happen for any
future codecs, so I don't feel like it's worth over-complicating it.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH 1/1] extcon: arizona: Rename hpdet_ip to make its purpose clearer

2015-04-28 Thread Richard Fitzgerald
Renamed to hpdet_ip_version to make it clearer what it does
and that the value in it is simply a version number.

Signed-off-by: Richard Fitzgerald 
---
 drivers/extcon/extcon-arizona.c |   10 +-
 1 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/extcon/extcon-arizona.c b/drivers/extcon/extcon-arizona.c
index d9e763c..02b181a 100644
--- a/drivers/extcon/extcon-arizona.c
+++ b/drivers/extcon/extcon-arizona.c
@@ -94,7 +94,7 @@ struct arizona_extcon_info {
bool detecting;
int jack_flips;
 
-   int hpdet_ip;
+   int hpdet_ip_version;
 
struct extcon_dev *edev;
 };
@@ -380,7 +380,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info 
*info)
return ret;
}
 
-   switch (info->hpdet_ip) {
+   switch (info->hpdet_ip_version) {
case 0:
if (!(val & ARIZONA_HP_DONE)) {
dev_err(arizona->dev, "HPDET did not complete: %x\n",
@@ -441,7 +441,7 @@ static int arizona_hpdet_read(struct arizona_extcon_info 
*info)
 
default:
dev_warn(arizona->dev, "Unknown HPDET IP revision %d\n",
-info->hpdet_ip);
+info->hpdet_ip_version);
case 2:
if (!(val & ARIZONA_HP_DONE_B)) {
dev_err(arizona->dev, "HPDET did not complete: %x\n",
@@ -1161,7 +1161,7 @@ static int arizona_extcon_probe(struct platform_device 
*pdev)
break;
default:
info->micd_clamp = true;
-   info->hpdet_ip = 1;
+   info->hpdet_ip_version = 1;
break;
}
break;
@@ -1171,7 +1171,7 @@ static int arizona_extcon_probe(struct platform_device 
*pdev)
break;
default:
info->micd_clamp = true;
-   info->hpdet_ip = 2;
+   info->hpdet_ip_version = 2;
break;
}
break;
-- 
1.7.2.5

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


  1   2   3   4   5   6   7   8   >