Backlight Driver Design
1. Here the hardware interface uses the s3c2450 gpb1, that is, the timer 1.
The input frequency of the timer is pclk/{prescaler value + 1}/{divider value }.
First set prescaler value:
Static void bak_setprescaleandmux (DWORD v_prescale, DWORD v_mux) <br/>{< br/> // set prescale. <br/> If (v_prescale <= 255) <br/> {<br/> v_ppwmregs-> t1_0 = v_ppwmregs-> t1_0 &(~ 0xff) | v_prescale; <br/>}< br/> // set divider value. timer1 is used <br/> switch (v_mux) <br/>{< br/> case 1: // 1/2 <br/> v_ppwmregs-> tcfg1 = v_ppwmregs-> tcfg1 &(~ 0xf0) | (0x0 <4); <br/> break; <br/> case 2: // 1/4 <br/> v_ppwmregs-> tcfg1 = v_ppwmregs-> tcfg1 &(~ 0xf0) | (0x1 <4); <br/> break; <br/> case 3: // 1/8 <br/> v_ppwmregs-> tcfg1 = v_ppwmregs-> tcfg1 &(~ 0xf0) | (0x2 <4); <br/> break; <br/> case 4: // 1/16 <br/> v_ppwmregs-> tcfg1 = v_ppwmregs-> tcfg1 &(~ 0xf0) | (0x3 <4); <br/> break; <br/> case 5: <br/> default: // external tclk0 <br/> v_ppwmregs-> tcfg1 = v_ppwmregs-> tcfg1 &(~ 0xf0) | (0x4 <4); <br/> break; <br/>}< br/>}
Then set divider value:
Static void bak_settcntb (DWORD v_tcntb) <br/>{< br/> If (v_tcntb <= 0 xFFFF) <br/>{< br/> v_ppwmregs-> tcntb1 = v_tcntb; <br/>}< br/>}
2. Set the PWM pulse width of the tout1 Timer:
Static void bak_settcmpb (DWORD v_tcmpb) <br/>{< br/> If (v_tcmpb <= 0 xFFFF) <br/>{< br/> v_ppwmregs-> tcmpb1 = v_tcmpb; <br/>}< br/>}
3. After these settings are complete, tout1 can be enabled. The Code is as follows:
Static void bak_startpwmtimer (void) <br/>{< br/> // set gpb1 to tout1. <br/> v_piopregs-> gpbcon & = ~ (0x03 <2); <br/> v_piopregs-> gpbcon | = (0x02 <2); <br/> // stop PWM timer 1, first. <br/> v_ppwmregs-> tcon & = ~ (0xf <8); <br/> v_ppwmregs-> tcon | = (0x6 <8 ); // here 0x2 <8 OK !!!!! <Br/> // start it again. <br/> v_ppwmregs-> tcon & = ~ (0xf <8); <br/> v_ppwmregs-> tcon | = (0x9 <8); <br/>}
4. The backlight brightness adjustment code is as follows (set the brightness to 10 levels ):
Static void bak_adjuctbacklightlevel (DWORD v_level) <br/>{< br/> If (v_level> = bak_level_min) & (v_level <= bak_level_max )) // v_level = [] <br/>{< br/> l_dwbacklightlevel = v_level; <br/> bak_settcmpb (l_dwtcntb * la_dwlevel [v_Level-1])/100 ); <br/>}< br/>}
5. After all the above operations are completed, you can compile a universal stream interface program. Because the program is relatively simple, here
The code for attaching only xxx_iocontrol is as follows:
Bool bak_iocontrol (<br/> DWORD hopencontext, <br/> DWORD dwcode, <br/> pbyte pbufin, <br/> DWORD dwlenin, <br/> pbyte pbufout, <br/> DWORD dwlenout, <br/> pdword pdwactualout <br/>) <br/>{< br/> DWORD dwerr = error_invalid_parameter; <br/> bool BRC; </P> <p> retailmsg (lqm_bakdbg, (text ("[lqm: BKL] IOCTL code = % d/R/N"), dwcode )); <br/> switch (dwcode) <br/> {<br/> case ioctl_power_capabilities: // determines Dev Ice-specific capabilities <br/> retailmsg (dbgbak, (text ("[lqm: BKL] ioctl_power_capabilities/R/N "))); <br/> If (pbufout & dwlenout> = sizeof (power_capabilities) & pdwactualout) <br/>{< br/>__ try <br/>{< br/> ppower_capabilities powercaps = (ppower_capabilities) pbufout; <br/> // right now supports D0 (permanently on) and D4 (off) only. <br/> memset (powercaps, 0, sizeof (* powercaps); <br/> powercaps-> Dev Icedx = 0x12; // support D0, D1, D4 <br/> * pdwactualout = sizeof (* powercaps); <br/> BRC = true; <br/> dwerr = error_success; <br/>}< br/>__ effection_execute_handler) <br/>{< br/> retailmsg (dbgbak1, (Text ("<BKL> exception in IOCTL/R/N "))); <br/>}< br/> else <br/> BRC = false; <br/> break; </P> <p> case ioctl_power_query: // determines whether changing power state is feasible <br/> retailmsg (dbgb AK, (text ("<BKL> received ioctl_power_query/R/N"); <br/> If (pbufout & dwlenout> = sizeof (cedevice_power_state )) <br/> {<br/> // return a good status on any valid query, since we are always ready to <br/> // change power States (if asked for state we don't support, we move to next highest, eg D3-> D4 ). <br/>__ try <br/>{< br/> cedevice_power_state reqdx = * (pcedevice_power_state) pbufout; </P> <p> If (VA Performance_dx (reqdx) <br/>{< br/> // This is a valid DX state so return a good status. <br/> BRC = true; <br/> dwerr = error_success; <br/>}< br/> else <br/>{< br/> BRC = false; <br/>}< br/> retailmsg (dbgbak, (text ("<BKL> ioctl_power_query % S/R/N"), dwerr = error_success? (Text ("succeeded"): (text ("failed"); <br/>}< br/>__ processing t (prediction_execute_handler) <br/>{< br/> retailmsg (dbgbak1, (text ("<BKL> exception in IOCTL/R/N "))); <br/>}< br/> else <br/> BRC = false; <br/> break; </P> <p> case ioctl_power_set: // requests a change from one device power state to another <br/> retailmsg (lqm_bakdbg, (text ("[lqm: BKL] encoded ed ioctl_power_set/R/N "))); <br/> If (pbufout & Dwlenout> = sizeof (cedevice_power_state) <br/>{< br/>__ try <br/>{< br/> cedevice_power_state reqdx = * (pcedevice_power_state) pbufout; </P> <p> If (valid_dx (reqdx) <br/>{< br/> retailmsg (lqm_bakdbg, (text ("[lqm: BKL] partitioned ed ioctl_power_set = % d/R/N "), reqdx); <br/> If (reqdx = (cedevice_power_state) D2 | reqdx = (cedevice_power_state) d3) <br/> bklstatus = (cedevice_power_state) D4; <br/> else <br/> BK Lstatus = reqdx; </P> <p> // setevent (g_evtbacklight); <br/> // adjust the brightness and call the function to execute the adjustment. <br/> bak_hw_setbl (); <br/> * (bytes) pbufout = bklstatus; <br/> * pdwactualout = sizeof (cedevice_power_state); <br/> BRC = true; <br/> dwerr = error_success; <br/> retailmsg (lqm_bakdbg, (text ("[lqm: BKL] ioctl_power_set to d % d/R/N"), reqdx )); <br/>}< br/> else <br/> {<br/> BRC = false; <br/> retailmsg (dbgbak1, (text ("< BKL> invalid state request D % d/R/N "), reqdx); <br/>}< br/>__ processing t (prediction_execute_handler) <br/>{< br/> retailmsg (dbgbak1, (text ("<BKL> exception in IOCTL/R/N "))); <br/>}< br/> else <br/>{< br/> BRC = false; <br/>}< br/> break; </P> <p> case ioctl_power_get: // gets the current device power state <br/> retailmsg (dbgbak, (Text ("<BKL> received ioctl_power_get/R/n"); <br/> If (pbufout! = NULL & dwlenout> = sizeof (cedevice_power_state) <br/>{< br/>__ try <br/>{< br/> * (pcedevice_power_state) pbufout = getbacklightstatus (); </P> <p> BRC = true; <br/> dwerr = error_success; </P> <p> retailmsg (dbgbak, (Text ("<BKL> ioctl_power_get: Passing back % u/R/N"), getbacklightstatus (); <br/>}< br/>__ effection_execute_handler) <br/>{< br/> retailmsg (dbgbak1, (text ("<BKL> exception in IOCTL/R/N ") ); <Br/>}< br/> else <br/> BRC = false; <br/> break; <br/> // backlight brightness adjustment <br/> case ioctl_backlight_adjust: <br/> If (pbufout! = NULL & (dwlenout> = sizeof (DWORD) <br/>{< br/> DWORD dwbacklight = * (DWORD *) pbufout ); <br/> If (bak_level_max <dwbacklight) | (bak_level_min> dwbacklight) <br/>{< br/> * (DWORD *) pbufout = error_invalid_parameter; <br/> * pdwactualout = sizeof (DWORD); </P> <p> BRC = false; <br/>}< br/> else <br/> {<br/> bak_adjuctbacklightlevel (* (DWORD *) pbufout); <br/> // adjust backlight level. <br/> * (DWORD *) pbufout = Error_success; <br/> * pdwactualout = sizeof (DWORD); <br/> BRC = true; <br/>}< br/> else <br/>{< br/> BRC = false; <br/>}< br/> break; <br/> case ioctl_backlight_getlevel: <br/> If (pbufout! = NULL & (dwlenout> = sizeof (DWORD) <br/>{< br/> // return the current backlight level. <br/> * (DWORD *) pbufout = l_dwbacklightlevel; <br/> * pdwactualout = sizeof (DWORD); <br/> BRC = true; <br/>}< br/> else <br/>{< br/> BRC = false; <br/>}< br/> break; <br/>}< br/> return (BRC); <br/>}
We can see the following cases:
Ioctl_power_capabilities;
Ioctl_power_query;
Ioctl_power_set;
Ioctl_power_get;
Ioctl_backlight_adjust;
Ioctl_backlight_getlevel;
Where
Ioctl_power_capabilities: indicates that the power manager Requests the device driver to return the power status and related features supported by the device;
Ioctl_power_set: Requests the driver to update the power status of the device;
Ioctl_power_query: The power manager asks if the device is ready for status switching;
Ioctl_power_get: Request the driver to return the power status of the current device;
Ioctl_backlight_adjust: interface for adjusting the backlight brightness;
Ioctl_backlight_getlevel: interface for obtaining the backlight brightness level.
For specific calls to some interfaces, see the next article, the application design of backlight adjustment.