[RFC 1/4] Voltage/Current Regulator framework

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Regulator client / consumer API :-

diff --git a/include/linux/regulator/regulator.h b/include/linux/regulator/regulator.h
new file mode 100644
index 0000000..1a6f972
--- /dev/null
+++ b/include/linux/regulator/regulator.h
@@ -0,0 +1,363 @@
+/*
+ * regulator.h -- SoC Regulator support.
+ *
+ * Copyright (C) 2007, 2008 Wolfson Microelectronics PLC.
+ *
+ * Author: Liam Girdwood <lg@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Regulator Client Interface.
+ *
+ * A Power Management Regulator framework for SoC based devices.
+ * Features:-
+ *   o Voltage and current level control.
+ *   o Operating mode control.
+ *   o Regulator status.
+ *   o sysfs entries for showing client devices and status
+ *
+ * EXPERIMENTAL FEATURES:
+ *   Dynamic Regulator operating Mode Switching (DRMS) - allows regulators
+ *   to use most efficient operating mode depending upon voltage and load and
+ *   is transparent to client drivers.
+ *
+ *   e.g. Devices x,y,z share regulator r. Device x and y draw 20mA each during
+ *   IO and 1mA at idle. Device z draws 100mA when under load and 5mA when
+ *   idling. Regulator r has > 90% efficieny in NORMAL mode at loads > 100mA
+ *   but this drops rapidly to 60% when below 100mA. Regulator r has > 90%
+ *   efficiency in IDLE mode at loads < 10mA. Thus regulator r will operate
+ *   in normal mode for loads > 10mA and in IDLE mode for load <= 10mA.
+ *
+ *   Dynamic Regulator Voltage Selection (DRVS). Selects the highest voltage
+ *   output (within system constraints) for a regulator shared between several
+ *   devices. This allows all devices to operate within their voltage range and
+ *   will dynamically change the voltage when devices disable() thier supply
+ *   to the next highest level (thus saving power). This is based on an idea
+ *   by Amit Kucheria in an RFC to lakml.
+ *
+ *   e.g. devices x,y,z share regulator r. device x and y can operate between
+ *   1800mV and 1900mV, whilst device z can only operate at 1900mV. Regulator
+ *   r will output 1900mV when all devices are in use and 1800mV when devices
+ *   x and y are in use and device z is disabled.
+ */
+
+
+#ifndef __LINUX_REGULATOR_H_
+#define __LINUX_REGULATOR_H_
+
+/*
+ * Regulator operating modes.
+ *
+ * Regulators can run in a variety of different operating modes depending on
+ * output load. This allows further system power savings by selecting the
+ * best (and most efficient) regulator mode for a desired load.
+ *
+ * Most drivers will only care about NORMAL. The modes below are generic and
+ * will probably not match the naming convention of your regulator data sheet
+ * but should match the use cases in the datasheet.
+ *
+ * In order of power efficiency (least efficient at top).
+ *
+ *  Mode       Description
+ *  FAST       Regulator can handle fast changes in it's load.
+ *             e.g. useful in CPU voltage & frequency scaling where
+ *             load can quickly increase with CPU freqency increases.
+ *
+ *  NORMAL     Normal regulator power supply mode. Most drivers will
+ *             use this mode.
+ *
+ *  IDLE       Regulator runs in a more efficient mode for light
+ *             loads. Can be used for devices that have a low power
+ *             requirement during periods of inactivity. This mode
+ *             may be more noisy than NORMAL and may not be able
+ *             to handle fast load switching.
+ *
+ *  STANDBY    Regulator runs in the most efficient mode for very
+ *             light loads. Can be used by devices when they are
+ *             in a sleep/standby state. This mode is likely to be
+ *             the most noisy and may not be able to handle fast load
+ *             switching.
+ *
+ * NOTE: Most regulators will only support a subset of these modes. Some
+ * will only just support NORMAL.
+ */
+
+#define REGULATOR_MODE_FAST			0x1
+#define REGULATOR_MODE_NORMAL			0x2
+#define REGULATOR_MODE_IDLE			0x4
+#define REGULATOR_MODE_STANDBY			0x8
+
+/*
+ * Regulator notifier events.
+ *
+ * @UNDER_VOLTAGE:  Regulator output is under voltage.
+ * @OVER_CURRENT:   Regulator output current is too high.
+ * @POWER_ON:       Regulator power ON event.
+ * @POWER_OFF:      Regulator power OFF event.
+ * @REGULATION_OUT: Regulator output is out of regulation.
+ * @FAIL:           Regulator output has failed.
+ * @OVER_TEMP:      Regulator over temp.
+ */
+
+#define REGULATOR_EVENT_UNDER_VOLTAGE		0x1
+#define REGULATOR_EVENT_OVER_CURRENT		0x2
+#define REGULATOR_EVENT_POWER_ON		0x4
+#define REGULATOR_EVENT_POWER_OFF		0x8
+#define REGULATOR_EVENT_REGULATION_OUT		0x10
+#define REGULATOR_EVENT_FAIL			0x20
+#define REGULATOR_EVENT_OVER_TEMP		0x40
+
+/*
+ * Convenience conversion.
+ * Here atm, maybe there is somewhere better for this.
+ */
+#define mV_to_uV(mV)	(mV * 1000)
+#define uV_to_mV(uV)	(uV / 1000)
+#define V_to_uV(V)	(mV_to_uV(V * 1000))
+#define uV_to_V(uV)	(uV_to_mV(uV) / 1000)
+#define mA_to_uA(mA)	(mA * 1000)
+#define uA_to_mA(uA)	(uA / 1000)
+#define A_to_uA(A)	(mA_to_uA(A * 1000))
+#define uA_to_A(uA)	(uA_to_mA(uA) / 1000)
+
+struct regulator;
+
+#if defined (CONFIG_REGULATOR_API)
+
+/**
+ * regulator_get - lookup and obtain a reference to a regulator.
+ * @dev: device for regulator "consumer"
+ * @id: regulator ID
+ *
+ * Returns a struct regulator corresponding to the regulator producer, or
+ * IS_ERR() condition containing errno.
+ */
+struct regulator * __must_check regulator_get(struct device *dev, const char *id);
+
+/**
+ * regulator_put - "free" the regulator source
+ * @regulator: regulator source
+ *
+ * Note: drivers must ensure that all regulator_enable calls made on this
+ * regulator source are balanced by regulator_disable calls prior to calling
+ * this function.
+ */
+void regulator_put(struct regulator *regulator);
+
+/**
+ * regulator_enable - enable regulator output
+ * @regulator: regulator source
+ *
+ * Enable the regulator output at the predefined voltage or current value.
+ * NOTE: the output value can be set by other drivers, bootloader or may be
+ * hardwired in the regulator.
+ */
+int regulator_enable(struct regulator *regulator);
+
+/**
+ * regulator_disable - disable regulator output
+ * @regulator: regulator source
+ *
+ * Disable the regulator output voltage or current.
+ * NOTE: this will only disable the regulator output iff no other consumer
+ * devices have it enabled.
+ */
+int regulator_disable(struct regulator *regulator);
+
+/**
+ * regulator_is_enabled - is the regulator output enabled
+ * @regulator: regulator source
+ *
+ * Returns zero for disabled otherwise return number of enable requests.
+ */
+int regulator_is_enabled(struct regulator *regulator);
+
+/**
+ * regulator_set_voltage - set regulator output voltage
+ * @regulator: regulator source
+ * @uV: voltage in uV
+ *
+ * Sets a voltage regulator to the desired output voltage. This can be set
+ * during any regulator state. IOW, regulator can be disabled or enabled.
+ *
+ * If the regulator is enabled then the voltage will change to the new value
+ * immediately otherwise if the regulator is disabled the regulator will
+ * output at the new voltage when enabled.
+ *
+ * NOTE: If the regulator is shared between several devices then the highest
+ * request voltage that meets the system constraints will be used.
+ * NOTE: Regulator system constraints must be set for this regulator before
+ * calling this function otherwise this call will fail.
+ */
+int regulator_set_voltage(struct regulator *regulator, int uV);
+
+/**
+ * regulator_get_voltage - get regulator output voltage
+ * @regulator: regulator source
+ *
+ * This returns the current regulator voltage in uV.
+ *
+ * NOTE: If the regulator is disabled it will return the voltage value. This
+ * function should not be used to determine regulator state.
+ */
+int regulator_get_voltage(struct regulator *regulator);
+
+/**
+ * regulator_set_current - set regulator output current for a current sink
+ * @regulator: regulator source
+ * @uA: current in uA
+ *
+ * Sets current sink to the desired output current. This can be set during
+ * any regulator state. IOW, regulator can be disabled or enabled.
+ *
+ * If the regulator is enabled then the current will change to the new value
+ * immediately otherwise if the regulator is disabled the regulator will
+ * output at the new current when enabled.
+ *
+ * NOTE: Regulator system constraints must be set for this regulator before
+ * calling this function otherwise this call will fail.
+ */
+int regulator_set_current(struct regulator *regulator, int uA);
+
+/**
+ * regulator_get_current - get regulator output current
+ * @regulator: regulator source
+ *
+ * This returns the current supplied by the specified current sink in uA.
+ *
+ * NOTE: If the regulator is disabled it will return the current value. This
+ * function should not be used to determine regulator state.
+ */
+int regulator_get_current(struct regulator *regulator);
+
+/**
+ * regulator_set_mode - set regulator operating mode
+ * @regulator: regulator source
+ * @mode: operating mode - one of the REGULATOR_MODE constants
+ *
+ * Set regulator operating mode to increase regulator efficiency or improve
+ * regulation performance.
+ *
+ * NOTE: Regulator system constraints must be set for this regulator before
+ * calling this function otherwise this call will fail.
+ */
+int regulator_set_mode(struct regulator *regulator, unsigned int mode);
+
+/**
+ * regulator_get_mode - set regulator operating mode
+ * @regulator: regulator source
+ *
+ * Get the current regulator operating mode.
+ */
+unsigned int regulator_get_mode(struct regulator *regulator);
+
+/**
+ * regulator_get_optimum_mode - get regulator optimum operating mode
+ * @regulator: regulator source
+ * @input_uV: input voltage
+ * @output_uV: output voltage
+ * @load_uV: load current
+ *
+ * Get the most efficient regulator operating mode for the given input
+ * and output voltages at a specific load..
+ */
+unsigned int regulator_get_optimum_mode(struct regulator *regulator,
+	int input_uV, int output_uV, int load_uA);
+
+/**
+ * regulator_register_client - register regulator event notifier
+ * @regulator: regulator source
+ * @notifier_block: notifier block
+ *
+ * Register notifier block to receive regulator events.
+ */
+int regulator_register_client(struct regulator *regulator,
+	struct notifier_block *nb);
+
+/**
+ * regulator_unregister_client - unregister regulator event notifier
+ * @regulator: regulator source
+ * @notifier_block: notifier block
+ *
+ * Unregister regulator event notifier block.
+ */
+int regulator_unregister_client(struct regulator *regulator,
+	struct notifier_block *nb);
+
+/**
+ * regulator_notify_load - notify regulator of new device load
+ * @regulator: regulator
+ * @dev: device
+ * @uA: load
+ *
+ * Notifies the regulator core of a new device load. This is then used by
+ * DRMS (if enabled by constraints) to select the most efficient regulator
+ * operating mode for the new regulator loading.
+ *
+ * Client devices notify their supply regulator of the maximum power
+ * they will require (can be taken from device datasheet in the power
+ * consumption tables) when they change operational status and hence power
+ * state. Examples of operational state changes that can affect power
+ * consumption are :-
+ *
+ *    o Device is opened / closed.
+ *    o Device I/O is about to begin or has just finished.
+ *    o Device is idling in between work.
+ *
+ * This information is also exported via sysfs to userspace.
+ *
+ * DRMS would then sum the total requested load on the regulator and change
+ * to the most efficient operating mode if platform constraints allow.
+ */
+void regulator_drms_notify_load(struct regulator *regulator, int uA);
+
+/**
+ * regulator_get_drvdata - get regulator driver data
+ * @regulator: regulator
+ */
+void *regulator_get_drvdata(struct regulator *regulator);
+
+/**
+ * regulator_set_drvdata - get regulator driver data
+ * @regulator: regulator
+ * @data: data
+ */
+void regulator_set_drvdata(struct regulator *regulator, void *data);
+
+#else
+
+/*
+ * Make sure client drivers will still build on systems with no software
+ * controllable voltage or current regulators.
+ */
+#define regulator_get(dev, id)	({ (void)(dev); (void)(id); NULL; })
+#define regulator_put(regulator) do { (void)(regulator);} while (0)
+#define regulator_enable(regulator) ({ (void)(regulator); 0; })
+#define regulator_disable(regulator) ({ (void)(regulator); 0; })
+#define regulator_is_enabled(regulator) ({ (void)(regulator); 1; })
+#define regulator_set_voltage(regulator, uV) \
+	({ (void)(regulator); (void)(uV); 0; })
+#define regulator_get_voltage(regulator) ({ (void)(regulator); 0; })
+#define regulator_set_current(regulator, uA) \
+	({ (void)(regulator); (void)(uA); 0; })
+#define regulator_get_current(regulator) ({ (void)(regulator); 0; })
+#define regulator_set_mode(regulator, mode) \
+	({ (void)(regulator); (void)(mode); 0; })
+#define regulator_get_mode(regulator) ({ (void)(regulator); 0; })
+#define regulator_get_optimum_mode(regulator, input_uV, output_uV, load_uA) \
+	({ (void)(regulator); (void)(input_uV); (void)(output_uV); (void)(load_uA); 0; })
+#define regulator_register_client(regulator, nb) \
+	({ (void)(regulator); (void)(nb); 0; })
+#define regulator_unregister_client(regulator, nb) \
+	do { (void)(regulator); (void)(nb);} while (0)
+#define regulator_notify_load(regulator, dev, uA) \
+	do { (void)(regulator); (void)(dev); (void)(uA);} while (0)
+#define regulator_get_drvdata(regulator) ({ (void)(regulator); NULL; })
+#define regulator_set_drvdata(regulator, data) \
+	do { (void)(regulator); (void)(data);} while (0)
+
+#endif
+
+#endif


_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux