Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
On 29/03/17 07:54, Quentin Schulz wrote: > Hi, > > On 28/03/2017 19:30, Icenowy Zheng wrote: >> This adds support for the Allwinner H3 thermal sensor. >> >> Allwinner H3 has a thermal sensor like the one in A33, but have its >> registers nearly all re-arranged, sample clock moved to CCU and a pair >> of bus clock and reset added. It's also the base of newer SoCs' thermal >> sensors. >> >> An option is added to gpadc_data struct, to indicate whether this device >> is a new-generation Allwinner thermal sensor. >> >> The thermal sensors on A64 and H5 is like the one on H3, but with of >> course different formula factors. >> >> Signed-off-by: Icenowy Zheng>> --- >> drivers/iio/adc/sun4i-gpadc-iio.c | 130 >> -- >> include/linux/mfd/sun4i-gpadc.h | 33 +- >> 2 files changed, 141 insertions(+), 22 deletions(-) >> >> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c >> b/drivers/iio/adc/sun4i-gpadc-iio.c >> index 74705aa37982..7512b1cae877 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 >> >> @@ -56,6 +58,7 @@ struct gpadc_data { >> unsigned inttp_adc_select; >> unsigned int(*adc_chan_select)(unsigned int chan); >> unsigned intadc_chan_mask; >> +boolgen2_ths; >> }; >> > > Instead of a boolean, give the TEMP_DATA register address. > >> static const struct gpadc_data sun4i_gpadc_data = { >> @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, >> +}; > > Separate patch for this? Indeed, ideal to rework original first (really easy to review) then add support for new part. > >> + >> +static const struct gpadc_data sun8i_h3_gpadc_data = { >> +/* >> + * The original formula on the datasheet seems to be wrong. >> + * These factors are calculated based on the formula in the BSP >> + * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem >> + * is the temperature in Celsius degree and T is the raw value >> + * from the sensor. >> + */ >> +.temp_offset = -1791, >> +.temp_scale = -121, >> +.gen2_ths = true, >> }; >> >> struct sun4i_gpadc_iio { >> @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { >> atomic_tignore_temp_data_irq; >> const struct gpadc_data *data; >> boolno_irq; >> +struct clk *ths_bus_clk; >> +struct clk *ths_clk; >> +struct reset_control*reset; >> /* prevents concurrent reads of temperature and ADC */ >> struct mutexmutex; >> }; >> @@ -274,7 +293,11 @@ 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); >> +if (info->data->gen2_ths) >> +regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, >> +val); >> +else >> +regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); >> > > Instead of gen2_ths, use the TEMP_DATA register address. Agreed. Put a set of register addresses into the gpadc_data structure. Both more flexible and easier to read. > >> pm_runtime_mark_last_busy(indio_dev->dev.parent); >> pm_runtime_put_autosuspend(indio_dev->dev.parent); >> @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct device >> *dev) >> { >> 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 */ >> -regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); >> +if (info->data->gen2_ths) { >> +/* Disable temperature sensor */ >> +regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); >> +} else { >> +/* Disable the ADC on IP */ >> +regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); >> +/* Disable temperature sensor on IP */ >> +regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); >> +} >> > > Either use another register address or add a suspend function to struct > gpadc_data which will be different for each version of the IP. > >> return 0; >> } >> @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
On 29/03/17 07:54, Quentin Schulz wrote: > Hi, > > On 28/03/2017 19:30, Icenowy Zheng wrote: >> This adds support for the Allwinner H3 thermal sensor. >> >> Allwinner H3 has a thermal sensor like the one in A33, but have its >> registers nearly all re-arranged, sample clock moved to CCU and a pair >> of bus clock and reset added. It's also the base of newer SoCs' thermal >> sensors. >> >> An option is added to gpadc_data struct, to indicate whether this device >> is a new-generation Allwinner thermal sensor. >> >> The thermal sensors on A64 and H5 is like the one on H3, but with of >> course different formula factors. >> >> Signed-off-by: Icenowy Zheng >> --- >> drivers/iio/adc/sun4i-gpadc-iio.c | 130 >> -- >> include/linux/mfd/sun4i-gpadc.h | 33 +- >> 2 files changed, 141 insertions(+), 22 deletions(-) >> >> diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c >> b/drivers/iio/adc/sun4i-gpadc-iio.c >> index 74705aa37982..7512b1cae877 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 >> >> @@ -56,6 +58,7 @@ struct gpadc_data { >> unsigned inttp_adc_select; >> unsigned int(*adc_chan_select)(unsigned int chan); >> unsigned intadc_chan_mask; >> +boolgen2_ths; >> }; >> > > Instead of a boolean, give the TEMP_DATA register address. > >> static const struct gpadc_data sun4i_gpadc_data = { >> @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, >> +}; > > Separate patch for this? Indeed, ideal to rework original first (really easy to review) then add support for new part. > >> + >> +static const struct gpadc_data sun8i_h3_gpadc_data = { >> +/* >> + * The original formula on the datasheet seems to be wrong. >> + * These factors are calculated based on the formula in the BSP >> + * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem >> + * is the temperature in Celsius degree and T is the raw value >> + * from the sensor. >> + */ >> +.temp_offset = -1791, >> +.temp_scale = -121, >> +.gen2_ths = true, >> }; >> >> struct sun4i_gpadc_iio { >> @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { >> atomic_tignore_temp_data_irq; >> const struct gpadc_data *data; >> boolno_irq; >> +struct clk *ths_bus_clk; >> +struct clk *ths_clk; >> +struct reset_control*reset; >> /* prevents concurrent reads of temperature and ADC */ >> struct mutexmutex; >> }; >> @@ -274,7 +293,11 @@ 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); >> +if (info->data->gen2_ths) >> +regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, >> +val); >> +else >> +regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); >> > > Instead of gen2_ths, use the TEMP_DATA register address. Agreed. Put a set of register addresses into the gpadc_data structure. Both more flexible and easier to read. > >> pm_runtime_mark_last_busy(indio_dev->dev.parent); >> pm_runtime_put_autosuspend(indio_dev->dev.parent); >> @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct device >> *dev) >> { >> 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 */ >> -regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); >> +if (info->data->gen2_ths) { >> +/* Disable temperature sensor */ >> +regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); >> +} else { >> +/* Disable the ADC on IP */ >> +regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); >> +/* Disable temperature sensor on IP */ >> +regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); >> +} >> > > Either use another register address or add a suspend function to struct > gpadc_data which will be different for each version of the IP. > >> return 0; >> } >> @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device >> *dev) >> { >>
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
On Wed, Mar 29, 2017 at 02:57:02PM +0800, Icenowy Zheng wrote: > > > @@ -691,6 +777,12 @@ static int sun4i_gpadc_remove(struct platform_device > > > *pdev) > > > if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF)) > > > iio_map_array_unregister(indio_dev); > > > > > > + if (info->data->gen2_ths) { > > > + clk_disable_unprepare(info->ths_clk); > > > + clk_disable_unprepare(info->ths_bus_clk); > > > + reset_control_deassert(info->reset); > > > + } > > > + > > > > I'm not really fond of using this boolean as I don't see it being > > possibly reused for any other SoCs that has a GPADC or THS. > > Because you didn't care new SoCs :-) > > All SoCs after H3 (A64, H5, R40) uses the same THS architecture with > H3. That's not really Quentin's point. His point is that having things like flags and/or variables to identify various behaviours that might differ from one SoC to the other usually works better when you want to support several of them. For example, replacing the gen2_ths by one variable with the number of clocks, one with the number of channels, a bool to say it has a reset, etc. definitely works better for us when Allwinner does some mix and match between each SoC. And this happen most of the time. Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
On Wed, Mar 29, 2017 at 02:57:02PM +0800, Icenowy Zheng wrote: > > > @@ -691,6 +777,12 @@ static int sun4i_gpadc_remove(struct platform_device > > > *pdev) > > > if (!info->no_irq && IS_ENABLED(CONFIG_THERMAL_OF)) > > > iio_map_array_unregister(indio_dev); > > > > > > + if (info->data->gen2_ths) { > > > + clk_disable_unprepare(info->ths_clk); > > > + clk_disable_unprepare(info->ths_bus_clk); > > > + reset_control_deassert(info->reset); > > > + } > > > + > > > > I'm not really fond of using this boolean as I don't see it being > > possibly reused for any other SoCs that has a GPADC or THS. > > Because you didn't care new SoCs :-) > > All SoCs after H3 (A64, H5, R40) uses the same THS architecture with > H3. That's not really Quentin's point. His point is that having things like flags and/or variables to identify various behaviours that might differ from one SoC to the other usually works better when you want to support several of them. For example, replacing the gen2_ths by one variable with the number of clocks, one with the number of channels, a bool to say it has a reset, etc. definitely works better for us when Allwinner does some mix and match between each SoC. And this happen most of the time. Maxime -- Maxime Ripard, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com signature.asc Description: PGP signature
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
On Wed, 29 Mar 2017, Icenowy Zheng wrote: > > 2017年3月29日 14:54于 Quentin Schulz写道: > > > > Hi, > > > > On 28/03/2017 19:30, Icenowy Zheng wrote: > > > This adds support for the Allwinner H3 thermal sensor. > > > > > > Allwinner H3 has a thermal sensor like the one in A33, but have its > > > registers nearly all re-arranged, sample clock moved to CCU and a pair > > > of bus clock and reset added. It's also the base of newer SoCs' thermal > > > sensors. > > > > > > An option is added to gpadc_data struct, to indicate whether this device > > > is a new-generation Allwinner thermal sensor. > > > > > > The thermal sensors on A64 and H5 is like the one on H3, but with of > > > course different formula factors. > > > > > > Signed-off-by: Icenowy Zheng > > > --- > > > drivers/iio/adc/sun4i-gpadc-iio.c | 130 > > >-- > > > include/linux/mfd/sun4i-gpadc.h | 33 +- > > > 2 files changed, 141 insertions(+), 22 deletions(-) How have you managed to reply un-threaded? Please ensure you mailer attaches your reply to the rest of the thread, or things will become very confusing, very quickly. > > > diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c > > > b/drivers/iio/adc/sun4i-gpadc-iio.c > > > index 74705aa37982..7512b1cae877 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 > > > > > > @@ -56,6 +58,7 @@ struct gpadc_data { > > > unsigned int tp_adc_select; > > > unsigned int (*adc_chan_select)(unsigned int chan); > > > unsigned int adc_chan_mask; > > > + bool gen2_ths; > > > }; > > > > > > > Instead of a boolean, give the TEMP_DATA register address. > > > > > static const struct gpadc_data sun4i_gpadc_data = { > > > @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, > > > +}; > > > > Separate patch for this? > > > > > + > > > +static const struct gpadc_data sun8i_h3_gpadc_data = { > > > + /* > > > + * The original formula on the datasheet seems to be wrong. > > > + * These factors are calculated based on the formula in the BSP > > > + * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem > > > + * is the temperature in Celsius degree and T is the raw value > > > + * from the sensor. > > > + */ > > > + .temp_offset = -1791, > > > + .temp_scale = -121, > > > + .gen2_ths = true, > > > }; > > > > > > struct sun4i_gpadc_iio { > > > @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { > > > atomic_t ignore_temp_data_irq; > > > const struct gpadc_data *data; > > > bool no_irq; > > > + struct clk *ths_bus_clk; > > > + struct clk *ths_clk; > > > + struct reset_control *reset; > > > /* prevents concurrent reads of temperature and ADC */ > > > struct mutex mutex; > > > }; > > > @@ -274,7 +293,11 @@ 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); > > > + if (info->data->gen2_ths) > > > + regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, > > > + val); > > > + else > > > + regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); > > > > > > > Instead of gen2_ths, use the TEMP_DATA register address. > > > > > pm_runtime_mark_last_busy(indio_dev->dev.parent); > > > pm_runtime_put_autosuspend(indio_dev->dev.parent); > > > @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct > > > device *dev) > > > { > > > 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 */ > > > - regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > > > + if (info->data->gen2_ths) { > > > + /* Disable temperature sensor */ > > > + regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); > > > + } else { > > > + /* Disable the ADC on IP */ > > > + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); > > > + /* Disable temperature sensor on IP */ > > > + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > > > + } > > > > > > > Either use another register address or add a suspend function to struct > > gpadc_data which will be different for each version of the IP. > > > > > return 0; > > > } > > > @@ -398,19 +426,36 @@
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
On Wed, 29 Mar 2017, Icenowy Zheng wrote: > > 2017年3月29日 14:54于 Quentin Schulz 写道: > > > > Hi, > > > > On 28/03/2017 19:30, Icenowy Zheng wrote: > > > This adds support for the Allwinner H3 thermal sensor. > > > > > > Allwinner H3 has a thermal sensor like the one in A33, but have its > > > registers nearly all re-arranged, sample clock moved to CCU and a pair > > > of bus clock and reset added. It's also the base of newer SoCs' thermal > > > sensors. > > > > > > An option is added to gpadc_data struct, to indicate whether this device > > > is a new-generation Allwinner thermal sensor. > > > > > > The thermal sensors on A64 and H5 is like the one on H3, but with of > > > course different formula factors. > > > > > > Signed-off-by: Icenowy Zheng > > > --- > > > drivers/iio/adc/sun4i-gpadc-iio.c | 130 > > >-- > > > include/linux/mfd/sun4i-gpadc.h | 33 +- > > > 2 files changed, 141 insertions(+), 22 deletions(-) How have you managed to reply un-threaded? Please ensure you mailer attaches your reply to the rest of the thread, or things will become very confusing, very quickly. > > > diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c > > > b/drivers/iio/adc/sun4i-gpadc-iio.c > > > index 74705aa37982..7512b1cae877 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 > > > > > > @@ -56,6 +58,7 @@ struct gpadc_data { > > > unsigned int tp_adc_select; > > > unsigned int (*adc_chan_select)(unsigned int chan); > > > unsigned int adc_chan_mask; > > > + bool gen2_ths; > > > }; > > > > > > > Instead of a boolean, give the TEMP_DATA register address. > > > > > static const struct gpadc_data sun4i_gpadc_data = { > > > @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, > > > +}; > > > > Separate patch for this? > > > > > + > > > +static const struct gpadc_data sun8i_h3_gpadc_data = { > > > + /* > > > + * The original formula on the datasheet seems to be wrong. > > > + * These factors are calculated based on the formula in the BSP > > > + * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem > > > + * is the temperature in Celsius degree and T is the raw value > > > + * from the sensor. > > > + */ > > > + .temp_offset = -1791, > > > + .temp_scale = -121, > > > + .gen2_ths = true, > > > }; > > > > > > struct sun4i_gpadc_iio { > > > @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { > > > atomic_t ignore_temp_data_irq; > > > const struct gpadc_data *data; > > > bool no_irq; > > > + struct clk *ths_bus_clk; > > > + struct clk *ths_clk; > > > + struct reset_control *reset; > > > /* prevents concurrent reads of temperature and ADC */ > > > struct mutex mutex; > > > }; > > > @@ -274,7 +293,11 @@ 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); > > > + if (info->data->gen2_ths) > > > + regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, > > > + val); > > > + else > > > + regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); > > > > > > > Instead of gen2_ths, use the TEMP_DATA register address. > > > > > pm_runtime_mark_last_busy(indio_dev->dev.parent); > > > pm_runtime_put_autosuspend(indio_dev->dev.parent); > > > @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct > > > device *dev) > > > { > > > 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 */ > > > - regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > > > + if (info->data->gen2_ths) { > > > + /* Disable temperature sensor */ > > > + regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); > > > + } else { > > > + /* Disable the ADC on IP */ > > > + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); > > > + /* Disable temperature sensor on IP */ > > > + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > > > + } > > > > > > > Either use another register address or add a suspend function to struct > > gpadc_data which will be different for each version of the IP. > > > > > return 0; > > > } > > > @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device > >
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
Hi, On 28/03/2017 19:30, Icenowy Zheng wrote: > This adds support for the Allwinner H3 thermal sensor. > > Allwinner H3 has a thermal sensor like the one in A33, but have its > registers nearly all re-arranged, sample clock moved to CCU and a pair > of bus clock and reset added. It's also the base of newer SoCs' thermal > sensors. > > An option is added to gpadc_data struct, to indicate whether this device > is a new-generation Allwinner thermal sensor. > > The thermal sensors on A64 and H5 is like the one on H3, but with of > course different formula factors. > > Signed-off-by: Icenowy Zheng> --- > drivers/iio/adc/sun4i-gpadc-iio.c | 130 > -- > include/linux/mfd/sun4i-gpadc.h | 33 +- > 2 files changed, 141 insertions(+), 22 deletions(-) > > diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c > b/drivers/iio/adc/sun4i-gpadc-iio.c > index 74705aa37982..7512b1cae877 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 > > @@ -56,6 +58,7 @@ struct gpadc_data { > unsigned inttp_adc_select; > unsigned int(*adc_chan_select)(unsigned int chan); > unsigned intadc_chan_mask; > + boolgen2_ths; > }; > Instead of a boolean, give the TEMP_DATA register address. > static const struct gpadc_data sun4i_gpadc_data = { > @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, > +}; Separate patch for this? > + > +static const struct gpadc_data sun8i_h3_gpadc_data = { > + /* > + * The original formula on the datasheet seems to be wrong. > + * These factors are calculated based on the formula in the BSP > + * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem > + * is the temperature in Celsius degree and T is the raw value > + * from the sensor. > + */ > + .temp_offset = -1791, > + .temp_scale = -121, > + .gen2_ths = true, > }; > > struct sun4i_gpadc_iio { > @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { > atomic_tignore_temp_data_irq; > const struct gpadc_data *data; > boolno_irq; > + struct clk *ths_bus_clk; > + struct clk *ths_clk; > + struct reset_control*reset; > /* prevents concurrent reads of temperature and ADC */ > struct mutexmutex; > }; > @@ -274,7 +293,11 @@ 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); > + if (info->data->gen2_ths) > + regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, > + val); > + else > + regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); > Instead of gen2_ths, use the TEMP_DATA register address. > pm_runtime_mark_last_busy(indio_dev->dev.parent); > pm_runtime_put_autosuspend(indio_dev->dev.parent); > @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct device > *dev) > { > 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 */ > - regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > + if (info->data->gen2_ths) { > + /* Disable temperature sensor */ > + regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); > + } else { > + /* Disable the ADC on IP */ > + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); > + /* Disable temperature sensor on IP */ > + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > + } > Either use another register address or add a suspend function to struct gpadc_data which will be different for each version of the IP. > return 0; > } > @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device > *dev) > { > struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev)); > > - /* clkin = 6MHz */ > - regmap_write(info->regmap, SUN4I_GPADC_CTRL0, > - SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) | > - SUN4I_GPADC_CTRL0_FS_DIV(7) | > - SUN4I_GPADC_CTRL0_T_ACQ(63)); > -
Re: [RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
Hi, On 28/03/2017 19:30, Icenowy Zheng wrote: > This adds support for the Allwinner H3 thermal sensor. > > Allwinner H3 has a thermal sensor like the one in A33, but have its > registers nearly all re-arranged, sample clock moved to CCU and a pair > of bus clock and reset added. It's also the base of newer SoCs' thermal > sensors. > > An option is added to gpadc_data struct, to indicate whether this device > is a new-generation Allwinner thermal sensor. > > The thermal sensors on A64 and H5 is like the one on H3, but with of > course different formula factors. > > Signed-off-by: Icenowy Zheng > --- > drivers/iio/adc/sun4i-gpadc-iio.c | 130 > -- > include/linux/mfd/sun4i-gpadc.h | 33 +- > 2 files changed, 141 insertions(+), 22 deletions(-) > > diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c > b/drivers/iio/adc/sun4i-gpadc-iio.c > index 74705aa37982..7512b1cae877 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 > > @@ -56,6 +58,7 @@ struct gpadc_data { > unsigned inttp_adc_select; > unsigned int(*adc_chan_select)(unsigned int chan); > unsigned intadc_chan_mask; > + boolgen2_ths; > }; > Instead of a boolean, give the TEMP_DATA register address. > static const struct gpadc_data sun4i_gpadc_data = { > @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, > +}; Separate patch for this? > + > +static const struct gpadc_data sun8i_h3_gpadc_data = { > + /* > + * The original formula on the datasheet seems to be wrong. > + * These factors are calculated based on the formula in the BSP > + * kernel, which is originally Tem = 217 - (T / 8.253), in which Tem > + * is the temperature in Celsius degree and T is the raw value > + * from the sensor. > + */ > + .temp_offset = -1791, > + .temp_scale = -121, > + .gen2_ths = true, > }; > > struct sun4i_gpadc_iio { > @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { > atomic_tignore_temp_data_irq; > const struct gpadc_data *data; > boolno_irq; > + struct clk *ths_bus_clk; > + struct clk *ths_clk; > + struct reset_control*reset; > /* prevents concurrent reads of temperature and ADC */ > struct mutexmutex; > }; > @@ -274,7 +293,11 @@ 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); > + if (info->data->gen2_ths) > + regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, > + val); > + else > + regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); > Instead of gen2_ths, use the TEMP_DATA register address. > pm_runtime_mark_last_busy(indio_dev->dev.parent); > pm_runtime_put_autosuspend(indio_dev->dev.parent); > @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct device > *dev) > { > 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 */ > - regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > + if (info->data->gen2_ths) { > + /* Disable temperature sensor */ > + regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); > + } else { > + /* Disable the ADC on IP */ > + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); > + /* Disable temperature sensor on IP */ > + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); > + } > Either use another register address or add a suspend function to struct gpadc_data which will be different for each version of the IP. > return 0; > } > @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device > *dev) > { > struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev)); > > - /* clkin = 6MHz */ > - regmap_write(info->regmap, SUN4I_GPADC_CTRL0, > - SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) | > - SUN4I_GPADC_CTRL0_FS_DIV(7) | > - SUN4I_GPADC_CTRL0_T_ACQ(63)); > -
[RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
This adds support for the Allwinner H3 thermal sensor. Allwinner H3 has a thermal sensor like the one in A33, but have its registers nearly all re-arranged, sample clock moved to CCU and a pair of bus clock and reset added. It's also the base of newer SoCs' thermal sensors. An option is added to gpadc_data struct, to indicate whether this device is a new-generation Allwinner thermal sensor. The thermal sensors on A64 and H5 is like the one on H3, but with of course different formula factors. Signed-off-by: Icenowy Zheng--- drivers/iio/adc/sun4i-gpadc-iio.c | 130 -- include/linux/mfd/sun4i-gpadc.h | 33 +- 2 files changed, 141 insertions(+), 22 deletions(-) diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index 74705aa37982..7512b1cae877 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 @@ -56,6 +58,7 @@ struct gpadc_data { unsigned inttp_adc_select; unsigned int(*adc_chan_select)(unsigned int chan); unsigned intadc_chan_mask; + boolgen2_ths; }; static const struct gpadc_data sun4i_gpadc_data = { @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, +}; + +static const struct gpadc_data sun8i_h3_gpadc_data = { + /* +* The original formula on the datasheet seems to be wrong. +* These factors are calculated based on the formula in the BSP +* kernel, which is originally Tem = 217 - (T / 8.253), in which Tem +* is the temperature in Celsius degree and T is the raw value +* from the sensor. +*/ + .temp_offset = -1791, + .temp_scale = -121, + .gen2_ths = true, }; struct sun4i_gpadc_iio { @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { atomic_tignore_temp_data_irq; const struct gpadc_data *data; boolno_irq; + struct clk *ths_bus_clk; + struct clk *ths_clk; + struct reset_control*reset; /* prevents concurrent reads of temperature and ADC */ struct mutexmutex; }; @@ -274,7 +293,11 @@ 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); + if (info->data->gen2_ths) + regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, + val); + else + regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); pm_runtime_mark_last_busy(indio_dev->dev.parent); pm_runtime_put_autosuspend(indio_dev->dev.parent); @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev) { 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 */ - regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); + if (info->data->gen2_ths) { + /* Disable temperature sensor */ + regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); + } else { + /* Disable the ADC on IP */ + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); + /* Disable temperature sensor on IP */ + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); + } return 0; } @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device *dev) { struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev)); - /* clkin = 6MHz */ - regmap_write(info->regmap, SUN4I_GPADC_CTRL0, -SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) | -SUN4I_GPADC_CTRL0_FS_DIV(7) | -SUN4I_GPADC_CTRL0_T_ACQ(63)); - regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en); - regmap_write(info->regmap, SUN4I_GPADC_CTRL3, -SUN4I_GPADC_CTRL3_FILTER_EN | -SUN4I_GPADC_CTRL3_FILTER_TYPE(1)); - /* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */ - regmap_write(info->regmap, SUN4I_GPADC_TPR, -SUN4I_GPADC_TPR_TEMP_ENABLE | -SUN4I_GPADC_TPR_TEMP_PERIOD(800)); +
[RFC PATCH 2/3] iio: adc: sun4i-gpadc-iio: add support for H3 thermal sensor
This adds support for the Allwinner H3 thermal sensor. Allwinner H3 has a thermal sensor like the one in A33, but have its registers nearly all re-arranged, sample clock moved to CCU and a pair of bus clock and reset added. It's also the base of newer SoCs' thermal sensors. An option is added to gpadc_data struct, to indicate whether this device is a new-generation Allwinner thermal sensor. The thermal sensors on A64 and H5 is like the one on H3, but with of course different formula factors. Signed-off-by: Icenowy Zheng --- drivers/iio/adc/sun4i-gpadc-iio.c | 130 -- include/linux/mfd/sun4i-gpadc.h | 33 +- 2 files changed, 141 insertions(+), 22 deletions(-) diff --git a/drivers/iio/adc/sun4i-gpadc-iio.c b/drivers/iio/adc/sun4i-gpadc-iio.c index 74705aa37982..7512b1cae877 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 @@ -56,6 +58,7 @@ struct gpadc_data { unsigned inttp_adc_select; unsigned int(*adc_chan_select)(unsigned int chan); unsigned intadc_chan_mask; + boolgen2_ths; }; static const struct gpadc_data sun4i_gpadc_data = { @@ -88,7 +91,20 @@ 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_A23_GPADC_CTRL1_CHOP_TEMP_EN, +}; + +static const struct gpadc_data sun8i_h3_gpadc_data = { + /* +* The original formula on the datasheet seems to be wrong. +* These factors are calculated based on the formula in the BSP +* kernel, which is originally Tem = 217 - (T / 8.253), in which Tem +* is the temperature in Celsius degree and T is the raw value +* from the sensor. +*/ + .temp_offset = -1791, + .temp_scale = -121, + .gen2_ths = true, }; struct sun4i_gpadc_iio { @@ -103,6 +119,9 @@ struct sun4i_gpadc_iio { atomic_tignore_temp_data_irq; const struct gpadc_data *data; boolno_irq; + struct clk *ths_bus_clk; + struct clk *ths_clk; + struct reset_control*reset; /* prevents concurrent reads of temperature and ADC */ struct mutexmutex; }; @@ -274,7 +293,11 @@ 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); + if (info->data->gen2_ths) + regmap_read(info->regmap, SUN8I_H3_GPADC_TEMP_DATA, + val); + else + regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, val); pm_runtime_mark_last_busy(indio_dev->dev.parent); pm_runtime_put_autosuspend(indio_dev->dev.parent); @@ -386,10 +409,15 @@ static int sun4i_gpadc_runtime_suspend(struct device *dev) { 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 */ - regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); + if (info->data->gen2_ths) { + /* Disable temperature sensor */ + regmap_write(info->regmap, SUN8I_H3_GPADC_CTRL2, 0); + } else { + /* Disable the ADC on IP */ + regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0); + /* Disable temperature sensor on IP */ + regmap_write(info->regmap, SUN4I_GPADC_TPR, 0); + } return 0; } @@ -398,19 +426,36 @@ static int sun4i_gpadc_runtime_resume(struct device *dev) { struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev)); - /* clkin = 6MHz */ - regmap_write(info->regmap, SUN4I_GPADC_CTRL0, -SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) | -SUN4I_GPADC_CTRL0_FS_DIV(7) | -SUN4I_GPADC_CTRL0_T_ACQ(63)); - regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en); - regmap_write(info->regmap, SUN4I_GPADC_CTRL3, -SUN4I_GPADC_CTRL3_FILTER_EN | -SUN4I_GPADC_CTRL3_FILTER_TYPE(1)); - /* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */ - regmap_write(info->regmap, SUN4I_GPADC_TPR, -SUN4I_GPADC_TPR_TEMP_ENABLE | -SUN4I_GPADC_TPR_TEMP_PERIOD(800)); + if