summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c122
1 files changed, 98 insertions, 24 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
index 535c0a0051..7e40b95437 100644
--- a/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
+++ b/firmware/target/arm/imx31/gigabeat-s/backlight-imx31.c
@@ -65,50 +65,124 @@ static const struct
65}; 65};
66#endif /* HAVE_BACKLIGHT_BRIGHTNESS */ 66#endif /* HAVE_BACKLIGHT_BRIGHTNESS */
67 67
68/* Bits always combined with ramping bits */
69#define MC13783_LED_CONTROL0_BITS \
70 (MC13783_LEDEN | MC13783_BOOSTEN | MC13783_ABMODE_MONCH_LEDMD1234 | \
71 MC13783_ABREF_400MV)
72
73static struct mutex backlight_mutex; /* Block brightness change while
74 * setting up fading */
75static bool backlight_on_status = true; /* Is on or off? */
76static uint32_t backlight_pwm_bits; /* Final PWM setting for fade-in */
77
78/* Backlight ramping settings */
79static uint32_t led_ramp_mask = MC13783_LEDMDRAMPDOWN | MC13783_LEDMDRAMPUP;
80
68bool _backlight_init(void) 81bool _backlight_init(void)
69{ 82{
70 mc13783_write(MC13783_LED_CONTROL0, 83 mutex_init(&backlight_mutex);
71 MC13783_LEDEN | 84
72 MC13783_LEDMDRAMPUP | 85 /* Set default LED register value */
73 MC13783_LEDMDRAMPDOWN | 86 mc13783_write(MC13783_LED_CONTROL0, MC13783_LED_CONTROL0_BITS);
74 MC13783_BOOSTEN | 87
75 MC13783_ABMODE_MONCH_LEDMD1234 | 88 /* Our PWM and I-Level is different than retailos (but same apparent
76 MC13783_ABREF_400MV); 89 * brightness), so init to our default. */
90 _backlight_set_brightness(DEFAULT_BRIGHTNESS_SETTING);
77 return true; 91 return true;
78} 92}
79 93
94void backlight_set_fade_out(bool value)
95{
96 if (value)
97 led_ramp_mask |= MC13783_LEDMDRAMPDOWN;
98 else
99 led_ramp_mask &= ~MC13783_LEDMDRAMPDOWN;
100}
101
102void backlight_set_fade_in(bool value)
103{
104 if (value)
105 led_ramp_mask |= MC13783_LEDMDRAMPUP;
106 else
107 led_ramp_mask &= ~MC13783_LEDMDRAMPUP;
108}
109
80void _backlight_on(void) 110void _backlight_on(void)
81{ 111{
82 /* LEDEN=1 */ 112 static const char regs[2] =
83 mc13783_set(MC13783_LED_CONTROL0, MC13783_LEDEN); 113 {
114 MC13783_LED_CONTROL0,
115 MC13783_LED_CONTROL2
116 };
117
118 uint32_t data[2];
119
120 mutex_lock(&backlight_mutex);
121
122 /* Set/clear LEDRAMPUP bit, clear LEDRAMPDOWN bit */
123 data[0] = MC13783_LED_CONTROL0_BITS;
124
125 if (!backlight_on_status)
126 data[0] |= led_ramp_mask & MC13783_LEDMDRAMPUP;
127
128 backlight_on_status = true;
129
130 /* Specify final PWM setting */
131 data[1] = mc13783_read(MC13783_LED_CONTROL2);
132
133 if (data[1] != MC13783_DATA_ERROR)
134 {
135 data[1] &= ~MC13783_LEDMDDC;
136 data[1] |= backlight_pwm_bits;
137
138 /* Write regs within 30us of each other (requires single xfer) */
139 mc13783_write_regset(regs, data, 2);
140 }
141
142 mutex_unlock(&backlight_mutex);
84} 143}
85 144
86void _backlight_off(void) 145void _backlight_off(void)
87{ 146{
88 /* LEDEN=0 */ 147 uint32_t ctrl0 = MC13783_LED_CONTROL0_BITS;
89 mc13783_clear(MC13783_LED_CONTROL0, MC13783_LEDEN); 148
149 mutex_lock(&backlight_mutex);
150
151 if (backlight_on_status)
152 ctrl0 |= led_ramp_mask & MC13783_LEDMDRAMPDOWN;
153
154 backlight_on_status = false;
155
156 /* Set/clear LEDRAMPDOWN bit, clear LEDRAMPUP bit */
157 mc13783_write(MC13783_LED_CONTROL0, ctrl0);
158
159 /* Wait 100us - 500ms */
160 sleep(HZ/100);
161
162 /* Write final PWM setting */
163 mc13783_write_masked(MC13783_LED_CONTROL2, MC13783_LEDMDDCw(0),
164 MC13783_LEDMDDC);
165
166 mutex_unlock(&backlight_mutex);
90} 167}
91 168
92#ifdef HAVE_BACKLIGHT_BRIGHTNESS 169#ifdef HAVE_BACKLIGHT_BRIGHTNESS
93/* Assumes that the backlight has been initialized */ 170/* Assumes that the backlight has been initialized - parameter should
171 * already be range-checked in public interface. */
94void _backlight_set_brightness(int brightness) 172void _backlight_set_brightness(int brightness)
95{ 173{
96 uint32_t data, md, pwm; 174 uint32_t md;
97
98 if ((unsigned)brightness >= ARRAYLEN(led_md_pwm_table))
99 brightness = DEFAULT_BRIGHTNESS_SETTING;
100
101 data = mc13783_read(MC13783_LED_CONTROL2);
102 175
103 if (data == (uint32_t)-1) 176 mutex_lock(&backlight_mutex);
104 return;
105 177
106 md = led_md_pwm_table[brightness].md; 178 md = led_md_pwm_table[brightness].md;
107 pwm = led_md_pwm_table[brightness].pwm; 179 backlight_pwm_bits = backlight_on_status ?
180 MC13783_LEDMDDCw(led_md_pwm_table[brightness].pwm) : 0;
108 181
109 data &= ~(MC13783_LEDMD | MC13783_LEDMDDC); 182 mc13783_write_masked(MC13783_LED_CONTROL2,
110 data |= MC13783_LEDMDw(md) | MC13783_LEDMDDCw(pwm); 183 MC13783_LEDMDw(md) | backlight_pwm_bits,
184 MC13783_LEDMD | MC13783_LEDMDDC);
111 185
112 mc13783_write(MC13783_LED_CONTROL2, data); 186 mutex_unlock(&backlight_mutex);
113} 187}
114#endif /* HAVE_BACKLIGHT_BRIGHTNESS */ 188#endif /* HAVE_BACKLIGHT_BRIGHTNESS */