diff options
Diffstat (limited to 'common/wmt_display/pwm.c')
-rwxr-xr-x | common/wmt_display/pwm.c | 306 |
1 files changed, 306 insertions, 0 deletions
diff --git a/common/wmt_display/pwm.c b/common/wmt_display/pwm.c new file mode 100755 index 0000000..d19cd50 --- /dev/null +++ b/common/wmt_display/pwm.c @@ -0,0 +1,306 @@ +/*++ + * linux/drivers/video/wmt/lcd.c + * WonderMedia video post processor (VPP) driver + * + * Copyright c 2010 WonderMedia Technologies, Inc. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * WonderMedia Technologies, Inc. + * 4F, 533, Chung-Cheng Road, Hsin-Tien, Taipei 231, R.O.C +--*/ + +/* + * ChangeLog + * + * 2010-08-05 Sam Shen <samshen@wondermedia.com.tw> + * * Add License declaration and ChangeLog + */ + + +/*----------------------- DEPENDENCE -----------------------------------------*/ +#include "vpp.h" +#include "wmt_display.h" +/*----------------------- Backlight --------------------------------------*/ +#ifdef CONFIG_VPP_SHENZHEN +#include "../../board/wmt/include/wmt_iomux.h" + +#define ENV_LOGO_LED "wmt.logo.led" + +static void logo_led_power_on(int on); +#endif + +#define pwm_write_reg(addr,val,wait) \ + REG32_VAL(addr) = val; \ + while(REG32_VAL(0xd8220040)&=wait); + +#define UBOOT_PWM_INVERT 0x10 +void lcd_blt_enable(int no,int enable) +{ +#ifdef CONFIG_VPP_SHENZHEN + lcd_backlight_power_on(enable != 0); +#endif + pwm_set_enable(no,enable); + +#ifdef CONFIG_VPP_SHENZHEN + logo_led_power_on(enable); +#endif + +} /* End of vt8430_blt_enable */ + +void lcd_blt_set_level(int no,int level) +{ + return; +} + +void lcd_blt_set_freq(int no,unsigned int freq) +{ + return; +} + +void lcd_blt_set_pwm(int no, int level, int freq) +{ + int clock = auto_pll_divisor(DEV_PWM,GET_FREQ, 0, 0); + int period, duty, scalar; + + clock = clock / freq; + scalar = 0; + period = 2000; + + while(period > 1023) { + scalar++; + period = clock / scalar; + } + + duty = (period*level)/100; + duty = (duty)? (duty-1):0; + scalar = scalar-1; + period = period -1; + + pwm_set_period(no,period); + pwm_set_duty(no,duty); + pwm_set_scalar(no,scalar); + if ((g_pwm_setting.config&UBOOT_PWM_INVERT) != 0) + pwm_set_control(no,(level)? 0x37:0x8); + else + pwm_set_control(no,(level)? 0x35:0x8); + pwm_set_gpio(no,level); +} + +void pwm_set_enable(int no,int enable) +{ + unsigned int addr,reg,reg1; + + addr = PWM_CTRL_REG_ADDR + (0x10 * no); + reg = REG32_VAL(addr); + if( enable ){ + reg |= PWM_ENABLE; + } + else { + reg &= ~PWM_ENABLE; + } + + pwm_write_reg(addr,reg,PWM_CTRL_UPDATE << (4*no)); + reg1 = REG32_VAL(addr); + pwm_set_gpio(no,enable); +} + +void pwm_set_control(int no,unsigned int ctrl) +{ + unsigned int addr; + + addr = PWM_CTRL_REG_ADDR + (0x10 * no); + pwm_write_reg(addr,ctrl,PWM_CTRL_UPDATE << (8*no)); +} /* End of pwm_proc */ + +void pwm_set_scalar(int no,unsigned int scalar) +{ + unsigned int addr; + + addr = PWM_SCALAR_REG_ADDR + (0x10 * no); + pwm_write_reg(addr,scalar,PWM_SCALAR_UPDATE << (8*no)); +} + +void pwm_set_period(int no,unsigned int period) +{ + unsigned int addr; + + addr = PWM_PERIOD_REG_ADDR + (0x10 * no); + pwm_write_reg(addr,period,PWM_PERIOD_UPDATE << (8*no)); +} + +void pwm_set_duty(int no,unsigned int duty) +{ + unsigned int addr; + + addr = PWM_DUTY_REG_ADDR + (0x10 * no); + pwm_write_reg(addr,duty,PWM_DUTY_UPDATE << (8*no)); +} + +unsigned int pwm_get_period(int no) +{ + unsigned int addr; + + addr = PWM_PERIOD_REG_ADDR + (0x10 * no); + return (REG32_VAL(addr) & 0xFFF); +} + +unsigned int pwm_get_duty(int no) +{ + unsigned int addr; + + addr = PWM_DUTY_REG_ADDR + (0x10 * no); + return (REG32_VAL(addr) & 0xFFF); +} + +unsigned int pwm_get_enable(int no) +{ + unsigned int addr,reg; + + addr = PWM_CTRL_REG_ADDR + (0x10 * no); + reg = REG32_VAL(addr); + reg &= PWM_ENABLE; + return reg; +} + +void set_lcd_power(int on) +{ + unsigned int val; + + if ((g_lcd_pw_pin.ctl == 0) || (g_lcd_pw_pin.oc == 0) || (g_lcd_pw_pin.od == 0)) { + printf("lcd power ping not define\n"); + return; + } + val = 1<<g_lcd_pw_pin.bitmap; + if (g_lcd_pw_pin.act == 0) + on = ~on; + REG32_VAL(g_lcd_pw_pin.ctl) |= val; + REG32_VAL(g_lcd_pw_pin.oc) |= val; + if (on) { + REG32_VAL(g_lcd_pw_pin.od) |= val; + } else { + REG32_VAL(g_lcd_pw_pin.od) &= ~val; + } +} + +void pwm_set_gpio(int no,int enable) +{ + /* unsigned int pwm_pin; */ + + if( enable ) { + if((g_pwm_setting.config&UBOOT_PWM_INVERT) != 0) + REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) &= 0xFE; + else + REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) |= 0x01; + + REG8_VAL(GPIO_OC_GP20_PWM0_BYTE_ADDR) &= 0xFE; + REG8_VAL(GPIO_CTRL_GP20_PWM0_BYTE_ADDR) &= 0xFE; + } else { + if((g_pwm_setting.config&UBOOT_PWM_INVERT) != 0) + REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) |= 0x01; + else + REG8_VAL(GPIO_OD_GP20_PWM0_BYTE_ADDR) &= 0xFE; + + REG8_VAL(GPIO_OC_GP20_PWM0_BYTE_ADDR) |= 0x01; + REG8_VAL(GPIO_CTRL_GP20_PWM0_BYTE_ADDR) |= 0x01; + } + /* set to PWM mode */ + if ( no == 0 ) + REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x1000; + else if( no == 1 ) + REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x80; + /* do not control back-light power in pwm */ + /* + pwm_pin = REG32_VAL(PWM_CTRL_REG_ADDR + (0x10 * no)); + if (((pwm_pin&PWM_ENABLE) != 0)&&(enable == 1)) + set_lcd_power(1); + if (((pwm_pin&PWM_ENABLE) == 0)&&(enable == 0)) + set_lcd_power(0); + */ +} + +#ifdef CONFIG_VPP_SHENZHEN + +static void logo_led_set_pwm(int no, int level, int freq, int active, int init) +{ + int clock; + int period, duty, scalar; + + if(init) { + clock = auto_pll_divisor(DEV_PWM,GET_FREQ, 0, 0); + clock = clock / freq; + scalar = 0; + period = 2000; + + while(period > 1023) { + scalar++; + period = clock / scalar; + } + + duty = (period*level)/100; + duty = (duty)? (duty-1):0; + scalar = scalar-1; + period = period -1; + + pwm_set_period(no,period); + pwm_set_duty(no,duty); + pwm_set_scalar(no,scalar); + REG32_VAL(PIN_SHARING_SEL_4BYTE_ADDR) &= ~0x80; + } + + if (active == 0) + pwm_set_control(no,(level)? 0x37:0x8); + else + pwm_set_control(no,(level)? 0x35:0x8); +} + +#define PWM2_GPIO_NO 200 + +static void logo_led_power_on(int on) +{ + int ret; + static int led_init; + static struct gpio_param_t led_control_pin; + + if(led_init == -1) + return; + + if(led_init == 0) { + ret = parse_gpio_param(ENV_LOGO_LED, &led_control_pin); + if(ret) { + led_init = -1; + return; + } + + led_init = 1; + } + + switch (led_control_pin.gpiono) { + case PWM2_GPIO_NO: + if(on) + logo_led_set_pwm(2, 100, 220000, led_control_pin.act, 1); + else + logo_led_set_pwm(2, 100, 220000, !led_control_pin.act, 1); + break; + + default: + if(on) + gpio_direction_output(led_control_pin.gpiono, led_control_pin.act); + else + gpio_direction_output(led_control_pin.gpiono, !led_control_pin.act); + break; + } +} +#endif + |