본문 바로가기

임베디드

PWM 기능과 LCD Backlight 드라이버

Allwinner i3/S3에는 16bit 분해능의 PWM 출력핀 2개가 있으며 일반적인 Cycle 모드와 좀 생소한 Pulse 모드를 지원한다.

그런데 커널 드라이버에는 일반적인 Cycle 모드만 구현되어 있는것으로 보인다.

 

 

 

PWM 포트 2개중 1개는 LCD 백라이트의 밝기 조정하는데 사용하였다.

 

먼저 PWM sysfs 노드를 이용하여 LCD 백라이트 밝기를 조정해보자.

참고로 현재 device tree에는 PWM 0번 채널만 활성화되어 있으니, PWM 1번 채널도 사용하려면 DTS를 수정하여야 한다.

 

아래 명령어로 활성화된 PWM 포트를 확인하고 node를 통해 접근할 수 있도록 export 시켜 보았다.

ls -l /sys/class/pwm/
echo 0 > /sys/class/pwm/pwmchip0/export 
ls -l /sys/class/pwm/pwmchip0/pwm0

마지막 결과는 아래와 같으며, 이제 pwm0 노드를 통해 제어가 가능해졌다.

# ls -l /sys/class/pwm/pwmchip0/pwm0/
total 0
-r--r--r--    1 root     root          4096 Jan  1 02:33 capture
-rw-r--r--    1 root     root          4096 Jan  1 02:33 duty_cycle
-rw-r--r--    1 root     root          4096 Jan  1 02:25 enable
-rw-r--r--    1 root     root          4096 Jan  1 02:31 period
-rw-r--r--    1 root     root          4096 Jan  1 02:26 polarity
drwxr-xr-x    2 root     root             0 Jan  1 02:21 power
-rw-r--r--    1 root     root          4096 Jan  1 02:33 uevent 

PWM 주파수가 1Khz가 되도록 할려면 주기를 1msec로 설정한다. 숫자 단위는 nsec이므로 1000000을 넣어준다.

그 다음 PWM 포트를 활성화 하고, 그 뒤에 50%의 듀티비가 되도록 0.5msec를 입력해 보았다.

echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period
echo 1 > /sys/class/pwm/pwmchip0/pwm0/enable
echo 500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle

그런데 LCD 화면에 아무것도 안보인다. 백라이트가 꺼진것 처럼 보인다.

기본 PWM 출력 위상 조절값인 polarity가 "inversed" 상태라서 그렇다. 이것으로 "normal"로 변경하고 period값을 조정하면 LCD 백라이트의 밝기가 변하는 것을 알 수 있다.

echo normal > /sys/class/pwm/pwmchip0/pwm0/polarity
echo 500000 > /sys/class/pwm/pwmchip0/pwm0/period
echo 100000 > /sys/class/pwm/pwmchip0/pwm0/period
echo 70000 > /sys/class/pwm/pwmchip0/pwm0/period
echo 1000000 > /sys/class/pwm/pwmchip0/pwm0/period

 

이렇게 PWM을 직접 제어해서 LCD 백라이트 밝기를 조절할 수 있으나, backlight 전용 드라이버를 사용하면 훨씬 깔끔해진다.

Device tree를 아래와 같이 수정하였다.

9 단계로 duty ratio 100%가 가장 밝고, 30%면 가장 흐리고 0이면 꺼진다. 기본값은 가장 밝은 9단계이다.

10%와 20%를 추가해 보았으나 LCD가 거의 보이질 않아 다시 제거하였다.

        backlight: backlight {
                compatible = "pwm-backlight";
                pwms = <&pwm 0 1000000 1>;
                brightness-levels = <0 30 40 50 60 70 80 90 100>;
                default-brightness-level = <8>;
                status = "okay";
        };

 

그리고 커널 menuconfig를 통해 아래 2개의 드라이버를 활성화 시켰다.

CONFIG_BACKLIGHT_CLASS_DEVICE=y
CONFIG_BACKLIGHT_PWM=y

 

이러게 변경하면 brightness sysfs를 이용하여 간단하게 9단계로 쉽게 LCD 백라이트 밝기 조절이 가능하다.

echo 0 >  /sys/class/backlight/backlight/brightness
echo 1 >  /sys/class/backlight/backlight/brightness
echo 2 >  /sys/class/backlight/backlight/brightness
echo 3 >  /sys/class/backlight/backlight/brightness
echo 4 >  /sys/class/backlight/backlight/brightness
echo 5 >  /sys/class/backlight/backlight/brightness
echo 6 >  /sys/class/backlight/backlight/brightness
echo 7 >  /sys/class/backlight/backlight/brightness
echo 8 >  /sys/class/backlight/backlight/brightness
echo 9 >  /sys/class/backlight/backlight/brightness
sh: write error: Invalid argument

 

관련 업데이트 내용을 github에 commit 하였다.

https://github.com/foxnux/linux/commit/f96ab6a070d3158d80dc1497d738cfdcb218cf16