vp6500: Add backlight device
SVN-Revision: 20843
This commit is contained in:
parent
498bf7402a
commit
e438c665db
3 changed files with 187 additions and 8 deletions
|
@ -20,9 +20,9 @@
|
|||
#include <linux/input.h>
|
||||
#include <linux/input/matrix_keypad.h>
|
||||
#include <linux/gpio_keys.h>
|
||||
#include <linux/pwm_backlight.h>
|
||||
|
||||
static unsigned int vp6500_pins[] = {
|
||||
|
||||
/* UART1 */
|
||||
PE12_PF_UART1_TXD,
|
||||
PE13_PF_UART1_RXD,
|
||||
|
@ -52,8 +52,14 @@ static unsigned int vp6500_pins[] = {
|
|||
PA30_PF_CONTRAST,
|
||||
PA31_PF_OE_ACD,
|
||||
#endif
|
||||
|
||||
/* LCD Backlight */
|
||||
PE5_PF_PWMO,
|
||||
VP6500_GPIO_BACKLIGHT_EN | GPIO_GPIO | GPIO_OUT,
|
||||
};
|
||||
|
||||
/* Flash */
|
||||
|
||||
static struct physmap_flash_data vp6500_flash_data = {
|
||||
.width = 2,
|
||||
};
|
||||
|
@ -74,6 +80,8 @@ static struct platform_device vp6500_nor_mtd_device = {
|
|||
.resource = &vp6500_flash_resource,
|
||||
};
|
||||
|
||||
/* LEDs */
|
||||
|
||||
static struct gpio_led vp6500_leds[] = {
|
||||
{
|
||||
.name = "vp6500:orange:keypad",
|
||||
|
@ -108,6 +116,8 @@ static struct platform_device vp6500_leds_device = {
|
|||
},
|
||||
};
|
||||
|
||||
/* Keypad */
|
||||
|
||||
static const uint32_t vp6500_keypad_keys[] = {
|
||||
KEY(0, 3, KEY_F2),
|
||||
KEY(0, 4, KEY_RIGHT),
|
||||
|
@ -180,11 +190,38 @@ static struct platform_device vp6500_key_device = {
|
|||
},
|
||||
};
|
||||
|
||||
/* LCD backlight */
|
||||
|
||||
static int vp6500_backlight_notify(struct device *dev, int brightness)
|
||||
{
|
||||
gpio_set_value(VP6500_GPIO_BACKLIGHT_EN, !!brightness);
|
||||
|
||||
return brightness;
|
||||
}
|
||||
|
||||
static struct platform_pwm_backlight_data vp6500_backlight_data = {
|
||||
.max_brightness = 255,
|
||||
.dft_brightness = 100,
|
||||
.pwm_period_ns = 15000000,
|
||||
.notify = vp6500_backlight_notify,
|
||||
};
|
||||
|
||||
static struct platform_device vp6500_backlight_device = {
|
||||
.name = "pwm-backlight",
|
||||
.id = -1,
|
||||
.dev = {
|
||||
.parent = &mxc_pwm_device.dev,
|
||||
.platform_data = &vp6500_backlight_data,
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
static struct platform_device *platform_devices[] __initdata = {
|
||||
&vp6500_nor_mtd_device,
|
||||
&vp6500_leds_device,
|
||||
&vp6500_keypad_device,
|
||||
&vp6500_key_device,
|
||||
&vp6500_backlight_device,
|
||||
};
|
||||
|
||||
static void __init vp6500_board_init(void)
|
||||
|
@ -193,6 +230,7 @@ static void __init vp6500_board_init(void)
|
|||
"vp6500");
|
||||
|
||||
mxc_register_device(&mxc_uart_device0, NULL);
|
||||
mxc_register_device(&mxc_pwm_device, NULL);
|
||||
|
||||
platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices));
|
||||
}
|
||||
|
|
|
@ -2,12 +2,16 @@
|
|||
#ifndef __BOARD_VP6500__
|
||||
#define __BOARD_VP6500__
|
||||
|
||||
#define VP6500_GPIO_POWER_KEY 39
|
||||
#define VP6500_GPIO_CAMERA_DIRECTION 45
|
||||
#define VP6500_GPIO_LED_KEYPAD 82
|
||||
#define VP6500_GPIO_AMP_ENABLE 89
|
||||
#define VP6500_GPIO_LED_RED 91
|
||||
#define VP6500_GPIO_LED_GREEN 92
|
||||
#define VP6500_GPIO_LED_CAMERA 93
|
||||
#define VP6500_GPIO_POWER_KEY GPIO_PORTB | 5
|
||||
#define VP6500_GPIO_CAMERA_DIRECTION GPIO_PORTB | 13
|
||||
#define VP6500_GPIO_LED_KEYPAD GPIO_PORTC | 18
|
||||
#define VP6500_GPIO_AMP_ENABLE GPIO_PORTC | 25
|
||||
#define VP6500_GPIO_LED_RED GPIO_PORTC | 27
|
||||
#define VP6500_GPIO_LED_GREEN GPIO_PORTC | 28
|
||||
#define VP6500_GPIO_LED_CAMERA GPIO_PORTC | 29
|
||||
#define VP6500_GPIO_BACKLIGHT_EN GPIO_PORTE | 10
|
||||
|
||||
#define VP6500_GPIO_TLV_RESET GPIO_PORTB | 27
|
||||
#define VP6500_GPIO_TLV_ENABLE GPIO_PORTC | 25
|
||||
|
||||
#endif
|
||||
|
|
137
target/linux/mx2/patches-2.6.34/040-pwm.patch
Normal file
137
target/linux/mx2/patches-2.6.34/040-pwm.patch
Normal file
|
@ -0,0 +1,137 @@
|
|||
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
|
||||
index c36f263..acc5dc1 100644
|
||||
--- a/arch/arm/plat-mxc/pwm.c
|
||||
+++ b/arch/arm/plat-mxc/pwm.c
|
||||
@@ -25,6 +25,11 @@
|
||||
#define MX1_PWMS 0x04 /* PWM Sample Register */
|
||||
#define MX1_PWMP 0x08 /* PWM Period Register */
|
||||
|
||||
+#define MX1_PWMC_EN (1 << 4)
|
||||
+#define MX1_PWMC_PRESCALER_MASK (0x7f << 8)
|
||||
+#define MX1_PWMC_PRESCALER(x) ((x & 0x7f) << 8)
|
||||
+#define MX1_PWMC_CLKSEL_MASK 0x3
|
||||
+#define MX1_PWMC_CLKSEL(x) ((x & 0x3))
|
||||
|
||||
/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
|
||||
|
||||
@@ -54,25 +59,32 @@ struct pwm_device {
|
||||
|
||||
int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
|
||||
{
|
||||
+ unsigned long long c;
|
||||
+ unsigned long period_cycles, duty_cycles, prescale;
|
||||
+
|
||||
if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
|
||||
return -EINVAL;
|
||||
|
||||
- if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) {
|
||||
- unsigned long long c;
|
||||
- unsigned long period_cycles, duty_cycles, prescale;
|
||||
- u32 cr;
|
||||
+ c = clk_get_rate(pwm->clk);
|
||||
+
|
||||
+ c = c * period_ns;
|
||||
+
|
||||
+ if (cpu_is_mx1() || cpu_is_mx2())
|
||||
+ c >>= 1;
|
||||
|
||||
- c = clk_get_rate(pwm->clk);
|
||||
- c = c * period_ns;
|
||||
- do_div(c, 1000000000);
|
||||
- period_cycles = c;
|
||||
+ do_div(c, 1000000000);
|
||||
+ period_cycles = c;
|
||||
|
||||
- prescale = period_cycles / 0x10000 + 1;
|
||||
+ prescale = period_cycles / 0x10000 + 1;
|
||||
|
||||
- period_cycles /= prescale;
|
||||
- c = (unsigned long long)period_cycles * duty_ns;
|
||||
- do_div(c, period_ns);
|
||||
- duty_cycles = c;
|
||||
+ period_cycles /= prescale;
|
||||
+ c = (unsigned long long)period_cycles * duty_ns;
|
||||
+ do_div(c, period_ns);
|
||||
+ duty_cycles = c;
|
||||
+
|
||||
+
|
||||
+ if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) {
|
||||
+ u32 cr;
|
||||
|
||||
writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
|
||||
writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
|
||||
@@ -86,25 +98,28 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
|
||||
|
||||
writel(cr, pwm->mmio_base + MX3_PWMCR);
|
||||
} else if (cpu_is_mx1() || cpu_is_mx21()) {
|
||||
- /* The PWM subsystem allows for exact frequencies. However,
|
||||
- * I cannot connect a scope on my device to the PWM line and
|
||||
- * thus cannot provide the program the PWM controller
|
||||
- * exactly. Instead, I'm relying on the fact that the
|
||||
- * Bootloader (u-boot or WinCE+haret) has programmed the PWM
|
||||
- * function group already. So I'll just modify the PWM sample
|
||||
- * register to follow the ratio of duty_ns vs. period_ns
|
||||
- * accordingly.
|
||||
- *
|
||||
- * This is good enough for programming the brightness of
|
||||
- * the LCD backlight.
|
||||
- *
|
||||
- * The real implementation would divide PERCLK[0] first by
|
||||
- * both the prescaler (/1 .. /128) and then by CLKSEL
|
||||
- * (/2 .. /16).
|
||||
- */
|
||||
- u32 max = readl(pwm->mmio_base + MX1_PWMP);
|
||||
- u32 p = max * duty_ns / period_ns;
|
||||
- writel(max - p, pwm->mmio_base + MX1_PWMS);
|
||||
+ unsigned long clksel = 0;
|
||||
+ u32 ctrl;
|
||||
+
|
||||
+ while (prescale >= 0x80 && clksel < 4) {
|
||||
+ prescale >>= 1;
|
||||
+ ++clksel;
|
||||
+ }
|
||||
+
|
||||
+ if (clksel > 3)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ ctrl = readl(pwm->mmio_base + MX1_PWMC);
|
||||
+ writel(ctrl & ~MX1_PWMC_EN, pwm->mmio_base + MX1_PWMC);
|
||||
+
|
||||
+ writel(duty_cycles, pwm->mmio_base + MX1_PWMS);
|
||||
+ writel(period_cycles, pwm->mmio_base + MX1_PWMP);
|
||||
+
|
||||
+ ctrl &= ~(MX1_PWMC_PRESCALER_MASK | MX1_PWMC_CLKSEL_MASK);
|
||||
+ ctrl |= MX1_PWMC_PRESCALER(prescale);
|
||||
+ ctrl |= MX1_PWMC_CLKSEL(clksel);
|
||||
+ writel(ctrl, pwm->mmio_base + MX1_PWMC);
|
||||
+
|
||||
} else {
|
||||
BUG();
|
||||
}
|
||||
@@ -116,6 +130,11 @@ EXPORT_SYMBOL(pwm_config);
|
||||
int pwm_enable(struct pwm_device *pwm)
|
||||
{
|
||||
int rc = 0;
|
||||
+ if (cpu_is_mx1() || cpu_is_mx2()) {
|
||||
+ u32 ctrl;
|
||||
+ ctrl = readl(pwm->mmio_base + MX1_PWMC);
|
||||
+ writel(ctrl | MX1_PWMC_EN, pwm->mmio_base + MX1_PWMC);
|
||||
+ }
|
||||
|
||||
if (!pwm->clk_enabled) {
|
||||
rc = clk_enable(pwm->clk);
|
||||
@@ -128,7 +147,13 @@ EXPORT_SYMBOL(pwm_enable);
|
||||
|
||||
void pwm_disable(struct pwm_device *pwm)
|
||||
{
|
||||
- writel(0, pwm->mmio_base + MX3_PWMCR);
|
||||
+ if (cpu_is_mx27() || cpu_is_mx3() || cpu_is_mx25()) {
|
||||
+ writel(0, pwm->mmio_base + MX3_PWMCR);
|
||||
+ } else if (cpu_is_mx1() || cpu_is_mx2()) {
|
||||
+ u32 ctrl;
|
||||
+ ctrl = readl(pwm->mmio_base + MX1_PWMC);
|
||||
+ writel(ctrl & ~MX1_PWMC_EN, pwm->mmio_base + MX1_PWMC);
|
||||
+ }
|
||||
|
||||
if (pwm->clk_enabled) {
|
||||
clk_disable(pwm->clk);
|
Loading…
Reference in a new issue