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.marc...@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.marc...@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,
--
Przemyslaw Marczak
Samsung R&D Institute Poland
Samsung Electronics
p.marc...@samsung.com
_______________________________________________
U-Boot mailing list
U-Boot@lists.denx.de
http://lists.denx.de/mailman/listinfo/u-boot

Reply via email to