devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Marek Vasut <marex-ynQEQJNshbs@public.gmane.org>
To: Harald Geyer <harald-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>,
	Jonathan Cameron <jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Shawn Guo <shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	Sascha Hauer <kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org>
Cc: Stefan Wahren <stefan.wahren-eS4NqCHxEME@public.gmane.org>,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH 1/3] iio: mxs-lradc: Add regulators for current sources
Date: Fri, 22 Apr 2016 17:50:09 +0200	[thread overview]
Message-ID: <571A4831.2020604@denx.de> (raw)
In-Reply-To: <1461333147-11873-2-git-send-email-harald-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>

On 04/22/2016 03:52 PM, Harald Geyer wrote:
> The hardware has two current sources ISRC0 and ISRC1 to allow measuring
> resistors without additional circuitry. This commit makes them available
> as regulators.
> 
> Tested on an imx233-olinuxino board.
> 
> Signed-off-by: Harald Geyer <harald-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>
> ---
> The current regulator API doesn't fit this type of device very well: Typically
> consumers will want to set a defined current, ie. min_uA == max_uA, but they
> can't without help from configuration data, because the valid values aren't
> reported by the API for current regulators. I have been thinking about
> extending the API, but currently AFAIK no such consumers exist and most
> users, like myself, will force the regulator to a defined value in
> devicetree anyway.

I am tempted to block this patch and ask you to properly split the
mxs-lradc driver into MFD with touchscreen and IIO part and only then
add the regulator bits. The lradc is becoming a katamari of ad-hoc
misplaced functionality.

>  .../bindings/staging/iio/adc/mxs-lradc.txt         |  29 ++++
>  drivers/iio/adc/Kconfig                            |   1 +
>  drivers/iio/adc/mxs-lradc.c                        | 152 +++++++++++++++++++++
>  3 files changed, 182 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
> index 555fb11..983952c 100644
> --- a/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
> +++ b/Documentation/devicetree/bindings/staging/iio/adc/mxs-lradc.txt
> @@ -19,6 +19,15 @@ Optional properties:
>  - fsl,settling: delay between plate switch to next sample. Allowed value is
>                  1 ... 2047. It counts at 2 kHz and its default is
>                  10 (= 5 ms)
> +- ISRC0: A node describing the regulator of internal current source 0
> +- ISRC1: A node describing the regulator of internal current source 1
> +
> +Required properties for the ISRCx sub-nodes:
> +- regulator-max-microamp: See standard regulator binding documentation.
> +                          Valid values are from 0 to 300 in steps of 20.
> +
> +Optional properties for the ISRCx sub-nodes:
> +Any standard regulator properties that apply to current regulators.
>  
>  Example for i.MX23 SoC:
>  
> @@ -31,6 +40,16 @@ Example for i.MX23 SoC:
>  		fsl,ave-ctrl = <4>;
>  		fsl,ave-delay = <2>;
>  		fsl,settling = <10>;
> +
> +		isrc_lradc0: ISRC0 {
> +			regulator-max-microamp = <300>;
> +		};
> +
> +		isrc_lradc1: ISRC1 {
> +			regulator-max-microamp = <120>;
> +			regulator-min-microamp = <120>;
> +			regulator-always-on;
> +		};
>  	};
>  
>  Example for i.MX28 SoC:
> @@ -44,4 +63,14 @@ Example for i.MX28 SoC:
>  		fsl,ave-ctrl = <4>;
>  		fsl,ave-delay = <2>;
>  		fsl,settling = <10>;
> +
> +		isrc_lradc0: ISRC0 {
> +			regulator-max-microamp = <300>;
> +		};
> +
> +		isrc_lradc6: ISRC1 {
> +			regulator-max-microamp = <120>;
> +			regulator-min-microamp = <120>;
> +			regulator-always-on;
> +		};
>  	};
> diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig
> index 5937030..1968d1c 100644
> --- a/drivers/iio/adc/Kconfig
> +++ b/drivers/iio/adc/Kconfig
> @@ -319,6 +319,7 @@ config MXS_LRADC
>          tristate "Freescale i.MX23/i.MX28 LRADC"
>          depends on (ARCH_MXS || COMPILE_TEST) && HAS_IOMEM
>          depends on INPUT
> +        depends on REGULATOR
>          select STMP_DEVICE
>          select IIO_BUFFER
>          select IIO_TRIGGERED_BUFFER
> diff --git a/drivers/iio/adc/mxs-lradc.c b/drivers/iio/adc/mxs-lradc.c
> index 33051b8..f22f339 100644
> --- a/drivers/iio/adc/mxs-lradc.c
> +++ b/drivers/iio/adc/mxs-lradc.c
> @@ -40,6 +40,10 @@
>  #include <linux/iio/triggered_buffer.h>
>  #include <linux/iio/sysfs.h>
>  
> +#include <linux/regulator/driver.h>
> +#include <linux/regulator/machine.h>
> +#include <linux/regulator/of_regulator.h>
> +
>  #define DRIVER_NAME		"mxs-lradc"
>  
>  #define LRADC_MAX_DELAY_CHANS	4
> @@ -261,6 +265,9 @@ struct mxs_lradc {
>  	unsigned		over_sample_delay;
>  	/* time in clocks to wait after the plates where switched */
>  	unsigned		settling_delay;
> +
> +	struct regulator_desc isrc0;
> +	struct regulator_desc isrc1;
>  };
>  
>  #define	LRADC_CTRL0				0x00
> @@ -305,6 +312,11 @@ struct mxs_lradc {
>  #define	LRADC_CTRL2				0x20
>  #define	LRADC_CTRL2_DIVIDE_BY_TWO_OFFSET	24
>  #define	LRADC_CTRL2_TEMPSENSE_PWD		BIT(15)
> +#define	LRADC_CTRL2_TEMP_SENSOR_IENABLE1	BIT(9)
> +#define	LRADC_CTRL2_TEMP_SENSOR_IENABLE0	BIT(8)
> +#define	LRADC_CTRL2_TEMP_ISRC1_OFFSET		4
> +#define	LRADC_CTRL2_TEMP_ISRC0_OFFSET		0
> +#define	LRADC_CTRL2_TEMP_ISRC_MASK		0x0f
>  
>  #define	LRADC_STATUS				0x40
>  #define	LRADC_STATUS_TOUCH_DETECT_RAW		BIT(0)
> @@ -1383,6 +1395,109 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
>  	.validate_scan_mask = &mxs_lradc_validate_scan_mask,
>  };
>  
> +static int mxs_lradc_regulator_is_enabled(struct regulator_dev *dev)
> +{
> +	struct mxs_lradc *lradc = rdev_get_drvdata(dev);
> +	int reg = readl(lradc->base + LRADC_CTRL2);
> +
> +	if (dev->desc == &lradc->isrc0)
> +		return reg & LRADC_CTRL2_TEMP_SENSOR_IENABLE0;
> +	else if (dev->desc == &lradc->isrc1)
> +		return reg & LRADC_CTRL2_TEMP_SENSOR_IENABLE1;
> +
> +	/* This should never happen */
> +	return -ENODEV;
> +}
> +
> +#define LRADC_REGVALUE2uA(regval, offset) \
> +	(20 * ((regval >> offset) & LRADC_CTRL2_TEMP_ISRC_MASK))
> +
> +static int mxs_lradc_regulator_get_current_limit(struct regulator_dev *dev)
> +{
> +	struct mxs_lradc *lradc = rdev_get_drvdata(dev);
> +	int reg = readl(lradc->base + LRADC_CTRL2);
> +
> +	if (dev->desc == &lradc->isrc0)
> +		return LRADC_REGVALUE2uA(reg, LRADC_CTRL2_TEMP_ISRC0_OFFSET);
> +	else if (dev->desc == &lradc->isrc1)
> +		return LRADC_REGVALUE2uA(reg, LRADC_CTRL2_TEMP_ISRC1_OFFSET);
> +
> +	/* This should never happen */
> +	return -ENODEV;
> +}
> +
> +static int mxs_lradc_regulator_enable(struct regulator_dev *dev)
> +{
> +	struct mxs_lradc *lradc = rdev_get_drvdata(dev);
> +
> +	if (dev->desc == &lradc->isrc0)
> +		mxs_lradc_reg_set(lradc, LRADC_CTRL2_TEMP_SENSOR_IENABLE0,
> +				  LRADC_CTRL2);
> +	else if (dev->desc == &lradc->isrc1)
> +		mxs_lradc_reg_set(lradc, LRADC_CTRL2_TEMP_SENSOR_IENABLE1,
> +				  LRADC_CTRL2);
> +	else
> +		/* This should never happen */
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int mxs_lradc_regulator_disable(struct regulator_dev *dev)
> +{
> +	struct mxs_lradc *lradc = rdev_get_drvdata(dev);
> +
> +	if (dev->desc == &lradc->isrc0)
> +		mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_SENSOR_IENABLE0,
> +				    LRADC_CTRL2);
> +	else if (dev->desc == &lradc->isrc1)
> +		mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_SENSOR_IENABLE1,
> +				    LRADC_CTRL2);
> +	else
> +		/* This should never happen */
> +		return -ENODEV;
> +
> +	return 0;
> +}
> +
> +static int mxs_lradc_regulator_set_current_limit(struct regulator_dev *dev,
> +						 int min_uA, int max_uA)
> +{
> +	struct mxs_lradc *lradc = rdev_get_drvdata(dev);
> +	int offset, value;
> +
> +	if (dev->desc == &lradc->isrc0)
> +		offset = LRADC_CTRL2_TEMP_ISRC0_OFFSET;
> +	else if (dev->desc == &lradc->isrc1)
> +		offset = LRADC_CTRL2_TEMP_ISRC1_OFFSET;
> +	else
> +		/* This should never happen */
> +		return -ENODEV;
> +
> +	value = min_uA / 20;
> +	if (min_uA % 20)
> +		value++;
> +	if (value * 20 > max_uA)
> +		return -EINVAL;
> +	if (value & ~LRADC_CTRL2_TEMP_ISRC_MASK)
> +		/* This should never happen */
> +		return -EPERM;
> +
> +	mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_ISRC_MASK << offset,
> +			    LRADC_CTRL2);
> +	mxs_lradc_reg_set(lradc, value << offset, LRADC_CTRL2);
> +
> +	return 0;
> +}
> +
> +static struct regulator_ops mxs_lradc_regulator_current_ops = {
> +	.enable = mxs_lradc_regulator_enable,
> +	.is_enabled = mxs_lradc_regulator_is_enabled,
> +	.disable = mxs_lradc_regulator_disable,
> +	.get_current_limit = mxs_lradc_regulator_get_current_limit,
> +	.set_current_limit = mxs_lradc_regulator_set_current_limit,
> +};
> +
>  /*
>   * Driver initialization
>   */
> @@ -1519,6 +1634,10 @@ static void mxs_lradc_hw_stop(struct mxs_lradc *lradc)
>  
>  	for (i = 0; i < LRADC_MAX_DELAY_CHANS; i++)
>  		mxs_lradc_reg_wrt(lradc, 0, LRADC_DELAY(i));
> +
> +	mxs_lradc_reg_clear(lradc, LRADC_CTRL2_TEMP_SENSOR_IENABLE0 |
> +					LRADC_CTRL2_TEMP_SENSOR_IENABLE1,
> +			    LRADC_CTRL2);
>  }
>  
>  static const struct of_device_id mxs_lradc_dt_ids[] = {
> @@ -1592,6 +1711,32 @@ static int mxs_lradc_probe_touchscreen(struct mxs_lradc *lradc,
>  	return 0;
>  }
>  
> +static void mxs_lradc_reg_helper(struct device_node *np, const char *name,
> +				 struct regulator_config *conf,
> +				 struct regulator_desc *desc)
> +{
> +	struct regulator_dev *ret;
> +
> +	conf->of_node = of_get_child_by_name(np, name);
> +	if (!conf->of_node)
> +		return;
> +
> +	desc->name = name;
> +	desc->owner = THIS_MODULE;
> +	desc->type = REGULATOR_CURRENT;
> +	desc->ops = &mxs_lradc_regulator_current_ops;
> +
> +	conf->init_data = of_get_regulator_init_data(conf->dev, conf->of_node,
> +						     desc);
> +	ret = devm_regulator_register(conf->dev, desc, conf);
> +	if (IS_ERR(ret))
> +		/* Just pretend the regulator isn't there */
> +		dev_err(conf->dev, "Failed to register regulator %s: %ld\n",
> +			desc->name, PTR_ERR(ret));
> +
> +	of_node_put(conf->of_node);
> +}
> +
>  static int mxs_lradc_probe(struct platform_device *pdev)
>  {
>  	const struct of_device_id *of_id =
> @@ -1603,6 +1748,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
>  	struct mxs_lradc *lradc;
>  	struct iio_dev *iio;
>  	struct resource *iores;
> +	struct regulator_config regconf;
>  	int ret = 0, touch_ret;
>  	int i, s;
>  	u64 scale_uv;
> @@ -1727,6 +1873,12 @@ static int mxs_lradc_probe(struct platform_device *pdev)
>  		goto err_ts;
>  	}
>  
> +	/* Setup regulator devices for current source. */
> +	regconf.dev = dev;
> +	regconf.driver_data = lradc;
> +	mxs_lradc_reg_helper(node, "ISRC0", &regconf, &lradc->isrc0);
> +	mxs_lradc_reg_helper(node, "ISRC1", &regconf, &lradc->isrc1);
> +
>  	return 0;
>  
>  err_ts:
> 


-- 
Best regards,
Marek Vasut

  parent reply	other threads:[~2016-04-22 15:50 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-22 13:52 [PATCH 0/3] mxs-lradc: Add support for current sources Harald Geyer
     [not found] ` <1461333147-11873-1-git-send-email-harald-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>
2016-04-22 13:52   ` [PATCH 1/3] iio: mxs-lradc: Add regulators " Harald Geyer
     [not found]     ` <1461333147-11873-2-git-send-email-harald-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>
2016-04-22 15:50       ` Marek Vasut [this message]
     [not found]         ` <571A4831.2020604-ynQEQJNshbs@public.gmane.org>
2016-04-22 17:00           ` Ksenija Stanojević
     [not found]             ` <CAL7P5jKYp0JrF2MHdLkLTBvgYb0KSDwPEMuNPGxcctcxCRnazg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-04-22 19:23               ` Harald Geyer
     [not found]                 ` <f4c00c5c2242f6a951f1f8d8eca56357-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>
2016-04-23 21:08                   ` Jonathan Cameron
2016-04-22 16:11       ` Harald Geyer
2016-05-03 11:07       ` Stefan Wahren
     [not found]         ` <57288674.9050601-eS4NqCHxEME@public.gmane.org>
2016-05-03 11:22           ` Harald Geyer
     [not found]             ` <6cdd4f858dacf72e192a292f29c12feb-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org>
2016-05-04  7:15               ` Jonathan Cameron
     [not found]                 ` <1e7d5f3a-22c1-94d4-9620-7aa112602e39-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2016-05-04 11:38                   ` Harald Geyer
2016-04-22 13:52   ` [PATCH 2/3] ARM: dts: imx23: Provide regulators for the current sources of the LRADC Harald Geyer
2016-04-22 13:52   ` [PATCH 3/3] ARM: dts: imx28: " Harald Geyer
2016-04-29 15:12   ` [PATCH 0/3] mxs-lradc: Add support for current sources Stefan Wahren
     [not found]     ` <572379F5.8000501-eS4NqCHxEME@public.gmane.org>
2016-04-29 17:45       ` Harald Geyer
2016-05-01 18:02         ` Jonathan Cameron
     [not found]           ` <ac57f3e9-f8f2-a6ef-52fa-0a13d7df5d4f-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
2016-05-02 12:25             ` Harald Geyer
2016-05-02 12:29             ` Stefan Wahren

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=571A4831.2020604@denx.de \
    --to=marex-ynqeqjnshbs@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=harald-95f8Dae0BrPYtjvyW6yDsg@public.gmane.org \
    --cc=jic23-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=kernel-bIcnvbaLZ9MEGnE8C9+IrQ@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=shawnguo-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
    --cc=stefan.wahren-eS4NqCHxEME@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).