mirror of
https://github.com/adulau/aha.git
synced 2024-12-28 11:46:19 +00:00
Merge branch 'reg-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6
* 'reg-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: regulator: TI bq24022 Li-Ion Charger driver regulator: maintainers - add maintainers for regulator framework. regulator: documentation - ABI regulator: documentation - machine regulator: documentation - regulator driver regulator: documentation - consumer interface regulator: documentation - overview regulator: core kbuild files regulator: regulator test harness regulator: add support for fixed regulators. regulator: regulator framework core regulator: fixed regulator interface regulator: machine driver interface regulator: regulator driver interface regulator: consumer device interface
This commit is contained in:
commit
561b35b341
19 changed files with 3956 additions and 0 deletions
315
Documentation/ABI/testing/sysfs-class-regulator
Normal file
315
Documentation/ABI/testing/sysfs-class-regulator
Normal file
|
@ -0,0 +1,315 @@
|
|||
What: /sys/class/regulator/.../state
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
state. This holds the regulator output state.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'enabled'
|
||||
'disabled'
|
||||
'unknown'
|
||||
|
||||
'enabled' means the regulator output is ON and is supplying
|
||||
power to the system.
|
||||
|
||||
'disabled' means the regulator output is OFF and is not
|
||||
supplying power to the system..
|
||||
|
||||
'unknown' means software cannot determine the state.
|
||||
|
||||
NOTE: this field can be used in conjunction with microvolts
|
||||
and microamps to determine regulator output levels.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../type
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
type. This holds the regulator type.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'voltage'
|
||||
'current'
|
||||
'unknown'
|
||||
|
||||
'voltage' means the regulator output voltage can be controlled
|
||||
by software.
|
||||
|
||||
'current' means the regulator output current limit can be
|
||||
controlled by software.
|
||||
|
||||
'unknown' means software cannot control either voltage or
|
||||
current limit.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../microvolts
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
microvolts. This holds the regulator output voltage setting
|
||||
measured in microvolts (i.e. E-6 Volts).
|
||||
|
||||
NOTE: This value should not be used to determine the regulator
|
||||
output voltage level as this value is the same regardless of
|
||||
whether the regulator is enabled or disabled.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../microamps
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
microamps. This holds the regulator output current limit
|
||||
setting measured in microamps (i.e. E-6 Amps).
|
||||
|
||||
NOTE: This value should not be used to determine the regulator
|
||||
output current level as this value is the same regardless of
|
||||
whether the regulator is enabled or disabled.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../opmode
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
opmode. This holds the regulator operating mode setting.
|
||||
|
||||
The opmode value can be one of the following strings:
|
||||
|
||||
'fast'
|
||||
'normal'
|
||||
'idle'
|
||||
'standby'
|
||||
'unknown'
|
||||
|
||||
The modes are described in include/linux/regulator/regulator.h
|
||||
|
||||
NOTE: This value should not be used to determine the regulator
|
||||
output operating mode as this value is the same regardless of
|
||||
whether the regulator is enabled or disabled.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../min_microvolts
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
min_microvolts. This holds the minimum safe working regulator
|
||||
output voltage setting for this domain measured in microvolts.
|
||||
|
||||
NOTE: this will return the string 'constraint not defined' if
|
||||
the power domain has no min microvolts constraint defined by
|
||||
platform code.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../max_microvolts
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
max_microvolts. This holds the maximum safe working regulator
|
||||
output voltage setting for this domain measured in microvolts.
|
||||
|
||||
NOTE: this will return the string 'constraint not defined' if
|
||||
the power domain has no max microvolts constraint defined by
|
||||
platform code.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../min_microamps
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
min_microamps. This holds the minimum safe working regulator
|
||||
output current limit setting for this domain measured in
|
||||
microamps.
|
||||
|
||||
NOTE: this will return the string 'constraint not defined' if
|
||||
the power domain has no min microamps constraint defined by
|
||||
platform code.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../max_microamps
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
max_microamps. This holds the maximum safe working regulator
|
||||
output current limit setting for this domain measured in
|
||||
microamps.
|
||||
|
||||
NOTE: this will return the string 'constraint not defined' if
|
||||
the power domain has no max microamps constraint defined by
|
||||
platform code.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../num_users
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
num_users. This holds the number of consumer devices that
|
||||
have called regulator_enable() on this regulator.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../requested_microamps
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
requested_microamps. This holds the total requested load
|
||||
current in microamps for this regulator from all its consumer
|
||||
devices.
|
||||
|
||||
|
||||
What: /sys/class/regulator/.../parent
|
||||
Date: April 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Some regulator directories will contain a link called parent.
|
||||
This points to the parent or supply regulator if one exists.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_mem_microvolts
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_mem_microvolts. This holds the regulator output
|
||||
voltage setting for this domain measured in microvolts when
|
||||
the system is suspended to memory.
|
||||
|
||||
NOTE: this will return the string 'not defined' if
|
||||
the power domain has no suspend to memory voltage defined by
|
||||
platform code.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_disk_microvolts
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_disk_microvolts. This holds the regulator output
|
||||
voltage setting for this domain measured in microvolts when
|
||||
the system is suspended to disk.
|
||||
|
||||
NOTE: this will return the string 'not defined' if
|
||||
the power domain has no suspend to disk voltage defined by
|
||||
platform code.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_standby_microvolts
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_standby_microvolts. This holds the regulator output
|
||||
voltage setting for this domain measured in microvolts when
|
||||
the system is suspended to standby.
|
||||
|
||||
NOTE: this will return the string 'not defined' if
|
||||
the power domain has no suspend to standby voltage defined by
|
||||
platform code.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_mem_mode
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_mem_mode. This holds the regulator operating mode
|
||||
setting for this domain when the system is suspended to
|
||||
memory.
|
||||
|
||||
NOTE: this will return the string 'not defined' if
|
||||
the power domain has no suspend to memory mode defined by
|
||||
platform code.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_disk_mode
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_disk_mode. This holds the regulator operating mode
|
||||
setting for this domain when the system is suspended to disk.
|
||||
|
||||
NOTE: this will return the string 'not defined' if
|
||||
the power domain has no suspend to disk mode defined by
|
||||
platform code.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_standby_mode
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_standby_mode. This holds the regulator operating mode
|
||||
setting for this domain when the system is suspended to
|
||||
standby.
|
||||
|
||||
NOTE: this will return the string 'not defined' if
|
||||
the power domain has no suspend to standby mode defined by
|
||||
platform code.
|
||||
|
||||
What: /sys/class/regulator/.../suspend_mem_state
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_mem_state. This holds the regulator operating state
|
||||
when suspended to memory.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'enabled'
|
||||
'disabled'
|
||||
'not defined'
|
||||
|
||||
What: /sys/class/regulator/.../suspend_disk_state
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_disk_state. This holds the regulator operating state
|
||||
when suspended to disk.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'enabled'
|
||||
'disabled'
|
||||
'not defined'
|
||||
|
||||
What: /sys/class/regulator/.../suspend_standby_state
|
||||
Date: May 2008
|
||||
KernelVersion: 2.6.26
|
||||
Contact: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
Description:
|
||||
Each regulator directory will contain a field called
|
||||
suspend_standby_state. This holds the regulator operating
|
||||
state when suspended to standby.
|
||||
|
||||
This will be one of the following strings:
|
||||
|
||||
'enabled'
|
||||
'disabled'
|
||||
'not defined'
|
182
Documentation/power/regulator/consumer.txt
Normal file
182
Documentation/power/regulator/consumer.txt
Normal file
|
@ -0,0 +1,182 @@
|
|||
Regulator Consumer Driver Interface
|
||||
===================================
|
||||
|
||||
This text describes the regulator interface for consumer device drivers.
|
||||
Please see overview.txt for a description of the terms used in this text.
|
||||
|
||||
|
||||
1. Consumer Regulator Access (static & dynamic drivers)
|
||||
=======================================================
|
||||
|
||||
A consumer driver can get access to it's supply regulator by calling :-
|
||||
|
||||
regulator = regulator_get(dev, "Vcc");
|
||||
|
||||
The consumer passes in it's struct device pointer and power supply ID. The core
|
||||
then finds the correct regulator by consulting a machine specific lookup table.
|
||||
If the lookup is successful then this call will return a pointer to the struct
|
||||
regulator that supplies this consumer.
|
||||
|
||||
To release the regulator the consumer driver should call :-
|
||||
|
||||
regulator_put(regulator);
|
||||
|
||||
Consumers can be supplied by more than one regulator e.g. codec consumer with
|
||||
analog and digital supplies :-
|
||||
|
||||
digital = regulator_get(dev, "Vcc"); /* digital core */
|
||||
analog = regulator_get(dev, "Avdd"); /* analog */
|
||||
|
||||
The regulator access functions regulator_get() and regulator_put() will
|
||||
usually be called in your device drivers probe() and remove() respectively.
|
||||
|
||||
|
||||
2. Regulator Output Enable & Disable (static & dynamic drivers)
|
||||
====================================================================
|
||||
|
||||
A consumer can enable it's power supply by calling:-
|
||||
|
||||
int regulator_enable(regulator);
|
||||
|
||||
NOTE: The supply may already be enabled before regulator_enabled() is called.
|
||||
This may happen if the consumer shares the regulator or the regulator has been
|
||||
previously enabled by bootloader or kernel board initialization code.
|
||||
|
||||
A consumer can determine if a regulator is enabled by calling :-
|
||||
|
||||
int regulator_is_enabled(regulator);
|
||||
|
||||
This will return > zero when the regulator is enabled.
|
||||
|
||||
|
||||
A consumer can disable it's supply when no longer needed by calling :-
|
||||
|
||||
int regulator_disable(regulator);
|
||||
|
||||
NOTE: This may not disable the supply if it's shared with other consumers. The
|
||||
regulator will only be disabled when the enabled reference count is zero.
|
||||
|
||||
Finally, a regulator can be forcefully disabled in the case of an emergency :-
|
||||
|
||||
int regulator_force_disable(regulator);
|
||||
|
||||
NOTE: this will immediately and forcefully shutdown the regulator output. All
|
||||
consumers will be powered off.
|
||||
|
||||
|
||||
3. Regulator Voltage Control & Status (dynamic drivers)
|
||||
======================================================
|
||||
|
||||
Some consumer drivers need to be able to dynamically change their supply
|
||||
voltage to match system operating points. e.g. CPUfreq drivers can scale
|
||||
voltage along with frequency to save power, SD drivers may need to select the
|
||||
correct card voltage, etc.
|
||||
|
||||
Consumers can control their supply voltage by calling :-
|
||||
|
||||
int regulator_set_voltage(regulator, min_uV, max_uV);
|
||||
|
||||
Where min_uV and max_uV are the minimum and maximum acceptable voltages in
|
||||
microvolts.
|
||||
|
||||
NOTE: this can be called when the regulator is enabled or disabled. If called
|
||||
when enabled, then the voltage changes instantly, otherwise the voltage
|
||||
configuration changes and the voltage is physically set when the regulator is
|
||||
next enabled.
|
||||
|
||||
The regulators configured voltage output can be found by calling :-
|
||||
|
||||
int regulator_get_voltage(regulator);
|
||||
|
||||
NOTE: get_voltage() will return the configured output voltage whether the
|
||||
regulator is enabled or disabled and should NOT be used to determine regulator
|
||||
output state. However this can be used in conjunction with is_enabled() to
|
||||
determine the regulator physical output voltage.
|
||||
|
||||
|
||||
4. Regulator Current Limit Control & Status (dynamic drivers)
|
||||
===========================================================
|
||||
|
||||
Some consumer drivers need to be able to dynamically change their supply
|
||||
current limit to match system operating points. e.g. LCD backlight driver can
|
||||
change the current limit to vary the backlight brightness, USB drivers may want
|
||||
to set the limit to 500mA when supplying power.
|
||||
|
||||
Consumers can control their supply current limit by calling :-
|
||||
|
||||
int regulator_set_current_limit(regulator, min_uV, max_uV);
|
||||
|
||||
Where min_uA and max_uA are the minimum and maximum acceptable current limit in
|
||||
microamps.
|
||||
|
||||
NOTE: this can be called when the regulator is enabled or disabled. If called
|
||||
when enabled, then the current limit changes instantly, otherwise the current
|
||||
limit configuration changes and the current limit is physically set when the
|
||||
regulator is next enabled.
|
||||
|
||||
A regulators current limit can be found by calling :-
|
||||
|
||||
int regulator_get_current_limit(regulator);
|
||||
|
||||
NOTE: get_current_limit() will return the current limit whether the regulator
|
||||
is enabled or disabled and should not be used to determine regulator current
|
||||
load.
|
||||
|
||||
|
||||
5. Regulator Operating Mode Control & Status (dynamic drivers)
|
||||
=============================================================
|
||||
|
||||
Some consumers can further save system power by changing the operating mode of
|
||||
their supply regulator to be more efficient when the consumers operating state
|
||||
changes. e.g. consumer driver is idle and subsequently draws less current
|
||||
|
||||
Regulator operating mode can be changed indirectly or directly.
|
||||
|
||||
Indirect operating mode control.
|
||||
--------------------------------
|
||||
Consumer drivers can request a change in their supply regulator operating mode
|
||||
by calling :-
|
||||
|
||||
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
||||
|
||||
This will cause the core to recalculate the total load on the regulator (based
|
||||
on all it's consumers) and change operating mode (if necessary and permitted)
|
||||
to best match the current operating load.
|
||||
|
||||
The load_uA value can be determined from the consumers datasheet. e.g.most
|
||||
datasheets have tables showing the max current consumed in certain situations.
|
||||
|
||||
Most consumers will use indirect operating mode control since they have no
|
||||
knowledge of the regulator or whether the regulator is shared with other
|
||||
consumers.
|
||||
|
||||
Direct operating mode control.
|
||||
------------------------------
|
||||
Bespoke or tightly coupled drivers may want to directly control regulator
|
||||
operating mode depending on their operating point. This can be achieved by
|
||||
calling :-
|
||||
|
||||
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
|
||||
unsigned int regulator_get_mode(struct regulator *regulator);
|
||||
|
||||
Direct mode will only be used by consumers that *know* about the regulator and
|
||||
are not sharing the regulator with other consumers.
|
||||
|
||||
|
||||
6. Regulator Events
|
||||
===================
|
||||
Regulators can notify consumers of external events. Events could be received by
|
||||
consumers under regulator stress or failure conditions.
|
||||
|
||||
Consumers can register interest in regulator events by calling :-
|
||||
|
||||
int regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
|
||||
Consumers can uregister interest by calling :-
|
||||
|
||||
int regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
|
||||
Regulators use the kernel notifier framework to send event to thier interested
|
||||
consumers.
|
101
Documentation/power/regulator/machine.txt
Normal file
101
Documentation/power/regulator/machine.txt
Normal file
|
@ -0,0 +1,101 @@
|
|||
Regulator Machine Driver Interface
|
||||
===================================
|
||||
|
||||
The regulator machine driver interface is intended for board/machine specific
|
||||
initialisation code to configure the regulator subsystem. Typical things that
|
||||
machine drivers would do are :-
|
||||
|
||||
1. Regulator -> Device mapping.
|
||||
2. Regulator supply configuration.
|
||||
3. Power Domain constraint setting.
|
||||
|
||||
|
||||
|
||||
1. Regulator -> device mapping
|
||||
==============================
|
||||
Consider the following machine :-
|
||||
|
||||
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
||||
|
|
||||
+-> [Consumer B @ 3.3V]
|
||||
|
||||
The drivers for consumers A & B must be mapped to the correct regulator in
|
||||
order to control their power supply. This mapping can be achieved in machine
|
||||
initialisation code by calling :-
|
||||
|
||||
int regulator_set_device_supply(const char *regulator, struct device *dev,
|
||||
const char *supply);
|
||||
|
||||
and is shown with the following code :-
|
||||
|
||||
regulator_set_device_supply("Regulator-1", devB, "Vcc");
|
||||
regulator_set_device_supply("Regulator-2", devA, "Vcc");
|
||||
|
||||
This maps Regulator-1 to the 'Vcc' supply for Consumer B and maps Regulator-2
|
||||
to the 'Vcc' supply for Consumer A.
|
||||
|
||||
|
||||
2. Regulator supply configuration.
|
||||
==================================
|
||||
Consider the following machine (again) :-
|
||||
|
||||
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
||||
|
|
||||
+-> [Consumer B @ 3.3V]
|
||||
|
||||
Regulator-1 supplies power to Regulator-2. This relationship must be registered
|
||||
with the core so that Regulator-1 is also enabled when Consumer A enables it's
|
||||
supply (Regulator-2).
|
||||
|
||||
This relationship can be register with the core via :-
|
||||
|
||||
int regulator_set_supply(const char *regulator, const char *regulator_supply);
|
||||
|
||||
In this example we would use the following code :-
|
||||
|
||||
regulator_set_supply("Regulator-2", "Regulator-1");
|
||||
|
||||
Relationships can be queried by calling :-
|
||||
|
||||
const char *regulator_get_supply(const char *regulator);
|
||||
|
||||
|
||||
3. Power Domain constraint setting.
|
||||
===================================
|
||||
Each power domain within a system has physical constraints on voltage and
|
||||
current. This must be defined in software so that the power domain is always
|
||||
operated within specifications.
|
||||
|
||||
Consider the following machine (again) :-
|
||||
|
||||
Regulator-1 -+-> Regulator-2 --> [Consumer A @ 1.8 - 2.0V]
|
||||
|
|
||||
+-> [Consumer B @ 3.3V]
|
||||
|
||||
This gives us two regulators and two power domains:
|
||||
|
||||
Domain 1: Regulator-2, Consumer B.
|
||||
Domain 2: Consumer A.
|
||||
|
||||
Constraints can be registered by calling :-
|
||||
|
||||
int regulator_set_platform_constraints(const char *regulator,
|
||||
struct regulation_constraints *constraints);
|
||||
|
||||
The example is defined as follows :-
|
||||
|
||||
struct regulation_constraints domain_1 = {
|
||||
.min_uV = 3300000,
|
||||
.max_uV = 3300000,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
};
|
||||
|
||||
struct regulation_constraints domain_2 = {
|
||||
.min_uV = 1800000,
|
||||
.max_uV = 2000000,
|
||||
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,
|
||||
.valid_modes_mask = REGULATOR_MODE_NORMAL,
|
||||
};
|
||||
|
||||
regulator_set_platform_constraints("Regulator-1", &domain_1);
|
||||
regulator_set_platform_constraints("Regulator-2", &domain_2);
|
171
Documentation/power/regulator/overview.txt
Normal file
171
Documentation/power/regulator/overview.txt
Normal file
|
@ -0,0 +1,171 @@
|
|||
Linux voltage and current regulator framework
|
||||
=============================================
|
||||
|
||||
About
|
||||
=====
|
||||
|
||||
This framework is designed to provide a standard kernel interface to control
|
||||
voltage and current regulators.
|
||||
|
||||
The intention is to allow systems to dynamically control regulator power output
|
||||
in order to save power and prolong battery life. This applies to both voltage
|
||||
regulators (where voltage output is controllable) and current sinks (where
|
||||
current limit is controllable).
|
||||
|
||||
(C) 2008 Wolfson Microelectronics PLC.
|
||||
Author: Liam Girdwood <lg@opensource.wolfsonmicro.com>
|
||||
|
||||
|
||||
Nomenclature
|
||||
============
|
||||
|
||||
Some terms used in this document:-
|
||||
|
||||
o Regulator - Electronic device that supplies power to other devices.
|
||||
Most regulators can enable and disable their output whilst
|
||||
some can control their output voltage and or current.
|
||||
|
||||
Input Voltage -> Regulator -> Output Voltage
|
||||
|
||||
|
||||
o PMIC - Power Management IC. An IC that contains numerous regulators
|
||||
and often contains other susbsystems.
|
||||
|
||||
|
||||
o Consumer - Electronic device that is supplied power by a regulator.
|
||||
Consumers can be classified into two types:-
|
||||
|
||||
Static: consumer does not change it's supply voltage or
|
||||
current limit. It only needs to enable or disable it's
|
||||
power supply. It's supply voltage is set by the hardware,
|
||||
bootloader, firmware or kernel board initialisation code.
|
||||
|
||||
Dynamic: consumer needs to change it's supply voltage or
|
||||
current limit to meet operation demands.
|
||||
|
||||
|
||||
o Power Domain - Electronic circuit that is supplied it's input power by the
|
||||
output power of a regulator, switch or by another power
|
||||
domain.
|
||||
|
||||
The supply regulator may be behind a switch(s). i.e.
|
||||
|
||||
Regulator -+-> Switch-1 -+-> Switch-2 --> [Consumer A]
|
||||
| |
|
||||
| +-> [Consumer B], [Consumer C]
|
||||
|
|
||||
+-> [Consumer D], [Consumer E]
|
||||
|
||||
That is one regulator and three power domains:
|
||||
|
||||
Domain 1: Switch-1, Consumers D & E.
|
||||
Domain 2: Switch-2, Consumers B & C.
|
||||
Domain 3: Consumer A.
|
||||
|
||||
and this represents a "supplies" relationship:
|
||||
|
||||
Domain-1 --> Domain-2 --> Domain-3.
|
||||
|
||||
A power domain may have regulators that are supplied power
|
||||
by other regulators. i.e.
|
||||
|
||||
Regulator-1 -+-> Regulator-2 -+-> [Consumer A]
|
||||
|
|
||||
+-> [Consumer B]
|
||||
|
||||
This gives us two regulators and two power domains:
|
||||
|
||||
Domain 1: Regulator-2, Consumer B.
|
||||
Domain 2: Consumer A.
|
||||
|
||||
and a "supplies" relationship:
|
||||
|
||||
Domain-1 --> Domain-2
|
||||
|
||||
|
||||
o Constraints - Constraints are used to define power levels for performance
|
||||
and hardware protection. Constraints exist at three levels:
|
||||
|
||||
Regulator Level: This is defined by the regulator hardware
|
||||
operating parameters and is specified in the regulator
|
||||
datasheet. i.e.
|
||||
|
||||
- voltage output is in the range 800mV -> 3500mV.
|
||||
- regulator current output limit is 20mA @ 5V but is
|
||||
10mA @ 10V.
|
||||
|
||||
Power Domain Level: This is defined in software by kernel
|
||||
level board initialisation code. It is used to constrain a
|
||||
power domain to a particular power range. i.e.
|
||||
|
||||
- Domain-1 voltage is 3300mV
|
||||
- Domain-2 voltage is 1400mV -> 1600mV
|
||||
- Domain-3 current limit is 0mA -> 20mA.
|
||||
|
||||
Consumer Level: This is defined by consumer drivers
|
||||
dynamically setting voltage or current limit levels.
|
||||
|
||||
e.g. a consumer backlight driver asks for a current increase
|
||||
from 5mA to 10mA to increase LCD illumination. This passes
|
||||
to through the levels as follows :-
|
||||
|
||||
Consumer: need to increase LCD brightness. Lookup and
|
||||
request next current mA value in brightness table (the
|
||||
consumer driver could be used on several different
|
||||
personalities based upon the same reference device).
|
||||
|
||||
Power Domain: is the new current limit within the domain
|
||||
operating limits for this domain and system state (e.g.
|
||||
battery power, USB power)
|
||||
|
||||
Regulator Domains: is the new current limit within the
|
||||
regulator operating parameters for input/ouput voltage.
|
||||
|
||||
If the regulator request passes all the constraint tests
|
||||
then the new regulator value is applied.
|
||||
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The framework is designed and targeted at SoC based devices but may also be
|
||||
relevant to non SoC devices and is split into the following four interfaces:-
|
||||
|
||||
|
||||
1. Consumer driver interface.
|
||||
|
||||
This uses a similar API to the kernel clock interface in that consumer
|
||||
drivers can get and put a regulator (like they can with clocks atm) and
|
||||
get/set voltage, current limit, mode, enable and disable. This should
|
||||
allow consumers complete control over their supply voltage and current
|
||||
limit. This also compiles out if not in use so drivers can be reused in
|
||||
systems with no regulator based power control.
|
||||
|
||||
See Documentation/power/regulator/consumer.txt
|
||||
|
||||
2. Regulator driver interface.
|
||||
|
||||
This allows regulator drivers to register their regulators and provide
|
||||
operations to the core. It also has a notifier call chain for propagating
|
||||
regulator events to clients.
|
||||
|
||||
See Documentation/power/regulator/regulator.txt
|
||||
|
||||
3. Machine interface.
|
||||
|
||||
This interface is for machine specific code and allows the creation of
|
||||
voltage/current domains (with constraints) for each regulator. It can
|
||||
provide regulator constraints that will prevent device damage through
|
||||
overvoltage or over current caused by buggy client drivers. It also
|
||||
allows the creation of a regulator tree whereby some regulators are
|
||||
supplied by others (similar to a clock tree).
|
||||
|
||||
See Documentation/power/regulator/machine.txt
|
||||
|
||||
4. Userspace ABI.
|
||||
|
||||
The framework also exports a lot of useful voltage/current/opmode data to
|
||||
userspace via sysfs. This could be used to help monitor device power
|
||||
consumption and status.
|
||||
|
||||
See Documentation/ABI/testing/regulator-sysfs.txt
|
30
Documentation/power/regulator/regulator.txt
Normal file
30
Documentation/power/regulator/regulator.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
Regulator Driver Interface
|
||||
==========================
|
||||
|
||||
The regulator driver interface is relatively simple and designed to allow
|
||||
regulator drivers to register their services with the core framework.
|
||||
|
||||
|
||||
Registration
|
||||
============
|
||||
|
||||
Drivers can register a regulator by calling :-
|
||||
|
||||
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
void *reg_data);
|
||||
|
||||
This will register the regulators capabilities and operations the regulator
|
||||
core. The core does not touch reg_data (private to regulator driver).
|
||||
|
||||
Regulators can be unregistered by calling :-
|
||||
|
||||
void regulator_unregister(struct regulator_dev *rdev);
|
||||
|
||||
|
||||
Regulator Events
|
||||
================
|
||||
Regulators can send events (e.g. over temp, under voltage, etc) to consumer
|
||||
drivers by calling :-
|
||||
|
||||
int regulator_notifier_call_chain(struct regulator_dev *rdev,
|
||||
unsigned long event, void *data);
|
|
@ -4504,6 +4504,15 @@ M: kaber@trash.net
|
|||
L: netdev@vger.kernel.org
|
||||
S: Maintained
|
||||
|
||||
VOLTAGE AND CURRENT REGULATOR FRAMEWORK
|
||||
P: Liam Girdwood
|
||||
M: lg@opensource.wolfsonmicro.com
|
||||
P: Mark Brown
|
||||
M: broonie@opensource.wolfsonmicro.com
|
||||
W: http://opensource.wolfsonmicro.com/node/15
|
||||
T: git kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6.git
|
||||
S: Supported
|
||||
|
||||
VT1211 HARDWARE MONITOR DRIVER
|
||||
P: Juerg Haefliger
|
||||
M: juergh@gmail.com
|
||||
|
|
|
@ -1225,6 +1225,8 @@ source "drivers/dma/Kconfig"
|
|||
|
||||
source "drivers/dca/Kconfig"
|
||||
|
||||
source "drivers/regulator/Kconfig"
|
||||
|
||||
source "drivers/uio/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -97,3 +97,4 @@ obj-$(CONFIG_PPC_PS3) += ps3/
|
|||
obj-$(CONFIG_OF) += of/
|
||||
obj-$(CONFIG_SSB) += ssb/
|
||||
obj-$(CONFIG_VIRTIO) += virtio/
|
||||
obj-$(CONFIG_REGULATOR) += regulator/
|
||||
|
|
59
drivers/regulator/Kconfig
Normal file
59
drivers/regulator/Kconfig
Normal file
|
@ -0,0 +1,59 @@
|
|||
menu "Voltage and Current regulators"
|
||||
|
||||
config REGULATOR
|
||||
bool "Voltage and Current Regulator Support"
|
||||
default n
|
||||
help
|
||||
Generic Voltage and Current Regulator support.
|
||||
|
||||
This framework is designed to provide a generic interface to voltage
|
||||
and current regulators within the Linux kernel. It's intended to
|
||||
provide voltage and current control to client or consumer drivers and
|
||||
also provide status information to user space applications through a
|
||||
sysfs interface.
|
||||
|
||||
The intention is to allow systems to dynamically control regulator
|
||||
output in order to save power and prolong battery life. This applies
|
||||
to both voltage regulators (where voltage output is controllable) and
|
||||
current sinks (where current output is controllable).
|
||||
|
||||
This framework safely compiles out if not selected so that client
|
||||
drivers can still be used in systems with no software controllable
|
||||
regulators.
|
||||
|
||||
If unsure, say no.
|
||||
|
||||
config REGULATOR_DEBUG
|
||||
bool "Regulator debug support"
|
||||
depends on REGULATOR
|
||||
help
|
||||
Say yes here to enable debugging support.
|
||||
|
||||
config REGULATOR_FIXED_VOLTAGE
|
||||
tristate
|
||||
default n
|
||||
select REGULATOR
|
||||
|
||||
config REGULATOR_VIRTUAL_CONSUMER
|
||||
tristate "Virtual regulator consumer support"
|
||||
default n
|
||||
select REGULATOR
|
||||
help
|
||||
This driver provides a virtual consumer for the voltage and
|
||||
current regulator API which provides sysfs controls for
|
||||
configuring the supplies requested. This is mainly useful
|
||||
for test purposes.
|
||||
|
||||
If unsure, say no.
|
||||
|
||||
config REGULATOR_BQ24022
|
||||
tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC"
|
||||
default n
|
||||
select REGULATOR
|
||||
help
|
||||
This driver controls a TI bq24022 Charger attached via
|
||||
GPIOs. The provided current regulator can enable/disable
|
||||
charging select between 100 mA and 500 mA charging current
|
||||
limit.
|
||||
|
||||
endmenu
|
12
drivers/regulator/Makefile
Normal file
12
drivers/regulator/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
#
|
||||
# Makefile for regulator drivers.
|
||||
#
|
||||
|
||||
|
||||
obj-$(CONFIG_REGULATOR) += core.o
|
||||
obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
|
||||
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
|
||||
|
||||
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
|
||||
|
||||
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
|
167
drivers/regulator/bq24022.c
Normal file
167
drivers/regulator/bq24022.c
Normal file
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
* Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
|
||||
* 1-Cell Li-Ion Charger connected via GPIOs.
|
||||
*
|
||||
* Copyright (c) 2008 Philipp Zabel
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/regulator/bq24022.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
|
||||
static int bq24022_set_current_limit(struct regulator_dev *rdev,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
struct platform_device *pdev = rdev_get_drvdata(rdev);
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
|
||||
dev_dbg(&pdev->dev, "setting current limit to %s mA\n",
|
||||
max_uA >= 500000 ? "500" : "100");
|
||||
|
||||
/* REVISIT: maybe return error if min_uA != 0 ? */
|
||||
gpio_set_value(pdata->gpio_iset2, max_uA >= 500000);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq24022_get_current_limit(struct regulator_dev *rdev)
|
||||
{
|
||||
struct platform_device *pdev = rdev_get_drvdata(rdev);
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
|
||||
return gpio_get_value(pdata->gpio_iset2) ? 500000 : 100000;
|
||||
}
|
||||
|
||||
static int bq24022_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct platform_device *pdev = rdev_get_drvdata(rdev);
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
|
||||
dev_dbg(&pdev->dev, "enabling charger\n");
|
||||
|
||||
gpio_set_value(pdata->gpio_nce, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq24022_disable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct platform_device *pdev = rdev_get_drvdata(rdev);
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
|
||||
dev_dbg(&pdev->dev, "disabling charger\n");
|
||||
|
||||
gpio_set_value(pdata->gpio_nce, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int bq24022_is_enabled(struct regulator_dev *rdev)
|
||||
{
|
||||
struct platform_device *pdev = rdev_get_drvdata(rdev);
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
|
||||
return !gpio_get_value(pdata->gpio_nce);
|
||||
}
|
||||
|
||||
static struct regulator_ops bq24022_ops = {
|
||||
.set_current_limit = bq24022_set_current_limit,
|
||||
.get_current_limit = bq24022_get_current_limit,
|
||||
.enable = bq24022_enable,
|
||||
.disable = bq24022_disable,
|
||||
.is_enabled = bq24022_is_enabled,
|
||||
};
|
||||
|
||||
static struct regulator_desc bq24022_desc = {
|
||||
.name = "bq24022",
|
||||
.ops = &bq24022_ops,
|
||||
.type = REGULATOR_CURRENT,
|
||||
};
|
||||
|
||||
static int __init bq24022_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
struct regulator_dev *bq24022;
|
||||
int ret;
|
||||
|
||||
if (!pdata || !pdata->gpio_nce || !pdata->gpio_iset2)
|
||||
return -EINVAL;
|
||||
|
||||
ret = gpio_request(pdata->gpio_nce, "ncharge_en");
|
||||
if (ret) {
|
||||
dev_dbg(&pdev->dev, "couldn't request nCE GPIO: %d\n",
|
||||
pdata->gpio_nce);
|
||||
goto err_ce;
|
||||
}
|
||||
ret = gpio_request(pdata->gpio_iset2, "charge_mode");
|
||||
if (ret) {
|
||||
dev_dbg(&pdev->dev, "couldn't request ISET2 GPIO: %d\n",
|
||||
pdata->gpio_iset2);
|
||||
goto err_iset2;
|
||||
}
|
||||
ret = gpio_direction_output(pdata->gpio_iset2, 0);
|
||||
ret = gpio_direction_output(pdata->gpio_nce, 1);
|
||||
|
||||
bq24022 = regulator_register(&bq24022_desc, pdev);
|
||||
if (IS_ERR(bq24022)) {
|
||||
dev_dbg(&pdev->dev, "couldn't register regulator\n");
|
||||
ret = PTR_ERR(bq24022);
|
||||
goto err_reg;
|
||||
}
|
||||
platform_set_drvdata(pdev, bq24022);
|
||||
dev_dbg(&pdev->dev, "registered regulator\n");
|
||||
|
||||
return 0;
|
||||
err_reg:
|
||||
gpio_free(pdata->gpio_iset2);
|
||||
err_iset2:
|
||||
gpio_free(pdata->gpio_nce);
|
||||
err_ce:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __devexit bq24022_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct bq24022_mach_info *pdata = pdev->dev.platform_data;
|
||||
struct regulator_dev *bq24022 = platform_get_drvdata(pdev);
|
||||
|
||||
regulator_unregister(bq24022);
|
||||
gpio_free(pdata->gpio_iset2);
|
||||
gpio_free(pdata->gpio_nce);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver bq24022_driver = {
|
||||
.driver = {
|
||||
.name = "bq24022",
|
||||
},
|
||||
.remove = __devexit_p(bq24022_remove),
|
||||
};
|
||||
|
||||
static int __init bq24022_init(void)
|
||||
{
|
||||
return platform_driver_probe(&bq24022_driver, bq24022_probe);
|
||||
}
|
||||
|
||||
static void __exit bq24022_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&bq24022_driver);
|
||||
}
|
||||
|
||||
/*
|
||||
* make sure this is probed before gpio_vbus and pda_power,
|
||||
* but after asic3 or other GPIO expander drivers.
|
||||
*/
|
||||
subsys_initcall(bq24022_init);
|
||||
module_exit(bq24022_exit);
|
||||
|
||||
MODULE_AUTHOR("Philipp Zabel");
|
||||
MODULE_DESCRIPTION("TI bq24022 Li-Ion Charger driver");
|
||||
MODULE_LICENSE("GPL");
|
1903
drivers/regulator/core.c
Normal file
1903
drivers/regulator/core.c
Normal file
File diff suppressed because it is too large
Load diff
129
drivers/regulator/fixed.c
Normal file
129
drivers/regulator/fixed.c
Normal file
|
@ -0,0 +1,129 @@
|
|||
/*
|
||||
* fixed.c
|
||||
*
|
||||
* Copyright 2008 Wolfson Microelectronics PLC.
|
||||
*
|
||||
* Author: Mark Brown <broonie@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 as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*
|
||||
* This is useful for systems with mixed controllable and
|
||||
* non-controllable regulators, as well as for allowing testing on
|
||||
* systems with no controllable regulators.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/fixed.h>
|
||||
|
||||
struct fixed_voltage_data {
|
||||
struct regulator_desc desc;
|
||||
struct regulator_dev *dev;
|
||||
int microvolts;
|
||||
};
|
||||
|
||||
static int fixed_voltage_is_enabled(struct regulator_dev *dev)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int fixed_voltage_enable(struct regulator_dev *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fixed_voltage_get_voltage(struct regulator_dev *dev)
|
||||
{
|
||||
struct fixed_voltage_data *data = rdev_get_drvdata(dev);
|
||||
|
||||
return data->microvolts;
|
||||
}
|
||||
|
||||
static struct regulator_ops fixed_voltage_ops = {
|
||||
.is_enabled = fixed_voltage_is_enabled,
|
||||
.enable = fixed_voltage_enable,
|
||||
.get_voltage = fixed_voltage_get_voltage,
|
||||
};
|
||||
|
||||
static int regulator_fixed_voltage_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct fixed_voltage_config *config = pdev->dev.platform_data;
|
||||
struct fixed_voltage_data *drvdata;
|
||||
int ret;
|
||||
|
||||
drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL);
|
||||
if (drvdata == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL);
|
||||
if (drvdata->desc.name == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
drvdata->desc.type = REGULATOR_VOLTAGE;
|
||||
drvdata->desc.owner = THIS_MODULE;
|
||||
drvdata->desc.ops = &fixed_voltage_ops,
|
||||
|
||||
drvdata->microvolts = config->microvolts;
|
||||
|
||||
drvdata->dev = regulator_register(&drvdata->desc, drvdata);
|
||||
if (IS_ERR(drvdata->dev)) {
|
||||
ret = PTR_ERR(drvdata->dev);
|
||||
goto err_name;
|
||||
}
|
||||
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
|
||||
dev_dbg(&pdev->dev, "%s supplying %duV\n", drvdata->desc.name,
|
||||
drvdata->microvolts);
|
||||
|
||||
return 0;
|
||||
|
||||
err_name:
|
||||
kfree(drvdata->desc.name);
|
||||
err:
|
||||
kfree(drvdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int regulator_fixed_voltage_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fixed_voltage_data *drvdata = platform_get_drvdata(pdev);
|
||||
|
||||
regulator_unregister(drvdata->dev);
|
||||
kfree(drvdata->desc.name);
|
||||
kfree(drvdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver regulator_fixed_voltage_driver = {
|
||||
.probe = regulator_fixed_voltage_probe,
|
||||
.remove = regulator_fixed_voltage_remove,
|
||||
.driver = {
|
||||
.name = "reg-fixed-voltage",
|
||||
},
|
||||
};
|
||||
|
||||
static int __init regulator_fixed_voltage_init(void)
|
||||
{
|
||||
return platform_driver_register(®ulator_fixed_voltage_driver);
|
||||
}
|
||||
module_init(regulator_fixed_voltage_init);
|
||||
|
||||
static void __exit regulator_fixed_voltage_exit(void)
|
||||
{
|
||||
platform_driver_unregister(®ulator_fixed_voltage_driver);
|
||||
}
|
||||
module_exit(regulator_fixed_voltage_exit);
|
||||
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_DESCRIPTION("Fixed voltage regulator");
|
||||
MODULE_LICENSE("GPL");
|
345
drivers/regulator/virtual.c
Normal file
345
drivers/regulator/virtual.c
Normal file
|
@ -0,0 +1,345 @@
|
|||
/*
|
||||
* reg-virtual-consumer.c
|
||||
*
|
||||
* Copyright 2008 Wolfson Microelectronics PLC.
|
||||
*
|
||||
* Author: Mark Brown <broonie@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 as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
struct virtual_consumer_data {
|
||||
struct mutex lock;
|
||||
struct regulator *regulator;
|
||||
int enabled;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int min_uA;
|
||||
int max_uA;
|
||||
unsigned int mode;
|
||||
};
|
||||
|
||||
static void update_voltage_constraints(struct virtual_consumer_data *data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (data->min_uV && data->max_uV
|
||||
&& data->min_uV <= data->max_uV) {
|
||||
ret = regulator_set_voltage(data->regulator,
|
||||
data->min_uV, data->max_uV);
|
||||
if (ret != 0) {
|
||||
printk(KERN_ERR "regulator_set_voltage() failed: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->min_uV && data->max_uV && !data->enabled) {
|
||||
ret = regulator_enable(data->regulator);
|
||||
if (ret == 0)
|
||||
data->enabled = 1;
|
||||
else
|
||||
printk(KERN_ERR "regulator_enable() failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
if (!(data->min_uV && data->max_uV) && data->enabled) {
|
||||
ret = regulator_disable(data->regulator);
|
||||
if (ret == 0)
|
||||
data->enabled = 0;
|
||||
else
|
||||
printk(KERN_ERR "regulator_disable() failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
|
||||
static void update_current_limit_constraints(struct virtual_consumer_data
|
||||
*data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (data->max_uA
|
||||
&& data->min_uA <= data->max_uA) {
|
||||
ret = regulator_set_current_limit(data->regulator,
|
||||
data->min_uA, data->max_uA);
|
||||
if (ret != 0) {
|
||||
pr_err("regulator_set_current_limit() failed: %d\n",
|
||||
ret);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->max_uA && !data->enabled) {
|
||||
ret = regulator_enable(data->regulator);
|
||||
if (ret == 0)
|
||||
data->enabled = 1;
|
||||
else
|
||||
printk(KERN_ERR "regulator_enable() failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
|
||||
if (!(data->min_uA && data->max_uA) && data->enabled) {
|
||||
ret = regulator_disable(data->regulator);
|
||||
if (ret == 0)
|
||||
data->enabled = 0;
|
||||
else
|
||||
printk(KERN_ERR "regulator_disable() failed: %d\n",
|
||||
ret);
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t show_min_uV(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", data->min_uV);
|
||||
}
|
||||
|
||||
static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
long val;
|
||||
|
||||
if (strict_strtol(buf, 10, &val) != 0)
|
||||
return count;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
data->min_uV = val;
|
||||
update_voltage_constraints(data);
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_max_uV(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", data->max_uV);
|
||||
}
|
||||
|
||||
static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
long val;
|
||||
|
||||
if (strict_strtol(buf, 10, &val) != 0)
|
||||
return count;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
data->max_uV = val;
|
||||
update_voltage_constraints(data);
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_min_uA(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", data->min_uA);
|
||||
}
|
||||
|
||||
static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
long val;
|
||||
|
||||
if (strict_strtol(buf, 10, &val) != 0)
|
||||
return count;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
data->min_uA = val;
|
||||
update_current_limit_constraints(data);
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_max_uA(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
return sprintf(buf, "%d\n", data->max_uA);
|
||||
}
|
||||
|
||||
static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
long val;
|
||||
|
||||
if (strict_strtol(buf, 10, &val) != 0)
|
||||
return count;
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
|
||||
data->max_uA = val;
|
||||
update_current_limit_constraints(data);
|
||||
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t show_mode(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
|
||||
switch (data->mode) {
|
||||
case REGULATOR_MODE_FAST:
|
||||
return sprintf(buf, "fast\n");
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
return sprintf(buf, "normal\n");
|
||||
case REGULATOR_MODE_IDLE:
|
||||
return sprintf(buf, "idle\n");
|
||||
case REGULATOR_MODE_STANDBY:
|
||||
return sprintf(buf, "standby\n");
|
||||
default:
|
||||
return sprintf(buf, "unknown\n");
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t set_mode(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct virtual_consumer_data *data = dev_get_drvdata(dev);
|
||||
unsigned int mode;
|
||||
int ret;
|
||||
|
||||
if (strncmp(buf, "fast", strlen("fast")) == 0)
|
||||
mode = REGULATOR_MODE_FAST;
|
||||
else if (strncmp(buf, "normal", strlen("normal")) == 0)
|
||||
mode = REGULATOR_MODE_NORMAL;
|
||||
else if (strncmp(buf, "idle", strlen("idle")) == 0)
|
||||
mode = REGULATOR_MODE_IDLE;
|
||||
else if (strncmp(buf, "standby", strlen("standby")) == 0)
|
||||
mode = REGULATOR_MODE_STANDBY;
|
||||
else {
|
||||
dev_err(dev, "Configuring invalid mode\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
mutex_lock(&data->lock);
|
||||
ret = regulator_set_mode(data->regulator, mode);
|
||||
if (ret == 0)
|
||||
data->mode = mode;
|
||||
else
|
||||
dev_err(dev, "Failed to configure mode: %d\n", ret);
|
||||
mutex_unlock(&data->lock);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(min_microvolts, 0666, show_min_uV, set_min_uV);
|
||||
static DEVICE_ATTR(max_microvolts, 0666, show_max_uV, set_max_uV);
|
||||
static DEVICE_ATTR(min_microamps, 0666, show_min_uA, set_min_uA);
|
||||
static DEVICE_ATTR(max_microamps, 0666, show_max_uA, set_max_uA);
|
||||
static DEVICE_ATTR(mode, 0666, show_mode, set_mode);
|
||||
|
||||
struct device_attribute *attributes[] = {
|
||||
&dev_attr_min_microvolts,
|
||||
&dev_attr_max_microvolts,
|
||||
&dev_attr_min_microamps,
|
||||
&dev_attr_max_microamps,
|
||||
&dev_attr_mode,
|
||||
};
|
||||
|
||||
static int regulator_virtual_consumer_probe(struct platform_device *pdev)
|
||||
{
|
||||
char *reg_id = pdev->dev.platform_data;
|
||||
struct virtual_consumer_data *drvdata;
|
||||
int ret, i;
|
||||
|
||||
drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL);
|
||||
if (drvdata == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto err;
|
||||
}
|
||||
|
||||
mutex_init(&drvdata->lock);
|
||||
|
||||
drvdata->regulator = regulator_get(&pdev->dev, reg_id);
|
||||
if (IS_ERR(drvdata->regulator)) {
|
||||
ret = PTR_ERR(drvdata->regulator);
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(attributes); i++) {
|
||||
ret = device_create_file(&pdev->dev, attributes[i]);
|
||||
if (ret != 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
drvdata->mode = regulator_get_mode(drvdata->regulator);
|
||||
|
||||
platform_set_drvdata(pdev, drvdata);
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
for (i = 0; i < ARRAY_SIZE(attributes); i++)
|
||||
device_remove_file(&pdev->dev, attributes[i]);
|
||||
kfree(drvdata);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int regulator_virtual_consumer_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct virtual_consumer_data *drvdata = platform_get_drvdata(pdev);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(attributes); i++)
|
||||
device_remove_file(&pdev->dev, attributes[i]);
|
||||
if (drvdata->enabled)
|
||||
regulator_disable(drvdata->regulator);
|
||||
regulator_put(drvdata->regulator);
|
||||
|
||||
kfree(drvdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver regulator_virtual_consumer_driver = {
|
||||
.probe = regulator_virtual_consumer_probe,
|
||||
.remove = regulator_virtual_consumer_remove,
|
||||
.driver = {
|
||||
.name = "reg-virt-consumer",
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static int __init regulator_virtual_consumer_init(void)
|
||||
{
|
||||
return platform_driver_register(®ulator_virtual_consumer_driver);
|
||||
}
|
||||
module_init(regulator_virtual_consumer_init);
|
||||
|
||||
static void __exit regulator_virtual_consumer_exit(void)
|
||||
{
|
||||
platform_driver_unregister(®ulator_virtual_consumer_driver);
|
||||
}
|
||||
module_exit(regulator_virtual_consumer_exit);
|
||||
|
||||
MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
|
||||
MODULE_DESCRIPTION("Virtual regulator consumer");
|
||||
MODULE_LICENSE("GPL");
|
21
include/linux/regulator/bq24022.h
Normal file
21
include/linux/regulator/bq24022.h
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
* Support for TI bq24022 (bqTINY-II) Dual Input (USB/AC Adpater)
|
||||
* 1-Cell Li-Ion Charger connected via GPIOs.
|
||||
*
|
||||
* Copyright (c) 2008 Philipp Zabel
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* bq24022_mach_info - platform data for bq24022
|
||||
* @gpio_nce: GPIO line connected to the nCE pin, used to enable / disable charging
|
||||
* @gpio_iset2: GPIO line connected to the ISET2 pin, used to limit charging current to 100 mA / 500 mA
|
||||
*/
|
||||
struct bq24022_mach_info {
|
||||
int gpio_nce;
|
||||
int gpio_iset2;
|
||||
};
|
284
include/linux/regulator/consumer.h
Normal file
284
include/linux/regulator/consumer.h
Normal file
|
@ -0,0 +1,284 @@
|
|||
/*
|
||||
* consumer.h -- SoC Regulator consumer support.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 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 Consumer 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% efficiency 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_REGULATOR_CONSUMER_H_
|
||||
#define __LINUX_REGULATOR_CONSUMER_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 frequency 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.
|
||||
*
|
||||
* These modes can be OR'ed together to make up a mask of valid register modes.
|
||||
*/
|
||||
|
||||
#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.
|
||||
* REGULATION_OUT Regulator output is out of regulation.
|
||||
* FAIL Regulator output has failed.
|
||||
* OVER_TEMP Regulator over temp.
|
||||
* FORCE_DISABLE Regulator shut down by software.
|
||||
*
|
||||
* NOTE: These events can be OR'ed together when passed into handler.
|
||||
*/
|
||||
|
||||
#define REGULATOR_EVENT_UNDER_VOLTAGE 0x01
|
||||
#define REGULATOR_EVENT_OVER_CURRENT 0x02
|
||||
#define REGULATOR_EVENT_REGULATION_OUT 0x04
|
||||
#define REGULATOR_EVENT_FAIL 0x08
|
||||
#define REGULATOR_EVENT_OVER_TEMP 0x10
|
||||
#define REGULATOR_EVENT_FORCE_DISABLE 0x20
|
||||
|
||||
struct regulator;
|
||||
|
||||
/**
|
||||
* struct regulator_bulk_data - Data used for bulk regulator operations.
|
||||
*
|
||||
* @supply The name of the supply. Initialised by the user before
|
||||
* using the bulk regulator APIs.
|
||||
* @consumer The regulator consumer for the supply. This will be managed
|
||||
* by the bulk API.
|
||||
*
|
||||
* The regulator APIs provide a series of regulator_bulk_() API calls as
|
||||
* a convenience to consumers which require multiple supplies. This
|
||||
* structure is used to manage data for these calls.
|
||||
*/
|
||||
struct regulator_bulk_data {
|
||||
const char *supply;
|
||||
struct regulator *consumer;
|
||||
};
|
||||
|
||||
#if defined(CONFIG_REGULATOR)
|
||||
|
||||
/* regulator get and put */
|
||||
struct regulator *__must_check regulator_get(struct device *dev,
|
||||
const char *id);
|
||||
void regulator_put(struct regulator *regulator);
|
||||
|
||||
/* regulator output control and status */
|
||||
int regulator_enable(struct regulator *regulator);
|
||||
int regulator_disable(struct regulator *regulator);
|
||||
int regulator_force_disable(struct regulator *regulator);
|
||||
int regulator_is_enabled(struct regulator *regulator);
|
||||
|
||||
int regulator_bulk_get(struct device *dev, int num_consumers,
|
||||
struct regulator_bulk_data *consumers);
|
||||
int regulator_bulk_enable(int num_consumers,
|
||||
struct regulator_bulk_data *consumers);
|
||||
int regulator_bulk_disable(int num_consumers,
|
||||
struct regulator_bulk_data *consumers);
|
||||
void regulator_bulk_free(int num_consumers,
|
||||
struct regulator_bulk_data *consumers);
|
||||
|
||||
int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV);
|
||||
int regulator_get_voltage(struct regulator *regulator);
|
||||
int regulator_set_current_limit(struct regulator *regulator,
|
||||
int min_uA, int max_uA);
|
||||
int regulator_get_current_limit(struct regulator *regulator);
|
||||
|
||||
int regulator_set_mode(struct regulator *regulator, unsigned int mode);
|
||||
unsigned int regulator_get_mode(struct regulator *regulator);
|
||||
int regulator_set_optimum_mode(struct regulator *regulator, int load_uA);
|
||||
|
||||
/* regulator notifier block */
|
||||
int regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
int regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb);
|
||||
|
||||
/* driver data - core doesn't touch */
|
||||
void *regulator_get_drvdata(struct regulator *regulator);
|
||||
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.
|
||||
*/
|
||||
static inline struct regulator *__must_check regulator_get(struct device *dev,
|
||||
const char *id)
|
||||
{
|
||||
/* Nothing except the stubbed out regulator API should be
|
||||
* looking at the value except to check if it is an error
|
||||
* value so the actual return value doesn't matter.
|
||||
*/
|
||||
return (struct regulator *)id;
|
||||
}
|
||||
static inline void regulator_put(struct regulator *regulator)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int regulator_enable(struct regulator *regulator)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_disable(struct regulator *regulator)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_is_enabled(struct regulator *regulator)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int regulator_bulk_get(struct device *dev,
|
||||
int num_consumers,
|
||||
struct regulator_bulk_data *consumers)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_bulk_enable(int num_consumers,
|
||||
struct regulator_bulk_data *consumers)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_bulk_disable(int num_consumers,
|
||||
struct regulator_bulk_data *consumers)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void regulator_bulk_free(int num_consumers,
|
||||
struct regulator_bulk_data *consumers)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int regulator_set_voltage(struct regulator *regulator,
|
||||
int min_uV, int max_uV)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_get_voltage(struct regulator *regulator)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_set_current_limit(struct regulator *regulator,
|
||||
int min_uA, int max_uA)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_get_current_limit(struct regulator *regulator)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_set_mode(struct regulator *regulator,
|
||||
unsigned int mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline unsigned int regulator_get_mode(struct regulator *regulator)
|
||||
{
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static inline int regulator_set_optimum_mode(struct regulator *regulator,
|
||||
int load_uA)
|
||||
{
|
||||
return REGULATOR_MODE_NORMAL;
|
||||
}
|
||||
|
||||
static inline int regulator_register_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int regulator_unregister_notifier(struct regulator *regulator,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void *regulator_get_drvdata(struct regulator *regulator)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void regulator_set_drvdata(struct regulator *regulator,
|
||||
void *data)
|
||||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
99
include/linux/regulator/driver.h
Normal file
99
include/linux/regulator/driver.h
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* driver.h -- SoC Regulator driver support.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 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_DRIVER_H_
|
||||
#define __LINUX_REGULATOR_DRIVER_H_
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
struct regulator_constraints;
|
||||
struct regulator_dev;
|
||||
|
||||
/**
|
||||
* struct regulator_ops - regulator operations.
|
||||
*
|
||||
* This struct describes regulator operations.
|
||||
*/
|
||||
struct regulator_ops {
|
||||
|
||||
/* get/set regulator voltage */
|
||||
int (*set_voltage) (struct regulator_dev *, int min_uV, int max_uV);
|
||||
int (*get_voltage) (struct regulator_dev *);
|
||||
|
||||
/* get/set regulator current */
|
||||
int (*set_current_limit) (struct regulator_dev *,
|
||||
int min_uA, int max_uA);
|
||||
int (*get_current_limit) (struct regulator_dev *);
|
||||
|
||||
/* enable/disable regulator */
|
||||
int (*enable) (struct regulator_dev *);
|
||||
int (*disable) (struct regulator_dev *);
|
||||
int (*is_enabled) (struct regulator_dev *);
|
||||
|
||||
/* get/set regulator operating mode (defined in regulator.h) */
|
||||
int (*set_mode) (struct regulator_dev *, unsigned int mode);
|
||||
unsigned int (*get_mode) (struct regulator_dev *);
|
||||
|
||||
/* get most efficient regulator operating mode for load */
|
||||
unsigned int (*get_optimum_mode) (struct regulator_dev *, int input_uV,
|
||||
int output_uV, int load_uA);
|
||||
|
||||
/* the operations below are for configuration of regulator state when
|
||||
* it's parent PMIC enters a global STANBY/HIBERNATE state */
|
||||
|
||||
/* set regulator suspend voltage */
|
||||
int (*set_suspend_voltage) (struct regulator_dev *, int uV);
|
||||
|
||||
/* enable/disable regulator in suspend state */
|
||||
int (*set_suspend_enable) (struct regulator_dev *);
|
||||
int (*set_suspend_disable) (struct regulator_dev *);
|
||||
|
||||
/* set regulator suspend operating mode (defined in regulator.h) */
|
||||
int (*set_suspend_mode) (struct regulator_dev *, unsigned int mode);
|
||||
};
|
||||
|
||||
/*
|
||||
* Regulators can either control voltage or current.
|
||||
*/
|
||||
enum regulator_type {
|
||||
REGULATOR_VOLTAGE,
|
||||
REGULATOR_CURRENT,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct regulator_desc - Regulator descriptor
|
||||
*
|
||||
*/
|
||||
struct regulator_desc {
|
||||
const char *name;
|
||||
int id;
|
||||
struct regulator_ops *ops;
|
||||
int irq;
|
||||
enum regulator_type type;
|
||||
struct module *owner;
|
||||
};
|
||||
|
||||
|
||||
struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
void *reg_data);
|
||||
void regulator_unregister(struct regulator_dev *rdev);
|
||||
|
||||
int regulator_notifier_call_chain(struct regulator_dev *rdev,
|
||||
unsigned long event, void *data);
|
||||
|
||||
void *rdev_get_drvdata(struct regulator_dev *rdev);
|
||||
int rdev_get_id(struct regulator_dev *rdev);
|
||||
|
||||
#endif
|
22
include/linux/regulator/fixed.h
Normal file
22
include/linux/regulator/fixed.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* fixed.h
|
||||
*
|
||||
* Copyright 2008 Wolfson Microelectronics PLC.
|
||||
*
|
||||
* Author: Mark Brown <broonie@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 as
|
||||
* published by the Free Software Foundation; either version 2 of the
|
||||
* License, or (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef __REGULATOR_FIXED_H
|
||||
#define __REGULATOR_FIXED_H
|
||||
|
||||
struct fixed_voltage_config {
|
||||
const char *supply_name;
|
||||
int microvolts;
|
||||
};
|
||||
|
||||
#endif
|
104
include/linux/regulator/machine.h
Normal file
104
include/linux/regulator/machine.h
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* machine.h -- SoC Regulator support, machine/board driver API.
|
||||
*
|
||||
* Copyright (C) 2007, 2008 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 Machine/Board Interface.
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_REGULATOR_MACHINE_H_
|
||||
#define __LINUX_REGULATOR_MACHINE_H_
|
||||
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
struct regulator;
|
||||
|
||||
/*
|
||||
* Regulator operation constraint flags. These flags are used to enable
|
||||
* certain regulator operations and can be OR'ed together.
|
||||
*
|
||||
* 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 regulator_state - regulator state during low power syatem states
|
||||
*
|
||||
* This describes a regulators state during a system wide low power state.
|
||||
*/
|
||||
struct regulator_state {
|
||||
int uV; /* suspend voltage */
|
||||
unsigned int mode; /* suspend regulator operating mode */
|
||||
int enabled; /* is regulator enabled in this suspend state */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct regulation_constraints - regulator operating constraints.
|
||||
*
|
||||
* This struct describes regulator and board/machine specific constraints.
|
||||
*/
|
||||
struct regulation_constraints {
|
||||
|
||||
char *name;
|
||||
|
||||
/* voltage output range (inclusive) - for voltage control */
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
|
||||
/* current output range (inclusive) - 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;
|
||||
|
||||
/* regulator input voltage - only if supply is another regulator */
|
||||
int input_uV;
|
||||
|
||||
/* regulator suspend states for global PMIC STANDBY/HIBERNATE */
|
||||
struct regulator_state state_disk;
|
||||
struct regulator_state state_mem;
|
||||
struct regulator_state state_standby;
|
||||
suspend_state_t initial_state; /* suspend state to set at init */
|
||||
|
||||
/* constriant flags */
|
||||
unsigned always_on:1; /* regulator never off when system is on */
|
||||
unsigned boot_on:1; /* bootloader/firmware enabled regulator */
|
||||
unsigned apply_uV:1; /* apply uV constraint iff min == max */
|
||||
};
|
||||
|
||||
int regulator_set_supply(const char *regulator, const char *regulator_supply);
|
||||
|
||||
const char *regulator_get_supply(const char *regulator);
|
||||
|
||||
int regulator_set_machine_constraints(const char *regulator,
|
||||
struct regulation_constraints *constraints);
|
||||
|
||||
int regulator_set_device_supply(const char *regulator, struct device *dev,
|
||||
const char *supply);
|
||||
|
||||
int regulator_suspend_prepare(suspend_state_t state);
|
||||
|
||||
#endif
|
Loading…
Reference in a new issue