All of lore.kernel.org
 help / color / mirror / Atom feed
From: lee.jones@linaro.org (Lee Jones)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 14/23] regulator: ab3100: device tree support
Date: Mon, 22 Apr 2013 11:47:36 +0100	[thread overview]
Message-ID: <20130422104736.GM3432@gmail.com> (raw)
In-Reply-To: <1366624645-6614-1-git-send-email-linus.walleij@stericsson.com>

On Mon, 22 Apr 2013, Linus Walleij wrote:

> From: Linus Walleij <linus.walleij@linaro.org>
> 
> This implements device tree support for the AB3100 regulators
> driver. The initial settings are moved out of platform data
> and into the driver for the device tree case, as it appears
> that there is no way to supply this as AUXDATA for an I2C
> device. The style and bindings are heavily inspired by
> Lee Jones' style for AB8500.
> 
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Mark Brown <broonie@kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

I don't see any issues with it.

Acked-by: Lee Jones <lee.jones@linaro.org>

> ---
> Hi Mark, seeking an ACK on this to take it through the ARM
> SoC tree.
> ---
>  drivers/mfd/ab3100-core.c  |   1 +
>  drivers/regulator/ab3100.c | 123 ++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 118 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
> index 2ec7725..a9bb140 100644
> --- a/drivers/mfd/ab3100-core.c
> +++ b/drivers/mfd/ab3100-core.c
> @@ -753,6 +753,7 @@ static struct mfd_cell ab3100_devs[] = {
>  	},
>  	{
>  		.name = "ab3100-regulators",
> +		.of_compatible = "stericsson,ab3100-regulators",
>  		.id = -1,
>  	},
>  	{
> diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
> index 740735d..be1e6ad 100644
> --- a/drivers/regulator/ab3100.c
> +++ b/drivers/regulator/ab3100.c
> @@ -17,6 +17,8 @@
>  #include <linux/regulator/driver.h>
>  #include <linux/mfd/ab3100.h>
>  #include <linux/mfd/abx500.h>
> +#include <linux/of.h>
> +#include <linux/regulator/of_regulator.h>
>  
>  /* LDO registers and some handy masking definitions for AB3100 */
>  #define AB3100_LDO_A		0x40
> @@ -345,7 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
>  {
>  	struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
>  
> -	return abreg->plfdata->external_voltage;
> +	if (abreg->plfdata)
> +		return abreg->plfdata->external_voltage;
> +	else
> +		/* TODO: encode external voltage into device tree */
> +		return 0;
>  }
>  
>  static struct regulator_ops regulator_ops_fixed = {
> @@ -490,6 +496,8 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
>  
>  static int ab3100_regulator_register(struct platform_device *pdev,
>  				     struct ab3100_platform_data *plfdata,
> +				     struct regulator_init_data *init_data,
> +				     struct device_node *np,
>  				     int id)
>  {
>  	struct regulator_desc *desc;
> @@ -518,9 +526,11 @@ static int ab3100_regulator_register(struct platform_device *pdev,
>  	 */
>  	reg->dev = &pdev->dev;
>  	if (plfdata) {
> -		/* This will be replaced by device tree data */
>  		reg->plfdata = plfdata;
>  		config.init_data = &plfdata->reg_constraints[i];
> +	} else if (np) {
> +		config.of_node = np;
> +		config.init_data = init_data;
>  	}
>  	config.dev = &pdev->dev;
>  	config.driver_data = reg;
> @@ -540,15 +550,103 @@ static int ab3100_regulator_register(struct platform_device *pdev,
>  	return 0;
>  }
>  
> +static struct of_regulator_match ab3100_regulator_matches[] = {
> +	{ .name = "ab3100_ldo_a", .driver_data = (void *) AB3100_LDO_A, },
> +	{ .name = "ab3100_ldo_c", .driver_data = (void *) AB3100_LDO_C, },
> +	{ .name = "ab3100_ldo_d", .driver_data = (void *) AB3100_LDO_D, },
> +	{ .name = "ab3100_ldo_e", .driver_data = (void *) AB3100_LDO_E, },
> +	{ .name = "ab3100_ldo_f", .driver_data = (void *) AB3100_LDO_F },
> +	{ .name = "ab3100_ldo_g", .driver_data = (void *) AB3100_LDO_G },
> +	{ .name = "ab3100_ldo_h", .driver_data = (void *) AB3100_LDO_H },
> +	{ .name = "ab3100_ldo_k", .driver_data = (void *) AB3100_LDO_K },
> +	{ .name = "ab3100_ext", .driver_data = (void *) AB3100_LDO_EXT },
> +	{ .name = "ab3100_buck", .driver_data = (void *) AB3100_BUCK },
> +};
> +
>  /*
> - * NOTE: the following functions are regulators pluralis - it is the
> - * binding to the AB3100 core driver and the parent platform device
> - * for all the different regulators.
> + * Initial settings of ab3100 registers.
> + * Common for below LDO regulator settings are that
> + * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
> + * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
>   */
> +/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
> +#define LDO_A_SETTING		0x16
> +/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
> +#define LDO_C_SETTING		0x10
> +/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
> +#define LDO_D_SETTING		0x10
> +/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
> +#define LDO_E_SETTING		0x10
> +/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
> +#define LDO_E_SLEEP_SETTING	0x00
> +/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
> +#define LDO_F_SETTING		0xD0
> +/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
> +#define LDO_G_SETTING		0x00
> +/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
> +#define LDO_H_SETTING		0x18
> +/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
> +#define LDO_K_SETTING		0x00
> +/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
> +#define LDO_EXT_SETTING		0x00
> +/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
> +#define BUCK_SETTING	0x7D
> +/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
> +#define BUCK_SLEEP_SETTING	0xAC
> +
> +static const u8 ab3100_reg_initvals[] = {
> +	LDO_A_SETTING,
> +	LDO_C_SETTING,
> +	LDO_E_SETTING,
> +	LDO_E_SLEEP_SETTING,
> +	LDO_F_SETTING,
> +	LDO_G_SETTING,
> +	LDO_H_SETTING,
> +	LDO_K_SETTING,
> +	LDO_EXT_SETTING,
> +	BUCK_SETTING,
> +	BUCK_SLEEP_SETTING,
> +	LDO_D_SETTING,
> +};
> +
> +static int
> +ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
> +{
> +	int err, i;
> +
> +	/*
> +	 * Set up the regulator registers, as was previously done with
> +	 * platform data.
> +	 */
> +	/* Set up regulators */
> +	for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
> +		err = abx500_set_register_interruptible(&pdev->dev, 0,
> +					ab3100_reg_init_order[i],
> +					ab3100_reg_initvals[i]);
> +		if (err) {
> +			dev_err(&pdev->dev, "regulator initialization failed with error %d\n",
> +				err);
> +			return err;
> +		}
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(ab3100_regulator_matches); i++) {
> +		err = ab3100_regulator_register(
> +			pdev, NULL, ab3100_regulator_matches[i].init_data,
> +			ab3100_regulator_matches[i].of_node,
> +			(int) ab3100_regulator_matches[i].driver_data);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
>  
>  static int ab3100_regulators_probe(struct platform_device *pdev)
>  {
>  	struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
> +	struct device_node *np = pdev->dev.of_node;
>  	int err = 0;
>  	u8 data;
>  	int i;
> @@ -567,6 +665,18 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
>  		dev_notice(&pdev->dev,
>  			   "chip is in inactive mode (Cold start)\n");
>  
> +	if (np) {
> +		err = of_regulator_match(&pdev->dev, np,
> +					 ab3100_regulator_matches,
> +					 ARRAY_SIZE(ab3100_regulator_matches));
> +		if (err < 0) {
> +			dev_err(&pdev->dev,
> +				"Error parsing regulator init data: %d\n", err);
> +			return err;
> +		}
> +		return ab3100_regulator_of_probe(pdev, np);
> +	}
> +
>  	/* Set up regulators */
>  	for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
>  		err = abx500_set_register_interruptible(&pdev->dev, 0,
> @@ -583,7 +693,8 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
>  	for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
>  		struct regulator_desc *desc = &ab3100_regulator_desc[i];
>  
> -		err = ab3100_regulator_register(pdev, plfdata, desc->id);
> +		err = ab3100_regulator_register(pdev, plfdata, NULL, NULL,
> +						desc->id);
>  		if (err)
>  			return err;
>  	}

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

WARNING: multiple messages have this Message-ID (diff)
From: Lee Jones <lee.jones-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
To: Linus Walleij <linus.walleij-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org>
Cc: devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org,
	Liam Girdwood <lgirdwood-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Mark Brown <broonie-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH 14/23] regulator: ab3100: device tree support
Date: Mon, 22 Apr 2013 11:47:36 +0100	[thread overview]
Message-ID: <20130422104736.GM3432@gmail.com> (raw)
In-Reply-To: <1366624645-6614-1-git-send-email-linus.walleij-0IS4wlFg1OjSUeElwK9/Pw@public.gmane.org>

On Mon, 22 Apr 2013, Linus Walleij wrote:

> From: Linus Walleij <linus.walleij@linaro.org>
> 
> This implements device tree support for the AB3100 regulators
> driver. The initial settings are moved out of platform data
> and into the driver for the device tree case, as it appears
> that there is no way to supply this as AUXDATA for an I2C
> device. The style and bindings are heavily inspired by
> Lee Jones' style for AB8500.
> 
> Cc: Lee Jones <lee.jones@linaro.org>
> Cc: Mark Brown <broonie@kernel.org>
> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

I don't see any issues with it.

Acked-by: Lee Jones <lee.jones@linaro.org>

> ---
> Hi Mark, seeking an ACK on this to take it through the ARM
> SoC tree.
> ---
>  drivers/mfd/ab3100-core.c  |   1 +
>  drivers/regulator/ab3100.c | 123 ++++++++++++++++++++++++++++++++++++++++++---
>  2 files changed, 118 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
> index 2ec7725..a9bb140 100644
> --- a/drivers/mfd/ab3100-core.c
> +++ b/drivers/mfd/ab3100-core.c
> @@ -753,6 +753,7 @@ static struct mfd_cell ab3100_devs[] = {
>  	},
>  	{
>  		.name = "ab3100-regulators",
> +		.of_compatible = "stericsson,ab3100-regulators",
>  		.id = -1,
>  	},
>  	{
> diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
> index 740735d..be1e6ad 100644
> --- a/drivers/regulator/ab3100.c
> +++ b/drivers/regulator/ab3100.c
> @@ -17,6 +17,8 @@
>  #include <linux/regulator/driver.h>
>  #include <linux/mfd/ab3100.h>
>  #include <linux/mfd/abx500.h>
> +#include <linux/of.h>
> +#include <linux/regulator/of_regulator.h>
>  
>  /* LDO registers and some handy masking definitions for AB3100 */
>  #define AB3100_LDO_A		0x40
> @@ -345,7 +347,11 @@ static int ab3100_get_voltage_regulator_external(struct regulator_dev *reg)
>  {
>  	struct ab3100_regulator *abreg = rdev_get_drvdata(reg);
>  
> -	return abreg->plfdata->external_voltage;
> +	if (abreg->plfdata)
> +		return abreg->plfdata->external_voltage;
> +	else
> +		/* TODO: encode external voltage into device tree */
> +		return 0;
>  }
>  
>  static struct regulator_ops regulator_ops_fixed = {
> @@ -490,6 +496,8 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = {
>  
>  static int ab3100_regulator_register(struct platform_device *pdev,
>  				     struct ab3100_platform_data *plfdata,
> +				     struct regulator_init_data *init_data,
> +				     struct device_node *np,
>  				     int id)
>  {
>  	struct regulator_desc *desc;
> @@ -518,9 +526,11 @@ static int ab3100_regulator_register(struct platform_device *pdev,
>  	 */
>  	reg->dev = &pdev->dev;
>  	if (plfdata) {
> -		/* This will be replaced by device tree data */
>  		reg->plfdata = plfdata;
>  		config.init_data = &plfdata->reg_constraints[i];
> +	} else if (np) {
> +		config.of_node = np;
> +		config.init_data = init_data;
>  	}
>  	config.dev = &pdev->dev;
>  	config.driver_data = reg;
> @@ -540,15 +550,103 @@ static int ab3100_regulator_register(struct platform_device *pdev,
>  	return 0;
>  }
>  
> +static struct of_regulator_match ab3100_regulator_matches[] = {
> +	{ .name = "ab3100_ldo_a", .driver_data = (void *) AB3100_LDO_A, },
> +	{ .name = "ab3100_ldo_c", .driver_data = (void *) AB3100_LDO_C, },
> +	{ .name = "ab3100_ldo_d", .driver_data = (void *) AB3100_LDO_D, },
> +	{ .name = "ab3100_ldo_e", .driver_data = (void *) AB3100_LDO_E, },
> +	{ .name = "ab3100_ldo_f", .driver_data = (void *) AB3100_LDO_F },
> +	{ .name = "ab3100_ldo_g", .driver_data = (void *) AB3100_LDO_G },
> +	{ .name = "ab3100_ldo_h", .driver_data = (void *) AB3100_LDO_H },
> +	{ .name = "ab3100_ldo_k", .driver_data = (void *) AB3100_LDO_K },
> +	{ .name = "ab3100_ext", .driver_data = (void *) AB3100_LDO_EXT },
> +	{ .name = "ab3100_buck", .driver_data = (void *) AB3100_BUCK },
> +};
> +
>  /*
> - * NOTE: the following functions are regulators pluralis - it is the
> - * binding to the AB3100 core driver and the parent platform device
> - * for all the different regulators.
> + * Initial settings of ab3100 registers.
> + * Common for below LDO regulator settings are that
> + * bit 7-5 controls voltage. Bit 4 turns regulator ON(1) or OFF(0).
> + * Bit 3-2 controls sleep enable and bit 1-0 controls sleep mode.
>   */
> +/* LDO_A 0x16: 2.75V, ON, SLEEP_A, SLEEP OFF GND */
> +#define LDO_A_SETTING		0x16
> +/* LDO_C 0x10: 2.65V, ON, SLEEP_A or B, SLEEP full power */
> +#define LDO_C_SETTING		0x10
> +/* LDO_D 0x10: 2.65V, ON, sleep mode not used */
> +#define LDO_D_SETTING		0x10
> +/* LDO_E 0x10: 1.8V, ON, SLEEP_A or B, SLEEP full power */
> +#define LDO_E_SETTING		0x10
> +/* LDO_E SLEEP 0x00: 1.8V, not used, SLEEP_A or B, not used */
> +#define LDO_E_SLEEP_SETTING	0x00
> +/* LDO_F 0xD0: 2.5V, ON, SLEEP_A or B, SLEEP full power */
> +#define LDO_F_SETTING		0xD0
> +/* LDO_G 0x00: 2.85V, OFF, SLEEP_A or B, SLEEP full power */
> +#define LDO_G_SETTING		0x00
> +/* LDO_H 0x18: 2.75V, ON, SLEEP_B, SLEEP full power */
> +#define LDO_H_SETTING		0x18
> +/* LDO_K 0x00: 2.75V, OFF, SLEEP_A or B, SLEEP full power */
> +#define LDO_K_SETTING		0x00
> +/* LDO_EXT 0x00: Voltage not set, OFF, not used, not used */
> +#define LDO_EXT_SETTING		0x00
> +/* BUCK 0x7D: 1.2V, ON, SLEEP_A and B, SLEEP low power */
> +#define BUCK_SETTING	0x7D
> +/* BUCK SLEEP 0xAC: 1.05V, Not used, SLEEP_A and B, Not used */
> +#define BUCK_SLEEP_SETTING	0xAC
> +
> +static const u8 ab3100_reg_initvals[] = {
> +	LDO_A_SETTING,
> +	LDO_C_SETTING,
> +	LDO_E_SETTING,
> +	LDO_E_SLEEP_SETTING,
> +	LDO_F_SETTING,
> +	LDO_G_SETTING,
> +	LDO_H_SETTING,
> +	LDO_K_SETTING,
> +	LDO_EXT_SETTING,
> +	BUCK_SETTING,
> +	BUCK_SLEEP_SETTING,
> +	LDO_D_SETTING,
> +};
> +
> +static int
> +ab3100_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
> +{
> +	int err, i;
> +
> +	/*
> +	 * Set up the regulator registers, as was previously done with
> +	 * platform data.
> +	 */
> +	/* Set up regulators */
> +	for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
> +		err = abx500_set_register_interruptible(&pdev->dev, 0,
> +					ab3100_reg_init_order[i],
> +					ab3100_reg_initvals[i]);
> +		if (err) {
> +			dev_err(&pdev->dev, "regulator initialization failed with error %d\n",
> +				err);
> +			return err;
> +		}
> +	}
> +
> +	for (i = 0; i < ARRAY_SIZE(ab3100_regulator_matches); i++) {
> +		err = ab3100_regulator_register(
> +			pdev, NULL, ab3100_regulator_matches[i].init_data,
> +			ab3100_regulator_matches[i].of_node,
> +			(int) ab3100_regulator_matches[i].driver_data);
> +		if (err)
> +			return err;
> +	}
> +
> +	return 0;
> +}
> +
>  
>  static int ab3100_regulators_probe(struct platform_device *pdev)
>  {
>  	struct ab3100_platform_data *plfdata = pdev->dev.platform_data;
> +	struct device_node *np = pdev->dev.of_node;
>  	int err = 0;
>  	u8 data;
>  	int i;
> @@ -567,6 +665,18 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
>  		dev_notice(&pdev->dev,
>  			   "chip is in inactive mode (Cold start)\n");
>  
> +	if (np) {
> +		err = of_regulator_match(&pdev->dev, np,
> +					 ab3100_regulator_matches,
> +					 ARRAY_SIZE(ab3100_regulator_matches));
> +		if (err < 0) {
> +			dev_err(&pdev->dev,
> +				"Error parsing regulator init data: %d\n", err);
> +			return err;
> +		}
> +		return ab3100_regulator_of_probe(pdev, np);
> +	}
> +
>  	/* Set up regulators */
>  	for (i = 0; i < ARRAY_SIZE(ab3100_reg_init_order); i++) {
>  		err = abx500_set_register_interruptible(&pdev->dev, 0,
> @@ -583,7 +693,8 @@ static int ab3100_regulators_probe(struct platform_device *pdev)
>  	for (i = 0; i < AB3100_NUM_REGULATORS; i++) {
>  		struct regulator_desc *desc = &ab3100_regulator_desc[i];
>  
> -		err = ab3100_regulator_register(pdev, plfdata, desc->id);
> +		err = ab3100_regulator_register(pdev, plfdata, NULL, NULL,
> +						desc->id);
>  		if (err)
>  			return err;
>  	}

-- 
Lee Jones
Linaro ST-Ericsson Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss@lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

  reply	other threads:[~2013-04-22 10:47 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-04-22  9:57 [PATCH 14/23] regulator: ab3100: device tree support Linus Walleij
2013-04-22  9:57 ` Linus Walleij
2013-04-22 10:47 ` Lee Jones [this message]
2013-04-22 10:47   ` Lee Jones
2013-04-24  9:54 ` Mark Brown
2013-04-24  9:54   ` Mark Brown

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=20130422104736.GM3432@gmail.com \
    --to=lee.jones@linaro.org \
    --cc=linux-arm-kernel@lists.infradead.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.