aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-ep93xx
diff options
context:
space:
mode:
authorHartley Sweeten <hartleys@visionengravers.com>2009-07-29 17:41:06 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-07-30 12:45:43 -0400
commitef12379f205bed7e92434e12ddd44e62d13bebe1 (patch)
treec372f5741826e7fbdaec8eac86191b52e3e621af /arch/arm/mach-ep93xx
parent3aa7a9a3cf8774f6701b1903a6353f9545f561ce (diff)
ARM: 5628/1: ep93xx: Introduce Pulse Width Modulator (PWM) driver
The EP93xx features two PWMs (one on the EP9307) with the following features: * Configurable dual output * Separate input clocks for each PWM output * 16-bit resolution * Programmable pulse width (duty cycle), interval (frequency), and polarity This adds the necessary core support as well as the driver. A sysfs interface is provided to control the PWM outputs. Signed-off-by: Matthieu Crapet <mcrapet@gmail.com> Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com> Acked-by: Ryan Mallon <ryan@bluewatersys.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-ep93xx')
-rw-r--r--arch/arm/mach-ep93xx/clock.c4
-rw-r--r--arch/arm/mach-ep93xx/core.c85
-rw-r--r--arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h1
-rw-r--r--arch/arm/mach-ep93xx/include/mach/platform.h4
4 files changed, 94 insertions, 0 deletions
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index b6b53447b1b4..3dd0e2a23095 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -72,6 +72,9 @@ static struct clk clk_keypad = {
72 .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN, 72 .enable_mask = EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
73 .set_rate = set_keytchclk_rate, 73 .set_rate = set_keytchclk_rate,
74}; 74};
75static struct clk clk_pwm = {
76 .rate = EP93XX_EXT_CLK_RATE,
77};
75 78
76/* DMA Clocks */ 79/* DMA Clocks */
77static struct clk clk_m2p0 = { 80static struct clk clk_m2p0 = {
@@ -137,6 +140,7 @@ static struct clk_lookup clocks[] = {
137 INIT_CK(NULL, "pll2", &clk_pll2), 140 INIT_CK(NULL, "pll2", &clk_pll2),
138 INIT_CK("ep93xx-ohci", NULL, &clk_usb_host), 141 INIT_CK("ep93xx-ohci", NULL, &clk_usb_host),
139 INIT_CK("ep93xx-keypad", NULL, &clk_keypad), 142 INIT_CK("ep93xx-keypad", NULL, &clk_keypad),
143 INIT_CK(NULL, "pwm_clk", &clk_pwm),
140 INIT_CK(NULL, "m2p0", &clk_m2p0), 144 INIT_CK(NULL, "m2p0", &clk_m2p0),
141 INIT_CK(NULL, "m2p1", &clk_m2p1), 145 INIT_CK(NULL, "m2p1", &clk_m2p1),
142 INIT_CK(NULL, "m2p2", &clk_m2p2), 146 INIT_CK(NULL, "m2p2", &clk_m2p2),
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 2b58df0184c1..40755298fa33 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -597,6 +597,91 @@ static struct platform_device ep93xx_leds = {
597}; 597};
598 598
599 599
600/*************************************************************************
601 * EP93xx pwm peripheral handling
602 *************************************************************************/
603static struct resource ep93xx_pwm0_resource[] = {
604 {
605 .start = EP93XX_PWM_PHYS_BASE,
606 .end = EP93XX_PWM_PHYS_BASE + 0x10 - 1,
607 .flags = IORESOURCE_MEM,
608 },
609};
610
611static struct platform_device ep93xx_pwm0_device = {
612 .name = "ep93xx-pwm",
613 .id = 0,
614 .num_resources = ARRAY_SIZE(ep93xx_pwm0_resource),
615 .resource = ep93xx_pwm0_resource,
616};
617
618static struct resource ep93xx_pwm1_resource[] = {
619 {
620 .start = EP93XX_PWM_PHYS_BASE + 0x20,
621 .end = EP93XX_PWM_PHYS_BASE + 0x30 - 1,
622 .flags = IORESOURCE_MEM,
623 },
624};
625
626static struct platform_device ep93xx_pwm1_device = {
627 .name = "ep93xx-pwm",
628 .id = 1,
629 .num_resources = ARRAY_SIZE(ep93xx_pwm1_resource),
630 .resource = ep93xx_pwm1_resource,
631};
632
633void __init ep93xx_register_pwm(int pwm0, int pwm1)
634{
635 if (pwm0)
636 platform_device_register(&ep93xx_pwm0_device);
637
638 /* NOTE: EP9307 does not have PWMOUT1 (pin EGPIO14) */
639 if (pwm1)
640 platform_device_register(&ep93xx_pwm1_device);
641}
642
643int ep93xx_pwm_acquire_gpio(struct platform_device *pdev)
644{
645 int err;
646
647 if (pdev->id == 0) {
648 err = 0;
649 } else if (pdev->id == 1) {
650 err = gpio_request(EP93XX_GPIO_LINE_EGPIO14,
651 dev_name(&pdev->dev));
652 if (err)
653 return err;
654 err = gpio_direction_output(EP93XX_GPIO_LINE_EGPIO14, 0);
655 if (err)
656 goto fail;
657
658 /* PWM 1 output on EGPIO[14] */
659 ep93xx_devcfg_set_bits(EP93XX_SYSCON_DEVCFG_PONG);
660 } else {
661 err = -ENODEV;
662 }
663
664 return err;
665
666fail:
667 gpio_free(EP93XX_GPIO_LINE_EGPIO14);
668 return err;
669}
670EXPORT_SYMBOL(ep93xx_pwm_acquire_gpio);
671
672void ep93xx_pwm_release_gpio(struct platform_device *pdev)
673{
674 if (pdev->id == 1) {
675 gpio_direction_input(EP93XX_GPIO_LINE_EGPIO14);
676 gpio_free(EP93XX_GPIO_LINE_EGPIO14);
677
678 /* EGPIO[14] used for GPIO */
679 ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_PONG);
680 }
681}
682EXPORT_SYMBOL(ep93xx_pwm_release_gpio);
683
684
600extern void ep93xx_gpio_init(void); 685extern void ep93xx_gpio_init(void);
601 686
602void __init ep93xx_init_devices(void) 687void __init ep93xx_init_devices(void)
diff --git a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
index a11ae779baa0..ea78e908fc82 100644
--- a/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
+++ b/arch/arm/mach-ep93xx/include/mach/ep93xx-regs.h
@@ -147,6 +147,7 @@
147#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000) 147#define EP93XX_ADC_BASE EP93XX_APB_IOMEM(0x00100000)
148#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000) 148#define EP93XX_TOUCHSCREEN_BASE EP93XX_APB_IOMEM(0x00100000)
149 149
150#define EP93XX_PWM_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00110000)
150#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000) 151#define EP93XX_PWM_BASE EP93XX_APB_IOMEM(0x00110000)
151 152
152#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000) 153#define EP93XX_RTC_PHYS_BASE (EP93XX_APB_PHYS_BASE + 0x00120000)
diff --git a/arch/arm/mach-ep93xx/include/mach/platform.h b/arch/arm/mach-ep93xx/include/mach/platform.h
index 0af0a3ba7047..5f5fa6574d34 100644
--- a/arch/arm/mach-ep93xx/include/mach/platform.h
+++ b/arch/arm/mach-ep93xx/include/mach/platform.h
@@ -5,6 +5,7 @@
5#ifndef __ASSEMBLY__ 5#ifndef __ASSEMBLY__
6 6
7struct i2c_board_info; 7struct i2c_board_info;
8struct platform_device;
8 9
9struct ep93xx_eth_data 10struct ep93xx_eth_data
10{ 11{
@@ -32,6 +33,9 @@ static inline void ep93xx_devcfg_clear_bits(unsigned int bits)
32 33
33void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr); 34void ep93xx_register_eth(struct ep93xx_eth_data *data, int copy_addr);
34void ep93xx_register_i2c(struct i2c_board_info *devices, int num); 35void ep93xx_register_i2c(struct i2c_board_info *devices, int num);
36void ep93xx_register_pwm(int pwm0, int pwm1);
37int ep93xx_pwm_acquire_gpio(struct platform_device *pdev);
38void ep93xx_pwm_release_gpio(struct platform_device *pdev);
35 39
36void ep93xx_init_devices(void); 40void ep93xx_init_devices(void);
37extern struct sys_timer ep93xx_timer; 41extern struct sys_timer ep93xx_timer;