요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.
1. 요약·해설
원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.
2. 영어 원문 전체
번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.
원문 전체 펼치기
===================================
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 its supply regulator by calling ::
regulator = regulator_get(dev, "Vcc");
The consumer passes in its 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 by means of bulk operations ::
struct regulator_bulk_data supplies[2];
supplies[0].supply = "Vcc"; /* digital core */
supplies[1].supply = "Avdd"; /* analog */
ret = regulator_bulk_get(dev, ARRAY_SIZE(supplies), supplies);
// convenience helper to call regulator_put() on multiple regulators
regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
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 its power supply by calling::
int regulator_enable(regulator);
NOTE:
The supply may already be enabled before regulator_enable() 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 set of regulators can be enabled with a single bulk operation ::
int regulator_bulk_enable(int num_consumers,
struct regulator_bulk_data *consumers);
A consumer can disable its supply when no longer needed by calling::
int regulator_disable(regulator);
Or a number of them ::
int regulator_bulk_disable(int num_consumers,
struct regulator_bulk_data *consumers);
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);
This operation is also supported for multiple regulators ::
int regulator_bulk_force_disable(int num_consumers,
struct regulator_bulk_data *consumers);
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_uA, max_uA);
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_load(struct regulator *regulator, int load_uA);
This will cause the core to recalculate the total load on the regulator (based
on all its 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 consumer's datasheet. e.g. most
datasheets have tables showing the maximum 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 unregister interest by calling::
int regulator_unregister_notifier(struct regulator *regulator,
struct notifier_block *nb);
Regulators use the kernel notifier framework to send event to their interested
consumers.
7. Regulator Direct Register Access
===================================
Some kinds of power management hardware or firmware are designed such that
they need to do low-level hardware access to regulators, with no involvement
from the kernel. Examples of such devices are:
- clocksource with a voltage-controlled oscillator and control logic to change
the supply voltage over I2C to achieve a desired output clock rate
- thermal management firmware that can issue an arbitrary I2C transaction to
perform system poweroff during overtemperature conditions
To set up such a device/firmware, various parameters like I2C address of the
regulator, addresses of various regulator registers etc. need to be configured
to it. The regulator framework provides the following helpers for querying
these details.
Bus-specific details, like I2C addresses or transfer rates are handled by the
regmap framework. To get the regulator's regmap (if supported), use::
struct regmap *regulator_get_regmap(struct regulator *regulator);
To obtain the hardware register offset and bitmask for the regulator's voltage
selector register, use::
int regulator_get_hardware_vsel_register(struct regulator *regulator,
unsigned *vsel_reg,
unsigned *vsel_mask);
To convert a regulator framework voltage selector code (used by
regulator_list_voltage) to a hardware-specific voltage selector that can be
directly written to the voltage selector register, use::
int regulator_list_hardware_vsel(struct regulator *regulator,
unsigned selector);
To access the hardware for enabling/disabling the regulator, consumers must
use regulator_get_exclusive(), as it can't work if there's more than one
consumer. To enable/disable regulator use::
int regulator_hardware_enable(struct regulator *regulator, bool enable);
3. 한국어 전문 번역
영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.
Consumer driver interface 개요
1-8이 문서는 consumer device driver를 위한 regulator interface를 설명합니다. 여기서 사용하는 용어는 `overview.txt`, 현재 tree의 `Documentation/power/regulator/overview.rst`를 참고합니다.
===================================
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.
Supply regulator 획득과 해제
9-42Consumer driver는 `regulator_get(dev, "Vcc")`를 호출해 supply regulator에 접근합니다. Consumer는 `struct device` pointer와 power supply ID를 전달하고, core는 machine-specific lookup table에서 올바른 regulator를 찾습니다. 성공하면 이 consumer에 전력을 공급하는 `struct regulator` pointer를 반환합니다.
Regulator를 해제할 때는 `regulator_put(regulator)`를 호출합니다.
Codec의 digital·analog supply처럼 consumer 하나가 여러 regulator에서 전력을 받을 수 있습니다. 이 경우 `struct regulator_bulk_data supplies[]`에 `Vcc`, `Avdd` 같은 supply ID를 채우고 `regulator_bulk_get()`으로 한꺼번에 얻습니다. `regulator_bulk_free()`는 여러 regulator에 `regulator_put()`을 호출하는 convenience helper입니다.
일반적으로 `regulator_get()`은 device driver의 `probe()`에서, `regulator_put()`은 `remove()`에서 호출합니다.
Probe와 remove에 맞춰 단일 또는 bulk regulator handle을 관리합니다.
여러 supply를 갖는 consumer는 bulk helper로 오류 처리와 해제를 단순화합니다.
1. Consumer Regulator Access (static & dynamic drivers)
=======================================================
A consumer driver can get access to its supply regulator by calling ::
regulator = regulator_get(dev, "Vcc");
The consumer passes in its 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 by means of bulk operations ::
struct regulator_bulk_data supplies[2];
supplies[0].supply = "Vcc"; /* digital core */
supplies[1].supply = "Avdd"; /* analog */
ret = regulator_bulk_get(dev, ARRAY_SIZE(supplies), supplies);
// convenience helper to call regulator_put() on multiple regulators
regulator_bulk_free(ARRAY_SIZE(supplies), supplies);
The regulator access functions regulator_get() and regulator_put() will
usually be called in your device drivers probe() and remove() respectively.
Output enable과 disable
43-93Consumer는 `regulator_enable(regulator)`로 power supply를 enable합니다. 공유 regulator이거나 bootloader 또는 kernel board initialization code가 미리 enable했을 수 있으므로 호출 전에 이미 켜져 있을 수 있습니다.
`regulator_is_enabled(regulator)`는 regulator가 enable되어 있으면 0보다 큰 값을 반환합니다. 여러 regulator는 `regulator_bulk_enable()`로 한 번에 enable할 수 있습니다.
더 이상 필요 없으면 `regulator_disable(regulator)`을 호출하며 여러 regulator에는 `regulator_bulk_disable()`을 사용합니다. 다른 consumer와 공유한다면 즉시 꺼지지 않을 수 있고 enable reference count가 0이 될 때만 regulator가 disable됩니다.
Emergency에서는 `regulator_force_disable(regulator)` 또는 `regulator_bulk_force_disable()`로 강제 disable할 수 있습니다. 이 동작은 regulator output을 즉시 강제로 끄므로 모든 consumer의 전원이 차단됩니다.
정상 disable은 reference count를 존중하지만 force disable은 모든 consumer를 즉시 끕니다.
2. Regulator Output Enable & Disable (static & dynamic drivers)
===============================================================
A consumer can enable its power supply by calling::
int regulator_enable(regulator);
NOTE:
The supply may already be enabled before regulator_enable() 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 set of regulators can be enabled with a single bulk operation ::
int regulator_bulk_enable(int num_consumers,
struct regulator_bulk_data *consumers);
A consumer can disable its supply when no longer needed by calling::
int regulator_disable(regulator);
Or a number of them ::
int regulator_bulk_disable(int num_consumers,
struct regulator_bulk_data *consumers);
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);
This operation is also supported for multiple regulators ::
int regulator_bulk_force_disable(int num_consumers,
struct regulator_bulk_data *consumers);
NOTE:
this will immediately and forcefully shutdown the regulator output. All
consumers will be powered off.
Voltage 제어와 상태
94-124일부 consumer driver는 system operating point에 맞춰 supply voltage를 동적으로 바꿔야 합니다. CPUfreq driver는 frequency와 voltage를 함께 scaling해 power를 절약하고, SD driver는 올바른 card voltage를 선택할 수 있습니다.
`regulator_set_voltage(regulator, min_uV, max_uV)`는 microvolt 단위의 허용 minimum·maximum voltage 범위를 요청합니다.
Regulator가 enable 또는 disable 상태일 때 모두 호출할 수 있습니다. Enable 상태라면 voltage가 즉시 바뀌고, disable 상태라면 configuration만 바뀌었다가 다음 enable 때 실제 voltage가 설정됩니다.
`regulator_get_voltage(regulator)`는 configure된 output voltage를 반환합니다. Enable 여부와 무관하게 configuration을 반환하므로 output state 판정에 사용하면 안 됩니다. 실제 physical output voltage를 판단하려면 `regulator_is_enabled()`와 함께 사용합니다.
Configured value와 실제 energized output을 구분합니다.
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.
Current limit 제어와 상태
125-155일부 consumer driver는 operating point에 맞춰 supply current limit을 동적으로 바꿔야 합니다. LCD backlight driver는 current limit으로 밝기를 바꾸고, USB driver는 전력 공급 시 limit을 500mA로 설정할 수 있습니다.
`regulator_set_current_limit(regulator, min_uA, max_uA)`는 microamp 단위의 허용 minimum·maximum current limit을 요청합니다.
Regulator가 enable 또는 disable 상태일 때 모두 호출할 수 있습니다. Enable 상태에서는 current limit이 즉시 바뀌고, disable 상태에서는 configuration이 바뀐 뒤 다음 enable 때 실제 limit이 설정됩니다.
`regulator_get_current_limit(regulator)`는 enable 여부와 무관하게 current limit 설정을 반환하므로 regulator의 실제 current load를 판단하는 데 사용하면 안 됩니다.
설정된 limit은 실제 load 측정값이 아닙니다.
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_uA, max_uA);
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.
간접·직접 operating mode 제어
156-197Consumer의 operating state가 바뀌어 current draw가 줄어들 때 supply regulator의 operating mode를 더 효율적인 방식으로 바꾸면 system power를 더 절약할 수 있습니다. Mode는 간접 또는 직접 제어할 수 있습니다.
간접 방식에서 consumer driver는 `regulator_set_load(regulator, load_uA)`로 예상 load를 알립니다. Core는 모든 consumer를 기준으로 regulator total load를 다시 계산하고, 필요하고 허용되는 경우 현재 load에 가장 잘 맞는 operating mode로 바꿉니다.
`load_uA`는 특정 상황의 maximum current consumption 표가 있는 consumer datasheet에서 결정할 수 있습니다. 대부분의 consumer는 regulator의 세부사항이나 다른 consumer와의 공유 여부를 모르므로 간접 제어를 사용합니다.
특수하게 밀접 결합된 driver는 `regulator_set_mode()`와 `regulator_get_mode()`로 operating point에 따라 regulator mode를 직접 제어할 수 있습니다. Direct mode는 regulator를 정확히 알고 다른 consumer와 공유하지 않는 consumer만 사용합니다.
공유 supply에서는 core가 모든 load를 합산하는 간접 방식을 사용합니다.
각 consumer의 datasheet load를 합산해 core가 허용된 최적 mode를 고릅니다.
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_load(struct regulator *regulator, int load_uA);
This will cause the core to recalculate the total load on the regulator (based
on all its 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 consumer's datasheet. e.g. most
datasheets have tables showing the maximum 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.
Regulator event
198-216Regulator는 stress 또는 failure 조건 같은 외부 event를 consumer에 알릴 수 있습니다.
Consumer는 `regulator_register_notifier(regulator, nb)`로 event 관심을 등록하고 `regulator_unregister_notifier(regulator, nb)`로 해제합니다.
Regulator는 kernel notifier framework를 사용해 관심을 등록한 consumer에 event를 보냅니다.
Provider event가 notifier chain을 통해 등록 consumer에 전달됩니다.
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 unregister interest by calling::
int regulator_unregister_notifier(struct regulator *regulator,
struct notifier_block *nb);
Regulators use the kernel notifier framework to send event to their interested
consumers.
직접 hardware register 접근 지원
217-257일부 power-management hardware나 firmware는 kernel 개입 없이 regulator에 low-level hardware access를 해야 합니다. 예로 voltage-controlled oscillator가 있는 clocksource가 I2C로 supply voltage를 바꿔 원하는 clock rate를 만들거나, thermal firmware가 overtemperature 때 임의 I2C transaction으로 system poweroff를 수행하는 경우가 있습니다.
이런 장치나 firmware에는 regulator의 I2C address와 여러 register address 같은 parameter를 설정해야 하므로 regulator framework가 세부정보 조회 helper를 제공합니다.
I2C address나 transfer rate 같은 bus-specific 정보는 regmap framework가 처리합니다. 지원되는 경우 `regulator_get_regmap(regulator)`로 regulator의 `struct regmap`을 얻습니다.
`regulator_get_hardware_vsel_register(regulator, vsel_reg, vsel_mask)`는 voltage-selector register의 hardware offset과 bitmask를 얻습니다.
`regulator_list_hardware_vsel(regulator, selector)`는 `regulator_list_voltage`가 사용하는 framework voltage-selector code를 voltage-selector register에 직접 쓸 수 있는 hardware-specific selector로 변환합니다.
Enable/disable hardware에 직접 접근하려면 consumer가 하나뿐이어야 하므로 `regulator_get_exclusive()`를 사용해야 합니다. 이후 `regulator_hardware_enable(regulator, enable)`로 regulator를 enable 또는 disable합니다.
Bus 정보, selector 정보, exclusive enable을 별도 helper로 제공합니다.
7. Regulator Direct Register Access
===================================
Some kinds of power management hardware or firmware are designed such that
they need to do low-level hardware access to regulators, with no involvement
from the kernel. Examples of such devices are:
- clocksource with a voltage-controlled oscillator and control logic to change
the supply voltage over I2C to achieve a desired output clock rate
- thermal management firmware that can issue an arbitrary I2C transaction to
perform system poweroff during overtemperature conditions
To set up such a device/firmware, various parameters like I2C address of the
regulator, addresses of various regulator registers etc. need to be configured
to it. The regulator framework provides the following helpers for querying
these details.
Bus-specific details, like I2C addresses or transfer rates are handled by the
regmap framework. To get the regulator's regmap (if supported), use::
struct regmap *regulator_get_regmap(struct regulator *regulator);
To obtain the hardware register offset and bitmask for the regulator's voltage
selector register, use::
int regulator_get_hardware_vsel_register(struct regulator *regulator,
unsigned *vsel_reg,
unsigned *vsel_mask);
To convert a regulator framework voltage selector code (used by
regulator_list_voltage) to a hardware-specific voltage selector that can be
directly written to the voltage selector register, use::
int regulator_list_hardware_vsel(struct regulator *regulator,
unsigned selector);
To access the hardware for enabling/disabling the regulator, consumers must
use regulator_get_exclusive(), as it can't work if there's more than one
consumer. To enable/disable regulator use::
int regulator_hardware_enable(struct regulator *regulator, bool enable);
요약·해설
consumer.rst:1-257Consumer의 regulator 획득·enable·voltage/current/mode 제어, event와 direct hardware access API를 설명합니다.