From 75540c1ac3c7bd72ac8e092058f9714875239995 Mon Sep 17 00:00:00 2001 From: eric miao Date: Sun, 13 Apr 2008 21:44:04 +0100 Subject: [ARM] pxa: Add PXA support for PWM API Patch mainly from Eric Miao, with minor edits by rmk. Note: PWM0 and PWM2 share the same register I/O space and clock gating on pxa{27x, 3xx}, thus PWM2 is treated in the driver as a child PWM of PWM0. And this is also true for PWM1/3. Signed-off-by: eric miao Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 5 + arch/arm/mach-pxa/Makefile | 1 + arch/arm/mach-pxa/devices.c | 60 +++++++++ arch/arm/mach-pxa/devices.h | 5 + arch/arm/mach-pxa/pwm.c | 299 ++++++++++++++++++++++++++++++++++++++++++++ arch/arm/mach-pxa/pxa25x.c | 6 +- arch/arm/mach-pxa/pxa27x.c | 5 +- arch/arm/mach-pxa/pxa3xx.c | 4 + 8 files changed, 382 insertions(+), 3 deletions(-) create mode 100644 arch/arm/mach-pxa/pwm.c (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5da7a682049..9c01505b182 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -273,4 +273,9 @@ config PXA_SSP tristate help Enable support for PXA2xx SSP ports + +config PXA_PWM + tristate + help + Enable support for PXA2xx/PXA3xx PWM controllers endif diff --git a/arch/arm/mach-pxa/Makefile b/arch/arm/mach-pxa/Makefile index 0e6d05bb81a..02cbc3cfbe0 100644 --- a/arch/arm/mach-pxa/Makefile +++ b/arch/arm/mach-pxa/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CPU_FREQ) += cpu-pxa.o # Generic drivers that other drivers may depend upon obj-$(CONFIG_PXA_SSP) += ssp.o +obj-$(CONFIG_PXA_PWM) += pwm.o # SoC-specific code obj-$(CONFIG_PXA25x) += mfp-pxa2xx.o pxa25x.o diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index d6c05b6eab3..794a1076db7 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -280,6 +280,36 @@ struct platform_device pxa_device_rtc = { #ifdef CONFIG_PXA25x +static struct resource pxa25x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm0 = { + .name = "pxa25x-pwm", + .id = 0, + .resource = pxa25x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm0), +}; + +static struct resource pxa25x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0000f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa25x_device_pwm1 = { + .name = "pxa25x-pwm", + .id = 1, + .resource = pxa25x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa25x_resource_pwm1), +}; + static u64 pxa25x_ssp_dma_mask = DMA_BIT_MASK(32); static struct resource pxa25x_resource_ssp[] = { @@ -568,6 +598,36 @@ struct platform_device pxa27x_device_ssp3 = { .num_resources = ARRAY_SIZE(pxa27x_resource_ssp3), }; +static struct resource pxa27x_resource_pwm0[] = { + [0] = { + .start = 0x40b00000, + .end = 0x40b0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm0 = { + .name = "pxa27x-pwm", + .id = 0, + .resource = pxa27x_resource_pwm0, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm0), +}; + +static struct resource pxa27x_resource_pwm1[] = { + [0] = { + .start = 0x40c00000, + .end = 0x40c0001f, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device pxa27x_device_pwm1 = { + .name = "pxa27x-pwm", + .id = 1, + .resource = pxa27x_resource_pwm1, + .num_resources = ARRAY_SIZE(pxa27x_resource_pwm1), +}; + static struct resource pxa27x_resource_camera[] = { [0] = { .start = 0x50000000, diff --git a/arch/arm/mach-pxa/devices.h b/arch/arm/mach-pxa/devices.h index fcab017f27e..e620a3373d4 100644 --- a/arch/arm/mach-pxa/devices.h +++ b/arch/arm/mach-pxa/devices.h @@ -24,4 +24,9 @@ extern struct platform_device pxa27x_device_ssp2; extern struct platform_device pxa27x_device_ssp3; extern struct platform_device pxa3xx_device_ssp4; +extern struct platform_device pxa25x_device_pwm0; +extern struct platform_device pxa25x_device_pwm1; +extern struct platform_device pxa27x_device_pwm0; +extern struct platform_device pxa27x_device_pwm1; + void __init pxa_register_device(struct platform_device *dev, void *data); diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c new file mode 100644 index 00000000000..70fb3ca6a05 --- /dev/null +++ b/arch/arm/mach-pxa/pwm.c @@ -0,0 +1,299 @@ +/* + * linux/arch/arm/mach-pxa/pwm.c + * + * simple driver for PWM (Pulse Width Modulator) controller + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 2008-02-13 initial version + * eric miao + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +/* PWM registers and bits definitions */ +#define PWMCR (0x00) +#define PWMDCR (0x04) +#define PWMPCR (0x08) + +#define PWMCR_SD (1 << 6) +#define PWMDCR_FD (1 << 10) + +struct pwm_device { + struct list_head node; + struct platform_device *pdev; + + const char *label; + struct clk *clk; + void __iomem *mmio_base; + + unsigned int use_count; + unsigned int pwm_id; +}; + +/* + * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE + * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE + */ +int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns) +{ + unsigned long long c; + unsigned long period_cycles, prescale, pv, dc; + + if (pwm == NULL || period_ns == 0 || duty_ns > period_ns) + return -EINVAL; + + c = clk_get_rate(pwm->clk); + c = c * period_ns; + do_div(c, 1000000000); + period_cycles = c; + + if (period_cycles < 0) + period_cycles = 1; + prescale = (period_cycles - 1) / 1024; + pv = period_cycles / (prescale + 1) - 1; + + if (prescale > 63) + return -EINVAL; + + if (duty_ns == period_ns) + dc = PWMDCR_FD; + else + dc = (pv + 1) * duty_ns / period_ns; + + /* NOTE: the clock to PWM has to be enabled first + * before writing to the registers + */ + clk_enable(pwm->clk); + __raw_writel(prescale, pwm->mmio_base + PWMCR); + __raw_writel(dc, pwm->mmio_base + PWMDCR); + __raw_writel(pv, pwm->mmio_base + PWMPCR); + clk_disable(pwm->clk); + + return 0; +} +EXPORT_SYMBOL(pwm_config); + +int pwm_enable(struct pwm_device *pwm) +{ + return clk_enable(pwm->clk); +} +EXPORT_SYMBOL(pwm_enable); + +void pwm_disable(struct pwm_device *pwm) +{ + clk_disable(pwm->clk); +} +EXPORT_SYMBOL(pwm_disable); + +static DEFINE_MUTEX(pwm_lock); +static LIST_HEAD(pwm_list); + +struct pwm_device *pwm_request(int pwm_id, const char *label) +{ + struct pwm_device *pwm; + int found = 0; + + mutex_lock(&pwm_lock); + + list_for_each_entry(pwm, &pwm_list, node) { + if (pwm->pwm_id == pwm_id && pwm->use_count == 0) { + pwm->use_count++; + pwm->label = label; + found = 1; + break; + } + } + + mutex_unlock(&pwm_lock); + + return (found) ? pwm : NULL; +} +EXPORT_SYMBOL(pwm_request); + +void pwm_free(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + + if (pwm->use_count) { + pwm->use_count--; + pwm->label = NULL; + } else + pr_warning("PWM device already freed\n"); + + mutex_unlock(&pwm_lock); +} +EXPORT_SYMBOL(pwm_free); + +static inline void __add_pwm(struct pwm_device *pwm) +{ + mutex_lock(&pwm_lock); + list_add_tail(&pwm->node, &pwm_list); + mutex_unlock(&pwm_lock); +} + +static struct pwm_device *pwm_probe(struct platform_device *pdev, + unsigned int pwm_id, struct pwm_device *parent_pwm) +{ + struct pwm_device *pwm; + struct resource *r; + int ret = 0; + + pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL); + if (pwm == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return ERR_PTR(-ENOMEM); + } + + pwm->clk = clk_get(&pdev->dev, "PWMCLK"); + if (IS_ERR(pwm->clk)) { + ret = PTR_ERR(pwm->clk); + goto err_free; + } + + pwm->use_count = 0; + pwm->pwm_id = pwm_id; + pwm->pdev = pdev; + + if (parent_pwm != NULL) { + /* registers for the second PWM has offset of 0x10 */ + pwm->mmio_base = parent_pwm->mmio_base + 0x10; + __add_pwm(pwm); + return pwm; + } + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (r == NULL) { + dev_err(&pdev->dev, "no memory resource defined\n"); + ret = -ENODEV; + goto err_free_clk; + } + + r = request_mem_region(r->start, r->end - r->start + 1, pdev->name); + if (r == NULL) { + dev_err(&pdev->dev, "failed to request memory resource\n"); + ret = -EBUSY; + goto err_free_clk; + } + + pwm->mmio_base = ioremap(r->start, r->end - r->start + 1); + if (pwm->mmio_base == NULL) { + dev_err(&pdev->dev, "failed to ioremap() registers\n"); + ret = -ENODEV; + goto err_free_mem; + } + + __add_pwm(pwm); + platform_set_drvdata(pdev, pwm); + return pwm; + +err_free_mem: + release_mem_region(r->start, r->end - r->start + 1); +err_free_clk: + clk_put(pwm->clk); +err_free: + kfree(pwm); + return ERR_PTR(ret); +} + +static int __devinit pxa25x_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm = pwm_probe(pdev, pdev->id, NULL); + + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + return 0; +} + +static int __devinit pxa27x_pwm_probe(struct platform_device *pdev) +{ + struct pwm_device *pwm; + + pwm = pwm_probe(pdev, pdev->id * 2, NULL); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + pwm = pwm_probe(pdev, pdev->id * 2 + 1, pwm); + if (IS_ERR(pwm)) + return PTR_ERR(pwm); + + return 0; +} + +static int __devexit pwm_remove(struct platform_device *pdev) +{ + struct pwm_device *pwm; + struct resource *r; + + pwm = platform_get_drvdata(pdev); + if (pwm == NULL) + return -ENODEV; + + mutex_lock(&pwm_lock); + list_del(&pwm->node); + mutex_unlock(&pwm_lock); + + iounmap(pwm->mmio_base); + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(r->start, r->end - r->start + 1); + + clk_put(pwm->clk); + kfree(pwm); + return 0; +} + +static struct platform_driver pxa25x_pwm_driver = { + .driver = { + .name = "pxa25x-pwm", + }, + .probe = pxa25x_pwm_probe, + .remove = __devexit_p(pwm_remove), +}; + +static struct platform_driver pxa27x_pwm_driver = { + .driver = { + .name = "pxa27x-pwm", + }, + .probe = pxa27x_pwm_probe, + .remove = __devexit_p(pwm_remove), +}; + +static int __init pwm_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&pxa25x_pwm_driver); + if (ret) { + printk(KERN_ERR "failed to register pxa25x_pwm_driver\n"); + return ret; + } + + ret = platform_driver_register(&pxa27x_pwm_driver); + if (ret) { + printk(KERN_ERR "failed to register pxa27x_pwm_driver\n"); + return ret; + } + + return ret; +} +arch_initcall(pwm_init); + +static void __exit pwm_exit(void) +{ + platform_driver_unregister(&pxa25x_pwm_driver); + platform_driver_unregister(&pxa27x_pwm_driver); +} +module_exit(pwm_exit); diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e5b417d14bb..2bed3f98d41 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -129,12 +129,12 @@ static struct clk pxa25x_clks[] = { INIT_CKEN("SSPCLK", SSP, 3686400, 0, &pxa25x_device_ssp.dev), INIT_CKEN("SSPCLK", NSSP, 3686400, 0, &pxa25x_device_nssp.dev), INIT_CKEN("SSPCLK", ASSP, 3686400, 0, &pxa25x_device_assp.dev), + INIT_CKEN("PWMCLK", PWM0, 3686400, 0, &pxa25x_device_pwm0.dev), + INIT_CKEN("PWMCLK", PWM1, 3686400, 0, &pxa25x_device_pwm1.dev), INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), /* - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), - INIT_CKEN("PWMCLK", PWM0, 3686400, 0, NULL), INIT_CKEN("I2SCLK", I2S, 14745600, 0, NULL), */ INIT_CKEN("FICPCLK", FICP, 47923000, 0, NULL), @@ -269,6 +269,8 @@ static struct platform_device *pxa25x_devices[] __initdata = { &pxa25x_device_ssp, &pxa25x_device_nssp, &pxa25x_device_assp, + &pxa25x_device_pwm0, + &pxa25x_device_pwm1, }; static struct sys_device pxa25x_sysdev[] = { diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e945836e12..bc2e80f6967 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -157,12 +157,13 @@ static struct clk pxa27x_clks[] = { INIT_CKEN("SSPCLK", SSP1, 13000000, 0, &pxa27x_device_ssp1.dev), INIT_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), INIT_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), + INIT_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), + INIT_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), INIT_CKEN("AC97CLK", AC97, 24576000, 0, NULL), INIT_CKEN("AC97CONFCLK", AC97CONF, 24576000, 0, NULL), /* - INIT_CKEN("PWMCLK", PWM0, 13000000, 0, NULL), INIT_CKEN("MSLCLK", MSL, 48000000, 0, NULL), INIT_CKEN("USIMCLK", USIM, 48000000, 0, NULL), INIT_CKEN("MSTKCLK", MEMSTK, 19500000, 0, NULL), @@ -363,6 +364,8 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp1, &pxa27x_device_ssp2, &pxa27x_device_ssp3, + &pxa27x_device_pwm0, + &pxa27x_device_pwm1, }; static struct sys_device pxa27x_sysdev[] = { diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 644550bfa33..0f717df1fdb 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -239,6 +239,8 @@ static struct clk pxa3xx_clks[] = { PXA3xx_CKEN("SSPCLK", SSP2, 13000000, 0, &pxa27x_device_ssp2.dev), PXA3xx_CKEN("SSPCLK", SSP3, 13000000, 0, &pxa27x_device_ssp3.dev), PXA3xx_CKEN("SSPCLK", SSP4, 13000000, 0, &pxa3xx_device_ssp4.dev), + PXA3xx_CKEN("PWMCLK", PWM0, 13000000, 0, &pxa27x_device_pwm0.dev), + PXA3xx_CKEN("PWMCLK", PWM1, 13000000, 0, &pxa27x_device_pwm1.dev), PXA3xx_CKEN("MMCCLK", MMC1, 19500000, 0, &pxa_device_mci.dev), PXA3xx_CKEN("MMCCLK", MMC2, 19500000, 0, &pxa3xx_device_mci2.dev), @@ -530,6 +532,8 @@ static struct platform_device *devices[] __initdata = { &pxa27x_device_ssp2, &pxa27x_device_ssp3, &pxa3xx_device_ssp4, + &pxa27x_device_pwm0, + &pxa27x_device_pwm1, }; static struct sys_device pxa3xx_sysdev[] = { -- cgit v1.2.3 From 02a8e76979f9b439642e67955edb865c112926f6 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:15:32 +0100 Subject: [ARM] pxa: corgibl_limit_intensity build errors If CONFIG_BACKLIGHT_CORGI is not selected, then corgibl_limit_intensity() is not present. However, both corgi_pm.c and sharp_pm.c reference this symbol, resulting in a link error. Wrap the references with the relevant ifdefs, and avoid the resulting NULL pointer dereference by making the code in sharpsl_pm.c also conditional on the config symbol. Signed-off-by: Russell King --- arch/arm/mach-pxa/corgi_pm.c | 2 ++ arch/arm/mach-pxa/spitz_pm.c | 2 ++ 2 files changed, 4 insertions(+) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 0a85f706e88..ae91c4b1135 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -204,7 +204,9 @@ static struct sharpsl_charger_machinfo corgi_pm_machinfo = { .read_devdata = corgipm_read_devdata, .charger_wakeup = corgi_charger_wakeup, .should_wakeup = corgi_should_wakeup, +#ifdef CONFIG_BACKLIGHT_CORGI .backlight_limit = corgibl_limit_intensity, +#endif .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 23f050feb20..48396f4eb26 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -207,7 +207,9 @@ struct sharpsl_charger_machinfo spitz_pm_machinfo = { .read_devdata = spitzpm_read_devdata, .charger_wakeup = spitz_charger_wakeup, .should_wakeup = spitz_should_wakeup, +#ifdef CONFIG_BACKLIGHT_CORGI .backlight_limit = corgibl_limit_intensity, +#endif .charge_on_volt = SHARPSL_CHARGE_ON_VOLT, .charge_on_temp = SHARPSL_CHARGE_ON_TEMP, .charge_acin_high = SHARPSL_CHARGE_ON_ACIN_HIGH, -- cgit v1.2.3 From 284d115ec9b70d7c38752d10ad393a198db07a4b Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:32:16 +0100 Subject: [ARM] pxa: separate PXA25x and PXA27x UDC register definitions The PXA25x and PXA27x USB device controller register definitions are different. Currently, they live side by side in pxa-regs.h, but only one set is available depending on the setting of PXA25x or PXA27x. This means that if we build to support both PXA25x and PXA27x, the PXA27x definitions are unavailable, even to PXA27x specific code. Remove these definitions from pxa-regs.h, and place them in separate files. Include these files where appropriate. Note: according to the dependencies in drivers/usb/gadget/Kconfig, we do not support the UDC on PXA27x nor PXA3xx CPUs, so remove the platform devices from pxa27x.c and pxa3xx.c. Signed-off-by: Russell King --- arch/arm/mach-pxa/em-x270.c | 1 + arch/arm/mach-pxa/pxa27x.c | 2 +- arch/arm/mach-pxa/pxa3xx.c | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/em-x270.c b/arch/arm/mach-pxa/em-x270.c index edc4f07a230..1269ac99150 100644 --- a/arch/arm/mach-pxa/em-x270.c +++ b/arch/arm/mach-pxa/em-x270.c @@ -24,6 +24,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index 7e945836e12..cdaf573e0f1 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -353,7 +353,7 @@ void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) } static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, diff --git a/arch/arm/mach-pxa/pxa3xx.c b/arch/arm/mach-pxa/pxa3xx.c index 644550bfa33..7fbe78649da 100644 --- a/arch/arm/mach-pxa/pxa3xx.c +++ b/arch/arm/mach-pxa/pxa3xx.c @@ -520,7 +520,7 @@ void __init pxa3xx_init_irq(void) */ static struct platform_device *devices[] __initdata = { - &pxa_device_udc, +/* &pxa_device_udc, The UDC driver is PXA25x only */ &pxa_device_ffuart, &pxa_device_btuart, &pxa_device_stuart, -- cgit v1.2.3 From 720046de27ec2a96d4497dbca8ee98657efa059c Mon Sep 17 00:00:00 2001 From: Russell King Date: Thu, 24 Apr 2008 15:13:36 +0100 Subject: [ARM] pxa: don't register lpd270 cpld_irq sysdev if !lpd270 Don't register the LPD270 cpld_irq system device when we're not running on a LPD270 machine - "cpld_irq" is also registered (separately) by Lubbock and Mainstone. Signed-off-by: Russell King --- arch/arm/mach-pxa/lpd270.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index a20e4b1649d..6fd7b8b753f 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -134,9 +134,12 @@ static struct sys_device lpd270_irq_device = { static int __init lpd270_irq_device_init(void) { - int ret = sysdev_class_register(&lpd270_irq_sysclass); - if (ret == 0) - ret = sysdev_register(&lpd270_irq_device); + int ret = -ENODEV; + if (machine_is_logicpd_pxa270()) { + ret = sysdev_class_register(&lpd270_irq_sysclass); + if (ret == 0) + ret = sysdev_register(&lpd270_irq_device); + } return ret; } -- cgit v1.2.3 From ffdf786291636137ef2d51c3a5d340793032aa28 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 May 2008 14:57:59 +0100 Subject: [ARM] pxa: Add PXA3_ prefix to PXA3 specific constants standby.S contains both PXA2 and PXA3 specific code. The PXA3 specific constants clash with the PXA2 ones, so give them a prefix. Signed-off-by: Russell King --- arch/arm/mach-pxa/standby.S | 82 ++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index 167412e6bec..a37ef1c4b9e 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -35,20 +35,20 @@ ENTRY(pxa_cpu_standby) #ifdef CONFIG_PXA3xx -#define MDCNFG 0x0000 -#define MDCNFG_DMCEN (1 << 30) -#define DDR_HCAL 0x0060 -#define DDR_HCAL_HCRNG 0x1f -#define DDR_HCAL_HCPROG (1 << 28) -#define DDR_HCAL_HCEN (1 << 31) -#define DMCIER 0x0070 -#define DMCIER_EDLP (1 << 29) -#define DMCISR 0x0078 -#define RCOMP 0x0100 -#define RCOMP_SWEVAL (1 << 31) +#define PXA3_MDCNFG 0x0000 +#define PXA3_MDCNFG_DMCEN (1 << 30) +#define PXA3_DDR_HCAL 0x0060 +#define PXA3_DDR_HCAL_HCRNG 0x1f +#define PXA3_DDR_HCAL_HCPROG (1 << 28) +#define PXA3_DDR_HCAL_HCEN (1 << 31) +#define PXA3_DMCIER 0x0070 +#define PXA3_DMCIER_EDLP (1 << 29) +#define PXA3_DMCISR 0x0078 +#define PXA3_RCOMP 0x0100 +#define PXA3_RCOMP_SWEVAL (1 << 31) ENTRY(pm_enter_standby_start) - mov r1, #0xf6000000 @ DMEMC_REG_BASE (MDCNFG) + mov r1, #0xf6000000 @ DMEMC_REG_BASE (PXA3_MDCNFG) add r1, r1, #0x00100000 /* @@ -59,54 +59,54 @@ ENTRY(pm_enter_standby_start) * This also means that only the dynamic memory controller * can be reliably accessed in the code following standby. */ - ldr r2, [r1] @ Dummy read MDCNFG + ldr r2, [r1] @ Dummy read PXA3_MDCNFG mcr p14, 0, r0, c7, c0, 0 .rept 8 nop .endr - ldr r0, [r1, #DDR_HCAL] @ Clear (and wait for) HCEN - bic r0, r0, #DDR_HCAL_HCEN - str r0, [r1, #DDR_HCAL] -1: ldr r0, [r1, #DDR_HCAL] - tst r0, #DDR_HCAL_HCEN + ldr r0, [r1, #PXA3_DDR_HCAL] @ Clear (and wait for) HCEN + bic r0, r0, #PXA3_DDR_HCAL_HCEN + str r0, [r1, #PXA3_DDR_HCAL] +1: ldr r0, [r1, #PXA3_DDR_HCAL] + tst r0, #PXA3_DDR_HCAL_HCEN bne 1b - ldr r0, [r1, #RCOMP] @ Initiate RCOMP - orr r0, r0, #RCOMP_SWEVAL - str r0, [r1, #RCOMP] + ldr r0, [r1, #PXA3_RCOMP] @ Initiate RCOMP + orr r0, r0, #PXA3_RCOMP_SWEVAL + str r0, [r1, #PXA3_RCOMP] - mov r0, #~0 @ Clear interrupts - str r0, [r1, #DMCISR] + mov r0, #~0 @ Clear interrupts + str r0, [r1, #PXA3_DMCISR] - ldr r0, [r1, #DMCIER] @ set DMIER[EDLP] - orr r0, r0, #DMCIER_EDLP - str r0, [r1, #DMCIER] + ldr r0, [r1, #PXA3_DMCIER] @ set DMIER[EDLP] + orr r0, r0, #PXA3_DMCIER_EDLP + str r0, [r1, #PXA3_DMCIER] - ldr r0, [r1, #DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN - bic r0, r0, #DDR_HCAL_HCRNG - orr r0, r0, #DDR_HCAL_HCEN | DDR_HCAL_HCPROG - str r0, [r1, #DDR_HCAL] + ldr r0, [r1, #PXA3_DDR_HCAL] @ clear HCRNG, set HCPROG, HCEN + bic r0, r0, #PXA3_DDR_HCAL_HCRNG + orr r0, r0, #PXA3_DDR_HCAL_HCEN | PXA3_DDR_HCAL_HCPROG + str r0, [r1, #PXA3_DDR_HCAL] -1: ldr r0, [r1, #DMCISR] - tst r0, #DMCIER_EDLP +1: ldr r0, [r1, #PXA3_DMCISR] + tst r0, #PXA3_DMCIER_EDLP beq 1b - ldr r0, [r1, #MDCNFG] @ set MDCNFG[DMCEN] - orr r0, r0, #MDCNFG_DMCEN - str r0, [r1, #MDCNFG] -1: ldr r0, [r1, #MDCNFG] - tst r0, #MDCNFG_DMCEN + ldr r0, [r1, #PXA3_MDCNFG] @ set PXA3_MDCNFG[DMCEN] + orr r0, r0, #PXA3_MDCNFG_DMCEN + str r0, [r1, #PXA3_MDCNFG] +1: ldr r0, [r1, #PXA3_MDCNFG] + tst r0, #PXA3_MDCNFG_DMCEN beq 1b - ldr r0, [r1, #DDR_HCAL] @ set DDR_HCAL[HCRNG] + ldr r0, [r1, #PXA3_DDR_HCAL] @ set PXA3_DDR_HCAL[HCRNG] orr r0, r0, #2 @ HCRNG - str r0, [r1, #DDR_HCAL] + str r0, [r1, #PXA3_DDR_HCAL] - ldr r0, [r1, #DMCIER] @ Clear the interrupt + ldr r0, [r1, #PXA3_DMCIER] @ Clear the interrupt bic r0, r0, #0x20000000 - str r0, [r1, #DMCIER] + str r0, [r1, #PXA3_DMCIER] mov pc, lr ENTRY(pm_enter_standby_end) -- cgit v1.2.3 From bc3a595988468b8a9c2526b9fb8d7bcaa27cc1a7 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 2 Jun 2008 18:49:27 +0100 Subject: [ARM] 5075/1: i2c-pxa: move i2c pin setup and PCFR_PI2CEN handling into arch/arm/mach-pxa This fixes a build error introduced when the power manager register definitions were moved into pxa2xx-regs.h. Signed-off-by: Philipp Zabel Signed-off-by: Russell King --- arch/arm/mach-pxa/devices.c | 9 +++++++++ arch/arm/mach-pxa/pxa27x.c | 3 +++ 2 files changed, 12 insertions(+) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c index d6c05b6eab3..af6cc3dbb9a 100644 --- a/arch/arm/mach-pxa/devices.c +++ b/arch/arm/mach-pxa/devices.c @@ -10,11 +10,13 @@ #include #include #include +#include #include #include #include #include "devices.h" +#include "generic.h" void __init pxa_register_device(struct platform_device *dev, void *data) { @@ -233,8 +235,15 @@ struct platform_device pxa_device_i2c = { .num_resources = ARRAY_SIZE(pxai2c_resources), }; +static unsigned long pxa27x_i2c_mfp_cfg[] = { + GPIO117_I2C_SCL, + GPIO118_I2C_SDA, +}; + void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) { + if (cpu_is_pxa27x()) + pxa2xx_mfp_config(ARRAY_AND_SIZE(pxa27x_i2c_mfp_cfg)); pxa_register_device(&pxa_device_i2c, info); } diff --git a/arch/arm/mach-pxa/pxa27x.c b/arch/arm/mach-pxa/pxa27x.c index cdaf573e0f1..48cbdc771a8 100644 --- a/arch/arm/mach-pxa/pxa27x.c +++ b/arch/arm/mach-pxa/pxa27x.c @@ -349,6 +349,9 @@ struct platform_device pxa27x_device_i2c_power = { void __init pxa_set_i2c_power_info(struct i2c_pxa_platform_data *info) { + local_irq_disable(); + PCFR |= PCFR_PI2CEN; + local_irq_enable(); pxa27x_device_i2c_power.dev.platform_data = info; } -- cgit v1.2.3 From 0b0a9df6038752674e54e333cd247c877d29aab8 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 May 2008 14:59:36 +0100 Subject: [ARM] pxa: separate out power manager and clock registers The power manager and core clock registers aren't present in PXA3 CPUs. Move them out of pxa-regs.h into pxa2xx-regs.h, and include pxa2xx-regs.h where necessary. Signed-off-by: Russell King --- arch/arm/mach-pxa/clock.c | 2 +- arch/arm/mach-pxa/corgi.c | 1 + arch/arm/mach-pxa/corgi_pm.c | 1 + arch/arm/mach-pxa/generic.c | 1 + arch/arm/mach-pxa/magician.c | 1 + arch/arm/mach-pxa/mfp-pxa2xx.c | 1 + arch/arm/mach-pxa/poodle.c | 1 + arch/arm/mach-pxa/pxa25x.c | 1 + arch/arm/mach-pxa/standby.S | 1 + arch/arm/mach-pxa/trizeps4.c | 2 ++ 10 files changed, 11 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/clock.c b/arch/arm/mach-pxa/clock.c index e97dc59813c..180c8bb5304 100644 --- a/arch/arm/mach-pxa/clock.c +++ b/arch/arm/mach-pxa/clock.c @@ -12,7 +12,7 @@ #include #include -#include +#include #include #include diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c index b757dd75665..b37671b7188 100644 --- a/arch/arm/mach-pxa/corgi.c +++ b/arch/arm/mach-pxa/corgi.c @@ -36,6 +36,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index ae91c4b1135..53c4499ebdb 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "sharpsl.h" diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c index 44617938f3f..c2f102339f5 100644 --- a/arch/arm/mach-pxa/generic.c +++ b/arch/arm/mach-pxa/generic.c @@ -26,6 +26,7 @@ #include #include +#include /* for __pxa_set_cken */ #include "generic.h" diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index badba064dc0..b94cae48314 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/mfp-pxa2xx.c b/arch/arm/mach-pxa/mfp-pxa2xx.c index 22097a1707c..d1cdb4ecb0b 100644 --- a/arch/arm/mach-pxa/mfp-pxa2xx.c +++ b/arch/arm/mach-pxa/mfp-pxa2xx.c @@ -20,6 +20,7 @@ #include #include +#include #include #include "generic.h" diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c index 0b30f25cff3..f81c10cafd4 100644 --- a/arch/arm/mach-pxa/poodle.c +++ b/arch/arm/mach-pxa/poodle.c @@ -32,6 +32,7 @@ #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/pxa25x.c b/arch/arm/mach-pxa/pxa25x.c index e5b417d14bb..3b848dc3ca1 100644 --- a/arch/arm/mach-pxa/pxa25x.c +++ b/arch/arm/mach-pxa/pxa25x.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/arm/mach-pxa/standby.S b/arch/arm/mach-pxa/standby.S index a37ef1c4b9e..40bb70eff3f 100644 --- a/arch/arm/mach-pxa/standby.S +++ b/arch/arm/mach-pxa/standby.S @@ -14,6 +14,7 @@ #include #include +#include .text diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c index 931885d86b9..bc7c465ef32 100644 --- a/arch/arm/mach-pxa/trizeps4.c +++ b/arch/arm/mach-pxa/trizeps4.c @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -487,6 +488,7 @@ static void __init trizeps4_map_io(void) ConXS_BCR = trizeps_conxs_bcr; #endif +#warning FIXME - accessing PM registers directly is deprecated PWER = 0x00000002; PFER = 0x00000000; PRER = 0x00000002; -- cgit v1.2.3 From 5855a1e3c0714242b8a1875383b63ccf9bafaab7 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Mon, 12 May 2008 06:41:13 +0100 Subject: [ARM] 5035/1: Ensure that zone adjustment is done only on CM-X270 Adjust zones for PCI DMA only if machine_is_armcore() to allow running the same kernel on different PXA machines. Signed-off-by: Mike Rapoport Signed-off-by: Russell King --- arch/arm/mach-pxa/cm-x270-pci.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/cm-x270-pci.c b/arch/arm/mach-pxa/cm-x270-pci.c index ac7f05f9f3e..319c9ff3ab9 100644 --- a/arch/arm/mach-pxa/cm-x270-pci.c +++ b/arch/arm/mach-pxa/cm-x270-pci.c @@ -41,18 +41,20 @@ void __init cmx270_pci_adjust_zones(int node, unsigned long *zone_size, { unsigned int sz = SZ_64M >> PAGE_SHIFT; - pr_info("Adjusting zones for CM-x270\n"); - - /* - * Only adjust if > 64M on current system - */ - if (node || (zone_size[0] <= sz)) - return; - - zone_size[1] = zone_size[0] - sz; - zone_size[0] = sz; - zhole_size[1] = zhole_size[0]; - zhole_size[0] = 0; + if (machine_is_armcore()) { + pr_info("Adjusting zones for CM-x270\n"); + + /* + * Only adjust if > 64M on current system + */ + if (node || (zone_size[0] <= sz)) + return; + + zone_size[1] = zone_size[0] - sz; + zone_size[0] = sz; + zhole_size[1] = zhole_size[0]; + zhole_size[0] = 0; + } } static void cmx270_it8152_irq_demux(unsigned int irq, struct irq_desc *desc) -- cgit v1.2.3 From 63b43f5d3264f4d70b5d29885997253d33259744 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 20 Apr 2008 17:36:20 +0100 Subject: [ARM] pxa: allow PXA to be built for multiple platforms Convert the 'choice' into a 'menu' to allow multiple platforms to be selected. This means to do a build check across PXA, you don't end up spending a lifetime building _twenty_ sodding kernels. Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 5da7a682049..2563753fba7 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -20,8 +20,7 @@ endmenu endif -choice - prompt "Select target board" +menu "Select target boards" config ARCH_GUMSTIX bool "Gumstix XScale boards" @@ -138,7 +137,7 @@ config MACH_PCM027 select PXA27x select IWMMXT -endchoice +endmenu choice prompt "Used baseboard" -- cgit v1.2.3 From 043fbc099af0fc0ec94112c7235b7544147149f4 Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 31 May 2008 16:16:54 +0100 Subject: [ARM] 5072/1: corgi_pm: don't register devices on non-corgi machines Signed-off-by: Dmitry Baryshkov Acked-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/mach-pxa/corgi_pm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/corgi_pm.c b/arch/arm/mach-pxa/corgi_pm.c index 53c4499ebdb..e91c0f26c41 100644 --- a/arch/arm/mach-pxa/corgi_pm.c +++ b/arch/arm/mach-pxa/corgi_pm.c @@ -229,6 +229,10 @@ static int __devinit corgipm_init(void) { int ret; + if (!machine_is_corgi() && !machine_is_shepherd() + && !machine_is_husky()) + return -ENODEV; + corgipm_device = platform_device_alloc("sharpsl-pm", -1); if (!corgipm_device) return -ENOMEM; -- cgit v1.2.3 From 5806d8abf6b152f23d057c2e6b9199892883a8df Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 31 May 2008 16:17:32 +0100 Subject: [ARM] 5073/1: spitz_pm: don't register devices on non-spitz machines Signed-off-by: Dmitry Baryshkov Acked-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/mach-pxa/spitz_pm.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/spitz_pm.c b/arch/arm/mach-pxa/spitz_pm.c index 48396f4eb26..360354084ae 100644 --- a/arch/arm/mach-pxa/spitz_pm.c +++ b/arch/arm/mach-pxa/spitz_pm.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include "sharpsl.h" @@ -231,6 +232,10 @@ static int __devinit spitzpm_init(void) { int ret; + if (!machine_is_spitz() && !machine_is_akita() + && !machine_is_borzoi()) + return -ENODEV; + spitzpm_device = platform_device_alloc("sharpsl-pm", -1); if (!spitzpm_device) return -ENOMEM; -- cgit v1.2.3 From 69eaf23a9797e1bdf16e210ef4da3e756a41f4de Mon Sep 17 00:00:00 2001 From: Dmitry Baryshkov Date: Sat, 31 May 2008 16:14:48 +0100 Subject: [ARM] 5071/2: Drop PXA_SHARPSL_25x/27x case from PXA Kconfig. As nothing in the code references to the PXA_SHARPSL_25x/27x, we can drop that Kconfig case and permit all-zaurus builds. Signed-off-by: Dmitry Baryshkov Acked-by: Richard Purdie Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 41 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 25 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 2563753fba7..caccbbc41b4 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -148,23 +148,6 @@ config MACH_PCM990_BASEBOARD endchoice -if PXA_SHARPSL - -choice - prompt "Select target Sharp Zaurus device range" - -config PXA_SHARPSL_25x - bool "Sharp PXA25x models (SL-5600, SL-C7xx and SL-C6000x)" - select PXA25x - -config PXA_SHARPSL_27x - bool "Sharp PXA270 models (SL-Cxx00)" - select PXA27x - -endchoice - -endif - if ARCH_GUMSTIX choice @@ -198,28 +181,33 @@ endmenu config MACH_POODLE bool "Enable Sharp SL-5600 (Poodle) Support" - depends on PXA_SHARPSL_25x + depends on PXA_SHARPSL + select PXA25x select SHARP_LOCOMO select PXA_SSP config MACH_CORGI bool "Enable Sharp SL-C700 (Corgi) Support" - depends on PXA_SHARPSL_25x + depends on PXA_SHARPSL + select PXA25x select PXA_SHARP_C7xx config MACH_SHEPHERD bool "Enable Sharp SL-C750 (Shepherd) Support" - depends on PXA_SHARPSL_25x + depends on PXA_SHARPSL + select PXA25x select PXA_SHARP_C7xx config MACH_HUSKY bool "Enable Sharp SL-C760 (Husky) Support" - depends on PXA_SHARPSL_25x + depends on PXA_SHARPSL + select PXA25x select PXA_SHARP_C7xx config MACH_AKITA bool "Enable Sharp SL-1000 (Akita) Support" - depends on PXA_SHARPSL_27x + depends on PXA_SHARPSL + select PXA27x select PXA_SHARP_Cxx00 select MACH_SPITZ select I2C @@ -227,17 +215,20 @@ config MACH_AKITA config MACH_SPITZ bool "Enable Sharp Zaurus SL-3000 (Spitz) Support" - depends on PXA_SHARPSL_27x + depends on PXA_SHARPSL + select PXA27x select PXA_SHARP_Cxx00 config MACH_BORZOI bool "Enable Sharp Zaurus SL-3100 (Borzoi) Support" - depends on PXA_SHARPSL_27x + depends on PXA_SHARPSL + select PXA27x select PXA_SHARP_Cxx00 config MACH_TOSA bool "Enable Sharp SL-6000x (Tosa) Support" - depends on PXA_SHARPSL_25x + depends on PXA_SHARPSL + select PXA25x config PXA25x bool -- cgit v1.2.3 From 0b1c25d2c0f35b4cdd3f04f365cff31fc5a21813 Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Mon, 30 Jun 2008 18:09:03 +0100 Subject: [ARM] 5136/1: pxa: fix PWM device order for pxa27x Currently PWM0/2 (pxa27x_device_pwm0 at 0x40b00000 and 0x40b00010 are registered as as pwm_id 0 and 1, PWM1/3 (pxa27x_device_pwm1 at 0x40c00000 and 0x40c00010) are registered as pwm_id 2 and 3. This patch corrects the pwm_ids to match the documented register names. Signed-off-by: Philipp Zabel Acked-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/pwm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index 70fb3ca6a05..fa9323ee854 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -221,11 +221,11 @@ static int __devinit pxa27x_pwm_probe(struct platform_device *pdev) { struct pwm_device *pwm; - pwm = pwm_probe(pdev, pdev->id * 2, NULL); + pwm = pwm_probe(pdev, pdev->id, NULL); if (IS_ERR(pwm)) return PTR_ERR(pwm); - pwm = pwm_probe(pdev, pdev->id * 2 + 1, pwm); + pwm = pwm_probe(pdev, pdev->id + 2, pwm); if (IS_ERR(pwm)) return PTR_ERR(pwm); -- cgit v1.2.3 From b5f0228afa7810f3cad1f2f741cc747a2378b890 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 5 Jun 2008 10:45:02 +0100 Subject: [ARM] 5078/1: pxa-pwm: Add missing MODULE_LICENSE to be able to build the driver as a module Without a GPL-compatible license this driver cannot be built as a module, because the platform_driver_* API is only exported to GPL modules. Signed-off-by: Guennadi Liakhovetski Acked-by: Eric Miao Signed-off-by: Russell King --- arch/arm/mach-pxa/pwm.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index fa9323ee854..92fef391d99 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -297,3 +297,5 @@ static void __exit pwm_exit(void) platform_driver_unregister(&pxa27x_pwm_driver); } module_exit(pwm_exit); + +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From c860d701cc5f77b74c481dcbd25b2d8b31c622fc Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Tue, 10 Jun 2008 23:02:31 +0100 Subject: [ARM] 5087/1: Get the PWM layer to handle clock enable/disable properly. Allow pwm_enable()/pwm_disable() to be called as many times as the driver wants (and not even count them). The PWM model is different from things like the clock API where we need enable counting, because PWMs have one exclusive user per PWM whereas the clock API can have multiple users of the same clock. Acked-by: eric miao Signed-off-by: Robert Jarzmik Signed-off-by: Russell King --- arch/arm/mach-pxa/pwm.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index 92fef391d99..7c86dd1d108 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -36,6 +36,7 @@ struct pwm_device { const char *label; struct clk *clk; + int clk_enabled; void __iomem *mmio_base; unsigned int use_count; @@ -87,13 +88,23 @@ EXPORT_SYMBOL(pwm_config); int pwm_enable(struct pwm_device *pwm) { - return clk_enable(pwm->clk); + int rc = 0; + + if (!pwm->clk_enabled) { + rc = clk_enable(pwm->clk); + if (!rc) + pwm->clk_enabled = 1; + } + return rc; } EXPORT_SYMBOL(pwm_enable); void pwm_disable(struct pwm_device *pwm) { - clk_disable(pwm->clk); + if (pwm->clk_enabled) { + clk_disable(pwm->clk); + pwm->clk_enabled = 0; + } } EXPORT_SYMBOL(pwm_disable); @@ -161,6 +172,7 @@ static struct pwm_device *pwm_probe(struct platform_device *pdev, ret = PTR_ERR(pwm->clk); goto err_free; } + pwm->clk_enabled = 0; pwm->use_count = 0; pwm->pwm_id = pwm_id; -- cgit v1.2.3 From 5cca91479b8ac6a60b61bc56e72389c681387211 Mon Sep 17 00:00:00 2001 From: eric miao Date: Sun, 13 Apr 2008 21:46:34 +0100 Subject: [ARM] pxa: make zylonite use the generic PWM backlight driver Patch mostly by Eric Miao, minor edits by rmk. Signed-off-by: eric miao Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 2 ++ arch/arm/mach-pxa/zylonite.c | 26 +++++++++++++++++--------- arch/arm/mach-pxa/zylonite_pxa300.c | 4 +--- arch/arm/mach-pxa/zylonite_pxa320.c | 2 +- 4 files changed, 21 insertions(+), 13 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 9c01505b182..b7a3281c420 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -116,6 +116,7 @@ config MACH_COLIBRI config MACH_ZYLONITE bool "PXA3xx Development Platform" select PXA3xx + select HAVE_PWM config MACH_LITTLETON bool "PXA3xx Form Factor Platform (aka Littleton)" @@ -276,6 +277,7 @@ config PXA_SSP config PXA_PWM tristate + default BACKLIGHT_PWM help Enable support for PXA2xx/PXA3xx PWM controllers endif diff --git a/arch/arm/mach-pxa/zylonite.c b/arch/arm/mach-pxa/zylonite.c index 4a0028087ea..b13bb938513 100644 --- a/arch/arm/mach-pxa/zylonite.c +++ b/arch/arm/mach-pxa/zylonite.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include @@ -28,12 +29,12 @@ #include #include +#include "devices.h" #include "generic.h" #define MAX_SLOTS 3 struct platform_mmc_slot zylonite_mmc_slot[MAX_SLOTS]; -int gpio_backlight; int gpio_eth_irq; int wm9713_irq; @@ -62,10 +63,20 @@ static struct platform_device smc91x_device = { }; #if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) -static void zylonite_backlight_power(int on) -{ - gpio_set_value(gpio_backlight, on); -} +static struct platform_pwm_backlight_data zylonite_backlight_data = { + .pwm_id = 3, + .max_brightness = 100, + .dft_brightness = 100, + .pwm_period_ns = 10000, +}; + +static struct platform_device zylonite_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm1.dev, + .platform_data = &zylonite_backlight_data, + }, +}; static struct pxafb_mode_info toshiba_ltm035a776c_mode = { .pixclock = 110000, @@ -98,7 +109,6 @@ static struct pxafb_mode_info toshiba_ltm04c380k_mode = { static struct pxafb_mach_info zylonite_toshiba_lcd_info = { .num_modes = 1, .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, - .pxafb_backlight_power = zylonite_backlight_power, }; static struct pxafb_mode_info sharp_ls037_modes[] = { @@ -134,13 +144,11 @@ static struct pxafb_mach_info zylonite_sharp_lcd_info = { .modes = sharp_ls037_modes, .num_modes = 2, .lcd_conn = LCD_COLOR_TFT_16BPP | LCD_PCLK_EDGE_FALL, - .pxafb_backlight_power = zylonite_backlight_power, }; static void __init zylonite_init_lcd(void) { - /* backlight GPIO: output, default on */ - gpio_direction_output(gpio_backlight, 1); + platform_device_register(&zylonite_backlight_device); if (lcd_id & 0x20) { set_pxa_fb_info(&zylonite_sharp_lcd_info); diff --git a/arch/arm/mach-pxa/zylonite_pxa300.c b/arch/arm/mach-pxa/zylonite_pxa300.c index 324fb9daae2..6f7ae972b8d 100644 --- a/arch/arm/mach-pxa/zylonite_pxa300.c +++ b/arch/arm/mach-pxa/zylonite_pxa300.c @@ -50,6 +50,7 @@ static mfp_cfg_t common_mfp_cfg[] __initdata = { GPIO75_LCD_BIAS, GPIO76_LCD_VSYNC, GPIO127_LCD_CS_N, + GPIO20_PWM3_OUT, /* backlight */ /* BTUART */ GPIO111_UART2_RTS, @@ -200,9 +201,6 @@ void __init zylonite_pxa300_init(void) /* detect LCD panel */ zylonite_detect_lcd_panel(); - /* GPIO pin assignment */ - gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO20); - /* MMC card detect & write protect for controller 0 */ zylonite_mmc_slot[0].gpio_cd = EXT_GPIO(0); zylonite_mmc_slot[0].gpio_wp = EXT_GPIO(2); diff --git a/arch/arm/mach-pxa/zylonite_pxa320.c b/arch/arm/mach-pxa/zylonite_pxa320.c index 193d07903b0..2b4fc34919a 100644 --- a/arch/arm/mach-pxa/zylonite_pxa320.c +++ b/arch/arm/mach-pxa/zylonite_pxa320.c @@ -49,6 +49,7 @@ static mfp_cfg_t mfp_cfg[] __initdata = { GPIO15_2_LCD_LCLK, GPIO16_2_LCD_PCLK, GPIO17_2_LCD_BIAS, + GPIO14_PWM3_OUT, /* backlight */ /* FFUART */ GPIO41_UART1_RXD | MFP_LPM_EDGE_FALL, @@ -187,7 +188,6 @@ void __init zylonite_pxa320_init(void) zylonite_detect_lcd_panel(); /* GPIO pin assignment */ - gpio_backlight = mfp_to_gpio(MFP_PIN_GPIO14); gpio_eth_irq = mfp_to_gpio(MFP_PIN_GPIO9); /* MMC card detect & write protect for controller 0 */ -- cgit v1.2.3 From 402e490997ddaae310a080534a61d7ec24df8124 Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 13 Apr 2008 21:47:01 +0100 Subject: [ARM] pxa: make mainstone use the generic PWM backlight driver Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 1 + arch/arm/mach-pxa/mainstone.c | 63 ++++++++++++------------------------------- 2 files changed, 18 insertions(+), 46 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index b7a3281c420..2d711308076 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -41,6 +41,7 @@ config MACH_LOGICPD_PXA270 config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform" select PXA27x + select HAVE_PWM config ARCH_PXA_IDP bool "Accelent Xscale IDP" diff --git a/arch/arm/mach-pxa/mainstone.c b/arch/arm/mach-pxa/mainstone.c index 7399fb34da4..266594426e8 100644 --- a/arch/arm/mach-pxa/mainstone.c +++ b/arch/arm/mach-pxa/mainstone.c @@ -23,9 +23,9 @@ #include #include #include -#include #include #include +#include #include #include @@ -349,56 +349,27 @@ static struct platform_device mst_flash_device[2] = { }, }; -#ifdef CONFIG_BACKLIGHT_CLASS_DEVICE -static int mainstone_backlight_update_status(struct backlight_device *bl) -{ - int brightness = bl->props.brightness; - - if (bl->props.power != FB_BLANK_UNBLANK || - bl->props.fb_blank != FB_BLANK_UNBLANK) - brightness = 0; - - if (brightness != 0) - pxa_set_cken(CKEN_PWM0, 1); - - PWM_CTRL0 = 0; - PWM_PWDUTY0 = brightness; - PWM_PERVAL0 = bl->props.max_brightness; - - if (brightness == 0) - pxa_set_cken(CKEN_PWM0, 0); - return 0; /* pointless return value */ -} - -static int mainstone_backlight_get_brightness(struct backlight_device *bl) -{ - return PWM_PWDUTY0; -} +#if defined(CONFIG_FB_PXA) || defined(CONFIG_FB_PXA_MODULE) +static struct platform_pwm_backlight_data mainstone_backlight_data = { + .pwm_id = 0, + .max_brightness = 1023, + .dft_brightness = 1023, + .pwm_period_ns = 78770, +}; -static /*const*/ struct backlight_ops mainstone_backlight_ops = { - .update_status = mainstone_backlight_update_status, - .get_brightness = mainstone_backlight_get_brightness, +static struct platform_device mainstone_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &mainstone_backlight_data, + }, }; static void __init mainstone_backlight_register(void) { - struct backlight_device *bl; - - bl = backlight_device_register("mainstone-bl", &pxa_device_fb.dev, - NULL, &mainstone_backlight_ops); - if (IS_ERR(bl)) { - printk(KERN_ERR "mainstone: unable to register backlight: %ld\n", - PTR_ERR(bl)); - return; - } - - /* - * broken design - register-then-setup interfaces are - * utterly broken by definition. - */ - bl->props.max_brightness = 1023; - bl->props.brightness = 1023; - backlight_update_status(bl); + int ret = platform_device_register(&mainstone_backlight_device); + if (ret) + printk(KERN_ERR "mainstone: failed to register backlight device: %d\n", ret); } #else #define mainstone_backlight_register() do { } while (0) -- cgit v1.2.3 From 4a73071947d21f3aa39fa3a4bac104aaab94cfca Mon Sep 17 00:00:00 2001 From: Russell King Date: Sun, 18 May 2008 13:11:02 +0100 Subject: [ARM] pxa: make LogicPD 270 use the generic PWM backlight driver Acked-by: Lennert Buytenhek Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 1 + arch/arm/mach-pxa/lpd270.c | 38 +++++++++++++++++--------------------- 2 files changed, 18 insertions(+), 21 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 2d711308076..7db0fd87a45 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -37,6 +37,7 @@ config ARCH_LUBBOCK config MACH_LOGICPD_PXA270 bool "LogicPD PXA270 Card Engine Development Platform" select PXA27x + select HAVE_PWM config MACH_MAINSTONE bool "Intel HCDDBBVA0 Development Platform" diff --git a/arch/arm/mach-pxa/lpd270.c b/arch/arm/mach-pxa/lpd270.c index a20e4b1649d..f958403b43e 100644 --- a/arch/arm/mach-pxa/lpd270.c +++ b/arch/arm/mach-pxa/lpd270.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -233,21 +234,20 @@ static struct platform_device lpd270_flash_device[2] = { }, }; -static void lpd270_backlight_power(int on) -{ - if (on) { - pxa_gpio_mode(GPIO16_PWM0_MD); - pxa_set_cken(CKEN_PWM0, 1); - PWM_CTRL0 = 0; - PWM_PWDUTY0 = 0x3ff; - PWM_PERVAL0 = 0x3ff; - } else { - PWM_CTRL0 = 0; - PWM_PWDUTY0 = 0x0; - PWM_PERVAL0 = 0x3FF; - pxa_set_cken(CKEN_PWM0, 0); - } -} +static struct platform_pwm_backlight_data lpd270_backlight_data = { + .pwm_id = 0, + .max_brightness = 1, + .dft_brightness = 1, + .pwm_period_ns = 78770, +}; + +static struct platform_device lpd270_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &lpd270_backlight_data, + }, +}; /* 5.7" TFT QVGA (LoLo display number 1) */ static struct pxafb_mode_info sharp_lq057q3dc02_mode = { @@ -269,7 +269,6 @@ static struct pxafb_mach_info sharp_lq057q3dc02 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 12.1" TFT SVGA (LoLo display number 2) */ @@ -292,7 +291,6 @@ static struct pxafb_mach_info sharp_lq121s1dg31 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 3.6" TFT QVGA (LoLo display number 3) */ @@ -315,7 +313,6 @@ static struct pxafb_mach_info sharp_lq036q1da01 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 6.4" TFT VGA (LoLo display number 5) */ @@ -338,7 +335,6 @@ static struct pxafb_mach_info sharp_lq64d343 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 10.4" TFT VGA (LoLo display number 7) */ @@ -361,7 +357,6 @@ static struct pxafb_mach_info sharp_lq10d368 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; /* 3.5" TFT QVGA (LoLo display number 8) */ @@ -384,7 +379,6 @@ static struct pxafb_mach_info sharp_lq035q7db02_20 = { .num_modes = 1, .lccr0 = 0x07800080, .lccr3 = 0x00400000, - .pxafb_backlight_power = lpd270_backlight_power, }; static struct pxafb_mach_info *lpd270_lcd_to_use; @@ -414,6 +408,7 @@ __setup("lcd=", lpd270_set_lcd); static struct platform_device *platform_devices[] __initdata = { &smc91x_device, + &lpd270_backlight_device, &lpd270_audio_device, &lpd270_flash_device[0], &lpd270_flash_device[1], @@ -454,6 +449,7 @@ static void __init lpd270_init(void) * On LogicPD PXA270, we route AC97_SYSCLK via GPIO45. */ pxa_gpio_mode(GPIO45_SYSCLK_AC97_MD); + pxa_gpio_mode(GPIO16_PWM0_MD); platform_add_devices(platform_devices, ARRAY_SIZE(platform_devices)); -- cgit v1.2.3 From 43bda1a6d218744382547a2f8be3240d1c3a151b Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Tue, 1 Jul 2008 14:18:27 +0100 Subject: [ARM] 5141/1: PWM: pwm_request() should return an PTR_ERR() instead of NULL. Make the return of pwm_request() be more informative than just being NULL on error by using PTR_ERR() to respond with an approriate error. Signed-off-by: Ben Dooks Signed-off-by: Russell King --- arch/arm/mach-pxa/pwm.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/pwm.c b/arch/arm/mach-pxa/pwm.c index 7c86dd1d108..ce28cd9fed1 100644 --- a/arch/arm/mach-pxa/pwm.c +++ b/arch/arm/mach-pxa/pwm.c @@ -119,17 +119,23 @@ struct pwm_device *pwm_request(int pwm_id, const char *label) mutex_lock(&pwm_lock); list_for_each_entry(pwm, &pwm_list, node) { - if (pwm->pwm_id == pwm_id && pwm->use_count == 0) { - pwm->use_count++; - pwm->label = label; + if (pwm->pwm_id == pwm_id) { found = 1; break; } } - mutex_unlock(&pwm_lock); + if (found) { + if (pwm->use_count == 0) { + pwm->use_count++; + pwm->label = label; + } else + pwm = ERR_PTR(-EBUSY); + } else + pwm = ERR_PTR(-ENOENT); - return (found) ? pwm : NULL; + mutex_unlock(&pwm_lock); + return pwm; } EXPORT_SYMBOL(pwm_request); -- cgit v1.2.3 From 85847a360ff5012ed7932bb5bb63566ad584e02f Mon Sep 17 00:00:00 2001 From: Philipp Zabel Date: Thu, 22 May 2008 14:20:01 +0100 Subject: [ARM] 5045/1: magician: use the pwm_bl driver for the LCD backlight magician has a GPIO that modifies the brightness level additionally to the PWM duty value. This patch makes use of the pwm_bl notify callback to present userspace with a single brightness scale. This gets rid of the pxa_set_cken calls and direct PWM register access. Signed-off-by: Philipp Zabel Signed-off-by: Russell King --- arch/arm/mach-pxa/magician.c | 68 ++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 24 deletions(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c index badba064dc0..300caeb2137 100644 --- a/arch/arm/mach-pxa/magician.c +++ b/arch/arm/mach-pxa/magician.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -39,6 +40,7 @@ #include #include +#include "devices.h" #include "generic.h" static unsigned long magician_pin_config[] = { @@ -348,40 +350,58 @@ static struct pxafb_mach_info samsung_info = { * Backlight */ -static void magician_set_bl_intensity(int intensity) +static int magician_backlight_init(struct device *dev) { - if (intensity) { - PWM_CTRL0 = 1; - PWM_PERVAL0 = 0xc8; - if (intensity > 0xc7) { - PWM_PWDUTY0 = intensity - 0x48; - gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1); - } else { - PWM_PWDUTY0 = intensity; - gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0); - } - gpio_set_value(EGPIO_MAGICIAN_BL_POWER, 1); - pxa_set_cken(CKEN_PWM0, 1); + int ret; + + ret = gpio_request(EGPIO_MAGICIAN_BL_POWER, "BL_POWER"); + if (ret) + goto err; + ret = gpio_request(EGPIO_MAGICIAN_BL_POWER2, "BL_POWER2"); + if (ret) + goto err2; + return 0; + +err2: + gpio_free(EGPIO_MAGICIAN_BL_POWER); +err: + return ret; +} + +static int magician_backlight_notify(int brightness) +{ + gpio_set_value(EGPIO_MAGICIAN_BL_POWER, brightness); + if (brightness >= 200) { + gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 1); + return brightness - 72; } else { - /* PWM_PWDUTY0 = intensity; */ - gpio_set_value(EGPIO_MAGICIAN_BL_POWER, 0); - pxa_set_cken(CKEN_PWM0, 0); + gpio_set_value(EGPIO_MAGICIAN_BL_POWER2, 0); + return brightness; } } -static struct generic_bl_info backlight_info = { - .default_intensity = 0x64, - .limit_mask = 0x0b, - .max_intensity = 0xc7+0x48, - .set_bl_intensity = magician_set_bl_intensity, +static void magician_backlight_exit(struct device *dev) +{ + gpio_free(EGPIO_MAGICIAN_BL_POWER); + gpio_free(EGPIO_MAGICIAN_BL_POWER2); +} + +static struct platform_pwm_backlight_data backlight_data = { + .pwm_id = 0, + .max_brightness = 272, + .dft_brightness = 100, + .pwm_period_ns = 30923, + .init = magician_backlight_init, + .notify = magician_backlight_notify, + .exit = magician_backlight_exit, }; static struct platform_device backlight = { - .name = "generic-bl", + .name = "pwm-backlight", .dev = { - .platform_data = &backlight_info, + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &backlight_data, }, - .id = -1, }; /* -- cgit v1.2.3 From c0f7edb3099d538017c52556aab596b857dc92ee Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 13 Jun 2008 11:50:44 +0100 Subject: [ARM] 5094/1: pcm990: Add framebuffer and backlight support PCM990 boards can be assembled with either a Sharp STN or a NEC TFT LCD. This patch adds support for these displays and for the backlight, using the pwm_bl driver. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Russell King --- arch/arm/mach-pxa/Kconfig | 16 ++++++ arch/arm/mach-pxa/pcm990-baseboard.c | 99 +++++++++++++++++++++++++++++++++++- 2 files changed, 114 insertions(+), 1 deletion(-) (limited to 'arch/arm/mach-pxa') diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig index 7db0fd87a45..03cbd0f7285 100644 --- a/arch/arm/mach-pxa/Kconfig +++ b/arch/arm/mach-pxa/Kconfig @@ -149,6 +149,22 @@ choice config MACH_PCM990_BASEBOARD bool "PHYTEC PCM-990 development board" + select HAVE_PWM + +endchoice + +choice + prompt "display on pcm990" + depends on MACH_PCM990_BASEBOARD + +config PCM990_DISPLAY_SHARP + bool "sharp lq084v1dg21 stn display" + +config PCM990_DISPLAY_NEC + bool "nec nl6448bc20_18d tft display" + +config PCM990_DISPLAY_NONE + bool "no display" endchoice diff --git a/arch/arm/mach-pxa/pcm990-baseboard.c b/arch/arm/mach-pxa/pcm990-baseboard.c index 49d951db0f3..2564e16e4e2 100644 --- a/arch/arm/mach-pxa/pcm990-baseboard.c +++ b/arch/arm/mach-pxa/pcm990-baseboard.c @@ -24,6 +24,7 @@ #include #include #include +#include #include @@ -36,9 +37,99 @@ #include #include #include +#include + +#include "devices.h" + +/* + * pcm990_lcd_power - control power supply to the LCD + * @on: 0 = switch off, 1 = switch on + * + * Called by the pxafb driver + */ +#ifndef CONFIG_PCM990_DISPLAY_NONE +static void pcm990_lcd_power(int on, struct fb_var_screeninfo *var) +{ + if (on) { + /* enable LCD-Latches + * power on LCD + */ + __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = + PCM990_CTRL_LCDPWR + PCM990_CTRL_LCDON; + } else { + /* disable LCD-Latches + * power off LCD + */ + __PCM990_CTRL_REG(PCM990_CTRL_PHYS + PCM990_CTRL_REG3) = 0x00; + } +} +#endif + +#if defined(CONFIG_PCM990_DISPLAY_SHARP) +static struct pxafb_mode_info fb_info_sharp_lq084v1dg21 = { + .pixclock = 28000, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 20, + .left_margin = 103, + .right_margin = 47, + .vsync_len = 6, + .upper_margin = 28, + .lower_margin = 5, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info pcm990_fbinfo __initdata = { + .modes = &fb_info_sharp_lq084v1dg21, + .num_modes = 1, + .lccr0 = LCCR0_PAS, + .lccr3 = LCCR3_PCP, + .pxafb_lcd_power = pcm990_lcd_power, +}; +#elif defined(CONFIG_PCM990_DISPLAY_NEC) +struct pxafb_mode_info fb_info_nec_nl6448bc20_18d = { + .pixclock = 39720, + .xres = 640, + .yres = 480, + .bpp = 16, + .hsync_len = 32, + .left_margin = 16, + .right_margin = 48, + .vsync_len = 2, + .upper_margin = 12, + .lower_margin = 17, + .sync = 0, + .cmap_greyscale = 0, +}; + +static struct pxafb_mach_info pcm990_fbinfo __initdata = { + .modes = &fb_info_nec_nl6448bc20_18d, + .num_modes = 1, + .lccr0 = LCCR0_Act, + .lccr3 = LCCR3_PixFlEdg, + .pxafb_lcd_power = pcm990_lcd_power, +}; +#endif + +static struct platform_pwm_backlight_data pcm990_backlight_data = { + .pwm_id = 0, + .max_brightness = 1023, + .dft_brightness = 1023, + .pwm_period_ns = 78770, +}; + +static struct platform_device pcm990_backlight_device = { + .name = "pwm-backlight", + .dev = { + .parent = &pxa27x_device_pwm0.dev, + .platform_data = &pcm990_backlight_data, + }, +}; /* - * The PCM-990 development baseboard uses PCM-027's hardeware in the + * The PCM-990 development baseboard uses PCM-027's hardware in the * following way: * * - LCD support is in use @@ -393,6 +484,12 @@ void __init pcm990_baseboard_init(void) /* register CPLD's IRQ controller */ pcm990_init_irq(); +#ifndef CONFIG_PCM990_DISPLAY_NONE + set_pxa_fb_info(&pcm990_fbinfo); +#endif + pxa_gpio_mode(GPIO16_PWM0_MD); + platform_device_register(&pcm990_backlight_device); + platform_device_register(&pxa27x_device_ac97); /* MMC */ -- cgit v1.2.3