summaryrefslogtreecommitdiff
path: root/common/wmt_display/pwm.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/wmt_display/pwm.c')
-rwxr-xr-xcommon/wmt_display/pwm.c306
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
+