mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-02-06 14:01:39 +00:00
[documentation][device_driver_model] Add Chinese regulator docs and INDEX
Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
@page page_device Device Driver
|
||||
|
||||
- @subpage page_device_framework
|
||||
- @subpage page_device_dm
|
||||
- @subpage page_device_pin
|
||||
- @subpage page_device_uart
|
||||
- @subpage page_device_adc
|
||||
|
||||
@@ -0,0 +1,361 @@
|
||||
# Device Driver Model (DM) Documentation Index
|
||||
|
||||
This directory contains comprehensive documentation for RT-Thread's Device Driver Model and related subsystems.
|
||||
|
||||
## Core Documentation
|
||||
|
||||
- **[README.md](README.md)** - Device Driver Model Overview (English)
|
||||
- DM architecture and concepts
|
||||
- Bus, driver, and platform device models
|
||||
- OFW/Device Tree integration
|
||||
- Common APIs and usage patterns
|
||||
- Migration guide
|
||||
|
||||
- **[README_zh.md](README_zh.md)** - 设备驱动模型概述 (中文)
|
||||
- DM 架构和概念
|
||||
- 总线、驱动和平台设备模型
|
||||
- OFW/设备树集成
|
||||
- 通用 API 和使用模式
|
||||
- 迁移指南
|
||||
|
||||
## Module-Specific Documentation
|
||||
|
||||
### Power Management
|
||||
|
||||
#### Regulator Framework
|
||||
- **[regulator/README.md](regulator/README.md)** - Voltage/Current Regulator (English)
|
||||
- **[regulator/README_zh.md](regulator/README_zh.md)** - 电压/电流调节器 (中文)
|
||||
|
||||
**Status**: ✅ Complete
|
||||
**Topics Covered**:
|
||||
- Consumer API with complete examples
|
||||
- Provider (driver) implementation guide
|
||||
- Device tree bindings (fixed, GPIO, SCMI)
|
||||
- Best practices and troubleshooting
|
||||
- Performance considerations
|
||||
|
||||
#### Clock Framework
|
||||
- **clk/** - Clock Management Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Clock consumer API
|
||||
- Clock provider implementation
|
||||
- Clock tree management
|
||||
- Fixed-rate, PLL, mux, divider clocks
|
||||
- Device tree bindings
|
||||
|
||||
#### Pin Control
|
||||
- **pinctrl/** - Pin Multiplexing and Configuration
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Pin configuration API
|
||||
- Pin multiplexing
|
||||
- Pin control driver implementation
|
||||
- Device tree bindings
|
||||
|
||||
#### Reset Controller
|
||||
- **reset/** - Reset Controller Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Reset consumer API
|
||||
- Reset provider implementation
|
||||
- Device tree bindings
|
||||
|
||||
#### Power Domain
|
||||
- **pmdomain/** - Power Domain Management
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Power domain consumer API
|
||||
- Power domain provider implementation
|
||||
- Domain hierarchy
|
||||
- Device tree bindings
|
||||
|
||||
### Interrupt and Timing
|
||||
|
||||
#### Platform Interrupt Controller
|
||||
- **pic/** - Platform Interrupt Controller
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- IRQ domain management
|
||||
- IRQ mapping
|
||||
- PIC driver implementation
|
||||
|
||||
#### Hardware Timer
|
||||
- **hwtimer/** - Hardware Timer Framework (with DM support)
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Timer API with DM
|
||||
- Timer driver implementation
|
||||
- Device tree bindings
|
||||
|
||||
### Storage and Memory
|
||||
|
||||
#### NVMEM
|
||||
- **nvmem/** - Non-Volatile Memory Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- NVMEM consumer API
|
||||
- NVMEM provider implementation
|
||||
- EEPROM, OTP, eFuse support
|
||||
- Device tree bindings
|
||||
|
||||
#### Block Devices
|
||||
- **block/** - Block Device Layer (with DM support)
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Block device API with DM
|
||||
- Partition support
|
||||
- Device tree bindings
|
||||
|
||||
#### MTD
|
||||
- **mtd/** - Memory Technology Device (with DM support)
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- MTD framework with DM
|
||||
- NOR/NAND flash support
|
||||
- Device tree bindings
|
||||
|
||||
### Communication
|
||||
|
||||
#### Mailbox
|
||||
- **mailbox/** - Mailbox/Doorbell Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Mailbox consumer API
|
||||
- Mailbox controller driver
|
||||
- Inter-processor communication
|
||||
- Device tree bindings
|
||||
|
||||
#### DMA
|
||||
- **dma/** - DMA Engine Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- DMA consumer API
|
||||
- DMA controller driver
|
||||
- DMA transfer types
|
||||
- Device tree bindings
|
||||
|
||||
### Bus Controllers
|
||||
|
||||
#### PCI
|
||||
- **pci/** - PCI Bus Support
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- PCI device enumeration
|
||||
- PCI driver implementation
|
||||
- PCIe host controller
|
||||
- Device tree bindings
|
||||
|
||||
#### I2C (DM Extensions)
|
||||
- **i2c/** - I2C with DM Support
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- I2C with device tree
|
||||
- I2C controller driver with DM
|
||||
|
||||
#### SPI (DM Extensions)
|
||||
- **spi/** - SPI with DM Support
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- SPI with device tree
|
||||
- SPI controller driver with DM
|
||||
|
||||
### Specialized Hardware
|
||||
|
||||
#### Thermal Management
|
||||
- **thermal/** - Thermal Management Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Thermal zone management
|
||||
- Thermal cooling devices
|
||||
- Trip points
|
||||
- Device tree bindings
|
||||
|
||||
#### Multi-Function Device
|
||||
- **mfd/** - Multi-Function Device Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- MFD parent device
|
||||
- Sub-device registration
|
||||
- Shared resources
|
||||
- Device tree bindings
|
||||
|
||||
#### Industrial I/O
|
||||
- **iio/** - Industrial I/O Subsystem
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- IIO device framework
|
||||
- Channels and attributes
|
||||
- Buffered data capture
|
||||
- Device tree bindings
|
||||
|
||||
#### PHY Framework
|
||||
- **phy/** - Physical Layer Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- PHY consumer API
|
||||
- PHY provider implementation
|
||||
- USB, PCIe, SATA PHY support
|
||||
- Device tree bindings
|
||||
|
||||
#### Ethernet PHY
|
||||
- **phye/** - Ethernet PHY Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Ethernet PHY management
|
||||
- MDIO bus
|
||||
- PHY drivers
|
||||
- Device tree bindings
|
||||
|
||||
### System Support
|
||||
|
||||
#### Open Firmware (OFW)
|
||||
- **ofw/** - Device Tree Support
|
||||
|
||||
**Status**: ⚠️ Partially Documented
|
||||
**Existing**: [../ofw/dtc.md](../ofw/dtc.md)
|
||||
**Additional Planned Topics**:
|
||||
- FDT parsing internals
|
||||
- OFW API reference
|
||||
- Property reading helpers
|
||||
- IRQ and address translation
|
||||
|
||||
#### Firmware
|
||||
- **firmware/** - Firmware Framework
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- ARM SCMI support
|
||||
- Firmware loading
|
||||
- Device tree bindings
|
||||
|
||||
#### Hardware Cache
|
||||
- **hwcache/** - Hardware Cache Management
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Cache controller framework
|
||||
- L2/L3 cache management
|
||||
|
||||
#### Hardware Spinlock
|
||||
- **hwspinlock/** - Hardware Spinlock
|
||||
|
||||
**Status**: 📝 To Be Documented
|
||||
**Planned Topics**:
|
||||
- Hardware spinlock API
|
||||
- Multi-core synchronization
|
||||
|
||||
## Documentation Standards
|
||||
|
||||
All module documentation should include:
|
||||
|
||||
1. **Introduction**
|
||||
- General concept overview
|
||||
- RT-Thread specific implementation
|
||||
- Use cases
|
||||
|
||||
2. **Kconfig Configuration**
|
||||
- All configuration options
|
||||
- Menuconfig location
|
||||
- Dependencies
|
||||
|
||||
3. **Device Tree Bindings**
|
||||
- Standard properties
|
||||
- Example DTS nodes
|
||||
- Consumer usage examples
|
||||
|
||||
4. **Application Layer API**
|
||||
- Complete function reference
|
||||
- Parameter descriptions
|
||||
- Return values
|
||||
- Usage examples
|
||||
|
||||
5. **Driver Implementation Guide**
|
||||
- Key structures
|
||||
- Operations to implement
|
||||
- Complete driver examples
|
||||
- Best practices
|
||||
|
||||
6. **Comprehensive Examples**
|
||||
- Real-world use cases
|
||||
- Complete working code
|
||||
- Error handling patterns
|
||||
|
||||
7. **Troubleshooting**
|
||||
- Common issues
|
||||
- Debugging tips
|
||||
- Performance considerations
|
||||
|
||||
8. **Architecture Diagrams** (SVG)
|
||||
- Component relationships
|
||||
- Data flow
|
||||
- Clear and professional formatting
|
||||
|
||||
## Contributing
|
||||
|
||||
When adding new module documentation:
|
||||
|
||||
1. Follow the structure established by the regulator documentation
|
||||
2. Include both English and Chinese versions
|
||||
3. Provide complete, tested code examples
|
||||
4. Create clear SVG diagrams
|
||||
5. Cross-reference related modules
|
||||
6. Update this INDEX.md file
|
||||
|
||||
## Status Legend
|
||||
|
||||
- ✅ Complete - Full documentation available
|
||||
- ⚠️ Partial - Some documentation exists, needs completion
|
||||
- 📝 To Be Documented - Planned but not yet created
|
||||
- 🚧 In Progress - Currently being written
|
||||
|
||||
## Priority Modules
|
||||
|
||||
Based on usage frequency and importance:
|
||||
|
||||
1. ✅ **regulator** - Complete
|
||||
2. **clk** - High priority (power management)
|
||||
3. **pinctrl** - High priority (hardware configuration)
|
||||
4. **reset** - High priority (hardware control)
|
||||
5. **ofw** - High priority (device tree)
|
||||
6. **pic** - Medium priority (interrupt handling)
|
||||
7. **dma** - Medium priority (data transfer)
|
||||
8. **nvmem** - Medium priority (persistent data)
|
||||
9. **mailbox** - Medium priority (IPC)
|
||||
10. **thermal** - Medium priority (power management)
|
||||
|
||||
Other modules follow based on community needs and hardware support requirements.
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Device Driver Framework](../framework/device.md) - Basic device model
|
||||
- [Device Tree Compiler](../ofw/dtc.md) - DTC tool usage
|
||||
- [I2C Driver](../i2c/i2c.md) - Traditional I2C (compare with DM)
|
||||
- [SPI Driver](../spi/spi.md) - Traditional SPI (compare with DM)
|
||||
- [PIN Driver](../pin/pin.md) - Traditional PIN (compare with DM)
|
||||
|
||||
## External References
|
||||
|
||||
- [Device Tree Specification](https://devicetree-specification.readthedocs.io/)
|
||||
- [Linux Kernel Driver Model](https://www.kernel.org/doc/html/latest/driver-api/driver-model/)
|
||||
- [Linux Device Tree Bindings](https://www.kernel.org/doc/Documentation/devicetree/bindings/)
|
||||
- RT-Thread Source: `components/drivers/`
|
||||
@@ -0,0 +1,777 @@
|
||||
# Regulator 框架
|
||||
|
||||
## 简介
|
||||
|
||||
RT-Thread 的 Regulator(调节器)框架为嵌入式系统中的电压和电流调节器管理提供了标准化接口。调节器是为各种硬件外设、处理器和其他系统组件提供稳定电源供应的关键组件。
|
||||
|
||||
### 概述
|
||||
|
||||
电压调节器是一种电子电路,无论负载电流或输入电压如何变化,都能保持恒定的电压水平。它们对于以下方面至关重要:
|
||||
|
||||
- **电源管理**:高效的电源分配和管理
|
||||
- **电压调节**:动态电压和频率调节(DVFS)以优化功耗
|
||||
- **设备保护**:保护设备免受过压和过流影响
|
||||
- **系统稳定性**:确保硬件组件稳定运行
|
||||
|
||||
常见的调节器类型包括:
|
||||
- **线性调节器**:简单、低噪声但效率较低
|
||||
- **开关调节器(SMPS)**:更高效但可能产生噪声
|
||||
- **LDO(低压差调节器)**:压差低的线性调节器
|
||||
- **降压/升压转换器**:降压/升压开关调节器
|
||||
|
||||
### RT-Thread 实现
|
||||
|
||||
RT-Thread 的调节器框架位于 `components/drivers/regulator/`,提供:
|
||||
|
||||
1. **消费者 API**:设备驱动程序管理电源的简单接口
|
||||
2. **提供者 API**:实现调节器驱动程序的框架
|
||||
3. **调节器树**:调节器依赖关系的层次化管理
|
||||
4. **设备树集成**:从设备树自动配置
|
||||
5. **引用计数**:多消费者安全启用/禁用
|
||||
6. **通知链**:电压变化的事件通知
|
||||
7. **多驱动支持**:固定、GPIO 控制、SCMI 基础的调节器
|
||||
|
||||
**架构**:
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ 消费者驱动程序 │
|
||||
│ (UART, SPI, I2C, MMC, CPU 等) │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│ 消费者 API
|
||||
│ (get, enable, set_voltage 等)
|
||||
┌────────────────────┴────────────────────────────────────┐
|
||||
│ Regulator 框架核心 │
|
||||
│ - 引用计数 │
|
||||
│ - 调节器树管理 │
|
||||
│ - 通知链 │
|
||||
│ - 电压/电流验证 │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│ 提供者 API
|
||||
│ (操作回调)
|
||||
┌────────────────────┴────────────────────────────────────┐
|
||||
│ 调节器驱动程序 │
|
||||
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
|
||||
│ │ 固定 │ │ GPIO │ │ SCMI │ │
|
||||
│ │ 调节器 │ │ 调节器 │ │ 调节器 │ │
|
||||
│ └─────────────┘ └─────────────┘ └─────────────┘ │
|
||||
└────────────────────┬────────────────────────────────────┘
|
||||
│
|
||||
┌────────────────────┴────────────────────────────────────┐
|
||||
│ 硬件调节器 │
|
||||
│ (PMIC、分立调节器、电源) │
|
||||
└──────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Kconfig 配置
|
||||
|
||||
### 主配置
|
||||
|
||||
调节器框架依赖于设备驱动模型(DM):
|
||||
|
||||
```kconfig
|
||||
menuconfig RT_USING_REGULATOR
|
||||
bool "Using Voltage and Current Regulator"
|
||||
select RT_USING_ADT
|
||||
select RT_USING_ADT_REF
|
||||
depends on RT_USING_DM
|
||||
default n
|
||||
```
|
||||
|
||||
**在 menuconfig 中的位置**:
|
||||
```
|
||||
RT-Thread Components → Device Drivers → Using Voltage and Current Regulator
|
||||
```
|
||||
|
||||
**依赖项**:
|
||||
- `RT_USING_DM`:必须首先启用
|
||||
- `RT_USING_ADT`:抽象数据类型(自动)
|
||||
- `RT_USING_ADT_REF`:引用计数支持(自动)
|
||||
|
||||
### 调节器驱动选项
|
||||
|
||||
#### 固定调节器
|
||||
```kconfig
|
||||
config RT_REGULATOR_FIXED
|
||||
bool "Fixed regulator support"
|
||||
depends on RT_USING_REGULATOR
|
||||
depends on RT_USING_PIN
|
||||
depends on RT_USING_PINCTRL
|
||||
default y
|
||||
```
|
||||
|
||||
支持固定输出电压的调节器,可选通过 GPIO 使能引脚控制。
|
||||
|
||||
#### GPIO 调节器
|
||||
```kconfig
|
||||
config RT_REGULATOR_GPIO
|
||||
bool "GPIO regulator support"
|
||||
depends on RT_USING_REGULATOR
|
||||
depends on RT_USING_PIN
|
||||
default y
|
||||
```
|
||||
|
||||
支持通过 GPIO 引脚选择多个电压级别的调节器。
|
||||
|
||||
#### SCMI 调节器
|
||||
```kconfig
|
||||
config RT_REGULATOR_SCMI
|
||||
bool "SCMI regulator support"
|
||||
depends on RT_USING_REGULATOR
|
||||
depends on RT_USING_OFW
|
||||
depends on RT_FIRMWARE_ARM_SCMI
|
||||
default n
|
||||
```
|
||||
|
||||
支持通过 ARM 系统控制和管理接口(SCMI)控制的调节器。
|
||||
|
||||
## 设备树绑定
|
||||
|
||||
### 通用属性
|
||||
|
||||
所有调节器节点支持这些标准属性:
|
||||
|
||||
```dts
|
||||
regulator-name = "supply_name"; /* 可读名称 */
|
||||
regulator-min-microvolt = <value>; /* 最小电压(µV)*/
|
||||
regulator-max-microvolt = <value>; /* 最大电压(µV)*/
|
||||
regulator-min-microamp = <value>; /* 最小电流(µA)*/
|
||||
regulator-max-microamp = <value>; /* 最大电流(µA)*/
|
||||
regulator-ramp-delay = <value>; /* 电压变化率(µV/µs)*/
|
||||
regulator-enable-ramp-delay = <value>; /* 使能延迟(µs)*/
|
||||
regulator-settling-time-us = <value>; /* 稳定时间(µs)*/
|
||||
regulator-settling-time-up-us = <value>; /* 电压升高稳定时间 */
|
||||
regulator-settling-time-down-us = <value>; /* 电压降低稳定时间 */
|
||||
enable-active-high; /* 使能引脚高电平有效(默认)*/
|
||||
regulator-boot-on; /* 启动时使能 */
|
||||
regulator-always-on; /* 永不禁用 */
|
||||
regulator-soft-start; /* 使能软启动 */
|
||||
regulator-pull-down; /* 关闭时使能下拉 */
|
||||
regulator-over-current-protection; /* 使能过流保护 */
|
||||
```
|
||||
|
||||
### 固定调节器示例
|
||||
|
||||
固定调节器具有恒定的输出电压:
|
||||
|
||||
```dts
|
||||
regulators {
|
||||
/* 简单的固定 3.3V 调节器 */
|
||||
vcc_3v3: regulator-vcc-3v3 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc-3v3";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
regulator-always-on;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
/* 带 GPIO 使能控制的固定调节器 */
|
||||
vcc_sd: regulator-vcc-sd {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc-sd";
|
||||
regulator-min-microvolt = <3300000>;
|
||||
regulator-max-microvolt = <3300000>;
|
||||
gpio = <&gpio0 10 GPIO_ACTIVE_HIGH>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&sd_power_pins>;
|
||||
enable-active-high;
|
||||
startup-delay-us = <100000>; /* 100ms */
|
||||
off-on-delay-us = <10000>; /* 10ms */
|
||||
};
|
||||
|
||||
/* 由另一个调节器供电的调节器 */
|
||||
vcc_1v8: regulator-vcc-1v8 {
|
||||
compatible = "regulator-fixed";
|
||||
regulator-name = "vcc-1v8";
|
||||
regulator-min-microvolt = <1800000>;
|
||||
regulator-max-microvolt = <1800000>;
|
||||
vin-supply = <&vcc_3v3>; /* 父供电 */
|
||||
regulator-always-on;
|
||||
};
|
||||
};
|
||||
```
|
||||
|
||||
### 设备树中的消费者使用
|
||||
|
||||
设备使用 supply 属性引用调节器:
|
||||
|
||||
```dts
|
||||
/* 带多个电源的 UART */
|
||||
uart0: serial@10000000 {
|
||||
compatible = "vendor,uart";
|
||||
reg = <0x10000000 0x1000>;
|
||||
interrupts = <32>;
|
||||
clocks = <&clk_uart0>;
|
||||
|
||||
/* 电源 */
|
||||
vdd-supply = <&vcc_3v3>; /* 核心供电 */
|
||||
vddio-supply = <&vcc_1v8>; /* I/O 供电 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
/* 带调节器控制的 MMC/SD 控制器 */
|
||||
mmc0: mmc@20000000 {
|
||||
compatible = "vendor,mmc";
|
||||
reg = <0x20000000 0x1000>;
|
||||
|
||||
vmmc-supply = <&vcc_sd>; /* 卡电源 */
|
||||
vqmmc-supply = <&vcc_1v8>; /* I/O 电平转换器电源 */
|
||||
|
||||
status = "okay";
|
||||
};
|
||||
```
|
||||
|
||||
## 应用层 API
|
||||
|
||||
### 概述
|
||||
|
||||
消费者 API 为设备驱动程序提供管理其电源供应的函数。所有操作都使用通过 get API 获得的不透明 `struct rt_regulator` 指针。
|
||||
|
||||
### 获取和释放调节器
|
||||
|
||||
#### rt_regulator_get
|
||||
|
||||
```c
|
||||
struct rt_regulator *rt_regulator_get(struct rt_device *dev, const char *id);
|
||||
```
|
||||
|
||||
为设备获取调节器。
|
||||
|
||||
**参数**:
|
||||
- `dev`:设备结构指针
|
||||
- `id`:供电名称(匹配设备树中的 `<name>-supply`,例如 "vdd"、"vmmc")
|
||||
|
||||
**返回值**:
|
||||
- 成功时返回调节器指针
|
||||
- 失败时返回 NULL
|
||||
|
||||
**示例**:
|
||||
```c
|
||||
struct rt_device *dev = &pdev->parent;
|
||||
struct rt_regulator *vdd_reg;
|
||||
|
||||
/* 获取 "vdd" 供电 */
|
||||
vdd_reg = rt_regulator_get(dev, "vdd");
|
||||
if (!vdd_reg) {
|
||||
LOG_E("Failed to get vdd regulator");
|
||||
return -RT_ERROR;
|
||||
}
|
||||
```
|
||||
|
||||
#### rt_regulator_put
|
||||
|
||||
```c
|
||||
void rt_regulator_put(struct rt_regulator *reg);
|
||||
```
|
||||
|
||||
释放调节器引用。
|
||||
|
||||
**参数**:
|
||||
- `reg`:从 `rt_regulator_get()` 获得的调节器指针
|
||||
|
||||
### 启用和禁用
|
||||
|
||||
#### rt_regulator_enable
|
||||
|
||||
```c
|
||||
rt_err_t rt_regulator_enable(struct rt_regulator *reg);
|
||||
```
|
||||
|
||||
启用调节器。使用引用计数,因此多次启用需要匹配的禁用。
|
||||
|
||||
**参数**:
|
||||
- `reg`:调节器指针
|
||||
|
||||
**返回值**:
|
||||
- 成功时返回 `RT_EOK`
|
||||
- 失败时返回错误代码
|
||||
|
||||
**注意**:
|
||||
- 自动启用父调节器
|
||||
- 如果配置了启用延迟,则等待
|
||||
- 调用通知链
|
||||
|
||||
**示例**:
|
||||
```c
|
||||
rt_err_t ret;
|
||||
|
||||
ret = rt_regulator_enable(vdd_reg);
|
||||
if (ret != RT_EOK) {
|
||||
LOG_E("Failed to enable regulator: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
#### rt_regulator_disable
|
||||
|
||||
```c
|
||||
rt_err_t rt_regulator_disable(struct rt_regulator *reg);
|
||||
```
|
||||
|
||||
禁用调节器。仅当引用计数达到零时才实际禁用。
|
||||
|
||||
**参数**:
|
||||
- `reg`:调节器指针
|
||||
|
||||
**返回值**:
|
||||
- 成功时返回 `RT_EOK`
|
||||
- 失败时返回错误代码
|
||||
|
||||
#### rt_regulator_is_enabled
|
||||
|
||||
```c
|
||||
rt_bool_t rt_regulator_is_enabled(struct rt_regulator *reg);
|
||||
```
|
||||
|
||||
检查调节器当前是否启用。
|
||||
|
||||
**参数**:
|
||||
- `reg`:调节器指针
|
||||
|
||||
**返回值**:
|
||||
- 启用时返回 `RT_TRUE`
|
||||
- 禁用时返回 `RT_FALSE`
|
||||
|
||||
### 电压控制
|
||||
|
||||
#### rt_regulator_set_voltage
|
||||
|
||||
```c
|
||||
rt_err_t rt_regulator_set_voltage(struct rt_regulator *reg, int min_uvolt, int max_uvolt);
|
||||
```
|
||||
|
||||
在范围内设置调节器输出电压。
|
||||
|
||||
**参数**:
|
||||
- `reg`:调节器指针
|
||||
- `min_uvolt`:最小可接受电压(微伏,µV)
|
||||
- `max_uvolt`:最大可接受电压(微伏,µV)
|
||||
|
||||
**返回值**:
|
||||
- 成功时返回 `RT_EOK`
|
||||
- 不支持电压控制时返回 `-RT_ENOSYS`
|
||||
- 失败时返回错误代码
|
||||
|
||||
**注意**:
|
||||
- 电压必须在调节器配置的范围内
|
||||
- 框架在指定范围内选择最佳电压
|
||||
- 电压变化后等待稳定时间
|
||||
- 调用通知链并发送电压变化事件
|
||||
|
||||
**示例**:
|
||||
```c
|
||||
/* 将电压设置为 1.8V ±5% */
|
||||
ret = rt_regulator_set_voltage(vdd_reg, 1710000, 1890000);
|
||||
if (ret != RT_EOK) {
|
||||
LOG_E("Failed to set voltage: %d", ret);
|
||||
}
|
||||
|
||||
/* 设置精确电压 */
|
||||
ret = rt_regulator_set_voltage(vdd_reg, 3300000, 3300000);
|
||||
```
|
||||
|
||||
#### rt_regulator_get_voltage
|
||||
|
||||
```c
|
||||
int rt_regulator_get_voltage(struct rt_regulator *reg);
|
||||
```
|
||||
|
||||
获取当前调节器输出电压。
|
||||
|
||||
**参数**:
|
||||
- `reg`:调节器指针
|
||||
|
||||
**返回值**:
|
||||
- 当前电压(微伏,µV)
|
||||
- 失败时返回负错误代码
|
||||
|
||||
**示例**:
|
||||
```c
|
||||
int voltage = rt_regulator_get_voltage(vdd_reg);
|
||||
if (voltage > 0) {
|
||||
LOG_I("当前电压: %d.%03dV", voltage / 1000000, (voltage / 1000) % 1000);
|
||||
}
|
||||
```
|
||||
|
||||
### 工作模式
|
||||
|
||||
#### rt_regulator_set_mode
|
||||
|
||||
```c
|
||||
rt_err_t rt_regulator_set_mode(struct rt_regulator *reg, rt_uint32_t mode);
|
||||
```
|
||||
|
||||
设置调节器工作模式。
|
||||
|
||||
**参数**:
|
||||
- `reg`:调节器指针
|
||||
- `mode`:工作模式标志:
|
||||
- `RT_REGULATOR_MODE_FAST`:高速模式(功耗较高)
|
||||
- `RT_REGULATOR_MODE_NORMAL`:正常工作模式
|
||||
- `RT_REGULATOR_MODE_IDLE`:空闲模式(性能降低)
|
||||
- `RT_REGULATOR_MODE_STANDBY`:待机模式(功耗最低)
|
||||
|
||||
**返回值**:
|
||||
- 成功时返回 `RT_EOK`
|
||||
- 不支持模式控制时返回 `-RT_ENOSYS`
|
||||
- 失败时返回错误代码
|
||||
|
||||
**示例**:
|
||||
```c
|
||||
/* 空闲期间设置为低功耗模式 */
|
||||
rt_regulator_set_mode(vdd_reg, RT_REGULATOR_MODE_IDLE);
|
||||
|
||||
/* 恢复正常模式 */
|
||||
rt_regulator_set_mode(vdd_reg, RT_REGULATOR_MODE_NORMAL);
|
||||
```
|
||||
|
||||
## 完整应用示例
|
||||
|
||||
### 示例:带调节器控制的 MMC/SD 驱动程序
|
||||
|
||||
```c
|
||||
#include <rtthread.h>
|
||||
#include <drivers/platform.h>
|
||||
#include <drivers/regulator.h>
|
||||
#include <drivers/clk.h>
|
||||
|
||||
struct mmc_host {
|
||||
void *base;
|
||||
int irq;
|
||||
struct rt_clk *clk;
|
||||
struct rt_regulator *vmmc; /* 卡电源 */
|
||||
struct rt_regulator *vqmmc; /* I/O 电压电源 */
|
||||
};
|
||||
|
||||
static rt_err_t mmc_power_on(struct mmc_host *host)
|
||||
{
|
||||
rt_err_t ret;
|
||||
|
||||
/* 启用卡电源 */
|
||||
ret = rt_regulator_enable(host->vmmc);
|
||||
if (ret != RT_EOK) {
|
||||
LOG_E("启用 vmmc 失败: %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 将 I/O 电压设置为初始 3.3V */
|
||||
ret = rt_regulator_enable(host->vqmmc);
|
||||
if (ret != RT_EOK) {
|
||||
LOG_E("启用 vqmmc 失败: %d", ret);
|
||||
goto err_disable_vmmc;
|
||||
}
|
||||
|
||||
ret = rt_regulator_set_voltage(host->vqmmc, 3300000, 3300000);
|
||||
if (ret != RT_EOK) {
|
||||
goto err_disable_vqmmc;
|
||||
}
|
||||
|
||||
/* 启用时钟 */
|
||||
ret = rt_clk_prepare_enable(host->clk);
|
||||
if (ret != RT_EOK) {
|
||||
goto err_disable_vqmmc;
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
err_disable_vqmmc:
|
||||
rt_regulator_disable(host->vqmmc);
|
||||
err_disable_vmmc:
|
||||
rt_regulator_disable(host->vmmc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void mmc_power_off(struct mmc_host *host)
|
||||
{
|
||||
/* 禁用时钟 */
|
||||
rt_clk_disable_unprepare(host->clk);
|
||||
|
||||
/* 按相反顺序禁用调节器 */
|
||||
rt_regulator_disable(host->vqmmc);
|
||||
rt_regulator_disable(host->vmmc);
|
||||
}
|
||||
|
||||
static rt_err_t mmc_probe(struct rt_platform_device *pdev)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *dev = &pdev->parent;
|
||||
struct mmc_host *host;
|
||||
|
||||
/* 分配主机结构 */
|
||||
host = rt_calloc(1, sizeof(*host));
|
||||
if (!host)
|
||||
return -RT_ENOMEM;
|
||||
|
||||
/* 映射 MMIO 区域 */
|
||||
host->base = rt_dm_dev_iomap(dev, 0);
|
||||
if (!host->base) {
|
||||
ret = -RT_ERROR;
|
||||
goto err_free_host;
|
||||
}
|
||||
|
||||
/* 获取 IRQ */
|
||||
host->irq = rt_dm_dev_get_irq(dev, 0);
|
||||
|
||||
/* 获取时钟 */
|
||||
host->clk = rt_clk_get_by_name(dev, "mmc");
|
||||
if (!host->clk) {
|
||||
ret = -RT_ERROR;
|
||||
goto err_iounmap;
|
||||
}
|
||||
|
||||
/* 获取调节器 */
|
||||
host->vmmc = rt_regulator_get(dev, "vmmc");
|
||||
host->vqmmc = rt_regulator_get(dev, "vqmmc");
|
||||
|
||||
/* 启动 MMC */
|
||||
if (host->vmmc || host->vqmmc) {
|
||||
ret = mmc_power_on(host);
|
||||
if (ret != RT_EOK) {
|
||||
goto err_put_regulators;
|
||||
}
|
||||
}
|
||||
|
||||
pdev->priv = host;
|
||||
LOG_I("MMC 主机已初始化");
|
||||
|
||||
return RT_EOK;
|
||||
|
||||
err_put_regulators:
|
||||
if (host->vqmmc)
|
||||
rt_regulator_put(host->vqmmc);
|
||||
if (host->vmmc)
|
||||
rt_regulator_put(host->vmmc);
|
||||
rt_clk_put(host->clk);
|
||||
err_iounmap:
|
||||
rt_iounmap(host->base);
|
||||
err_free_host:
|
||||
rt_free(host);
|
||||
return ret;
|
||||
}
|
||||
```
|
||||
|
||||
## 驱动实现指南
|
||||
|
||||
### 核心结构
|
||||
|
||||
#### rt_regulator_param
|
||||
|
||||
```c
|
||||
struct rt_regulator_param {
|
||||
const char *name; /* 调节器名称 */
|
||||
|
||||
int min_uvolt; /* 最小电压(µV)*/
|
||||
int max_uvolt; /* 最大电压(µV)*/
|
||||
int min_uamp; /* 最小电流(µA)*/
|
||||
int max_uamp; /* 最大电流(µA)*/
|
||||
int ramp_delay; /* 电压爬坡率(µV/µs)*/
|
||||
int enable_delay; /* 使能延迟(µs)*/
|
||||
int off_on_delay; /* 关闭到打开延迟(µs)*/
|
||||
|
||||
rt_uint32_t enable_active_high:1; /* 使能引脚极性 */
|
||||
rt_uint32_t boot_on:1; /* 启动时启用 */
|
||||
rt_uint32_t always_on:1; /* 永不禁用 */
|
||||
rt_uint32_t soft_start:1; /* 软启动启用 */
|
||||
};
|
||||
```
|
||||
|
||||
#### rt_regulator_ops
|
||||
|
||||
```c
|
||||
struct rt_regulator_ops {
|
||||
rt_err_t (*enable)(struct rt_regulator_node *reg);
|
||||
rt_err_t (*disable)(struct rt_regulator_node *reg);
|
||||
rt_bool_t (*is_enabled)(struct rt_regulator_node *reg);
|
||||
rt_err_t (*set_voltage)(struct rt_regulator_node *reg, int min_uvolt, int max_uvolt);
|
||||
int (*get_voltage)(struct rt_regulator_node *reg);
|
||||
rt_err_t (*set_mode)(struct rt_regulator_node *reg, rt_uint32_t mode);
|
||||
rt_int32_t (*get_mode)(struct rt_regulator_node *reg);
|
||||
};
|
||||
```
|
||||
|
||||
所有回调都是可选的。只实现硬件支持的功能。
|
||||
|
||||
### 简单固定调节器驱动程序示例
|
||||
|
||||
```c
|
||||
#include <rtthread.h>
|
||||
#include <drivers/platform.h>
|
||||
#include <drivers/regulator.h>
|
||||
#include <drivers/pin.h>
|
||||
|
||||
struct my_regulator {
|
||||
struct rt_regulator_node reg_node;
|
||||
struct rt_regulator_param param;
|
||||
rt_base_t enable_pin;
|
||||
};
|
||||
|
||||
static rt_err_t my_regulator_enable(struct rt_regulator_node *reg_node)
|
||||
{
|
||||
struct my_regulator *reg = rt_container_of(reg_node, struct my_regulator, reg_node);
|
||||
|
||||
if (reg->enable_pin >= 0) {
|
||||
rt_pin_mode(reg->enable_pin, PIN_MODE_OUTPUT);
|
||||
rt_pin_write(reg->enable_pin,
|
||||
reg->param.enable_active_high ? PIN_HIGH : PIN_LOW);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static rt_err_t my_regulator_disable(struct rt_regulator_node *reg_node)
|
||||
{
|
||||
struct my_regulator *reg = rt_container_of(reg_node, struct my_regulator, reg_node);
|
||||
|
||||
if (reg->enable_pin >= 0) {
|
||||
rt_pin_mode(reg->enable_pin, PIN_MODE_OUTPUT);
|
||||
rt_pin_write(reg->enable_pin,
|
||||
reg->param.enable_active_high ? PIN_LOW : PIN_HIGH);
|
||||
}
|
||||
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_regulator_ops my_regulator_ops = {
|
||||
.enable = my_regulator_enable,
|
||||
.disable = my_regulator_disable,
|
||||
};
|
||||
|
||||
static rt_err_t my_regulator_probe(struct rt_platform_device *pdev)
|
||||
{
|
||||
rt_err_t ret;
|
||||
struct rt_device *dev = &pdev->parent;
|
||||
struct my_regulator *reg;
|
||||
rt_uint32_t voltage;
|
||||
|
||||
/* 分配调节器结构 */
|
||||
reg = rt_calloc(1, sizeof(*reg));
|
||||
if (!reg)
|
||||
return -RT_ENOMEM;
|
||||
|
||||
/* 解析设备树属性 */
|
||||
rt_dm_dev_prop_read_u32(dev, "regulator-min-microvolt", &voltage);
|
||||
reg->param.min_uvolt = voltage;
|
||||
|
||||
rt_dm_dev_prop_read_u32(dev, "regulator-max-microvolt", &voltage);
|
||||
reg->param.max_uvolt = voltage;
|
||||
|
||||
reg->param.name = rt_dm_dev_get_name(dev);
|
||||
reg->param.enable_active_high =
|
||||
rt_dm_dev_prop_read_bool(dev, "enable-active-high");
|
||||
|
||||
/* 获取使能 GPIO 引脚 */
|
||||
reg->enable_pin = rt_pin_get_named_pin(dev, "enable", 0, RT_NULL, RT_NULL);
|
||||
|
||||
/* 初始化调节器节点 */
|
||||
reg->reg_node.dev = dev;
|
||||
reg->reg_node.supply_name = reg->param.name;
|
||||
reg->reg_node.ops = &my_regulator_ops;
|
||||
reg->reg_node.param = ®->param;
|
||||
|
||||
/* 向框架注册 */
|
||||
ret = rt_regulator_register(®->reg_node);
|
||||
if (ret != RT_EOK) {
|
||||
rt_free(reg);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pdev->priv = reg;
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
static const struct rt_ofw_node_id my_regulator_ofw_ids[] = {
|
||||
{ .compatible = "myvendor,my-regulator" },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct rt_platform_driver my_regulator_driver = {
|
||||
.name = "my-regulator",
|
||||
.ids = my_regulator_ofw_ids,
|
||||
.probe = my_regulator_probe,
|
||||
};
|
||||
|
||||
RT_PLATFORM_DRIVER_EXPORT(my_regulator_driver);
|
||||
```
|
||||
|
||||
## 最佳实践
|
||||
|
||||
### 对于消费者驱动程序
|
||||
|
||||
1. **始终检查返回值**:调节器操作可能失败
|
||||
2. **平衡启用/禁用**:每次启用都要匹配一次禁用
|
||||
3. **顺序很重要**:在时钟之前启用调节器,按相反顺序禁用
|
||||
4. **使用电压范围**:指定可接受的电压范围,而不是精确值
|
||||
5. **处理探测延迟**:调节器在早期启动时可能不可用
|
||||
|
||||
### 对于提供者驱动程序
|
||||
|
||||
1. **仅实现支持的操作**:不支持的操作留 NULL
|
||||
2. **使用引用计数**:不要自己跟踪启用,框架会处理
|
||||
3. **报告准确的参数**:提供正确的电压范围和延迟
|
||||
4. **处理父供电**:在设备树中为链式调节器设置 `vin-supply`
|
||||
|
||||
### 常见模式
|
||||
|
||||
#### 电源时序
|
||||
|
||||
```c
|
||||
/* 正确的上电顺序 */
|
||||
rt_regulator_enable(core_supply);
|
||||
rt_regulator_enable(io_supply);
|
||||
rt_clk_prepare_enable(clock);
|
||||
/* 初始化硬件 */
|
||||
|
||||
/* 正确的断电顺序(相反顺序)*/
|
||||
/* 关闭硬件 */
|
||||
rt_clk_disable_unprepare(clock);
|
||||
rt_regulator_disable(io_supply);
|
||||
rt_regulator_disable(core_supply);
|
||||
```
|
||||
|
||||
## 故障排除
|
||||
|
||||
### 常见问题
|
||||
|
||||
1. **找不到调节器**
|
||||
- 检查设备树:确保 `<name>-supply` 属性存在
|
||||
- 检查 compatible 字符串:验证调节器驱动已加载
|
||||
- 检查 Kconfig:启用调节器支持和驱动程序
|
||||
|
||||
2. **启用/禁用不平衡**
|
||||
- 计数启用/禁用调用:它们必须匹配
|
||||
- 检查错误路径:确保清理代码在失败时禁用
|
||||
- 使用调试:添加 LOG_D 调用以跟踪引用计数
|
||||
|
||||
3. **电压超出范围**
|
||||
- 检查设备树:验证 `regulator-min/max-microvolt` 属性
|
||||
- 检查硬件:确保物理调节器支持该电压
|
||||
- 检查父供电:父级必须支持子级的电压范围
|
||||
|
||||
## 性能考虑
|
||||
|
||||
### 内存使用
|
||||
|
||||
- 每个调节器节点:约 100-150 字节
|
||||
- 每个消费者引用:约 16 字节
|
||||
- 设备树开销:取决于复杂性
|
||||
|
||||
### 时序考虑
|
||||
|
||||
- 使能延迟:由硬件指定(µs 到 ms)
|
||||
- 爬坡延迟:电压相关(µs/伏)
|
||||
- 通知器开销:与注册的通知器数量成线性关系
|
||||
|
||||
## 相关模块
|
||||
|
||||
- **clk**:时钟管理,通常与调节器控制配对
|
||||
- **pinctrl**:引脚配置,可能需要电压切换
|
||||
- **pmdomain**:电源域管理,更高级别的电源控制
|
||||
- **thermal**:热管理,可能触发电压/频率调节
|
||||
|
||||
## 参考资料
|
||||
|
||||
- RT-Thread 源代码:`components/drivers/regulator/`
|
||||
- 头文件:`components/drivers/include/drivers/regulator.h`
|
||||
- 设备树绑定:[Linux Regulator 绑定](https://www.kernel.org/doc/Documentation/devicetree/bindings/regulator/)
|
||||
- [RT-Thread DM 文档](../README_zh.md)
|
||||
Reference in New Issue
Block a user