diff options
author | Bertrik Sikken <bertrik@sikken.nl> | 2009-07-11 13:43:04 +0000 |
---|---|---|
committer | Bertrik Sikken <bertrik@sikken.nl> | 2009-07-11 13:43:04 +0000 |
commit | 306753b1ed328bcb3cf999a199580031f3d29603 (patch) | |
tree | 46dafa69b2270adb64c5ab928b7f4deeb3663315 /firmware | |
parent | e976c51df8801a40a111c2c3d7fd0a30a0402b71 (diff) | |
download | rockbox-306753b1ed328bcb3cf999a199580031f3d29603.tar.gz rockbox-306753b1ed328bcb3cf999a199580031f3d29603.zip |
Meizu: use hardware PWM instead of interrupts+GPIO to set the backlight brightness level
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21772 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/s5l8700/backlight-meizu.c | 73 |
1 files changed, 19 insertions, 54 deletions
diff --git a/firmware/target/arm/s5l8700/backlight-meizu.c b/firmware/target/arm/s5l8700/backlight-meizu.c index 23dcbb1820..bc0c290e05 100644 --- a/firmware/target/arm/s5l8700/backlight-meizu.c +++ b/firmware/target/arm/s5l8700/backlight-meizu.c | |||
@@ -26,55 +26,20 @@ | |||
26 | #include "system.h" | 26 | #include "system.h" |
27 | 27 | ||
28 | /* | 28 | /* |
29 | Interrupt-driven backlight driver using the PWM mode of a hardware timer. | 29 | Backlight driver using the PWM mode of a hardware timer. |
30 | 30 | ||
31 | Backlight brightness is implemented by configuring one of the timers in | 31 | The PWM duty cycle depends exponentially on the configured brightness |
32 | the SoC for PWM mode. In this mode, two interrupts are generated for each | 32 | level. This makes the brightness curve more linear to the human eye. |
33 | cycle, one at the start of the cycle and another one sometime between the | ||
34 | first interrupt and the start of the next cycle. The backlight is switched | ||
35 | on at the first interrupt and switched off at the second interrupt. This | ||
36 | way, the position in time of the second interrupt determines the duty cycle | ||
37 | and thereby the brightness of the backlight. | ||
38 | The backlight is switched on and off by means of a GPIO pin. | ||
39 | */ | 33 | */ |
40 | 34 | ||
41 | void INT_TIMERA(void) | ||
42 | { | ||
43 | unsigned int tacon = TACON; | ||
44 | |||
45 | /* clear interrupts */ | ||
46 | TACON = tacon; | ||
47 | |||
48 | /* TA_INT1, start of PWM cycle: enable backlight */ | ||
49 | if (tacon & (1 << 17)) { | ||
50 | PDAT0 |= (1 << 2); | ||
51 | } | ||
52 | |||
53 | /* TA_INT0, disable backlight until next cycle */ | ||
54 | if (tacon & (1 << 16)) { | ||
55 | PDAT0 &= ~(1 << 2); | ||
56 | } | ||
57 | } | ||
58 | |||
59 | void _backlight_set_brightness(int brightness) | 35 | void _backlight_set_brightness(int brightness) |
60 | { | 36 | { |
61 | static const unsigned char logtable[] = {0, 1, 2, 3, 5, 7, 10, 15, 22, 31, 44, 63, 90, 127, 180, 255}; | 37 | /* pwm = (sqrt(2)**x)-1, where brightness level x = 0..16 */ |
38 | static const unsigned char logtable[] = | ||
39 | {0, 1, 2, 3, 5, 7, 10, 15, 22, 31, 44, 63, 90, 127, 180, 255}; | ||
62 | 40 | ||
63 | if (brightness == MIN_BRIGHTNESS_SETTING) { | 41 | /* set PWM width */ |
64 | /* turn backlight fully off and disable interrupt */ | 42 | TCDATA0 = 255 - logtable[brightness]; |
65 | PDAT0 &= ~(1 << 2); | ||
66 | INTMSK &= ~(1 << 5); | ||
67 | } | ||
68 | else if (brightness == MAX_BRIGHTNESS_SETTING) { | ||
69 | /* turn backlight fully on and disable interrupt */ | ||
70 | PDAT0 |= (1 << 2); | ||
71 | INTMSK &= ~(1 << 5); | ||
72 | } | ||
73 | else { | ||
74 | /* set PWM width and enable interrupt */ | ||
75 | TADATA0 = logtable[brightness]; | ||
76 | INTMSK |= (1 << 5); | ||
77 | } | ||
78 | } | 43 | } |
79 | 44 | ||
80 | void _backlight_on(void) | 45 | void _backlight_on(void) |
@@ -89,22 +54,22 @@ void _backlight_off(void) | |||
89 | 54 | ||
90 | bool _backlight_init(void) | 55 | bool _backlight_init(void) |
91 | { | 56 | { |
92 | /* enable backlight pin as GPIO */ | 57 | /* enable backlight pin as timer output */ |
93 | PCON0 = ((PCON0 & ~(3 << 4)) | (1 << 4)); | 58 | PCON0 = ((PCON0 & ~(3 << 4)) | (2 << 4)); |
94 | 59 | ||
95 | /* enable timer clock */ | 60 | /* enable timer clock */ |
96 | PWRCON &= ~(1 << 4); | 61 | PWRCON &= ~(1 << 4); |
97 | 62 | ||
98 | /* configure timer */ | 63 | /* configure timer */ |
99 | TACMD = (1 << 1); /* TA_CLR */ | 64 | TCCMD = (1 << 1); /* TC_CLR */ |
100 | TACMD = (1 << 0); /* TA_EN */ | 65 | TCCON = (0 << 13) | /* TC_INT1_EN */ |
101 | TACON = (1 << 13) | /* TA_INT1_EN */ | 66 | (0 << 12) | /* TC_INT0_EN */ |
102 | (1 << 12) | /* TA_INT0_EN */ | 67 | (0 << 11) | /* TC_START */ |
103 | (1 << 11) | /* TA_START */ | 68 | (3 << 8) | /* TC_CS = PCLK / 64 */ |
104 | (3 << 8) | /* TA_CS = PCLK / 64 */ | 69 | (1 << 4); /* TC_MODE_SEL = PWM mode */ |
105 | (1 << 4); /* TA_MODE_SEL = PWM mode */ | 70 | TCDATA1 = 255; /* set PWM period */ |
106 | TADATA1 = 255; /* set PWM period */ | 71 | TCPRE = 30; /* prescaler */ |
107 | TAPRE = 30; /* prescaler */ | 72 | TCCMD = (1 << 0); /* TC_EN */ |
108 | 73 | ||
109 | _backlight_on(); | 74 | _backlight_on(); |
110 | 75 | ||