diff options
author | Laura Lawrence <Laura.Lawrence@freescale.com> | 2008-01-25 01:05:10 -0600 |
---|---|---|
committer | Daniel Schaeffer <daniel.schaeffer@timesys.com> | 2008-08-25 15:20:36 -0400 |
commit | 973c485f7f3e8849bce29589aa23e27fc035953c (patch) | |
tree | 7759bcb625f5253755258ec9cca5bb385f9964ec /include/linux | |
parent | c1219fd957db3b7f789cb1a1ab6353cb34d31dc6 (diff) |
ENGR00063257 Add Regulator API
Description:
Generic interface to control voltage regulators at
http://opensource.wolfsonmicro.com/node/8 AudioPlus project
Signed-off-by: Rob Herring <ra7055@freescale.com>
Diffstat (limited to 'include/linux')
-rw-r--r-- | include/linux/regulator/regulator-drv.h | 107 | ||||
-rw-r--r-- | include/linux/regulator/regulator-platform.h | 102 | ||||
-rw-r--r-- | include/linux/regulator/regulator.h | 332 |
3 files changed, 541 insertions, 0 deletions
diff --git a/include/linux/regulator/regulator-drv.h b/include/linux/regulator/regulator-drv.h new file mode 100644 index 000000000000..5235af9619fe --- /dev/null +++ b/include/linux/regulator/regulator-drv.h @@ -0,0 +1,107 @@ +/* + * regulator-drv.h -- SoC Regulator support. + * + * Copyright (C) 2007 Wolfson Microelectronics PLC. + * + * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> + * + * 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 Driver Interface. + */ + + +#ifndef __LINUX_REGULATOR_DRV_H_ +#define __LINUX_REGULATOR_DRV_H_ + +#include <linux/device.h> +#include <linux/regulator/regulator.h> + +struct regulator_constraints; + +/** + * struct regulator_ops - regulator operations. + * + * This struct describes regulator operations. + */ +struct regulator_ops { + + /* get/set regulator voltage */ + int (*set_voltage)(struct regulator *, int uV); + int (*get_voltage)(struct regulator *); + + /* get/set regulator current */ + int (*set_current)(struct regulator *, int uA); + int (*get_current)(struct regulator *); + + /* enable/disable regulator */ + int (*enable)(struct regulator *); + int (*disable)(struct regulator *); + int (*is_enabled)(struct regulator *); + + /* get/set regulator mode (defined in regulator.h) */ + int (*set_mode)(struct regulator *, unsigned int mode); + unsigned int (*get_mode)(struct regulator *); + + /* get most efficient regulator mode for load */ + unsigned int (*get_optimum_mode)(struct regulator *, int input_uV, + int output_uV, int load_uA); +}; + +/** + * struct regulator + * + * Voltage / Current regulator. + */ +struct regulator { + const char *name; + int id; + struct regulator_ops *ops; + struct regulation_constraints *constraints; + int use_count; + + struct list_head list; + struct list_head user_list; + struct blocking_notifier_head notifier; + struct mutex mutex; + struct module *owner; + struct class_device cdev; + + struct regulator *parent; /* for tree */ + + void *reg_data; /* regulator data */ + void *vendor; /* regulator vendor extensions */ +}; + +/** + * regulator_register - register regulator + * @regulator: regulator source + * + * Called by regulator drivers to register a regulator. + * Returns 0 on success. + */ +int regulator_register(struct regulator *regulator); + +/** + * regulator_unregister - unregister regulator + * @regulator: regulator source + * + * Called by regulator drivers to unregister a regulator. + */ +void regulator_unregister(struct regulator *regulator); + +/** + * regulator_notifier_call_chain - call regulator event notifier + * @regulator: regulator source + * @event: notifier block + * @data: + * + * Called by regulator drivers to notify clients a regulator event has + * occurred. + */ +int regulator_notifier_call_chain(struct regulator *regulator, + unsigned long event, void *data); + +#endif diff --git a/include/linux/regulator/regulator-platform.h b/include/linux/regulator/regulator-platform.h new file mode 100644 index 000000000000..7f57e035eb34 --- /dev/null +++ b/include/linux/regulator/regulator-platform.h @@ -0,0 +1,102 @@ +/* + * regulator-platform.h -- SoC Regulator support. + * + * Copyright (C) 2007 Wolfson Microelectronics PLC. + * + * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> + * + * 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 Platform Interface. + */ + + +#ifndef __LINUX_REGULATOR_PLATFORM_H_ +#define __LINUX_REGULATOR_PLATFORM_H_ + +#include <linux/regulator/regulator.h> + +struct regulator; + +/* + * Regulator operations. + * + * @VOLTAGE: Regulator output voltage can be changed by software on this + * board/machine. + * @CURRENT: Regulator output current can be changed by software on this + * board machine. + * @MODE: Regulator operating mode can be changed by software on this + * board machine. + * @STATUS: Regulator can be enabled and disabled. + * @DRMS: Dynamic Regulator Mode Switching is enabled for this regulator. + */ + +#define REGULATOR_CHANGE_VOLTAGE 0x1 +#define REGULATOR_CHANGE_CURRENT 0x2 +#define REGULATOR_CHANGE_MODE 0x4 +#define REGULATOR_CHANGE_STATUS 0x8 +#define REGULATOR_CHANGE_DRMS 0x10 + +/** + * struct regulation_constraints - regulator operating constraints. + * + * This struct describes regulator and board/machine specific constraints. + */ +struct regulation_constraints { + + char *name; + + /* voltage output range - for voltage control */ + int min_uV; + int max_uV; + + /* current output range - for current control */ + int min_uA; + int max_uA; + + /* valid regulator operating modes for this machine */ + unsigned int valid_modes_mask; + + /* valid operations for regulator on this machine */ + unsigned int valid_ops_mask; + + /* input voltage */ + int input_uV; +}; + +/** + * regulator_set_platform_source - set regulator source regulator + * @regulator: regulator source + * @parent: source or parent regulator + * + * Called by platform initialisation code to set the source supply or "parent" + * regulator for this regulator. + */ +int regulator_set_platform_source(struct regulator *reg, + struct regulator *parent); + +/** + * regulator_get_platform_source - get regulator source regulator + * @regulator: regulator source + * + * Returns the regulator supply regulator or NULL if no supply regulator + * exists (i.e the regulator is supplied directly from USB, Line, Battery, etc) + */ +struct regulator *regulator_get_platform_source(struct regulator *regulator); + + +/** + * regulator_set_platform_constraints - sets regulator constraints + * @regulator: regulator source + * + * Allows platform initialisation code to define and constrain regulator + * circuits e.g. valid voltage/current ranges, etc. + * NOTE: Constraints must be set by platform code in order for some + * regulator operations to proceed i.e. set_voltage, set_current, set_mode. + */ +int regulator_set_platform_constraints(const char *regulator_name, + struct regulation_constraints *constraints); + +#endif diff --git a/include/linux/regulator/regulator.h b/include/linux/regulator/regulator.h new file mode 100644 index 000000000000..404b2472b11a --- /dev/null +++ b/include/linux/regulator/regulator.h @@ -0,0 +1,332 @@ +/* + * regulator.h -- SoC Regulator support. + * + * Copyright (C) 2007 Wolfson Microelectronics PLC. + * + * Author: Liam Girdwood <lg@opensource.wolfsonmicro.com> + * + * 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. + */ + + +#ifndef __LINUX_REGULATOR_H_ +#define __LINUX_REGULATOR_H_ + +/* + * Regulator operating modes. + * + * Regulators can run in a variety of different operating modes depending + * output load. This allows further power saving though regulator efficiency. + * + * 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. usefull in CPU voltage & frequency scaling where + * load can quickly increase with 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 most efficient mode for very + * light loads. Can be used by devices when they are + * in a sleep/standby state. This mode may be more noisy + * than NORMAL 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 undervoltage. + * @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) + +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 + * valid IS_ERR() condition containing errno. + * + * Drivers must assume that the clock source is not enabled. + */ +struct regulator *regulator_get(struct device *dev, const char *id); + +/** + * regulator_put - "free" the regulator source + * @regulator: regulator source + * @dev: device + * + * 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, struct device *dev); + +/** + * 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. + */ +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. + */ +int regulator_set_voltage(struct regulator *regulator, int uV); + +/** + * regulator_get_voltage - get regulator output voltage + * @regulator: regulator source + * + * This returns the 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 + * @regulator: regulator source + * @uV: voltage in uA + * + * Sets current regulator 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. + */ +int regulator_set_current(struct regulator *regulator, int uA); + +/** + * regulator_get_current - get regulator output current + * @regulator: regulator source + * + * This returns the regulator current 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 + * + * Set regulator operating mode to increase regulator efficiency or improve + * regulation performance. + */ +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 device max load + * @regulator: regulator + * @dev: device + * @uA: load + * + * Notifies the regulator of new max device load. Can be used by DRMS to select + * the most efficient regulator operating mode. + * + * Client devices notify their supply regulator of the maximum power + * they will require 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 IO is about to begin or has just finished. + * o Device is idling in between work. + * + * The power tables in device datasheets would be used by the driver for + * the power consumption in each operational state. 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, + struct device *dev, int uA); + +/** + * regulator_get_drvdata - get regulator driver data + * @regulator: regulator + */ +void *regulator_get_drvdata(struct regulator *regulator); + +/** + * regulator_set_drvdata - set regulator driver data + * @regulator: regulator + * @void: 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, dev) \ + do { (void)(regulator); (void)(dev); } 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 |