
Hello Robert,
On 03/10/2015 12:41 PM, Robert Baldyga wrote:
Hi,
On 03/03/2015 05:24 PM, Przemyslaw Marczak wrote:
This is the implementation of driver model regulator uclass api. To use it, the CONFIG_DM_PMIC is required with driver implementation, since it provides pmic devices basic I/O API.
The regulator framework is based on a 'struct dm_regulator_ops'. It provides a common function calls, for it's basic features:
- regulator_get_cnt() - number of outputs each type
- regulator_get_value_desc() - describe output value limits
- regulator_get_mode_desc() - describe output operation modes
- regulator_get/set_value() - output value (uV)
- regulator_get/set_state() - output on/off state
- regulator_get/set_mode() - output operation mode
To get the regulator device:
- regulator_get() - by name only
- regulator_i2c_get() - by i2c bus address (of pmic parent)
- regulator_spi_get() - by spi bus address (of pmic parent)
An optional and useful regulator framework features are two descriptors:
struct regulator_desc - describes the regulator name and output value limits should be defined by device driver for each regulator output.
struct regulator_mode_desc - (array) describes a number of operation modes supported by each regulator output.
The regulator framework features are described in file:
- include/power/regulator.h
Main files:
- drivers/power/regulator-uclass.c - provides regulator common functions api
- include/power/regulator.h - define all structures required by the regulator
Changes:
- new uclass-id: UCLASS_PMIC_REGULATOR
- new config: CONFIG_DM_REGULATOR
Signed-off-by: Przemyslaw Marczak p.marczak@samsung.com
Changes V2:
- new operations for regulator uclass:
-- get/set output state - for output on/off setting --- add enum: REGULATOR_OFF, REGULATOR_ON
- regulator uclass code rework and cleanup:
-- change name of: --- enum 'regulator_desc_type' to 'regulator_type' --- add type DVS --- struct 'regulator_desc' to 'regulator_value_desc'
-- regulator ops function calls: --- remove 'ldo/buck' from naming --- add new argument 'type' for define regulator type
-- regulator.h - update comments
drivers/power/Makefile | 1 + drivers/power/regulator-uclass.c | 227 ++++++++++++++++++++++++++++ include/dm/uclass-id.h | 1 + include/power/regulator.h | 310 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 539 insertions(+) create mode 100644 drivers/power/regulator-uclass.c create mode 100644 include/power/regulator.h
diff --git a/drivers/power/Makefile b/drivers/power/Makefile index 5c9a189..a6b7012 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_POWER_FSL) += power_fsl.o obj-$(CONFIG_POWER_I2C) += power_i2c.o obj-$(CONFIG_POWER_SPI) += power_spi.o obj-$(CONFIG_DM_PMIC) += pmic-uclass.o +obj-$(CONFIG_DM_REGULATOR) += regulator-uclass.o diff --git a/drivers/power/regulator-uclass.c b/drivers/power/regulator-uclass.c new file mode 100644 index 0000000..6b5c678 --- /dev/null +++ b/drivers/power/regulator-uclass.c @@ -0,0 +1,227 @@ +/*
- Copyright (C) 2014-2015 Samsung Electronics
- Przemyslaw Marczak p.marczak@samsung.com
- SPDX-License-Identifier: GPL-2.0+
- */
+#include <common.h> +#include <linux/types.h> +#include <fdtdec.h> +#include <dm.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <compiler.h> +#include <dm/device.h> +#include <dm/lists.h> +#include <dm/device-internal.h> +#include <errno.h>
+DECLARE_GLOBAL_DATA_PTR;
+int regulator_get_cnt(struct udevice *dev, int type, int *cnt) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->get_cnt)
return -EPERM;
- return ops->get_cnt(dev, type, cnt);
+}
+int regulator_get_value_desc(struct udevice *dev, int type, int number,
struct regulator_value_desc **desc)
+{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENXIO;
- if (!ops->get_value_desc)
return -EPERM;
- return ops->get_value_desc(dev, type, number, desc);
+}
+int regulator_get_mode_desc(struct udevice *dev, int type, int number,
int *mode_cnt, struct regulator_mode_desc **desc)
+{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENXIO;
- if (!ops->get_mode_desc_array)
return -EPERM;
- return ops->get_mode_desc_array(dev, type, number, mode_cnt, desc);
+}
+int regulator_get_value(struct udevice *dev, int type, int number, int *value) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->get_value)
return -EPERM;
- return ops->get_value(dev, type, number, value);
+}
+int regulator_set_value(struct udevice *dev, int type, int number, int value) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->set_value)
return -EPERM;
- return ops->set_value(dev, type, number, value);
+}
+int regulator_get_state(struct udevice *dev, int type, int number, int *state) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->get_state)
return -EPERM;
- return ops->get_state(dev, type, number, state);
+}
+int regulator_set_state(struct udevice *dev, int type, int number, int state) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->set_state)
return -EPERM;
- return ops->set_state(dev, type, number, state);
+}
+int regulator_get_mode(struct udevice *dev, int type, int number, int *mode) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->get_mode)
return -EPERM;
- return ops->get_mode(dev, type, number, mode);
+}
+int regulator_set_mode(struct udevice *dev, int type, int number, int mode) +{
- const struct dm_regulator_ops *ops;
- ops = pmic_get_uclass_ops(dev, UCLASS_PMIC_REGULATOR);
- if (!ops)
return -ENODEV;
- if (!ops->set_mode)
return -EPERM;
- return ops->set_mode(dev, type, number, mode);
+}
+int regulator_get(char *name, struct udevice **regulator) +{
- struct udevice *dev;
- struct uclass *uc;
- int ret;
- ret = uclass_get(UCLASS_PMIC_REGULATOR, &uc);
- if (ret) {
error("Regulator uclass not initialized!");
return ret;
- }
- uclass_foreach_dev(dev, uc) {
if (!dev)
continue;
if (!strncmp(name, dev->name, strlen(name))) {
ret = device_probe(dev);
if (ret)
error("Dev: %s probe failed", dev->name);
*regulator = dev;
Shouldn't we set regulator=NULL if device_probe() returns an error?
Thanks, this is fixed in V3.
Br, Robert
Best regards,