Re: [linux-sunxi] [PATCH 1/3] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2018-01-28 Thread Code Kipper
On 29 January 2018 at 08:38, Chen-Yu Tsai  wrote:
> On Mon, Jan 29, 2018 at 3:34 PM, Code Kipper  wrote:
>> On 29 January 2018 at 02:50, Chen-Yu Tsai  wrote:
>>> On Wed, Jan 24, 2018 at 10:10 PM,   wrote:
 From: Marcus Cooper 

 Some codecs require a different amount of a bit clocks per frame than
 what is calculated by the sample width. Use the tdm slot bindings to
 provide this mechanism.

 Signed-off-by: Marcus Cooper 
 ---
  sound/soc/sunxi/sun4i-i2s.c | 23 +--
  1 file changed, 21 insertions(+), 2 deletions(-)

 diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
 index dca1143c1150..d7a9141514cf 100644
 --- a/sound/soc/sunxi/sun4i-i2s.c
 +++ b/sound/soc/sunxi/sun4i-i2s.c
 @@ -96,6 +96,7 @@
  #define SUN8I_I2S_CTRL_BCLK_OUTBIT(18)
  #define SUN8I_I2S_CTRL_LRCK_OUTBIT(17)

 +#define SUN8I_I2S_FMT0_LRCK_MAX_PERIOD (GENMASK(17, 8) >> 8)
  #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASKGENMASK(17, 8)
  #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)

 @@ -193,6 +194,9 @@ struct sun4i_i2s {
 struct regmap_field *field_rxchansel;

 const struct sun4i_i2s_quirks   *variant;
 +
 +   unsigned inttdm_slots;
 +   unsigned intslot_width;
  };

  struct sun4i_i2s_clk_div {
 @@ -344,7 +348,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai 
 *dai,
 if (i2s->variant->has_fmt_set_lrck_period)
 regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
 -  SUN8I_I2S_FMT0_LRCK_PERIOD(32));
 +  SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));

 return 0;
  }
 @@ -418,7 +422,8 @@ static int sun4i_i2s_hw_params(struct 
 snd_pcm_substream *substream,
sr + i2s->variant->fmt_offset);

 return sun4i_i2s_set_clk_rate(dai, params_rate(params),
 - params_width(params));
 + i2s->tdm_slots ?
 + i2s->slot_width : 
 params_width(params));
  }

  static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
 @@ -691,6 +696,19 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai 
 *dai, int clk_id,
 return 0;
  }

 +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
 +   unsigned int tx_mask, unsigned int rx_mask,
 +   int slots, int width)
 +{
 +   struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
 +
 +   i2s->tdm_slots = slots;
 +
 +   i2s->slot_width = width;
 +
 +   return 0;
 +}
 +
>>>
>>> IIRC some of the DAI controllers actually support TDM. Would this
>>> change conflict with that in the future?
>>
>> Hi Wens,
>> I'm not sure..I was looking for a clean example of being able to
>> override the number of bclks in the lrclk width and some other
>> devices(Rpi) were doing it this way.  I open to suggestions,
>
> I'm not familiar with the issue either. If Mark doesn't have any
> objections, we could merge it for now, and fix it later if there
> are any complications.
>
> BTW, you didn't provide a device tree example (if any) for how
> to use this.

Hi Wens,

here is an example that I use for the Pine64 audio hat.
https://github.com/codekipper/linux-sunxi/commit/faa9dfba955bf71ca23b089b1cb678a14443216f#diff-1473a38b339685d191c5a87aab9c0fdfR80

I've done the same on the A64 for HDMI and analog audio which both use
the i2s and seem to require 32bit LRCK width.

BR,
CK

>
> ChenYu
>
>> BR,
>> CK
>>>
>>> Thanks
>>> ChenYu
>>>
  static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
 .hw_params  = sun4i_i2s_hw_params,
 .set_fmt= sun4i_i2s_set_fmt,
 @@ -698,6 +716,7 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops 
 = {
 .shutdown   = sun4i_i2s_shutdown,
 .startup= sun4i_i2s_startup,
 .trigger= sun4i_i2s_trigger,
 +   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
  };

  static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
 --
 2.16.0

 --
 You received this message because you are subscribed to the Google Groups 
 "linux-sunxi" group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to linux-sunxi+unsubscr...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.

-- 
You received this message 

Re: [linux-sunxi] [PATCH 1/3] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2018-01-28 Thread Chen-Yu Tsai
On Mon, Jan 29, 2018 at 3:34 PM, Code Kipper  wrote:
> On 29 January 2018 at 02:50, Chen-Yu Tsai  wrote:
>> On Wed, Jan 24, 2018 at 10:10 PM,   wrote:
>>> From: Marcus Cooper 
>>>
>>> Some codecs require a different amount of a bit clocks per frame than
>>> what is calculated by the sample width. Use the tdm slot bindings to
>>> provide this mechanism.
>>>
>>> Signed-off-by: Marcus Cooper 
>>> ---
>>>  sound/soc/sunxi/sun4i-i2s.c | 23 +--
>>>  1 file changed, 21 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
>>> index dca1143c1150..d7a9141514cf 100644
>>> --- a/sound/soc/sunxi/sun4i-i2s.c
>>> +++ b/sound/soc/sunxi/sun4i-i2s.c
>>> @@ -96,6 +96,7 @@
>>>  #define SUN8I_I2S_CTRL_BCLK_OUTBIT(18)
>>>  #define SUN8I_I2S_CTRL_LRCK_OUTBIT(17)
>>>
>>> +#define SUN8I_I2S_FMT0_LRCK_MAX_PERIOD (GENMASK(17, 8) >> 8)
>>>  #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASKGENMASK(17, 8)
>>>  #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
>>>
>>> @@ -193,6 +194,9 @@ struct sun4i_i2s {
>>> struct regmap_field *field_rxchansel;
>>>
>>> const struct sun4i_i2s_quirks   *variant;
>>> +
>>> +   unsigned inttdm_slots;
>>> +   unsigned intslot_width;
>>>  };
>>>
>>>  struct sun4i_i2s_clk_div {
>>> @@ -344,7 +348,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai 
>>> *dai,
>>> if (i2s->variant->has_fmt_set_lrck_period)
>>> regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
>>>SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
>>> -  SUN8I_I2S_FMT0_LRCK_PERIOD(32));
>>> +  SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
>>>
>>> return 0;
>>>  }
>>> @@ -418,7 +422,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
>>> *substream,
>>>sr + i2s->variant->fmt_offset);
>>>
>>> return sun4i_i2s_set_clk_rate(dai, params_rate(params),
>>> - params_width(params));
>>> + i2s->tdm_slots ?
>>> + i2s->slot_width : 
>>> params_width(params));
>>>  }
>>>
>>>  static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>>> @@ -691,6 +696,19 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai 
>>> *dai, int clk_id,
>>> return 0;
>>>  }
>>>
>>> +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
>>> +   unsigned int tx_mask, unsigned int rx_mask,
>>> +   int slots, int width)
>>> +{
>>> +   struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>>> +
>>> +   i2s->tdm_slots = slots;
>>> +
>>> +   i2s->slot_width = width;
>>> +
>>> +   return 0;
>>> +}
>>> +
>>
>> IIRC some of the DAI controllers actually support TDM. Would this
>> change conflict with that in the future?
>
> Hi Wens,
> I'm not sure..I was looking for a clean example of being able to
> override the number of bclks in the lrclk width and some other
> devices(Rpi) were doing it this way.  I open to suggestions,

I'm not familiar with the issue either. If Mark doesn't have any
objections, we could merge it for now, and fix it later if there
are any complications.

BTW, you didn't provide a device tree example (if any) for how
to use this.

ChenYu

> BR,
> CK
>>
>> Thanks
>> ChenYu
>>
>>>  static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
>>> .hw_params  = sun4i_i2s_hw_params,
>>> .set_fmt= sun4i_i2s_set_fmt,
>>> @@ -698,6 +716,7 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = 
>>> {
>>> .shutdown   = sun4i_i2s_shutdown,
>>> .startup= sun4i_i2s_startup,
>>> .trigger= sun4i_i2s_trigger,
>>> +   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
>>>  };
>>>
>>>  static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
>>> --
>>> 2.16.0
>>>
>>> --
>>> You received this message because you are subscribed to the Google Groups 
>>> "linux-sunxi" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to linux-sunxi+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [linux-sunxi] [PATCH 1/3] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2018-01-28 Thread Code Kipper
On 29 January 2018 at 02:50, Chen-Yu Tsai  wrote:
> On Wed, Jan 24, 2018 at 10:10 PM,   wrote:
>> From: Marcus Cooper 
>>
>> Some codecs require a different amount of a bit clocks per frame than
>> what is calculated by the sample width. Use the tdm slot bindings to
>> provide this mechanism.
>>
>> Signed-off-by: Marcus Cooper 
>> ---
>>  sound/soc/sunxi/sun4i-i2s.c | 23 +--
>>  1 file changed, 21 insertions(+), 2 deletions(-)
>>
>> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
>> index dca1143c1150..d7a9141514cf 100644
>> --- a/sound/soc/sunxi/sun4i-i2s.c
>> +++ b/sound/soc/sunxi/sun4i-i2s.c
>> @@ -96,6 +96,7 @@
>>  #define SUN8I_I2S_CTRL_BCLK_OUTBIT(18)
>>  #define SUN8I_I2S_CTRL_LRCK_OUTBIT(17)
>>
>> +#define SUN8I_I2S_FMT0_LRCK_MAX_PERIOD (GENMASK(17, 8) >> 8)
>>  #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASKGENMASK(17, 8)
>>  #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
>>
>> @@ -193,6 +194,9 @@ struct sun4i_i2s {
>> struct regmap_field *field_rxchansel;
>>
>> const struct sun4i_i2s_quirks   *variant;
>> +
>> +   unsigned inttdm_slots;
>> +   unsigned intslot_width;
>>  };
>>
>>  struct sun4i_i2s_clk_div {
>> @@ -344,7 +348,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai 
>> *dai,
>> if (i2s->variant->has_fmt_set_lrck_period)
>> regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
>>SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
>> -  SUN8I_I2S_FMT0_LRCK_PERIOD(32));
>> +  SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
>>
>> return 0;
>>  }
>> @@ -418,7 +422,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
>> *substream,
>>sr + i2s->variant->fmt_offset);
>>
>> return sun4i_i2s_set_clk_rate(dai, params_rate(params),
>> - params_width(params));
>> + i2s->tdm_slots ?
>> + i2s->slot_width : 
>> params_width(params));
>>  }
>>
>>  static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
>> @@ -691,6 +696,19 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai 
>> *dai, int clk_id,
>> return 0;
>>  }
>>
>> +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
>> +   unsigned int tx_mask, unsigned int rx_mask,
>> +   int slots, int width)
>> +{
>> +   struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
>> +
>> +   i2s->tdm_slots = slots;
>> +
>> +   i2s->slot_width = width;
>> +
>> +   return 0;
>> +}
>> +
>
> IIRC some of the DAI controllers actually support TDM. Would this
> change conflict with that in the future?

Hi Wens,
I'm not sure..I was looking for a clean example of being able to
override the number of bclks in the lrclk width and some other
devices(Rpi) were doing it this way.  I open to suggestions,
BR,
CK
>
> Thanks
> ChenYu
>
>>  static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
>> .hw_params  = sun4i_i2s_hw_params,
>> .set_fmt= sun4i_i2s_set_fmt,
>> @@ -698,6 +716,7 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
>> .shutdown   = sun4i_i2s_shutdown,
>> .startup= sun4i_i2s_startup,
>> .trigger= sun4i_i2s_trigger,
>> +   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
>>  };
>>
>>  static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
>> --
>> 2.16.0
>>
>> --
>> You received this message because you are subscribed to the Google Groups 
>> "linux-sunxi" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to linux-sunxi+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [linux-sunxi] [PATCH 1/3] ASoC: sun4i-i2s: Add set_tdm_slot functionality

2018-01-28 Thread Chen-Yu Tsai
On Wed, Jan 24, 2018 at 10:10 PM,   wrote:
> From: Marcus Cooper 
>
> Some codecs require a different amount of a bit clocks per frame than
> what is calculated by the sample width. Use the tdm slot bindings to
> provide this mechanism.
>
> Signed-off-by: Marcus Cooper 
> ---
>  sound/soc/sunxi/sun4i-i2s.c | 23 +--
>  1 file changed, 21 insertions(+), 2 deletions(-)
>
> diff --git a/sound/soc/sunxi/sun4i-i2s.c b/sound/soc/sunxi/sun4i-i2s.c
> index dca1143c1150..d7a9141514cf 100644
> --- a/sound/soc/sunxi/sun4i-i2s.c
> +++ b/sound/soc/sunxi/sun4i-i2s.c
> @@ -96,6 +96,7 @@
>  #define SUN8I_I2S_CTRL_BCLK_OUTBIT(18)
>  #define SUN8I_I2S_CTRL_LRCK_OUTBIT(17)
>
> +#define SUN8I_I2S_FMT0_LRCK_MAX_PERIOD (GENMASK(17, 8) >> 8)
>  #define SUN8I_I2S_FMT0_LRCK_PERIOD_MASKGENMASK(17, 8)
>  #define SUN8I_I2S_FMT0_LRCK_PERIOD(period) ((period - 1) << 8)
>
> @@ -193,6 +194,9 @@ struct sun4i_i2s {
> struct regmap_field *field_rxchansel;
>
> const struct sun4i_i2s_quirks   *variant;
> +
> +   unsigned inttdm_slots;
> +   unsigned intslot_width;
>  };
>
>  struct sun4i_i2s_clk_div {
> @@ -344,7 +348,7 @@ static int sun4i_i2s_set_clk_rate(struct snd_soc_dai *dai,
> if (i2s->variant->has_fmt_set_lrck_period)
> regmap_update_bits(i2s->regmap, SUN4I_I2S_FMT0_REG,
>SUN8I_I2S_FMT0_LRCK_PERIOD_MASK,
> -  SUN8I_I2S_FMT0_LRCK_PERIOD(32));
> +  SUN8I_I2S_FMT0_LRCK_PERIOD(word_size));
>
> return 0;
>  }
> @@ -418,7 +422,8 @@ static int sun4i_i2s_hw_params(struct snd_pcm_substream 
> *substream,
>sr + i2s->variant->fmt_offset);
>
> return sun4i_i2s_set_clk_rate(dai, params_rate(params),
> - params_width(params));
> + i2s->tdm_slots ?
> + i2s->slot_width : params_width(params));
>  }
>
>  static int sun4i_i2s_set_fmt(struct snd_soc_dai *dai, unsigned int fmt)
> @@ -691,6 +696,19 @@ static int sun4i_i2s_set_sysclk(struct snd_soc_dai *dai, 
> int clk_id,
> return 0;
>  }
>
> +static int sun4i_i2s_set_dai_tdm_slot(struct snd_soc_dai *dai,
> +   unsigned int tx_mask, unsigned int rx_mask,
> +   int slots, int width)
> +{
> +   struct sun4i_i2s *i2s = snd_soc_dai_get_drvdata(dai);
> +
> +   i2s->tdm_slots = slots;
> +
> +   i2s->slot_width = width;
> +
> +   return 0;
> +}
> +

IIRC some of the DAI controllers actually support TDM. Would this
change conflict with that in the future?

Thanks
ChenYu

>  static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
> .hw_params  = sun4i_i2s_hw_params,
> .set_fmt= sun4i_i2s_set_fmt,
> @@ -698,6 +716,7 @@ static const struct snd_soc_dai_ops sun4i_i2s_dai_ops = {
> .shutdown   = sun4i_i2s_shutdown,
> .startup= sun4i_i2s_startup,
> .trigger= sun4i_i2s_trigger,
> +   .set_tdm_slot   = sun4i_i2s_set_dai_tdm_slot,
>  };
>
>  static int sun4i_i2s_dai_probe(struct snd_soc_dai *dai)
> --
> 2.16.0
>
> --
> You received this message because you are subscribed to the Google Groups 
> "linux-sunxi" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to linux-sunxi+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 3/3] net: sun8i-emac: add support for new EMAC DT binding

2018-01-28 Thread Andre Przywara
The Ethernet MAC used in newer Allwinner SoCs (H3, A64, H5) got an
upstream Linux driver in v4.15.
This one uses a slightly different binding from the original one used
by the U-Boot driver.
The differences to the old binding are:
- The "syscon" address is held in a separate node, referenced via a
  phandle in the "syscon" property.
- The reference to the PHY is held in a property called "phy-handle",
  not "phy".
- The PHY register is at offset 0x30 in the syscon device, not at 0.
- The internal PHY is activated when the node, which phy-handle points
  to, is a child node of an "allwinner,sun8i-h3-mdio-internal" node.

Teach the U-Boot driver how to find its resources in a "new-style" DT,
so that we can use a Linux kernel compatible DT for U-Boot as well.
This keeps support for the old binding (for now?), to allow a smooth
transition.

Signed-off-by: Andre Przywara 
---
 drivers/net/sun8i_emac.c | 55 ++--
 1 file changed, 48 insertions(+), 7 deletions(-)

diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index df2b857310..4ba8959239 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -279,7 +279,7 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
int ret;
u32 reg;
 
-   reg = readl(priv->sysctl_reg);
+   reg = readl(priv->sysctl_reg + 0x30);
 
if (priv->variant == H3_EMAC) {
ret = sun8i_emac_set_syscon_ephy(priv, );
@@ -310,7 +310,7 @@ static int sun8i_emac_set_syscon(struct emac_eth_dev *priv)
return -EINVAL;
}
 
-   writel(reg, priv->sysctl_reg);
+   writel(reg, priv->sysctl_reg + 0x30);
 
return 0;
 }
@@ -806,17 +806,50 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct 
udevice *dev)
 #endif
 
pdata->iobase = devfdt_get_addr_name(dev, "emac");
+   if (pdata->iobase == FDT_ADDR_T_NONE)
+   pdata->iobase = devfdt_get_addr(dev);
+   if (pdata->iobase == FDT_ADDR_T_NONE) {
+   debug("%s: Cannot find MAC base address\n", __func__);
+   return -EINVAL;
+   }
+
priv->sysctl_reg = devfdt_get_addr_name(dev, "syscon");
+   if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
+   const fdt32_t *reg;
+
+   offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "syscon");
+   if (offset < 0) {
+   debug("%s: cannot find syscon node\n", __func__);
+   return -EINVAL;
+   }
+   reg = fdt_getprop(gd->fdt_blob, offset, "reg", NULL);
+   if (!reg) {
+   debug("%s: cannot find reg property in syscon node\n",
+ __func__);
+   return -EINVAL;
+   }
+   priv->sysctl_reg = fdt_translate_address((void *)gd->fdt_blob,
+offset, reg);
+   } else
+   priv->sysctl_reg -= 0x30;
+   if (priv->sysctl_reg == FDT_ADDR_T_NONE) {
+   debug("%s: Cannot find syscon base address\n", __func__);
+   return -EINVAL;
+   }
 
pdata->phy_interface = -1;
priv->phyaddr = -1;
priv->use_internal_phy = false;
 
-   offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
-  "phy");
-   if (offset > 0)
-   priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg",
-  -1);
+   offset = fdtdec_lookup_phandle(gd->fdt_blob, node, "phy");
+   if (offset < 0)
+   offset = fdtdec_lookup_phandle(gd->fdt_blob, node,
+  "phy-handle");
+   if (offset < 0) {
+   debug("%s: Cannot find PHY address\n", __func__);
+   return -EINVAL;
+   }
+   priv->phyaddr = fdtdec_get_int(gd->fdt_blob, offset, "reg", -1);
 
phy_mode = fdt_getprop(gd->fdt_blob, node, "phy-mode", NULL);
 
@@ -841,6 +874,14 @@ static int sun8i_emac_eth_ofdata_to_platdata(struct 
udevice *dev)
if (fdt_getprop(gd->fdt_blob, node,
"allwinner,use-internal-phy", NULL))
priv->use_internal_phy = true;
+   else {
+   int parent = fdt_parent_offset(gd->fdt_blob, offset);
+
+   if (parent >= 0 &&
+   !fdt_node_check_compatible(gd->fdt_blob, parent,
+   "allwinner,sun8i-h3-mdio-internal"))
+   priv->use_internal_phy = true;
+   }
}
 
priv->interface = pdata->phy_interface;
-- 
2.14.1

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to 

[linux-sunxi] [PATCH 2/3] net: sun8i-emac: support new pinctrl DT bindings

2018-01-28 Thread Andre Przywara
The Linux kernel driver for the Allwinner pin controller gained support
for generic properties, which are now also used in the DTs.
The sun8i-emac Ethernet driver for new Allwinner MACs reads the pins from
the DT, but so far only supported the old binding.
Update the parsing routine to cope with both the old and new bindings,
so that the newer DTs can be used with U-Boot and its Ethernet driver.

Signed-off-by: Andre Przywara 
---
 drivers/net/sun8i_emac.c | 52 
 1 file changed, 39 insertions(+), 13 deletions(-)

diff --git a/drivers/net/sun8i_emac.c b/drivers/net/sun8i_emac.c
index 3ccc6b0bb6..df2b857310 100644
--- a/drivers/net/sun8i_emac.c
+++ b/drivers/net/sun8i_emac.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef CONFIG_DM_GPIO
 #include 
 #endif
@@ -465,30 +466,55 @@ static int parse_phy_pins(struct udevice *dev)
}
 
drive = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
-"allwinner,drive", 4);
-   pull = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
-   "allwinner,pull", 0);
+"drive-strength", ~0);
+   if (drive != ~0) {
+   if (drive <= 10)
+   drive = SUN4I_PINCTRL_10_MA;
+   else if (drive <= 20)
+   drive = SUN4I_PINCTRL_20_MA;
+   else if (drive <= 30)
+   drive = SUN4I_PINCTRL_30_MA;
+   else
+   drive = SUN4I_PINCTRL_40_MA;
+   } else {
+   drive = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
+"allwinner,drive", 4);
+   }
+
+   if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-up", NULL))
+   pull = SUN4I_PINCTRL_PULL_UP;
+   else if (fdt_get_property(gd->fdt_blob, offset, "bias-disable", NULL))
+   pull = SUN4I_PINCTRL_NO_PULL;
+   else if (fdt_get_property(gd->fdt_blob, offset, "bias-pull-down", NULL))
+   pull = SUN4I_PINCTRL_PULL_DOWN;
+   else
+   pull = fdt_getprop_u32_default_node(gd->fdt_blob, offset, 0,
+   "allwinner,pull", 0);
for (i = 0; ; i++) {
int pin;
 
pin_name = fdt_stringlist_get(gd->fdt_blob, offset,
  "allwinner,pins", i, NULL);
-   if (!pin_name)
-   break;
-   if (pin_name[0] != 'P')
-   continue;
-   pin = (pin_name[1] - 'A') << 5;
-   if (pin >= 26 << 5)
+   if (!pin_name) {
+   pin_name = fdt_stringlist_get(gd->fdt_blob, offset,
+ "pins", i, NULL);
+   if (!pin_name)
+   break;
+   }
+
+   pin = sunxi_name_to_gpio(pin_name);
+   if (pin < 0)
continue;
-   pin += simple_strtol(_name[2], NULL, 10);
 
sunxi_gpio_set_cfgpin(pin, SUN8I_GPD8_GMAC);
-   sunxi_gpio_set_drv(pin, drive);
-   sunxi_gpio_set_pull(pin, pull);
+   if (drive != ~0)
+   sunxi_gpio_set_drv(pin, drive);
+   if (pull != ~0)
+   sunxi_gpio_set_pull(pin, pull);
}
 
if (!i) {
-   printf("WARNING: emac: cannot find allwinner,pins property\n");
+   printf("WARNING: emac: cannot find pins property\n");
return -2;
}
 
-- 
2.14.1

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 0/3] sunxi: sun8i-emac: Update DT bindings

2018-01-28 Thread Andre Przywara
The existing sun8i-emac driver in U-Boot uses some preliminary bindings,
which matched our own DTs. Now that the Linux kernel got a driver, lets
update our probe code to handle those Linux DTs as well.
The first patch adds the missing compatible strings for the pinctrl drivers,
which is needed for using the sunxi_name_to_gpio() lookup function.
Patch 2/3 updates the pinctrl parser used in the sun8i-emac driver, to cope
with the new, generic Allwinner pinctrl bindings.
The final patch extends the probe routine in the Ethernet driver to deal
with both the old and the new bindings.
This series allows to copy in the DTs from the latest kernel. Unfortunately
right now updating the DTs for the H5 and A64 breaks the build, as the
resulting binary (which embeds the DT) gets to large and triggers our new
image size check. As the H5 and H3 share most of the DT, we can't just
update the H3 DTs either. Hopefully we find some neat trick to work
around that.

Cheers,
Andre.

Andre Przywara (3):
  sunxi: gpio: add missing compatible strings
  net: sun8i-emac: support new pinctrl DT bindings
  net: sun8i-emac: add support for new EMAC DT binding

 drivers/gpio/sunxi_gpio.c |   4 ++
 drivers/net/sun8i_emac.c  | 107 +-
 2 files changed, 91 insertions(+), 20 deletions(-)

-- 
2.14.1

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH 1/3] sunxi: gpio: add missing compatible strings

2018-01-28 Thread Andre Przywara
The sunxi GPIO driver is missing some compatible strings for recent
SoCs. While most of the sunxi GPIO code seems to not rely on this (and
so works anyway), the sunxi_name_to_gpio() function does and fails at
the moment (for instance when resolving the MMC CD pin name).
Add the compatible strings for the A64, H5 and V3s, which were missing
from the list. This now covers all pinctrl nodes in our own DTs.

Signed-off-by: Andre Przywara 
---
 drivers/gpio/sunxi_gpio.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 3cf01b6e36..90fd7c1596 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -354,12 +354,16 @@ static const struct udevice_id sunxi_gpio_ids[] = {
ID("allwinner,sun8i-a83t-pinctrl",  a_all),
ID("allwinner,sun8i-h3-pinctrl",a_all),
ID("allwinner,sun8i-r40-pinctrl",   a_all),
+   ID("allwinner,sun8i-v3s-pinctrl",   a_all),
ID("allwinner,sun9i-a80-pinctrl",   a_all),
+   ID("allwinner,sun50i-a64-pinctrl",  a_all),
+   ID("allwinner,sun50i-h5-pinctrl",   a_all),
ID("allwinner,sun6i-a31-r-pinctrl", l_2),
ID("allwinner,sun8i-a23-r-pinctrl", l_1),
ID("allwinner,sun8i-a83t-r-pinctrl",l_1),
ID("allwinner,sun8i-h3-r-pinctrl",  l_1),
ID("allwinner,sun9i-a80-r-pinctrl", l_3),
+   ID("allwinner,sun50i-a64-r-pinctrl",l_1),
{ }
 };
 
-- 
2.14.1

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 08/16] iio: adc: sun4i-gpadc-iio: rework: add interrupt support

2018-01-28 Thread Philipp Rossak
This patch rewors the driver to support interrupts for the thermal part
of the sensor.

This is only available for the newer sensor (currently H3 and A83T).
The interrupt will be trigerd on data available and triggers the update
for the thermal sensors. All newer sensors have different amount of
sensors and different interrupts for each device the reset of the
interrupts need to be done different

For the newer sensors is the autosuspend disabled.

Signed-off-by: Philipp Rossak 
Acked-by: Jonathan  Cameron 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 60 +++
 include/linux/mfd/sun4i-gpadc.h   |  2 ++
 2 files changed, 56 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 74eeb5cd5218..b7b5451226b0 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -71,11 +71,14 @@ struct gpadc_data {
unsigned inttemp_data[MAX_SENSOR_COUNT];
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
+   u32 irq_clear_map;
+   u32 irq_control_map;
boolhas_bus_clk;
boolhas_bus_rst;
boolhas_mod_clk;
int sensor_count;
boolsupports_nvmem;
+   boolsupport_irq;
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -90,6 +93,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
 };
 
 static const struct gpadc_data sun5i_gpadc_data = {
@@ -104,6 +108,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
 };
 
 static const struct gpadc_data sun6i_gpadc_data = {
@@ -118,6 +123,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
 };
 
 static const struct gpadc_data sun8i_a33_gpadc_data = {
@@ -129,6 +135,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
 };
 
 struct sun4i_gpadc_iio {
@@ -332,6 +339,11 @@ static int sun4i_gpadc_temp_read(struct iio_dev 
*indio_dev, int *val,
return 0;
}
 
+   if (info->data->support_irq) {
+   regmap_read(info->regmap, info->data->temp_data[sensor], val);
+   return 0;
+   }
+
return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
 }
 
@@ -429,6 +441,17 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int 
irq, void *dev_id)
return IRQ_HANDLED;
 }
 
+static irqreturn_t sunxi_irq_thread(int irq, void *data)
+{
+   struct sun4i_gpadc_iio *info = data;
+
+   regmap_write(info->regmap, SUN8I_H3_THS_STAT, 
info->data->irq_clear_map);
+
+   thermal_zone_device_update(info->tzd, THERMAL_EVENT_TEMP_SAMPLE);
+
+   return IRQ_HANDLED;
+}
+
 static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
 {
/* Disable the ADC on IP */
@@ -572,12 +595,29 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
struct nvmem_cell *cell;
ssize_t cell_size;
u64 *cell_data;
+   int irq;
 
info->data = of_device_get_match_data(>dev);
if (!info->data)
return -ENODEV;
 
-   info->no_irq = true;
+   if (info->data->support_irq) {
+   /* only the new versions of ths support right now irqs */
+   irq = platform_get_irq(pdev, 0);
+   if (irq < 0) {
+   dev_err(>dev, "failed to get IRQ: %d\n", irq);
+   return irq;
+   }
+
+   ret = devm_request_threaded_irq(>dev, irq, NULL,
+   sunxi_irq_thread, IRQF_ONESHOT,
+   dev_name(>dev), info);
+   if (ret)
+   return ret;
+
+   } else
+   info->no_irq = true;
+
indio_dev->num_channels = ARRAY_SIZE(sun8i_a33_gpadc_channels);
indio_dev->channels = sun8i_a33_gpadc_channels;
 
@@ -789,11 +829,13 @@ static int sun4i_gpadc_probe(struct platform_device *pdev)
if (ret)
return ret;
 
-   pm_runtime_set_autosuspend_delay(>dev,
-SUN4I_GPADC_AUTOSUSPEND_DELAY);
-   pm_runtime_use_autosuspend(>dev);
-   pm_runtime_set_suspended(>dev);
-   pm_runtime_enable(>dev);
+   if (!info->data->support_irq) {
+   

[linux-sunxi] [PATCH v2 13/16] arm: dts: sun8i: h3: add thermal zone to H3

2018-01-28 Thread Philipp Rossak
This patch adds the thermal zones to the H3. We have only one sensor and
that is placed in the cpu.

Signed-off-by: Philipp Rossak 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index fbb007e5798e..3f83f6a27c74 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -72,6 +72,15 @@
};
};
 
+   thermal-zones {
+   cpu-thermal {
+   /* milliseconds */
+   polling-delay-passive = <250>;
+   polling-delay = <1000>;
+   thermal-sensors = < 0>;
+   };
+   };
+
timer {
compatible = "arm,armv7-timer";
interrupts = ,
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 12/16] arm: dts: sun8i: h3: add support for the thermal sensor in H3

2018-01-28 Thread Philipp Rossak
This patch adds the missing compatible and the thermal sensor cells.
The H3 has one sensor.

Signed-off-by: Philipp Rossak 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 5 +
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 8495deecedad..fbb007e5798e 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -128,3 +128,8 @@
  {
compatible = "allwinner,sun8i-h3-pinctrl";
 };
+
+ {
+   compatible = "allwinner,sun8i-h3-ths";
+   #thermal-sensor-cells = <0>;
+};
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 06/16] iio: adc: sun4i-gpadc-iio: rework: support multiple sensors

2018-01-28 Thread Philipp Rossak
For adding newer sensor some basic rework of the code is necessary.

This patch reworks the driver to be able to handle more than one
thermal sensor. Newer SoC like the A80 have 4 thermal sensors.
Because of this the maximal sensor count value was set to 4.

The sensor_id value is set during sensor registration and is for each
registered sensor indiviual. This makes it able to differntiate the
sensors when the value is read from the register.

In function sun4i_gpadc_read_raw(), the sensor number of the ths sensor
was directly set to 0 (sun4i_gpadc_temp_read(x,x,0)). This selects
in the temp_read function automatically sensor 0. A check for the
sensor_id is here not required since the old sensors only have one
thermal sensor. In addition to that is the sun4i_gpadc_read_raw()
function only used by the "older" sensors (before A33) where the
thermal sensor was a cobination of an adc and a thermal sensor.

Signed-off-by: Philipp Rossak 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 36 +++-
 include/linux/mfd/sun4i-gpadc.h   |  3 +++
 2 files changed, 26 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 51ec0104d678..ac9ad2f8232f 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -67,12 +67,13 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
-   unsigned inttemp_data;
+   unsigned inttemp_data[MAX_SENSOR_COUNT];
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
boolhas_bus_clk;
boolhas_bus_rst;
boolhas_mod_clk;
+   int sensor_count;
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -82,9 +83,10 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
 };
 
 static const struct gpadc_data sun5i_gpadc_data = {
@@ -94,9 +96,10 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
 };
 
 static const struct gpadc_data sun6i_gpadc_data = {
@@ -106,18 +109,20 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
 };
 
 static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
 };
 
 struct sun4i_gpadc_iio {
@@ -135,6 +140,7 @@ struct sun4i_gpadc_iio {
struct clk  *bus_clk;
struct clk  *mod_clk;
struct reset_control*reset;
+   int sensor_id;
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -302,14 +308,15 @@ static int sun4i_gpadc_adc_read(struct iio_dev 
*indio_dev, int channel,
return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
 }
 
-static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
+static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val,
+   int sensor)
 {
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
 
if (info->no_irq) {
pm_runtime_get_sync(indio_dev->dev.parent);
 
-   regmap_read(info->regmap, info->data->temp_data, val);
+   regmap_read(info->regmap, info->data->temp_data[sensor], val);
 

[linux-sunxi] [PATCH v2 14/16] arm: dts: sun8i: h3: enable H3 sid controller

2018-01-28 Thread Philipp Rossak
This patch enables the the sid controller in the H3. It can be used
for thermal calibration data.

Signed-off-by: Philipp Rossak 
---
 arch/arm/boot/dts/sun8i-h3.dtsi | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-h3.dtsi b/arch/arm/boot/dts/sun8i-h3.dtsi
index 3f83f6a27c74..9bb5cc29fec5 100644
--- a/arch/arm/boot/dts/sun8i-h3.dtsi
+++ b/arch/arm/boot/dts/sun8i-h3.dtsi
@@ -72,6 +72,13 @@
};
};
 
+   soc {
+   sid: eeprom@1c14000 {
+   compatible = "allwinner,sun8i-h3-sid";
+   reg = <0x01c14000 0x400>;
+   };
+   };
+
thermal-zones {
cpu-thermal {
/* milliseconds */
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 16/16] arm: dts: sun8i: a83t: add thermal zone to A83T

2018-01-28 Thread Philipp Rossak
This patch adds the thermal zones to the A83T. Sensor 0 is located besides the
cpu cluster 0. Sensor 1 is located besides cluster 1 and sensor 2 is located
besides in the gpu.

Signed-off-by: Philipp Rossak 
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 20 
 1 file changed, 20 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 9e53ff5ac4ed..4259a8726031 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -747,4 +747,24 @@
#size-cells = <0>;
};
};
+
+   thermal-zones {
+   cpu0_thermal: cpu0-thermal {
+   polling-delay-passive = <1000>;
+   polling-delay = <5000>;
+   thermal-sensors = < 0>;
+   };
+
+   cpu1_thermal: cpu1-thermal {
+   polling-delay-passive = <1000>;
+   polling-delay = <5000>;
+   thermal-sensors = < 1>;
+   };
+
+   gpu_thermal: gpu-thermal {
+   polling-delay-passive = <1000>;
+   polling-delay = <5000>;
+   thermal-sensors = < 2>;
+   };
+   };
 };
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 15/16] arm: dts: sun8i: a83t: add support for the thermal sensor in A83T

2018-01-28 Thread Philipp Rossak
As we have gained the support for the thermal sensor in A83T,
we can now add its device nodes to the device tree.

The A83T seems to have a broken IRQ 31, thus we use here IRQ 41.

Signed-off-by: Philipp Rossak 
---
 arch/arm/boot/dts/sun8i-a83t.dtsi | 8 
 1 file changed, 8 insertions(+)

diff --git a/arch/arm/boot/dts/sun8i-a83t.dtsi 
b/arch/arm/boot/dts/sun8i-a83t.dtsi
index 7f4955a5fab7..9e53ff5ac4ed 100644
--- a/arch/arm/boot/dts/sun8i-a83t.dtsi
+++ b/arch/arm/boot/dts/sun8i-a83t.dtsi
@@ -518,6 +518,14 @@
clocks = <>;
};
 
+   ths: thermal-sensor@1f04000 {
+   compatible = "allwinner,sun8i-a83t-ths";
+   reg = <0x01f04000 0x100>;
+   interrupts = ;
+   #thermal-sensor-cells = <1>;
+   #io-channel-cells = <0>;
+   };
+
watchdog@1c20ca0 {
compatible = "allwinner,sun6i-a31-wdt";
reg = <0x01c20ca0 0x20>;
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 11/16] arm: dts: sunxi-h3-h5: add support for the thermal sensor in H3 and H5

2018-01-28 Thread Philipp Rossak
As we have gained the support for the thermal sensor in H3 and H5,
we can now add its device nodes to the device tree. The H3 and H5 share
most of its compatible. The compatible and the thermal sensor cells
will be added in an additional patch per device.

Signed-off-by: Philipp Rossak 
---
 arch/arm/boot/dts/sunxi-h3-h5.dtsi | 9 +
 1 file changed, 9 insertions(+)

diff --git a/arch/arm/boot/dts/sunxi-h3-h5.dtsi 
b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
index 7a83b15225c7..413c789b588d 100644
--- a/arch/arm/boot/dts/sunxi-h3-h5.dtsi
+++ b/arch/arm/boot/dts/sunxi-h3-h5.dtsi
@@ -426,6 +426,15 @@
};
};
 
+   ths: thermal-sensor@1c25000 {
+   reg = <0x01c25000 0x100>;
+   interrupts = ;
+   clocks = < CLK_BUS_THS>, < CLK_THS>;
+   clock-names = "bus", "mod";
+   resets = < RST_BUS_THS>;
+   #io-channel-cells = <0>;
+   };
+
timer@1c20c00 {
compatible = "allwinner,sun4i-a10-timer";
reg = <0x01c20c00 0xa0>;
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 07/16] iio: adc: sun4i-gpadc-iio: rework: support nvmem calibration data

2018-01-28 Thread Philipp Rossak
This patch reworks the driver to support nvmem calibration cells.
The driver checks if the nvmem calibration is supported and reads out
the nvmem.

Signed-off-by: Philipp Rossak 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 44 +++
 1 file changed, 44 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index ac9ad2f8232f..74eeb5cd5218 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -74,6 +75,7 @@ struct gpadc_data {
boolhas_bus_rst;
boolhas_mod_clk;
int sensor_count;
+   boolsupports_nvmem;
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -87,6 +89,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
 };
 
 static const struct gpadc_data sun5i_gpadc_data = {
@@ -100,6 +103,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
 };
 
 static const struct gpadc_data sun6i_gpadc_data = {
@@ -113,6 +117,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
 };
 
 static const struct gpadc_data sun8i_a33_gpadc_data = {
@@ -123,6 +128,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
 };
 
 struct sun4i_gpadc_iio {
@@ -141,6 +147,8 @@ struct sun4i_gpadc_iio {
struct clk  *mod_clk;
struct reset_control*reset;
int sensor_id;
+   u32 calibration_data[2];
+   boolhas_calibration_data[2];
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -561,6 +569,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
struct resource *mem;
void __iomem *base;
int ret;
+   struct nvmem_cell *cell;
+   ssize_t cell_size;
+   u64 *cell_data;
 
info->data = of_device_get_match_data(>dev);
if (!info->data)
@@ -575,6 +586,39 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
if (IS_ERR(base))
return PTR_ERR(base);
 
+   info->has_calibration_data[0] = false;
+   info->has_calibration_data[1] = false;
+
+   if (!info->data->supports_nvmem)
+   goto no_nvmem;
+
+   cell = nvmem_cell_get(>dev, "calibration");
+   if (IS_ERR(cell)) {
+   if (PTR_ERR(cell) == -EPROBE_DEFER)
+   return PTR_ERR(cell);
+   goto no_nvmem;
+   }
+
+   cell_data = (u64 *)nvmem_cell_read(cell, _size);
+   nvmem_cell_put(cell);
+   switch (cell_size) {
+   case 8:
+   case 6:
+   info->has_calibration_data[1] = true;
+   info->calibration_data[1] = be32_to_cpu(
+   upper_32_bits(cell_data[0]));
+   case 4:
+   case 2:
+   info->has_calibration_data[0] = true;
+   info->calibration_data[0] = be32_to_cpu(
+   lower_32_bits(cell_data[0]));
+   break;
+   default:
+   break;
+   }
+
+no_nvmem:
+
info->regmap = devm_regmap_init_mmio(>dev, base,
 _gpadc_regmap_config);
if (IS_ERR(info->regmap)) {
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 09/16] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor

2018-01-28 Thread Philipp Rossak
This patch adds support for the H3 ths sensor.

The H3 supports interrupts. The interrupt is configured to update the
the sensor values every second. The calibration data is writen at the
begin of the init process.

Signed-off-by: Philipp Rossak 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 86 +++
 include/linux/mfd/sun4i-gpadc.h   | 22 ++
 2 files changed, 108 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index b7b5451226b0..8196203d65fe 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -61,6 +61,9 @@ struct sun4i_gpadc_iio;
 static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info);
 static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info);
 
+static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info);
+static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info);
+
 struct gpadc_data {
int temp_offset;
int temp_scale;
@@ -71,6 +74,10 @@ struct gpadc_data {
unsigned inttemp_data[MAX_SENSOR_COUNT];
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
+   u32 ctrl0_map;
+   u32 ctrl2_map;
+   u32 sensor_en_map;
+   u32 filter_map;
u32 irq_clear_map;
u32 irq_control_map;
boolhas_bus_clk;
@@ -138,6 +145,31 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.support_irq = false,
 };
 
+static const struct gpadc_data sun8i_h3_ths_data = {
+   .temp_offset = -1791,
+   .temp_scale = -121,
+   .temp_data = {SUN8I_H3_THS_TDATA0, 0, 0, 0},
+   .sample_start = sunxi_ths_sample_start,
+   .sample_end = sunxi_ths_sample_end,
+   .has_bus_clk = true,
+   .has_bus_rst = true,
+   .has_mod_clk = true,
+   .sensor_count = 1,
+   .supports_nvmem = true,
+   .support_irq = true,
+   .ctrl0_map = SUN4I_GPADC_CTRL0_T_ACQ(0xff),
+   .ctrl2_map = SUN8I_H3_THS_ACQ1(0x3f),
+   .sensor_en_map = SUN8I_H3_THS_TEMP_SENSE_EN0,
+   .filter_map = SUN4I_GPADC_CTRL3_FILTER_EN |
+   SUN4I_GPADC_CTRL3_FILTER_TYPE(0x2),
+   .irq_clear_map = SUN8I_H3_THS_INTS_ALARM_INT_0 |
+   SUN8I_H3_THS_INTS_SHUT_INT_0   |
+   SUN8I_H3_THS_INTS_TDATA_IRQ_0  |
+   SUN8I_H3_THS_INTS_ALARM_OFF_0,
+   .irq_control_map = SUN8I_H3_THS_INTC_TDATA_IRQ_EN0 |
+   SUN8I_H3_THS_TEMP_PERIOD(0x7),
+};
+
 struct sun4i_gpadc_iio {
struct iio_dev  *indio_dev;
struct completion   completion;
@@ -462,6 +494,16 @@ static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio 
*info)
return 0;
 }
 
+static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info)
+{
+   /* Disable ths interrupt */
+   regmap_write(info->regmap, SUN8I_H3_THS_INTC, 0x0);
+   /* Disable temperature sensor */
+   regmap_write(info->regmap, SUN8I_H3_THS_CTRL2, 0x0);
+
+   return 0;
+}
+
 static int sun4i_gpadc_runtime_suspend(struct device *dev)
 {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
@@ -473,6 +515,17 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
return info->data->sample_end(info);
 }
 
+static void sunxi_calibrate(struct sun4i_gpadc_iio *info)
+{
+   if (info->has_calibration_data[0])
+   regmap_write(info->regmap, SUNXI_THS_CDATA_0_1,
+   info->calibration_data[0]);
+
+   if (info->has_calibration_data[1])
+   regmap_write(info->regmap, SUNXI_THS_CDATA_2_3,
+   info->calibration_data[1]);
+}
+
 static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
 {
/* clkin = 6MHz */
@@ -492,6 +545,35 @@ static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio 
*info)
return 0;
 }
 
+static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
+{
+   u32 value;
+   sunxi_calibrate(info);
+
+   if (info->data->ctrl0_map)
+   regmap_write(info->regmap, SUN8I_H3_THS_CTRL0,
+   info->data->ctrl0_map);
+
+   regmap_write(info->regmap, SUN8I_H3_THS_CTRL2,
+   info->data->ctrl2_map);
+
+   regmap_write(info->regmap, SUN8I_H3_THS_STAT,
+   info->data->irq_clear_map);
+
+   regmap_write(info->regmap, SUN8I_H3_THS_FILTER,
+   info->data->filter_map);
+
+   regmap_write(info->regmap, SUN8I_H3_THS_INTC,
+   info->data->irq_control_map);
+
+   regmap_read(info->regmap, SUN8I_H3_THS_CTRL2, );
+
+   regmap_write(info->regmap, SUN8I_H3_THS_CTRL2,
+   info->data->sensor_en_map | value);
+
+   return 0;
+}
+
 static int sun4i_gpadc_runtime_resume(struct device *dev)
 {

[linux-sunxi] [PATCH v2 04/16] iio: adc: sun4i-gpadc-iio: rework: sampling start/end code readout reg

2018-01-28 Thread Philipp Rossak
For adding newer sensor some basic rework of the code is necessary.

This commit reworks the code and allows the sampling start/end code and
the position of value readout register to be altered. Later the start/end
functions will be used to configure the ths and start/stop the
sampling.

Signed-off-by: Icenowy Zheng 
Signed-off-by: Philipp Rossak 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 44 ++-
 1 file changed, 39 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 03804ff9c006..db57d9fffe48 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -49,6 +49,15 @@ static unsigned int sun6i_gpadc_chan_select(unsigned int 
chan)
return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
 }
 
+struct sun4i_gpadc_iio;
+
+/*
+ * Prototypes for these functions, which enable these functions to be
+ * referenced in gpadc_data structures.
+ */
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info);
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info);
+
 struct gpadc_data {
int temp_offset;
int temp_scale;
@@ -56,6 +65,9 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
+   unsigned inttemp_data;
+   int (*sample_start)(struct sun4i_gpadc_iio *info);
+   int (*sample_end)(struct sun4i_gpadc_iio *info);
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -65,6 +77,9 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
 };
 
 static const struct gpadc_data sun5i_gpadc_data = {
@@ -74,6 +89,9 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
 };
 
 static const struct gpadc_data sun6i_gpadc_data = {
@@ -83,12 +101,18 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
 };
 
 static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
 };
 
 struct sun4i_gpadc_iio {
@@ -277,7 +301,7 @@ static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, 
int *val)
if (info->no_irq) {
pm_runtime_get_sync(indio_dev->dev.parent);
 
-   regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val);
+   regmap_read(info->regmap, info->data->temp_data, val);
 
pm_runtime_mark_last_busy(indio_dev->dev.parent);
pm_runtime_put_autosuspend(indio_dev->dev.parent);
@@ -382,10 +406,8 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int 
irq, void *dev_id)
return IRQ_HANDLED;
 }
 
-static int sun4i_gpadc_runtime_suspend(struct device *dev)
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
 {
-   struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
-
/* Disable the ADC on IP */
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
/* Disable temperature sensor on IP */
@@ -394,10 +416,15 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
return 0;
 }
 
-static int sun4i_gpadc_runtime_resume(struct device *dev)
+static int sun4i_gpadc_runtime_suspend(struct device *dev)
 {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
 
+   return info->data->sample_end(info);
+}
+
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
+{
/* clkin = 6MHz */
regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
 SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
@@ -415,6 +442,13 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
return 0;
 }
 
+static int sun4i_gpadc_runtime_resume(struct device *dev)
+{
+   struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
+
+   return 

[linux-sunxi] [PATCH v2 10/16] iio: adc: sun4i-gpadc-iio: add support for A83T thermal sensor

2018-01-28 Thread Philipp Rossak
This patch adds support for the A83T ths sensor.

The A83T supports interrupts. The interrupt is configured to update the
the sensor values every second.

Signed-off-by: Philipp Rossak 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 38 ++
 include/linux/mfd/sun4i-gpadc.h   | 18 ++
 2 files changed, 56 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 8196203d65fe..9f7895ba1966 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -170,6 +170,40 @@ static const struct gpadc_data sun8i_h3_ths_data = {
SUN8I_H3_THS_TEMP_PERIOD(0x7),
 };
 
+static const struct gpadc_data sun8i_a83t_ths_data = {
+   .temp_offset = -2724,
+   .temp_scale = -70,
+   .temp_data = {SUN8I_H3_THS_TDATA0,
+   SUN8I_A83T_THS_TDATA1,
+   SUN8I_A83T_THS_TDATA2,
+   0},
+   .sample_start = sunxi_ths_sample_start,
+   .sample_end = sunxi_ths_sample_end,
+   .sensor_count = 3,
+   .supports_nvmem = false,
+   .support_irq = true,
+   .ctrl0_map = SUN4I_GPADC_CTRL0_T_ACQ(0x1f3),
+   .ctrl2_map = SUN8I_H3_THS_ACQ1(0x1f3),
+   .sensor_en_map = SUN8I_H3_THS_TEMP_SENSE_EN0 |
+   SUN8I_A83T_THS_TEMP_SENSE_EN1 |
+   SUN8I_A83T_THS_TEMP_SENSE_EN2,
+   .filter_map = SUN4I_GPADC_CTRL3_FILTER_EN |
+   SUN4I_GPADC_CTRL3_FILTER_TYPE(0x2),
+   .irq_clear_map = SUN8I_H3_THS_INTS_ALARM_INT_0 |
+   SUN8I_A83T_THS_INTS_ALARM_INT_1 |
+   SUN8I_A83T_THS_INTS_ALARM_INT_2 |
+   SUN8I_H3_THS_INTS_SHUT_INT_0  |
+   SUN8I_A83T_THS_INTS_SHUT_INT_1  |
+   SUN8I_A83T_THS_INTS_SHUT_INT_2  |
+   SUN8I_H3_THS_INTS_TDATA_IRQ_0 |
+   SUN8I_A83T_THS_INTS_TDATA_IRQ_1 |
+   SUN8I_A83T_THS_INTS_TDATA_IRQ_2,
+   .irq_control_map = SUN8I_H3_THS_INTC_TDATA_IRQ_EN0 |
+   SUN8I_A83T_THS_INTC_TDATA_IRQ_EN1 |
+   SUN8I_A83T_THS_INTC_TDATA_IRQ_EN2 |
+   SUN8I_H3_THS_TEMP_PERIOD(0x257),
+};
+
 struct sun4i_gpadc_iio {
struct iio_dev  *indio_dev;
struct completion   completion;
@@ -668,6 +702,10 @@ static const struct of_device_id sun4i_gpadc_of_id[] = {
.compatible = "allwinner,sun8i-h3-ths",
.data = _h3_ths_data,
},
+   {
+   .compatible = "allwinner,sun8i-a83t-ths",
+   .data = _a83t_ths_data,
+   },
{ /* sentinel */ }
 };
 
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 80b79c31cea3..32f15cc03363 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -99,21 +99,39 @@
 #define SUNXI_THS_CDATA_0_10x74
 #define SUNXI_THS_CDATA_2_30x78
 #define SUN8I_H3_THS_TDATA00x80
+#define SUN8I_A83T_THS_TDATA1  0x84
+#define SUN8I_A83T_THS_TDATA2  0x88
 
 #define SUN8I_H3_THS_ACQ1(x)   (GENMASK(31, 16) & ((x) 
<< 16))
 
 #define SUN8I_H3_THS_TEMP_SENSE_EN0BIT(0)
+#define SUN8I_A83T_THS_TEMP_SENSE_EN1  BIT(1)
+#define SUN8I_A83T_THS_TEMP_SENSE_EN2  BIT(2)
 
 #define SUN8I_H3_THS_TEMP_PERIOD(x)(GENMASK(31, 12) & ((x) 
<< 12))
 
 #define SUN8I_H3_THS_INTS_ALARM_INT_0  BIT(0)
+#define SUN8I_A83T_THS_INTS_ALARM_INT_1BIT(1)
+#define SUN8I_A83T_THS_INTS_ALARM_INT_2BIT(2)
 #define SUN8I_H3_THS_INTS_SHUT_INT_0   BIT(4)
+#define SUN8I_A83T_THS_INTS_SHUT_INT_1 BIT(5)
+#define SUN8I_A83T_THS_INTS_SHUT_INT_2 BIT(6)
 #define SUN8I_H3_THS_INTS_TDATA_IRQ_0  BIT(8)
+#define SUN8I_A83T_THS_INTS_TDATA_IRQ_1BIT(9)
+#define SUN8I_A83T_THS_INTS_TDATA_IRQ_2BIT(10)
 #define SUN8I_H3_THS_INTS_ALARM_OFF_0  BIT(12)
+#define SUN8I_A83T_THS_INTS_ALARM_OFF_1BIT(13)
+#define SUN8I_A83T_THS_INTS_ALARM_OFF_2BIT(14)
 
 #define SUN8I_H3_THS_INTC_ALARM_INT_EN0BIT(0)
+#define SUN8I_A83T_THS_INTC_ALARM_INT_EN1  BIT(1)
+#define SUN8I_A83T_THS_INTC_ALARM_INT_EN2  BIT(2)
 #define SUN8I_H3_THS_INTC_SHUT_INT_EN0 BIT(4)
+#define SUN8I_A83T_THS_INTC_SHUT_INT_EN1   BIT(5)
+#define SUN8I_A83T_THS_INTC_SHUT_INT_EN2   BIT(6)
 #define SUN8I_H3_THS_INTC_TDATA_IRQ_EN0BIT(8)
+#define SUN8I_A83T_THS_INTC_TDATA_IRQ_EN1  BIT(9)
+#define SUN8I_A83T_THS_INTC_TDATA_IRQ_EN2  BIT(10)
 
 #define MAX_SENSOR_COUNT   4
 
-- 

[linux-sunxi] [PATCH v2 05/16] iio: adc: sun4i-gpadc-iio: rework: support clocks and reset

2018-01-28 Thread Philipp Rossak
For adding newer sensor some basic rework of the code is necessary.

The SoCs after H3 has newer thermal sensor ADCs, which have two clock
inputs (bus clock and sampling clock) and a reset. The registers are
also re-arranged.

This commit reworks the code, adds the process of the clocks and
resets.

Signed-off-by: Philipp Rossak 
Signed-off-by: Icenowy Zheng 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 71 +++
 1 file changed, 71 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index db57d9fffe48..51ec0104d678 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -22,6 +22,7 @@
  * shutdown for not being used.
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -31,6 +32,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 
@@ -68,6 +70,9 @@ struct gpadc_data {
unsigned inttemp_data;
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
+   boolhas_bus_clk;
+   boolhas_bus_rst;
+   boolhas_mod_clk;
 };
 
 static const struct gpadc_data sun4i_gpadc_data = {
@@ -127,6 +132,9 @@ struct sun4i_gpadc_iio {
atomic_tignore_temp_data_irq;
const struct gpadc_data *data;
boolno_irq;
+   struct clk  *bus_clk;
+   struct clk  *mod_clk;
+   struct reset_control*reset;
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -420,6 +428,10 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
 {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
 
+   clk_disable(info->mod_clk);
+
+   clk_disable(info->bus_clk);
+
return info->data->sample_end(info);
 }
 
@@ -446,6 +458,10 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)
 {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
 
+   clk_enable(info->mod_clk);
+
+   clk_enable(info->bus_clk);
+
return info->data->sample_start(info);
 }
 
@@ -560,10 +576,59 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
return ret;
}
 
+   if (info->data->has_bus_rst) {
+   info->reset = devm_reset_control_get(>dev, NULL);
+   if (IS_ERR(info->reset)) {
+   ret = PTR_ERR(info->reset);
+   return ret;
+   }
+
+   ret = reset_control_deassert(info->reset);
+   if (ret)
+   return ret;
+   }
+
+   if (info->data->has_bus_clk) {
+   info->bus_clk = devm_clk_get(>dev, "bus");
+   if (IS_ERR(info->bus_clk)) {
+   ret = PTR_ERR(info->bus_clk);
+   goto assert_reset;
+   }
+
+   ret = clk_prepare_enable(info->bus_clk);
+   if (ret)
+   goto assert_reset;
+   }
+
+   if (info->data->has_mod_clk) {
+   info->mod_clk = devm_clk_get(>dev, "mod");
+   if (IS_ERR(info->mod_clk)) {
+   ret = PTR_ERR(info->mod_clk);
+   goto disable_bus_clk;
+   }
+
+   /* Running at 6MHz */
+   ret = clk_set_rate(info->mod_clk, 400);
+   if (ret)
+   goto disable_bus_clk;
+
+   ret = clk_prepare_enable(info->mod_clk);
+   if (ret)
+   goto disable_bus_clk;
+   }
+
if (IS_ENABLED(CONFIG_THERMAL_OF))
info->sensor_device = >dev;
 
return 0;
+
+disable_bus_clk:
+   clk_disable_unprepare(info->bus_clk);
+
+assert_reset:
+   reset_control_assert(info->reset);
+
+   return ret;
 }
 
 static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,
@@ -729,6 +794,12 @@ static int sun4i_gpadc_remove(struct platform_device *pdev)
if (!info->no_irq)
iio_map_array_unregister(indio_dev);
 
+   clk_disable_unprepare(info->mod_clk);
+
+   clk_disable_unprepare(info->bus_clk);
+
+   reset_control_assert(info->reset);
+
return 0;
 }
 
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 02/16] arm: config: sunxi_defconfig: enable SUN4I_GPADC

2018-01-28 Thread Philipp Rossak
This commit enables the SUN4I_GPADC config option and
sets the value to yes. This is needed to enable the ths sensors.

Signed-off-by: Philipp Rossak 
---
 arch/arm/configs/sunxi_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm/configs/sunxi_defconfig b/arch/arm/configs/sunxi_defconfig
index 5caaf971fb50..52c3990b9d91 100644
--- a/arch/arm/configs/sunxi_defconfig
+++ b/arch/arm/configs/sunxi_defconfig
@@ -131,6 +131,7 @@ CONFIG_DMA_SUN6I=y
 CONFIG_EXTCON=y
 CONFIG_IIO=y
 CONFIG_AXP20X_ADC=y
+CONFIG_SUN4I_GPADC=y
 CONFIG_PWM=y
 CONFIG_PWM_SUN4I=y
 CONFIG_PHY_SUN4I_USB=y
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 00/16] IIO-based thermal sensor driver for Allwinner H3 and A83T SoC

2018-01-28 Thread Philipp Rossak
Allwiner H3 and A83T SoCs have a thermal sensor, which is a large refactored
version of the old Allwinner "GPADC" (although it have already only
thermal part left in A33).

This patch tried to add support for the sensor in H3 and A83T based on
the A33 thermal sensor driver by Quentin Schulz, which is already merged.

This Patchseries is based on Icenowy Zhengs v4 patchseries [1]. 
The first 5 patches are reworked patches from the v4 patchseries. 
The rest of the patches add step by step a feature to support multible
sensors, nvmem calibration and interupts. This patchseries should make it
easy also to add other sunxi SoCs, like the H5, A64 and A80.

Patches that adds support for H5, A64 and A80 SoCs are allready prepared,
and will be upstreamed if this patchseries is applied and the testing is done.

I tried to pick up all the feedback from [1]. I hope I didn't miss anything.

Regards,
Philipp 

@Jonathan
Could you please check Patch 8 again. I moved some code from 
Patch 8 to 9. Please chek it again, if your still ok with it.
But I think it sould be ok.

changes since v1:
* collecting all acks 
* rewording commits/fix typos
* move code in place where it is used
* fix naming conventions of defines
* clarify commits
* update documentation to cover the new nvmem calibraion
* change nvmem calibration

Icenowy Zheng (1):
  iio: adc: sun4i-gpadc-iio: rename A33-specified registers to contain
A33

Philipp Rossak (15):
  dt-bindings: update the Allwinner GPADC device tree binding for H3 &
A83T
  arm: config: sunxi_defconfig: enable SUN4I_GPADC
  iio: adc: sun4i-gpadc-iio: rework: sampling start/end code readout reg
  iio: adc: sun4i-gpadc-iio: rework: support clocks and reset
  iio: adc: sun4i-gpadc-iio: rework: support multiple sensors
  iio: adc: sun4i-gpadc-iio: rework: support nvmem calibration data
  iio: adc: sun4i-gpadc-iio: rework: add interrupt support
  iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
  iio: adc: sun4i-gpadc-iio: add support for A83T thermal sensor
  arm: dts: sunxi-h3-h5: add support for the thermal sensor in H3 and H5
  arm: dts: sun8i: h3: add support for the thermal sensor in H3
  arm: dts: sun8i: h3: add thermal zone to H3
  arm: dts: sun8i: h3: enable H3 sid controller
  arm: dts: sun8i: a83t: add support for the thermal sensor in A83T
  arm: dts: sun8i: a83t: add thermal zone to A83T

 .../devicetree/bindings/mfd/sun4i-gpadc.txt|  50 ++-
 arch/arm/boot/dts/sun8i-a83t.dtsi  |  28 ++
 arch/arm/boot/dts/sun8i-h3.dtsi|  21 ++
 arch/arm/boot/dts/sunxi-h3-h5.dtsi |   9 +
 arch/arm/configs/sunxi_defconfig   |   1 +
 drivers/iio/adc/sun4i-gpadc-iio.c  | 367 -
 include/linux/mfd/sun4i-gpadc.h|  51 ++-
 7 files changed, 503 insertions(+), 24 deletions(-)

-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 03/16] iio: adc: sun4i-gpadc-iio: rename A33-specified registers to contain A33

2018-01-28 Thread Philipp Rossak
From: Icenowy Zheng 

As the H3 SoC, which is also in sun8i line, has totally different
register map for the thermal sensor (a cut down version of GPADC), we
should rename A23/A33-specified registers to contain A33, in order to
prevent obfuscation with H3 registers. Currently these registers are
only prefixed "SUN8I", not "SUN8I_A33".

Add "_A33" after "SUN8I" on the register names.

Signed-off-by: Icenowy Zheng 
Reviewed-by: Chen-Yu Tsai 
Acked-by: Maxime Ripard 
Acked-by: Lee Jones 
Acked-by: Jonathan Cameron 
---
 drivers/iio/adc/sun4i-gpadc-iio.c | 2 +-
 include/linux/mfd/sun4i-gpadc.h   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 04d7147e0110..03804ff9c006 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -88,7 +88,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
 static const struct gpadc_data sun8i_a33_gpadc_data = {
.temp_offset = -1662,
.temp_scale = 162,
-   .tp_mode_en = SUN8I_GPADC_CTRL1_CHOP_TEMP_EN,
+   .tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
 };
 
 struct sun4i_gpadc_iio {
diff --git a/include/linux/mfd/sun4i-gpadc.h b/include/linux/mfd/sun4i-gpadc.h
index 139872c2e0fe..78d31984a222 100644
--- a/include/linux/mfd/sun4i-gpadc.h
+++ b/include/linux/mfd/sun4i-gpadc.h
@@ -38,9 +38,9 @@
 #define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x)   (GENMASK(3, 0) & BIT(x))
 #define SUN6I_GPADC_CTRL1_ADC_CHAN_MASKGENMASK(3, 0)
 
-/* TP_CTRL1 bits for sun8i SoCs */
-#define SUN8I_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
-#define SUN8I_GPADC_CTRL1_GPADC_CALI_ENBIT(7)
+/* TP_CTRL1 bits for A33 */
+#define SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN BIT(8)
+#define SUN8I_A33_GPADC_CTRL1_GPADC_CALI_ENBIT(7)
 
 #define SUN4I_GPADC_CTRL2  0x08
 
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] [PATCH v2 01/16] dt-bindings: update the Allwinner GPADC device tree binding for H3 & A83T

2018-01-28 Thread Philipp Rossak
Allwinner H3 features a thermal sensor like the one in A33, but has its
register re-arranged, the clock divider moved to CCU (originally the
clock divider is in ADC) and added a pair of bus clock and reset.

Allwinner A83T features a thermal sensor similar to the H3, the ths clock,
the bus clock and the reset was removed from the CCU. The THS in A83T
has a clock that is directly connected and runs with 24 MHz.

Update the binding document to cover H3 and A83T.

Signed-off-by: Philipp Rossak 
---
 .../devicetree/bindings/mfd/sun4i-gpadc.txt| 50 --
 1 file changed, 47 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt 
b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
index 86dd8191b04c..22df0c5c23d4 100644
--- a/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
+++ b/Documentation/devicetree/bindings/mfd/sun4i-gpadc.txt
@@ -4,12 +4,35 @@ The Allwinner SoCs all have an ADC that can also act as a 
thermal sensor
 and sometimes as a touchscreen controller.
 
 Required properties:
-  - compatible: "allwinner,sun8i-a33-ths",
+  - compatible: must contain one of the following compatibles:
+   - "allwinner,sun8i-a33-ths"
+   - "allwinner,sun8i-h3-ths"
+   - "allwinner,sun8i-a83t-ths"
   - reg: mmio address range of the chip,
-  - #thermal-sensor-cells: shall be 0,
+  - #thermal-sensor-cells: shall be 0 or 1,
   - #io-channel-cells: shall be 0,
 
-Example:
+Required properties for the following compatibles:
+   - "allwinner,sun8i-h3-ths"
+   - "allwinner,sun8i-a83t-ths"
+  - interrupts: the sampling interrupt of the ADC,
+
+Required properties for the following compatibles:
+   - "allwinner,sun8i-h3-ths"
+  - clocks: the bus clock and the input clock of the ADC,
+  - clock-names: should be "bus" and "mod",
+  - resets: the bus reset of the ADC,
+
+Optional properties for the following compatibles:
+   - "allwinner,sun8i-h3-ths"
+  - nvmem-cells: A phandle to the calibration data provided by a nvmem device.
+   If unspecified default values shall be used. The size should
+   be 0x2 * sensorcount.
+  - nvmem-cell-names: Should be "calibration".
+
+Details see: bindings/nvmem/nvmem.txt
+
+Example for A33:
ths: ths@1c25000 {
compatible = "allwinner,sun8i-a33-ths";
reg = <0x01c25000 0x100>;
@@ -17,6 +40,27 @@ Example:
#io-channel-cells = <0>;
};
 
+Example for H3:
+   ths: thermal-sensor@1c25000 {
+   compatible = "allwinner,sun8i-h3-ths";
+   reg = <0x01c25000 0x400>;
+   clocks = < CLK_BUS_THS>, < CLK_THS>;
+   clock-names = "bus", "mod";
+   resets = < RST_BUS_THS>;
+   interrupts = ;
+   #thermal-sensor-cells = <0>;
+   #io-channel-cells = <0>;
+   };
+
+Example for A83T:
+   ths: thermal-sensor@1f04000 {
+   compatible = "allwinner,sun8i-a83t-ths";
+   reg = <0x01f04000 0x100>;
+   interrupts = ;
+   #thermal-sensor-cells = <1>;
+   #io-channel-cells = <0>;
+   };
+
 sun4i, sun5i and sun6i SoCs are also supported via the older binding:
 
 sun4i resistive touchscreen controller
-- 
2.11.0

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH 1/2] ARM: dts: sun8i: h3-h5: Move pinctrl of mmc0 from dts to dtsi

2018-01-28 Thread Joonas Kylmälä
Hi Maxime,

I started on working this patch set again after a while but I actually
couldn't understand one thing you said. Please see the inline reply.

Maxime Ripard:
> On Thu, Oct 26, 2017 at 02:57:00PM +, Joonas Kylmälä wrote:
>> Maxime Ripard:
>>> On Sun, Oct 22, 2017 at 12:19:56PM +0300, Joonas Kylmälä wrote:
 Most of the boards use the mmc0 pins and their attributes defined in
 mmc0_pins_a and mmc0_cd_pin. Let's default to those by moving the
 pinctrl attributes to the dtsi file. This makes it easier to modify
 device trees in the future as there is only one place to change the
 pinctrl attributes.

 As a side effect this patch also adds the detect pin of Orange Pi
 Zero's mmc0 under pinctrl as it should have been there right from the
 beginning.
>>>
>>> We're actually in the process of removing those gpio pinctrl
>>> nodes. Could you make that while you're at it?

Can you give an example of those GPIO pinctrl nodes that you want to get
removed? I don't understand what do you refer with "those".

Joonas

-- 
You received this message because you are subscribed to the Google Groups 
"linux-sunxi" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to linux-sunxi+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[linux-sunxi] Re: [PATCH 07/16] iio: adc: sun4i-gpadc-iio: rework: support nvmem calibration data

2018-01-28 Thread Philipp Rossak



On 28.01.2018 14:52, Icenowy Zheng wrote:



于 2018年1月28日 GMT+08:00 下午9:46:18, Philipp Rossak  写到:



On 28.01.2018 10:02, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:32 +0100
Philipp Rossak  wrote:


This patch reworks the driver to support nvmem calibration cells.
The driver checks if the nvmem calibration is supported and reads

out

the nvmem. At the beginning of the startup process the calibration

data

is written to the related registers.

Signed-off-by: Philipp Rossak 


A few minor suggestions inline.

Jonathan


---
   drivers/iio/adc/sun4i-gpadc-iio.c | 52

+++

   include/linux/mfd/sun4i-gpadc.h   |  2 ++
   2 files changed, 54 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c

b/drivers/iio/adc/sun4i-gpadc-iio.c

index bff06f2798e8..7b12666cdd9e 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -27,6 +27,7 @@
   #include 
   #include 
   #include 
+#include 
   #include 
   #include 
   #include 
@@ -81,6 +82,7 @@ struct gpadc_data {
boolhas_bus_rst;
boolhas_mod_clk;
int sensor_count;
+   boolsupports_nvmem;
   };
   
   static const struct gpadc_data sun4i_gpadc_data = {

@@ -94,6 +96,7 @@ static const struct gpadc_data sun4i_gpadc_data =

{

.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
   };
   
   static const struct gpadc_data sun5i_gpadc_data = {

@@ -107,6 +110,7 @@ static const struct gpadc_data sun5i_gpadc_data

= {

.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
   };
   
   static const struct gpadc_data sun6i_gpadc_data = {

@@ -120,6 +124,7 @@ static const struct gpadc_data sun6i_gpadc_data

= {

.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
   };
   
   static const struct gpadc_data sun8i_a33_gpadc_data = {

@@ -130,6 +135,7 @@ static const struct gpadc_data

sun8i_a33_gpadc_data = {

.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,


BTW A33 claims to support calibration data according to the manual.



Yes that's true, but I haven't seen a sid/nvmem driver for the a33. If 
that is available, we can change this for true (same on a83t).



   };
   
   struct sun4i_gpadc_iio {

@@ -148,6 +154,8 @@ struct sun4i_gpadc_iio {
struct clk  *mod_clk;
struct reset_control*reset;
int sensor_id;
+   u32 calibration_data[2];
+   boolhas_calibration_data[2];
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -459,6 +467,17 @@ static int sun4i_gpadc_runtime_suspend(struct

device *dev)

return info->data->sample_end(info);
   }
   
+static void sunxi_calibrate(struct sun4i_gpadc_iio *info)

+{
+   if (info->has_calibration_data[0])
+   regmap_write(info->regmap, SUNXI_THS_CDATA_0_1,
+   info->calibration_data[0]);
+
+   if (info->has_calibration_data[1])
+   regmap_write(info->regmap, SUNXI_THS_CDATA_2_3,
+   info->calibration_data[1]);
+}
+
   static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
   {
/* clkin = 6MHz */
@@ -481,6 +500,7 @@ static int sun4i_gpadc_sample_start(struct

sun4i_gpadc_iio *info)

   static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
   {
u32 value;
+   sunxi_calibrate(info);
   
   	if (info->data->ctrl0_map)

regmap_write(info->regmap, SUNXI_THS_CTRL0,
@@ -602,6 +622,9 @@ static int sun4i_gpadc_probe_dt(struct

platform_device *pdev,

struct resource *mem;
void __iomem *base;
int ret;
+   struct nvmem_cell *cell;
+   ssize_t cell_size;
+   u64 *cell_data;
   
   	info->data = of_device_get_match_data(>dev);

if (!info->data)
@@ -616,6 +639,35 @@ static int sun4i_gpadc_probe_dt(struct

platform_device *pdev,

if (IS_ERR(base))
return PTR_ERR(base);
   
+	info->has_calibration_data[0] = false;

+   info->has_calibration_data[1] = false;
+
+   if (!info->data->supports_nvmem)
+   goto no_nvmem;
+
+   cell = devm_nvmem_cell_get(>dev, "calibration");
+   if (IS_ERR(cell)) {
+   if (PTR_ERR(cell) == -EPROBE_DEFER)
+   return PTR_ERR(cell);

Use a goto here to no_nvmem.

Then you can drop the below 

[linux-sunxi] Re: [PATCH 04/16] iio: adc: sun4i-gpadc-iio: rework: sampling start/end code readout reg

2018-01-28 Thread Philipp Rossak



On 28.01.2018 14:37, Icenowy Zheng wrote:



于 2018年1月28日 GMT+08:00 下午9:34:17, Philipp Rossak  写到:



On 28.01.2018 09:43, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:29 +0100
Philipp Rossak  wrote:


For adding newer sensor some basic rework of the code is necessary.

This commit reworks the code and allows the sampling start/end code

and

the position of value readout register to be altered. Later the

start/end

functions will be used to configure the ths and start/stop the
sampling.

Signed-off-by: Icenowy Zheng 
Signed-off-by: Philipp Rossak 

Hmm. It almost always turns out to be a bad idea to assume a

particular

set of registers will be consistent across a hardware family.  Usual

convention

is just to prefix them with the first supported device and use them

across

the variants where they are correct.  I.e. don't use wild cards or

generic

names as they often end up implying a wider range of applicability

than

we want.



The new THS sensors seems to use the same THS ip core, only configured
with different amount of sensors. So for H3, A83T, H5, A80 and A64 the
registers are all the same.

I think the big question is, do we want to have a few very big patches.

Or more small patches with code that is used in later patches.


Allwinner H6 has changed the THS core again.

Please consider this :-)



Yes you are right the core is different! But it is already considered it.
They dropped ACQ1, the IRQs control/status are split in separate 
registers. I already have a good idea how to implement it, but I would 
like to add this in the second part of this patch series (containing 
support for A80, A64, and H5) or even later since the initial support 
and the CCU driver is missing right now.






A few other comments inline.  Reworking code to make it ready for

later

patches is fine, but this also adds a lot of new code which isn't

used until

much later in the series.  Move it there...


please see comments below.


---
   drivers/iio/adc/sun4i-gpadc-iio.c | 87

+++

   include/linux/mfd/sun4i-gpadc.h   | 19 +++--
   2 files changed, 94 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c

b/drivers/iio/adc/sun4i-gpadc-iio.c

index 03804ff9c006..363936b37c5a 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -49,6 +49,18 @@ static unsigned int

sun6i_gpadc_chan_select(unsigned int chan)

return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
   }
   
+struct sun4i_gpadc_iio;

+
+/*
+ * Prototypes for these functions, which enable these functions to

be

+ * referenced in gpadc_data structures.
+ */
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info);
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info);
+
+static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info);


Superficially this appears to be introduced but not used... Patch 9
is first to use it I think?  Introduce it then rather than here.



You are right, this function is used first in Patch 9. In an very early

version, I had this together with Patch 9. But then I had the feeling
that everything got too messy... Right now this is a very big patch
series and I wanted to have a clear structure in it and easy to review.

If I would rework this it will end up in squashing, Patch 4, Parts of
Patch 7, Patch 8 and Patch 9.


+static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info);
+
   struct gpadc_data {
int temp_offset;
int temp_scale;
@@ -56,6 +68,13 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
+   unsigned inttemp_data;
+   int (*sample_start)(struct sun4i_gpadc_iio *info);
+   int (*sample_end)(struct sun4i_gpadc_iio *info);
+   u32 ctrl0_map;
+   u32 ctrl2_map;
+   u32 sensor_en_map;
+   u32 filter_map;
   };
   
   static const struct gpadc_data sun4i_gpadc_data = {

@@ -65,6 +84,9 @@ static const struct gpadc_data sun4i_gpadc_data =

{

.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
   };
   
   static const struct gpadc_data sun5i_gpadc_data = {

@@ -74,6 +96,9 @@ static const struct gpadc_data sun5i_gpadc_data =

{

.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = 

[linux-sunxi] Re: [PATCH 06/16] iio: adc: sun4i-gpadc-iio: rework: support multible sensors

2018-01-28 Thread Philipp Rossak



On 28.01.2018 10:08, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:31 +0100
Philipp Rossak  wrote:

multible -> multiple


^^ Ok, I will fix that.


For adding newer sensor some basic rework of the code is necessary.

This patch reworks the driver to be able to handle more than one
thermal sensor. Newer SoC like the A80 have 4 thermal sensors.
Because of this the maximal sensor count value was set to 4.

The sensor_id value is set during sensor registration and is for each
registered sensor indiviual. This makes it able to differntiate the
sensors when the value is read from the register.

Signed-off-by: Philipp Rossak 

Question inline about why you aren't exposing the additional temperature
sensors as IIO channels?

Fine to not do so I suppose, but needs justifying.



^^ Ok, I will rework the commit mesage. Detailed explanation see below.

Jonathan


---
  drivers/iio/adc/sun4i-gpadc-iio.c | 36 +++-
  include/linux/mfd/sun4i-gpadc.h   |  6 ++
  2 files changed, 29 insertions(+), 13 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 1a80744bd472..bff06f2798e8 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -70,7 +70,7 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
-   unsigned inttemp_data;
+   unsigned inttemp_data[MAX_SENSOR_COUNT];
int (*sample_start)(struct sun4i_gpadc_iio *info);
int (*sample_end)(struct sun4i_gpadc_iio *info);
u32 ctrl0_map;
@@ -80,6 +80,7 @@ struct gpadc_data {
boolhas_bus_clk;
boolhas_bus_rst;
boolhas_mod_clk;
+   int sensor_count;
  };
  
  static const struct gpadc_data sun4i_gpadc_data = {

@@ -89,9 +90,10 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
  };
  
  static const struct gpadc_data sun5i_gpadc_data = {

@@ -101,9 +103,10 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
  };
  
  static const struct gpadc_data sun6i_gpadc_data = {

@@ -113,18 +116,20 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
  };
  
  static const struct gpadc_data sun8i_a33_gpadc_data = {

.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = SUN8I_A33_GPADC_CTRL1_CHOP_TEMP_EN,
-   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .temp_data = {SUN4I_GPADC_TEMP_DATA, 0, 0, 0},


[*] ^^

.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
+   .sensor_count = 1,
  };
  
  struct sun4i_gpadc_iio {

@@ -142,6 +147,7 @@ struct sun4i_gpadc_iio {
struct clk  *bus_clk;
struct clk  *mod_clk;
struct reset_control*reset;
+   int sensor_id;
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -309,14 +315,15 @@ static int sun4i_gpadc_adc_read(struct iio_dev 
*indio_dev, int channel,
return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
  }
  
-static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)

+static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val,
+   int sensor)
  {
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
  
  	if (info->no_irq) {

pm_runtime_get_sync(indio_dev->dev.parent);
  
-		regmap_read(info->regmap, info->data->temp_data, val);

+   regmap_read(info->regmap, 

[linux-sunxi] Re: [PATCH 07/16] iio: adc: sun4i-gpadc-iio: rework: support nvmem calibration data

2018-01-28 Thread Icenowy Zheng


于 2018年1月28日 GMT+08:00 下午9:46:18, Philipp Rossak  写到:
>
>
>On 28.01.2018 10:02, Jonathan Cameron wrote:
>> On Fri, 26 Jan 2018 16:19:32 +0100
>> Philipp Rossak  wrote:
>> 
>>> This patch reworks the driver to support nvmem calibration cells.
>>> The driver checks if the nvmem calibration is supported and reads
>out
>>> the nvmem. At the beginning of the startup process the calibration
>data
>>> is written to the related registers.
>>>
>>> Signed-off-by: Philipp Rossak 
>> 
>> A few minor suggestions inline.
>> 
>> Jonathan
>> 
>>> ---
>>>   drivers/iio/adc/sun4i-gpadc-iio.c | 52
>+++
>>>   include/linux/mfd/sun4i-gpadc.h   |  2 ++
>>>   2 files changed, 54 insertions(+)
>>>
>>> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c
>b/drivers/iio/adc/sun4i-gpadc-iio.c
>>> index bff06f2798e8..7b12666cdd9e 100644
>>> --- a/drivers/iio/adc/sun4i-gpadc-iio.c
>>> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c
>>> @@ -27,6 +27,7 @@
>>>   #include 
>>>   #include 
>>>   #include 
>>> +#include 
>>>   #include 
>>>   #include 
>>>   #include 
>>> @@ -81,6 +82,7 @@ struct gpadc_data {
>>> boolhas_bus_rst;
>>> boolhas_mod_clk;
>>> int sensor_count;
>>> +   boolsupports_nvmem;
>>>   };
>>>   
>>>   static const struct gpadc_data sun4i_gpadc_data = {
>>> @@ -94,6 +96,7 @@ static const struct gpadc_data sun4i_gpadc_data =
>{
>>> .sample_start = sun4i_gpadc_sample_start,
>>> .sample_end = sun4i_gpadc_sample_end,
>>> .sensor_count = 1,
>>> +   .supports_nvmem = false,
>>>   };
>>>   
>>>   static const struct gpadc_data sun5i_gpadc_data = {
>>> @@ -107,6 +110,7 @@ static const struct gpadc_data sun5i_gpadc_data
>= {
>>> .sample_start = sun4i_gpadc_sample_start,
>>> .sample_end = sun4i_gpadc_sample_end,
>>> .sensor_count = 1,
>>> +   .supports_nvmem = false,
>>>   };
>>>   
>>>   static const struct gpadc_data sun6i_gpadc_data = {
>>> @@ -120,6 +124,7 @@ static const struct gpadc_data sun6i_gpadc_data
>= {
>>> .sample_start = sun4i_gpadc_sample_start,
>>> .sample_end = sun4i_gpadc_sample_end,
>>> .sensor_count = 1,
>>> +   .supports_nvmem = false,
>>>   };
>>>   
>>>   static const struct gpadc_data sun8i_a33_gpadc_data = {
>>> @@ -130,6 +135,7 @@ static const struct gpadc_data
>sun8i_a33_gpadc_data = {
>>> .sample_start = sun4i_gpadc_sample_start,
>>> .sample_end = sun4i_gpadc_sample_end,
>>> .sensor_count = 1,
>>> +   .supports_nvmem = false,

BTW A33 claims to support calibration data according to the manual.

>>>   };
>>>   
>>>   struct sun4i_gpadc_iio {
>>> @@ -148,6 +154,8 @@ struct sun4i_gpadc_iio {
>>> struct clk  *mod_clk;
>>> struct reset_control*reset;
>>> int sensor_id;
>>> +   u32 calibration_data[2];
>>> +   boolhas_calibration_data[2];
>>> /* prevents concurrent reads of temperature and ADC */
>>> struct mutexmutex;
>>> struct thermal_zone_device  *tzd;
>>> @@ -459,6 +467,17 @@ static int sun4i_gpadc_runtime_suspend(struct
>device *dev)
>>> return info->data->sample_end(info);
>>>   }
>>>   
>>> +static void sunxi_calibrate(struct sun4i_gpadc_iio *info)
>>> +{
>>> +   if (info->has_calibration_data[0])
>>> +   regmap_write(info->regmap, SUNXI_THS_CDATA_0_1,
>>> +   info->calibration_data[0]);
>>> +
>>> +   if (info->has_calibration_data[1])
>>> +   regmap_write(info->regmap, SUNXI_THS_CDATA_2_3,
>>> +   info->calibration_data[1]);
>>> +}
>>> +
>>>   static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
>>>   {
>>> /* clkin = 6MHz */
>>> @@ -481,6 +500,7 @@ static int sun4i_gpadc_sample_start(struct
>sun4i_gpadc_iio *info)
>>>   static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
>>>   {
>>> u32 value;
>>> +   sunxi_calibrate(info);
>>>   
>>> if (info->data->ctrl0_map)
>>> regmap_write(info->regmap, SUNXI_THS_CTRL0,
>>> @@ -602,6 +622,9 @@ static int sun4i_gpadc_probe_dt(struct
>platform_device *pdev,
>>> struct resource *mem;
>>> void __iomem *base;
>>> int ret;
>>> +   struct nvmem_cell *cell;
>>> +   ssize_t cell_size;
>>> +   u64 *cell_data;
>>>   
>>> info->data = of_device_get_match_data(>dev);
>>> if (!info->data)
>>> @@ -616,6 +639,35 @@ static int sun4i_gpadc_probe_dt(struct
>platform_device *pdev,
>>> if (IS_ERR(base))
>>> return PTR_ERR(base);
>>>   
>>> +   info->has_calibration_data[0] = false;
>>> +   info->has_calibration_data[1] = false;
>>> +
>>> +   if (!info->data->supports_nvmem)
>>> +   goto no_nvmem;
>>> +
>>> +   cell = devm_nvmem_cell_get(>dev, "calibration");
>>> +   if (IS_ERR(cell)) {
>>> +   if (PTR_ERR(cell) == -EPROBE_DEFER)
>>> +   return PTR_ERR(cell);
>> Use a 

[linux-sunxi] Re: [PATCH 08/16] iio: adc: sun4i-gpadc-iio: rework: add interrupt support

2018-01-28 Thread Philipp Rossak



On 28.01.2018 10:06, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:33 +0100
Philipp Rossak  wrote:


This patch rewors the driver to support interrupts for the thermal part
of the sensor.

This is only available for the newer sensor (currently H3 and A83T).
The interrupt will be trigerd on data available and triggers the update
for the thermal sensors. All newer sensors have different amount of
sensors and different interrupts for each device the reset of the
interrupts need to be done different

For the newer sensors is the autosuspend disabled.

Signed-off-by: Philipp Rossak 

Really minor point inline, otherwise this looks fine to me.

Acked-by: Jonathan  Cameron 

---
  drivers/iio/adc/sun4i-gpadc-iio.c | 68 +++
  include/linux/mfd/sun4i-gpadc.h   | 33 +++
  2 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 7b12666cdd9e..77e07f042730 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -78,11 +78,14 @@ struct gpadc_data {
u32 ctrl2_map;
u32 sensor_en_map;
u32 filter_map;
+   u32 irq_clear_map;
+   u32 irq_control_map;
boolhas_bus_clk;
boolhas_bus_rst;
boolhas_mod_clk;
int sensor_count;
boolsupports_nvmem;
+   boolsupport_irq;
  };
  
  static const struct gpadc_data sun4i_gpadc_data = {

@@ -97,6 +100,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
  };
  
  static const struct gpadc_data sun5i_gpadc_data = {

@@ -111,6 +115,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
  };
  
  static const struct gpadc_data sun6i_gpadc_data = {

@@ -125,6 +130,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
  };
  
  static const struct gpadc_data sun8i_a33_gpadc_data = {

@@ -136,6 +142,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
.supports_nvmem = false,
+   .support_irq = false,
  };
  
  struct sun4i_gpadc_iio {

@@ -339,6 +346,11 @@ static int sun4i_gpadc_temp_read(struct iio_dev 
*indio_dev, int *val,
return 0;
}
  
+	if (info->data->support_irq) {

+   regmap_read(info->regmap, info->data->temp_data[sensor], val);
+   return 0;
+   }
+
return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
  }
  
@@ -436,6 +448,17 @@ static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)

return IRQ_HANDLED;
  }
  
+static irqreturn_t sunxi_irq_thread(int irq, void *data)

+{
+   struct sun4i_gpadc_iio *info = data;
+
+   regmap_write(info->regmap, SUNXI_THS_STAT, info->data->irq_clear_map);
+
+   thermal_zone_device_update(info->tzd, THERMAL_EVENT_TEMP_SAMPLE);
+
+   return IRQ_HANDLED;
+}
+
  static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info)
  {
/* Disable the ADC on IP */
@@ -448,6 +471,8 @@ static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio 
*info)
  
  static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info)

  {
+   /* Disable ths interrupt*/


Space before */


^^ Ok, I will rework that.


+   regmap_write(info->regmap, SUNXI_THS_INTC, 0x0);
/* Disable temperature sensor */
regmap_write(info->regmap, SUNXI_THS_CTRL2, 0x0);
  
@@ -509,9 +534,15 @@ static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)

regmap_write(info->regmap, SUNXI_THS_CTRL2,
info->data->ctrl2_map);
  
+	regmap_write(info->regmap, SUNXI_THS_STAT,

+   info->data->irq_clear_map);
+
regmap_write(info->regmap, SUNXI_THS_FILTER,
info->data->filter_map);
  
+	regmap_write(info->regmap, SUNXI_THS_INTC,

+   info->data->irq_control_map);
+
regmap_read(info->regmap, SUNXI_THS_CTRL2, );
  
  	regmap_write(info->regmap, SUNXI_THS_CTRL2,

@@ -625,12 +656,29 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
struct nvmem_cell *cell;
ssize_t cell_size;
u64 *cell_data;
+   int irq;
  
  	info->data = of_device_get_match_data(>dev);

if (!info->data)
return -ENODEV;
  
-	info->no_irq = true;

+   if (info->data->support_irq) {
+   /* 

[linux-sunxi] Re: [PATCH 07/16] iio: adc: sun4i-gpadc-iio: rework: support nvmem calibration data

2018-01-28 Thread Philipp Rossak



On 28.01.2018 10:02, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:32 +0100
Philipp Rossak  wrote:


This patch reworks the driver to support nvmem calibration cells.
The driver checks if the nvmem calibration is supported and reads out
the nvmem. At the beginning of the startup process the calibration data
is written to the related registers.

Signed-off-by: Philipp Rossak 


A few minor suggestions inline.

Jonathan


---
  drivers/iio/adc/sun4i-gpadc-iio.c | 52 +++
  include/linux/mfd/sun4i-gpadc.h   |  2 ++
  2 files changed, 54 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index bff06f2798e8..7b12666cdd9e 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -27,6 +27,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  #include 
@@ -81,6 +82,7 @@ struct gpadc_data {
boolhas_bus_rst;
boolhas_mod_clk;
int sensor_count;
+   boolsupports_nvmem;
  };
  
  static const struct gpadc_data sun4i_gpadc_data = {

@@ -94,6 +96,7 @@ static const struct gpadc_data sun4i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
  };
  
  static const struct gpadc_data sun5i_gpadc_data = {

@@ -107,6 +110,7 @@ static const struct gpadc_data sun5i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
  };
  
  static const struct gpadc_data sun6i_gpadc_data = {

@@ -120,6 +124,7 @@ static const struct gpadc_data sun6i_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
  };
  
  static const struct gpadc_data sun8i_a33_gpadc_data = {

@@ -130,6 +135,7 @@ static const struct gpadc_data sun8i_a33_gpadc_data = {
.sample_start = sun4i_gpadc_sample_start,
.sample_end = sun4i_gpadc_sample_end,
.sensor_count = 1,
+   .supports_nvmem = false,
  };
  
  struct sun4i_gpadc_iio {

@@ -148,6 +154,8 @@ struct sun4i_gpadc_iio {
struct clk  *mod_clk;
struct reset_control*reset;
int sensor_id;
+   u32 calibration_data[2];
+   boolhas_calibration_data[2];
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -459,6 +467,17 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
return info->data->sample_end(info);
  }
  
+static void sunxi_calibrate(struct sun4i_gpadc_iio *info)

+{
+   if (info->has_calibration_data[0])
+   regmap_write(info->regmap, SUNXI_THS_CDATA_0_1,
+   info->calibration_data[0]);
+
+   if (info->has_calibration_data[1])
+   regmap_write(info->regmap, SUNXI_THS_CDATA_2_3,
+   info->calibration_data[1]);
+}
+
  static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info)
  {
/* clkin = 6MHz */
@@ -481,6 +500,7 @@ static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio 
*info)
  static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info)
  {
u32 value;
+   sunxi_calibrate(info);
  
  	if (info->data->ctrl0_map)

regmap_write(info->regmap, SUNXI_THS_CTRL0,
@@ -602,6 +622,9 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
struct resource *mem;
void __iomem *base;
int ret;
+   struct nvmem_cell *cell;
+   ssize_t cell_size;
+   u64 *cell_data;
  
  	info->data = of_device_get_match_data(>dev);

if (!info->data)
@@ -616,6 +639,35 @@ static int sun4i_gpadc_probe_dt(struct platform_device 
*pdev,
if (IS_ERR(base))
return PTR_ERR(base);
  
+	info->has_calibration_data[0] = false;

+   info->has_calibration_data[1] = false;
+
+   if (!info->data->supports_nvmem)
+   goto no_nvmem;
+
+   cell = devm_nvmem_cell_get(>dev, "calibration");
+   if (IS_ERR(cell)) {
+   if (PTR_ERR(cell) == -EPROBE_DEFER)
+   return PTR_ERR(cell);

Use a goto here to no_nvmem.

Then you can drop the below else to make things more readable.

+   } else {
+   cell_data = (u64 *)nvmem_cell_read(cell, _size);
+   devm_nvmem_cell_put(>dev, cell);


I'm really not keen on use of devm for things we are intending
to drop almost immediately.  Just use the non managed versions
and clean up properly in the error paths (if there are any
where it is needed - which there 

[linux-sunxi] Re: [PATCH 04/16] iio: adc: sun4i-gpadc-iio: rework: sampling start/end code readout reg

2018-01-28 Thread Icenowy Zheng


于 2018年1月28日 GMT+08:00 下午9:34:17, Philipp Rossak  写到:
>
>
>On 28.01.2018 09:43, Jonathan Cameron wrote:
>> On Fri, 26 Jan 2018 16:19:29 +0100
>> Philipp Rossak  wrote:
>> 
>>> For adding newer sensor some basic rework of the code is necessary.
>>>
>>> This commit reworks the code and allows the sampling start/end code
>and
>>> the position of value readout register to be altered. Later the
>start/end
>>> functions will be used to configure the ths and start/stop the
>>> sampling.
>>>
>>> Signed-off-by: Icenowy Zheng 
>>> Signed-off-by: Philipp Rossak 
>> Hmm. It almost always turns out to be a bad idea to assume a
>particular
>> set of registers will be consistent across a hardware family.  Usual
>convention
>> is just to prefix them with the first supported device and use them
>across
>> the variants where they are correct.  I.e. don't use wild cards or
>generic
>> names as they often end up implying a wider range of applicability
>than
>> we want.
>>
>
>The new THS sensors seems to use the same THS ip core, only configured 
>with different amount of sensors. So for H3, A83T, H5, A80 and A64 the 
>registers are all the same.
>
>I think the big question is, do we want to have a few very big patches.
>
>Or more small patches with code that is used in later patches.

Allwinner H6 has changed the THS core again.

Please consider this :-)

>
>> A few other comments inline.  Reworking code to make it ready for
>later
>> patches is fine, but this also adds a lot of new code which isn't
>used until
>> much later in the series.  Move it there...
>
>please see comments below.
>
>>> ---
>>>   drivers/iio/adc/sun4i-gpadc-iio.c | 87
>+++
>>>   include/linux/mfd/sun4i-gpadc.h   | 19 +++--
>>>   2 files changed, 94 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c
>b/drivers/iio/adc/sun4i-gpadc-iio.c
>>> index 03804ff9c006..363936b37c5a 100644
>>> --- a/drivers/iio/adc/sun4i-gpadc-iio.c
>>> +++ b/drivers/iio/adc/sun4i-gpadc-iio.c
>>> @@ -49,6 +49,18 @@ static unsigned int
>sun6i_gpadc_chan_select(unsigned int chan)
>>> return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
>>>   }
>>>   
>>> +struct sun4i_gpadc_iio;
>>> +
>>> +/*
>>> + * Prototypes for these functions, which enable these functions to
>be
>>> + * referenced in gpadc_data structures.
>>> + */
>>> +static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info);
>>> +static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info);
>>> +
>>> +static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info);
>> 
>> Superficially this appears to be introduced but not used... Patch 9
>> is first to use it I think?  Introduce it then rather than here.
>> 
>
>You are right, this function is used first in Patch 9. In an very early
>
>version, I had this together with Patch 9. But then I had the feeling 
>that everything got too messy... Right now this is a very big patch 
>series and I wanted to have a clear structure in it and easy to review.
>
>If I would rework this it will end up in squashing, Patch 4, Parts of 
>Patch 7, Patch 8 and Patch 9.
>
>>> +static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info);
>>> +
>>>   struct gpadc_data {
>>> int temp_offset;
>>> int temp_scale;
>>> @@ -56,6 +68,13 @@ struct gpadc_data {
>>> unsigned inttp_adc_select;
>>> unsigned int(*adc_chan_select)(unsigned int chan);
>>> unsigned intadc_chan_mask;
>>> +   unsigned inttemp_data;
>>> +   int (*sample_start)(struct sun4i_gpadc_iio *info);
>>> +   int (*sample_end)(struct sun4i_gpadc_iio *info);
>>> +   u32 ctrl0_map;
>>> +   u32 ctrl2_map;
>>> +   u32 sensor_en_map;
>>> +   u32 filter_map;
>>>   };
>>>   
>>>   static const struct gpadc_data sun4i_gpadc_data = {
>>> @@ -65,6 +84,9 @@ static const struct gpadc_data sun4i_gpadc_data =
>{
>>> .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
>>> .adc_chan_select = _gpadc_chan_select,
>>> .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
>>> +   .temp_data = SUN4I_GPADC_TEMP_DATA,
>>> +   .sample_start = sun4i_gpadc_sample_start,
>>> +   .sample_end = sun4i_gpadc_sample_end,
>>>   };
>>>   
>>>   static const struct gpadc_data sun5i_gpadc_data = {
>>> @@ -74,6 +96,9 @@ static const struct gpadc_data sun5i_gpadc_data =
>{
>>> .tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
>>> .adc_chan_select = _gpadc_chan_select,
>>> .adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
>>> +   .temp_data = SUN4I_GPADC_TEMP_DATA,
>>> +   .sample_start = sun4i_gpadc_sample_start,
>>> +   .sample_end = sun4i_gpadc_sample_end,
>>>   };
>>>   
>>>   static const struct gpadc_data sun6i_gpadc_data = {
>>> @@ -83,12 +108,18 @@ static const struct gpadc_data sun6i_gpadc_data
>= {
>>> .tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
>>> 

[linux-sunxi] Re: [PATCH 04/16] iio: adc: sun4i-gpadc-iio: rework: sampling start/end code readout reg

2018-01-28 Thread Philipp Rossak



On 28.01.2018 09:43, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:29 +0100
Philipp Rossak  wrote:


For adding newer sensor some basic rework of the code is necessary.

This commit reworks the code and allows the sampling start/end code and
the position of value readout register to be altered. Later the start/end
functions will be used to configure the ths and start/stop the
sampling.

Signed-off-by: Icenowy Zheng 
Signed-off-by: Philipp Rossak 

Hmm. It almost always turns out to be a bad idea to assume a particular
set of registers will be consistent across a hardware family.  Usual convention
is just to prefix them with the first supported device and use them across
the variants where they are correct.  I.e. don't use wild cards or generic
names as they often end up implying a wider range of applicability than
we want.



The new THS sensors seems to use the same THS ip core, only configured 
with different amount of sensors. So for H3, A83T, H5, A80 and A64 the 
registers are all the same.


I think the big question is, do we want to have a few very big patches. 
Or more small patches with code that is used in later patches.



A few other comments inline.  Reworking code to make it ready for later
patches is fine, but this also adds a lot of new code which isn't used until
much later in the series.  Move it there...


please see comments below.


---
  drivers/iio/adc/sun4i-gpadc-iio.c | 87 +++
  include/linux/mfd/sun4i-gpadc.h   | 19 +++--
  2 files changed, 94 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 03804ff9c006..363936b37c5a 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -49,6 +49,18 @@ static unsigned int sun6i_gpadc_chan_select(unsigned int 
chan)
return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
  }
  
+struct sun4i_gpadc_iio;

+
+/*
+ * Prototypes for these functions, which enable these functions to be
+ * referenced in gpadc_data structures.
+ */
+static int sun4i_gpadc_sample_start(struct sun4i_gpadc_iio *info);
+static int sun4i_gpadc_sample_end(struct sun4i_gpadc_iio *info);
+
+static int sunxi_ths_sample_start(struct sun4i_gpadc_iio *info);


Superficially this appears to be introduced but not used... Patch 9
is first to use it I think?  Introduce it then rather than here.



You are right, this function is used first in Patch 9. In an very early 
version, I had this together with Patch 9. But then I had the feeling 
that everything got too messy... Right now this is a very big patch 
series and I wanted to have a clear structure in it and easy to review.


If I would rework this it will end up in squashing, Patch 4, Parts of 
Patch 7, Patch 8 and Patch 9.



+static int sunxi_ths_sample_end(struct sun4i_gpadc_iio *info);
+
  struct gpadc_data {
int temp_offset;
int temp_scale;
@@ -56,6 +68,13 @@ struct gpadc_data {
unsigned inttp_adc_select;
unsigned int(*adc_chan_select)(unsigned int chan);
unsigned intadc_chan_mask;
+   unsigned inttemp_data;
+   int (*sample_start)(struct sun4i_gpadc_iio *info);
+   int (*sample_end)(struct sun4i_gpadc_iio *info);
+   u32 ctrl0_map;
+   u32 ctrl2_map;
+   u32 sensor_en_map;
+   u32 filter_map;
  };
  
  static const struct gpadc_data sun4i_gpadc_data = {

@@ -65,6 +84,9 @@ static const struct gpadc_data sun4i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
  };
  
  static const struct gpadc_data sun5i_gpadc_data = {

@@ -74,6 +96,9 @@ static const struct gpadc_data sun5i_gpadc_data = {
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
  };
  
  static const struct gpadc_data sun6i_gpadc_data = {

@@ -83,12 +108,18 @@ static const struct gpadc_data sun6i_gpadc_data = {
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
.adc_chan_select = _gpadc_chan_select,
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
+   .temp_data = SUN4I_GPADC_TEMP_DATA,
+   .sample_start = sun4i_gpadc_sample_start,
+   .sample_end = sun4i_gpadc_sample_end,
  };
  
  static const struct gpadc_data sun8i_a33_gpadc_data = {

.temp_offset = -1662,
.temp_scale = 162,
.tp_mode_en = 

[linux-sunxi] Re: [PATCH 05/16] iio: adc: sun4i-gpadc-iio: rework: support clocks and reset

2018-01-28 Thread Philipp Rossak



On 28.01.2018 09:50, Jonathan Cameron wrote:

On Fri, 26 Jan 2018 16:19:30 +0100
Philipp Rossak  wrote:


For adding newer sensor some basic rework of the code is necessary.

The SoCs after H3 has newer thermal sensor ADCs, which have two clock
inputs (bus clock and sampling clock) and a reset. The registers are
also re-arranged.

This commit reworks the code, adds the process of the clocks and
resets.

Signed-off-by: Philipp Rossak 
Signed-off-by: Icenowy Zheng 


Both clock and reset code is safe against null parameters, so you can
drop a lot of 'is it here' checks in this.  They could be argued to
act as documentation of the fact we really don't expect them in some cases
I suppose...


Ok, this sounds good for me!
I will fix that in the next version of this patch series.


---
  drivers/iio/adc/sun4i-gpadc-iio.c | 80 +++
  1 file changed, 80 insertions(+)

diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c 
b/drivers/iio/adc/sun4i-gpadc-iio.c
index 363936b37c5a..1a80744bd472 100644
--- a/drivers/iio/adc/sun4i-gpadc-iio.c
+++ b/drivers/iio/adc/sun4i-gpadc-iio.c
@@ -22,6 +22,7 @@
   * shutdown for not being used.
   */
  
+#include 

  #include 
  #include 
  #include 
@@ -31,6 +32,7 @@
  #include 
  #include 
  #include 
+#include 
  #include 
  #include 
  
@@ -75,6 +77,9 @@ struct gpadc_data {

u32 ctrl2_map;
u32 sensor_en_map;
u32 filter_map;
+   boolhas_bus_clk;
+   boolhas_bus_rst;
+   boolhas_mod_clk;
  };
  
  static const struct gpadc_data sun4i_gpadc_data = {

@@ -134,6 +139,9 @@ struct sun4i_gpadc_iio {
atomic_tignore_temp_data_irq;
const struct gpadc_data *data;
boolno_irq;
+   struct clk  *bus_clk;
+   struct clk  *mod_clk;
+   struct reset_control*reset;
/* prevents concurrent reads of temperature and ADC */
struct mutexmutex;
struct thermal_zone_device  *tzd;
@@ -435,6 +443,12 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev)
  {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
  
+	if (info->data->has_mod_clk)

+   clk_disable(info->mod_clk);


Safe against null parameter... (see below)


+
+   if (info->data->has_bus_clk)
+   clk_disable(info->bus_clk);
+
return info->data->sample_end(info);
  }
  
@@ -483,6 +497,12 @@ static int sun4i_gpadc_runtime_resume(struct device *dev)

  {
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
  
+	if (info->data->has_mod_clk)

+   clk_enable(info->mod_clk);


clk_enable is safe against null parameter so could do without the checks.


+
+   if (info->data->has_bus_clk)
+   clk_enable(info->bus_clk);
+
return info->data->sample_start(info);
  }
  
@@ -597,10 +617,61 @@ static int sun4i_gpadc_probe_dt(struct platform_device *pdev,

return ret;
}
  
+	if (info->data->has_bus_rst) {

+   info->reset = devm_reset_control_get(>dev, NULL);
+   if (IS_ERR(info->reset)) {
+   ret = PTR_ERR(info->reset);
+   return ret;
+   }
+
+   ret = reset_control_deassert(info->reset);
+   if (ret)
+   return ret;
+   }
+
+   if (info->data->has_bus_clk) {
+   info->bus_clk = devm_clk_get(>dev, "bus");
+   if (IS_ERR(info->bus_clk)) {
+   ret = PTR_ERR(info->bus_clk);
+   goto assert_reset;
+   }
+
+   ret = clk_prepare_enable(info->bus_clk);
+   if (ret)
+   goto assert_reset;
+   }
+
+   if (info->data->has_mod_clk) {
+   info->mod_clk = devm_clk_get(>dev, "mod");
+   if (IS_ERR(info->mod_clk)) {
+   ret = PTR_ERR(info->mod_clk);
+   goto disable_bus_clk;
+   }
+
+   /* Running at 6MHz */
+   ret = clk_set_rate(info->mod_clk, 400);
+   if (ret)
+   goto disable_bus_clk;
+
+   ret = clk_prepare_enable(info->mod_clk);
+   if (ret)
+   goto disable_bus_clk;
+   }
+
if (IS_ENABLED(CONFIG_THERMAL_OF))
info->sensor_device = >dev;
  
  	return 0;

+
+disable_bus_clk:
+   if (info->data->has_bus_clk)
+   clk_disable_unprepare(info->bus_clk);
+
+assert_reset:
+   if (info->data->has_bus_rst)
+   reset_control_assert(info->reset);
+
+   return ret;
  }
  
  static int sun4i_gpadc_probe_mfd(struct platform_device *pdev,

@@ -766,6 +837,15 @@ static int