This adds support for getting and setting voltages.  This is necessary
to be able to change the CPU voltage when changing the CPU frequency
for example.

ok?

Index: dev/ofw/ofw_regulator.c
===================================================================
RCS file: /cvs/src/sys/dev/ofw/ofw_regulator.c,v
retrieving revision 1.1
diff -u -p -r1.1 ofw_regulator.c
--- dev/ofw/ofw_regulator.c     13 Aug 2016 10:52:21 -0000      1.1
+++ dev/ofw/ofw_regulator.c     18 Nov 2017 12:02:06 -0000
@@ -24,6 +24,19 @@
 #include <dev/ofw/ofw_pinctrl.h>
 #include <dev/ofw/ofw_regulator.h>
 
+LIST_HEAD(, regulator_device) regulator_devices =
+       LIST_HEAD_INITIALIZER(regulator_devices);
+
+void
+regulator_register(struct regulator_device *rd)
+{
+       rd->rd_phandle = OF_getpropint(rd->rd_node, "phandle", 0);
+       if (rd->rd_phandle == 0)
+               return;
+
+       LIST_INSERT_HEAD(&regulator_devices, rd, rd_list);
+}
+
 int
 regulator_set(uint32_t phandle, int enable)
 {
@@ -78,4 +91,44 @@ int
 regulator_disable(uint32_t phandle)
 {
        return regulator_set(phandle, 0);
+}
+
+uint32_t
+regulator_get_voltage(uint32_t phandle)
+{
+       struct regulator_device *rd;
+       int node;
+
+       LIST_FOREACH(rd, &regulator_devices, rd_list) {
+               if (rd->rd_phandle == phandle)
+                       break;
+       }
+
+       if (rd && rd->rd_get_voltage)
+               return rd->rd_get_voltage(rd->rd_cookie);
+
+       node = OF_getnodebyphandle(phandle);
+       if (node == 0)
+               return 0;
+
+       if (OF_is_compatible(node, "regulator-fixed"))
+               return OF_getpropint(node, "regulator-min-voltage", 0);
+
+       return 0;
+}
+
+int
+regulator_set_voltage(uint32_t phandle, uint32_t voltage)
+{
+       struct regulator_device *rd;
+
+       LIST_FOREACH(rd, &regulator_devices, rd_list) {
+               if (rd->rd_phandle == phandle)
+                       break;
+       }
+
+       if (rd && rd->rd_set_voltage)
+               return rd->rd_set_voltage(rd->rd_cookie, voltage);
+
+       return -1;
 }
Index: dev/ofw/ofw_regulator.h
===================================================================
RCS file: /cvs/src/sys/dev/ofw/ofw_regulator.h,v
retrieving revision 1.2
diff -u -p -r1.2 ofw_regulator.h
--- dev/ofw/ofw_regulator.h     21 Aug 2016 14:41:51 -0000      1.2
+++ dev/ofw/ofw_regulator.h     18 Nov 2017 12:02:06 -0000
@@ -18,7 +18,21 @@
 #ifndef _DEV_OFW_REGULATOR_H_
 #define _DEV_OFW_REGULATOR_H_
 
+struct regulator_device {
+       int     rd_node;
+       void    *rd_cookie;
+       uint32_t (*rd_get_voltage)(void *);
+       int     (*rd_set_voltage)(void *, uint32_t);
+
+       LIST_ENTRY(regulator_device) rd_list;
+       uint32_t rd_phandle;
+};
+
+void   regulator_register(struct regulator_device *);
+
 int    regulator_enable(uint32_t);
 int    regulator_disable(uint32_t);
+uint32_t regulator_get_voltage(uint32_t);
+int    regulator_set_voltage(uint32_t, uint32_t);
 
 #endif /* _DEV_OFW_REGULATOR_H_ */

Reply via email to