diff --git a/documentation/6.components/device-driver/INDEX.md b/documentation/6.components/device-driver/INDEX.md index b8600c9e79..bbdeb43f7a 100644 --- a/documentation/6.components/device-driver/INDEX.md +++ b/documentation/6.components/device-driver/INDEX.md @@ -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 diff --git a/documentation/6.components/device-driver/device_driver_model/INDEX.md b/documentation/6.components/device-driver/device_driver_model/INDEX.md new file mode 100644 index 0000000000..46bad2a0f9 --- /dev/null +++ b/documentation/6.components/device-driver/device_driver_model/INDEX.md @@ -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/` diff --git a/documentation/6.components/device-driver/device_driver_model/regulator/README_zh.md b/documentation/6.components/device-driver/device_driver_model/regulator/README_zh.md new file mode 100644 index 0000000000..4487f6da9c --- /dev/null +++ b/documentation/6.components/device-driver/device_driver_model/regulator/README_zh.md @@ -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 = ; /* 最小电压(µV)*/ +regulator-max-microvolt = ; /* 最大电压(µV)*/ +regulator-min-microamp = ; /* 最小电流(µA)*/ +regulator-max-microamp = ; /* 最大电流(µA)*/ +regulator-ramp-delay = ; /* 电压变化率(µV/µs)*/ +regulator-enable-ramp-delay = ; /* 使能延迟(µs)*/ +regulator-settling-time-us = ; /* 稳定时间(µs)*/ +regulator-settling-time-up-us = ; /* 电压升高稳定时间 */ +regulator-settling-time-down-us = ; /* 电压降低稳定时间 */ +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`:供电名称(匹配设备树中的 `-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 +#include +#include +#include + +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 +#include +#include +#include + +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. **找不到调节器** + - 检查设备树:确保 `-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)