PWM 配置
3 Mar 2025
Read time: 7 minute(s)
内核配置
-
在内核配置界面,按如下选择:
Linux Device Drivers ---> [*] Pulse-Width Modulation (PWM) Support ---> <*> ArtInChip PWM support <*> ArtInChip EPWM support
-
如需设置 PWM 模块的背光控制功能,执行下列配置,否则可跳过。
Linux Device Drivers ---> Graphics support ---> Backlight & LCD device support ---> <*> Lowlevel Backlight controls <*> Generic PWM based Backlight Driver
-
如使用 logo 功能,须在 Boot 阶段打开屏幕背光,否则可跳过。
U-Boot Device Drivers ---> [*] Enable support for pulse-width modulation devices (PWM) [*] Enable support for ArtInChip PWM Graphics support ---> [*] Generic PWM based Backlight Driver
DTS 参数配置
PWM 驱动支持从 DTS 中配置的自定义参数,如下表所示:
参数名称 |
类型 |
取值范围 |
功能说明 |
---|---|---|---|
mode |
String |
up/down/up-down-count |
配置增减模式 |
tb-clk-rate |
Integer |
(0, 24000000) |
时基计数器的工作时钟 |
action0 |
String |
none/low/high/inverse |
多个关键时点的触发行为 |
action1 |
String |
none/low/high/inverse |
多个关键时点的触发行为 |
default-level |
Integer |
[0, 1] |
默认/初始电平 |
注:
为了方便表达,所有参数名称都省略了前缀 “aic,”。
表中 action0 和 action1 四种取值的含义,定义如下:
Action 类型 |
行为描述 |
---|---|
none |
不做任何变化,保持之前的输出电平 |
low |
跳变为 0 电平 |
high |
跳变为 1 电平 |
inverse |
跳变为反向的电平,比如从 0 跳变为 1 |
D211 配置
common/d211.dtsi 中的参数配置:
pwm: pwm@19240000 { compatible = "artinchip,aic-pwm-v1.0"; reg = <0x0 0x19240000 0x0 0x1000>; interrupts-extended = <&plic0 90 IRQ_TYPE_LEVEL_HIGH>; #pwm-cells = <3>; clocks = <&cmu CLK_PWM>, <&cmu CLK_PLL_INT1>; clock-names = "pwm", "sysclk"; resets = <&rst RESET_PWM>; clock-rate = <48000000>; }; epwm: epwm@18200000 { compatible = "artinchip,aic-epwm-v1.0"; reg = <0x0 0x18200000 0x0 0x600>, <0 0x1820F000 0x0 0x1000>; interrupts-extended = <&plic0 25 IRQ_TYPE_LEVEL_HIGH>; #pwm-cells = <3>; clocks = <&cmu CLK_PWMCS>, <&cmu CLK_PLL_INT1>; clock-names = "pwmcs", "sysclk"; resets = <&rst RESET_PWMCS>; clock-rate = <48000000>; status = "disabled"; };
Board 配置
- PWM 通道配置xxx/board.dts 中的参数配置:
&pwm { status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&pwm2_pins_b>; /* mode: up-count, down-count, up-down-count action: none, low, high, inverse */ pwm0 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; aic,rise-edge-delay = <10>; aic,fall-edge-delay = <10>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "low", "none", "high"; aic,action1 = "none", "none", "none", "high", "none", "low"; status = "disabled"; }; pwm1 { aic,mode = "down-count"; aic,tb-clk-rate = <24000000>; aic,rise-edge-delay = <10>; aic,fall-edge-delay = <10>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "low", "none", "high"; aic,action1 = "none", "none", "none", "high", "none", "low"; status = "disabled"; }; pwm2 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "low", "none"; aic,action1 = "none", "none", "none", "low", "high", "none"; aic,default-level = <0>; aic,rise-edge-delay = <10>; aic,fall-edge-delay = <10>; status = "okay"; }; pwm3 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "low", "high", "none"; aic,action1 = "none", "none", "none", "high", "low", "none"; aic,rise-edge-delay = <10>; aic,fall-edge-delay = <10>; status = "disabled"; }; }; &epwm { status = "disabled"; pinctrl-names = "default"; pinctrl-0 = <&epwm0_pins_a>, <&epwm1_pins_a>, <&epwm2_pins_a>; /* mode: up-count, down-count, up-down-count action: none, low, high, inverse */ epwm0 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "none", "low"; aic,action1 = "none", "high", "none", "none", "none", "low"; status = "disabled"; }; epwm1 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "none", "low"; aic,action1 = "none", "high", "none", "none", "none", "low"; status = "disabled"; }; epwm2 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "none", "low"; aic,action1 = "none", "high", "none", "none", "none", "low"; status = "disabled"; }; epwm3 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "none", "low"; aic,action1 = "none", "high", "none", "none", "none", "low"; status = "disabled"; }; epwm4 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "none", "low"; aic,action1 = "none", "high", "none", "none", "none", "low"; status = "disabled"; }; epwm5 { aic,mode = "up-count"; aic,tb-clk-rate = <24000000>; /* CBD, CBU, CAD, CAU, PRD, ZRO */ aic,action0 = "none", "none", "none", "high", "none", "low"; aic,action1 = "none", "high", "none", "none", "none", "low"; status = "disabled"; }; };
- 背光控制配置需要在 xxx/board.dts 中新增一个 backlight 节点,如下:
backlight: backlight { compatible = "pwm-backlight"; /* pwm node name; pwm device No.; period_ns; pwm_polarity */ pwms = <&pwm 2 1000000 0>; brightness-levels = <0 10 20 30 40 50 60 70 80 90 100>; default-brightness-level = <8>; status = "okay"; };
其中 “&pwm 2” 表示要使用 pwm2 通道作为背光控制用(要确认和硬件上的电路连接是一致的)。
在屏幕 panel 节点中,需要引用 backlight:panel_lvds { compatible = "artinchip,aic-general-lvds-panel"; data-mapping = "vesa-24"; data-channel = "single-link1"; backlight = <&backlight>; status = "okay"; ... };