It's possible to use a GPIO with a kernel driver for making it work as a PWM.
HIGH _ _ _ _ _ _ _ _ | | | | | | | | | | | | | | | | GPIO | | | | | | | | | | | | | | | | __| |____| |____| |____| |____| |____| |____| |____| |____ LOW
Only tested in Attitude Adjustment. Patching, and building a custom firmware required.
Driver made by Bill Gatliff.
Emulates a PWM device using a GPIO pin and an hrtimer. Subject to CPU, scheduler and hardware limitations, can support many PWM outputs, e.g. as many as you have GPIO pins available for.
On a 200 MHz ARM9 processor, a PWM frequency of 100 Hz can be attained with this code so long as the duty cycle remains between about 20-80%. At higher or lower duty cycles, the transition events may arrive too close for the scheduler and CPU to reliably service.
Caveats:
Download the source code of Attitude Adjustment, and this file pwm-gpio-aa.tar.gz. Patch the build root
patch -p1 -i pwm-gpio-AA.patch
Enter in the kernel menu:
make kernel_menuconfig
and ensure configfs, PWM and GPIO_PWM are enabled.
You can use a native led at the router to test the driver, but first remove it from the board definition to get the gpio access.
Once flashed and openwrt running:
mkdir /config mount -t configfs none /config
Now create configurable GPIO PWM, example using the GPIO8
mkdir /config/gpio_pwm/8 echo 1 > /sys/class/pwm/gpio_pwm\:8/export
Check tick-hz
root@OpenWrt:/# cat /sys/class/pwm/gpio_pwm\:8/tick_hz 1000000000 root@OpenWrt:/#
Define the period for 100 Hz:
echo 10000000 > /sys/class/pwm/gpio_pwm\:8/period_ns
Define the duty cycle, 10%
echo 1000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns
Run it
echo 1 > /sys/class/pwm/gpio_pwm\:8/run
If a led is connected it should should bright at 10% or 90% depending on LED polarity.
Let's increase/decrease the virtual brightness
echo 1000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 2000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 3000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 4000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 5000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 6000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 7000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns echo 8000000 > /sys/class/pwm/gpio_pwm\:8/duty_ns
To disable, stop, unexport and delete it:
echo 0 > /sys/class/pwm/gpio_pwm\:8/run echo 1 > /sys/class/pwm/gpio_pwm\:8/unexport rm -rf /config/gpio_pwm/8