From 4082bc2934bf1e6363e2a5c4c98b3836e54d8695 Mon Sep 17 00:00:00 2001 From: Balaji Rao Date: Sun, 22 Feb 2009 04:39:57 +0000 Subject: move_pwm_code_to_plat_s3c.patch Since the pwm code in mach-2410 can be reused for 6410, move it to plat-s3c. Signed-off-by: Balaji Rao --- arch/arm/mach-s3c2410/Kconfig | 7 +- arch/arm/mach-s3c2410/Makefile | 1 - arch/arm/mach-s3c2410/include/mach/fiq_ipc_gta02.h | 2 +- arch/arm/mach-s3c2410/include/mach/pwm.h | 46 ---- arch/arm/mach-s3c2410/pwm.c | 288 --------------------- arch/arm/mach-s3c2442/Kconfig | 2 +- arch/arm/mach-s3c2442/fiq_c_isr.c | 2 +- arch/arm/plat-s3c/Kconfig | 5 + arch/arm/plat-s3c/Makefile | 2 + arch/arm/plat-s3c/include/plat/pwm.h | 45 ++++ arch/arm/plat-s3c/include/plat/regs-timer.h | 2 + arch/arm/plat-s3c/pwm.c | 288 +++++++++++++++++++++ 12 files changed, 346 insertions(+), 344 deletions(-) delete mode 100644 arch/arm/mach-s3c2410/include/mach/pwm.h delete mode 100644 arch/arm/mach-s3c2410/pwm.c create mode 100644 arch/arm/plat-s3c/include/plat/pwm.h create mode 100644 arch/arm/plat-s3c/pwm.c (limited to 'arch') diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig index ba58f9cac95..ea5d8f24f64 100644 --- a/arch/arm/mach-s3c2410/Kconfig +++ b/arch/arm/mach-s3c2410/Kconfig @@ -10,7 +10,7 @@ config CPU_S3C2410 select CPU_ARM920T select S3C2410_CLOCK select S3C2410_GPIO - select S3C2410_PWM + select S3C_PWM select CPU_LLSERIAL_S3C2410 select S3C2410_PM if PM help @@ -46,11 +46,6 @@ config MACH_BAST_IDE Internal node for machines with an BAST style IDE interface -config S3C2410_PWM - bool - help - PWM timer code for the S3C2410, and similar processors - menu "S3C2410 Machines" diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile index 6c537ecb1af..8929c9041c4 100644 --- a/arch/arm/mach-s3c2410/Makefile +++ b/arch/arm/mach-s3c2410/Makefile @@ -16,7 +16,6 @@ obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o obj-$(CONFIG_S3C2410_GPIO) += gpio.o #obj-$(CONFIG_S3C2410_CLOCK) += clock.o -obj-$(CONFIG_S3C2410_PWM) += pwm.o # Machine support diff --git a/arch/arm/mach-s3c2410/include/mach/fiq_ipc_gta02.h b/arch/arm/mach-s3c2410/include/mach/fiq_ipc_gta02.h index e74aa2ccc40..401d1fbc050 100644 --- a/arch/arm/mach-s3c2410/include/mach/fiq_ipc_gta02.h +++ b/arch/arm/mach-s3c2410/include/mach/fiq_ipc_gta02.h @@ -16,7 +16,7 @@ * for testing */ -#include +#include #include extern u8 fiq_ready; diff --git a/arch/arm/mach-s3c2410/include/mach/pwm.h b/arch/arm/mach-s3c2410/include/mach/pwm.h deleted file mode 100644 index 18c1bac8851..00000000000 --- a/arch/arm/mach-s3c2410/include/mach/pwm.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef __S3C2410_PWM_H -#define __S3C2410_PWM_H - -#include -#include -#include - -#include -#include -#include -#include -#include - -enum pwm_timer { - PWM0, - PWM1, - PWM2, - PWM3, - PWM4 -}; - -struct s3c2410_pwm { - enum pwm_timer timerid; - struct clk *pclk; - unsigned long pclk_rate; - unsigned long prescaler; - unsigned long divider; - unsigned long counter; - unsigned long comparer; -}; - -struct s3c24xx_pwm_platform_data{ - /* callback to attach platform children (to enforce suspend / resume - * ordering */ - void (*attach_child_devices)(struct device *parent_device); -}; - -int s3c2410_pwm_init(struct s3c2410_pwm *s3c2410_pwm); -int s3c2410_pwm_enable(struct s3c2410_pwm *s3c2410_pwm); -int s3c2410_pwm_disable(struct s3c2410_pwm *s3c2410_pwm); -int s3c2410_pwm_start(struct s3c2410_pwm *s3c2410_pwm); -int s3c2410_pwm_stop(struct s3c2410_pwm *s3c2410_pwm); -int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *s3c2410_pwm); -int s3c2410_pwm_dumpregs(void); - -#endif /* __S3C2410_PWM_H */ diff --git a/arch/arm/mach-s3c2410/pwm.c b/arch/arm/mach-s3c2410/pwm.c deleted file mode 100644 index 5d9ed5b653f..00000000000 --- a/arch/arm/mach-s3c2410/pwm.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * arch/arm/mach-s3c2410/3c2410-pwm.c - * - * Copyright (c) by Javi Roman - * for the Openmoko Project. - * - * S3C2410A SoC PWM support - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef CONFIG_PM - static unsigned long standby_reg_tcon; - static unsigned long standby_reg_tcfg0; - static unsigned long standby_reg_tcfg1; -#endif - -int s3c2410_pwm_disable(struct s3c2410_pwm *pwm) -{ - unsigned long tcon; - - /* stop timer */ - tcon = __raw_readl(S3C2410_TCON); - tcon &= 0xffffff00; - __raw_writel(tcon, S3C2410_TCON); - - clk_disable(pwm->pclk); - clk_put(pwm->pclk); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_disable); - -int s3c2410_pwm_init(struct s3c2410_pwm *pwm) -{ - pwm->pclk = clk_get(NULL, "timers"); - if (IS_ERR(pwm->pclk)) - return PTR_ERR(pwm->pclk); - - clk_enable(pwm->pclk); - pwm->pclk_rate = clk_get_rate(pwm->pclk); - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_init); - -int s3c2410_pwm_enable(struct s3c2410_pwm *pwm) -{ - unsigned long tcfg0, tcfg1, tcnt, tcmp; - - /* control registers bits */ - tcfg1 = __raw_readl(S3C2410_TCFG1); - tcfg0 = __raw_readl(S3C2410_TCFG0); - - /* divider & scaler slection */ - switch (pwm->timerid) { - case PWM0: - tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK; - tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; - break; - case PWM1: - tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK; - tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; - break; - case PWM2: - tcfg1 &= ~S3C2410_TCFG1_MUX2_MASK; - tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; - break; - case PWM3: - tcfg1 &= ~S3C2410_TCFG1_MUX3_MASK; - tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; - break; - case PWM4: - /* timer four is not capable of doing PWM */ - break; - default: - clk_disable(pwm->pclk); - clk_put(pwm->pclk); - return -1; - } - - /* divider & scaler values */ - tcfg1 |= pwm->divider; - __raw_writel(tcfg1, S3C2410_TCFG1); - - switch (pwm->timerid) { - case PWM0: - case PWM1: - tcfg0 |= pwm->prescaler; - __raw_writel(tcfg0, S3C2410_TCFG0); - break; - default: - if ((tcfg0 | pwm->prescaler) != tcfg0) { - printk(KERN_WARNING "not changing prescaler of PWM %u," - " since it's shared with timer4 (clock tick)\n", - pwm->timerid); - } - break; - } - - /* timer count and compare buffer initial values */ - tcnt = pwm->counter; - tcmp = pwm->comparer; - - __raw_writel(tcnt, S3C2410_TCNTB(pwm->timerid)); - __raw_writel(tcmp, S3C2410_TCMPB(pwm->timerid)); - - /* ensure timer is stopped */ - s3c2410_pwm_stop(pwm); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_enable); - -int s3c2410_pwm_start(struct s3c2410_pwm *pwm) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - switch (pwm->timerid) { - case PWM0: - tcon |= S3C2410_TCON_T0START; - tcon &= ~S3C2410_TCON_T0MANUALUPD; - break; - case PWM1: - tcon |= S3C2410_TCON_T1START; - tcon &= ~S3C2410_TCON_T1MANUALUPD; - break; - case PWM2: - tcon |= S3C2410_TCON_T2START; - tcon &= ~S3C2410_TCON_T2MANUALUPD; - break; - case PWM3: - tcon |= S3C2410_TCON_T3START; - tcon &= ~S3C2410_TCON_T3MANUALUPD; - break; - case PWM4: - /* timer four is not capable of doing PWM */ - default: - return -ENODEV; - } - - __raw_writel(tcon, S3C2410_TCON); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_start); - -int s3c2410_pwm_stop(struct s3c2410_pwm *pwm) -{ - unsigned long tcon; - - tcon = __raw_readl(S3C2410_TCON); - - switch (pwm->timerid) { - case PWM0: - tcon &= ~0x00000000; - tcon |= S3C2410_TCON_T0RELOAD; - tcon |= S3C2410_TCON_T0MANUALUPD; - break; - case PWM1: - tcon &= ~0x00000080; - tcon |= S3C2410_TCON_T1RELOAD; - tcon |= S3C2410_TCON_T1MANUALUPD; - break; - case PWM2: - tcon &= ~0x00000800; - tcon |= S3C2410_TCON_T2RELOAD; - tcon |= S3C2410_TCON_T2MANUALUPD; - break; - case PWM3: - tcon &= ~0x00008000; - tcon |= S3C2410_TCON_T3RELOAD; - tcon |= S3C2410_TCON_T3MANUALUPD; - break; - case PWM4: - /* timer four is not capable of doing PWM */ - default: - return -ENODEV; - } - - __raw_writel(tcon, S3C2410_TCON); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_stop); - -int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *pwm) -{ - __raw_writel(reg_value, S3C2410_TCMPB(pwm->timerid)); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_duty_cycle); - -int s3c2410_pwm_dumpregs(void) -{ - printk(KERN_INFO "TCON: %08lx, TCFG0: %08lx, TCFG1: %08lx\n", - (unsigned long) __raw_readl(S3C2410_TCON), - (unsigned long) __raw_readl(S3C2410_TCFG0), - (unsigned long) __raw_readl(S3C2410_TCFG1)); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c2410_pwm_dumpregs); - -static int __init s3c24xx_pwm_probe(struct platform_device *pdev) -{ - struct s3c24xx_pwm_platform_data *pdata = pdev->dev.platform_data; - - dev_info(&pdev->dev, "s3c24xx_pwm is registered \n"); - - /* if platform was interested, give him a chance to register - * platform devices that switch power with us as the parent - * at registration time -- ensures suspend / resume ordering - */ - if (pdata) - if (pdata->attach_child_devices) - (pdata->attach_child_devices)(&pdev->dev); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c24xx_pwm_suspend(struct platform_device *pdev, pm_message_t state) -{ - /* PWM config should be kept in suspending */ - standby_reg_tcon = __raw_readl(S3C2410_TCON); - standby_reg_tcfg0 = __raw_readl(S3C2410_TCFG0); - standby_reg_tcfg1 = __raw_readl(S3C2410_TCFG1); - - return 0; -} - -static int s3c24xx_pwm_resume(struct platform_device *pdev) -{ - __raw_writel(standby_reg_tcon, S3C2410_TCON); - __raw_writel(standby_reg_tcfg0, S3C2410_TCFG0); - __raw_writel(standby_reg_tcfg1, S3C2410_TCFG1); - - return 0; -} -#else -#define s3c24xx_pwm_suspend NULL -#define s3c24xx_pwm_resume NULL -#endif - -static struct platform_driver s3c24xx_pwm_driver = { - .driver = { - .name = "s3c24xx_pwm", - .owner = THIS_MODULE, - }, - .probe = s3c24xx_pwm_probe, - .suspend = s3c24xx_pwm_suspend, - .resume = s3c24xx_pwm_resume, -}; - -static int __init s3c24xx_pwm_init(void) -{ - return platform_driver_register(&s3c24xx_pwm_driver); -} - -static void __exit s3c24xx_pwm_exit(void) -{ -} - -MODULE_AUTHOR("Javi Roman "); -MODULE_LICENSE("GPL"); - -module_init(s3c24xx_pwm_init); -module_exit(s3c24xx_pwm_exit); diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig index 27453f02326..991ed6a2d0b 100644 --- a/arch/arm/mach-s3c2442/Kconfig +++ b/arch/arm/mach-s3c2442/Kconfig @@ -41,7 +41,7 @@ config MACH_NEO1973_GTA02 select POWER_SUPPLY select GTA02_HDQ select MACH_NEO1973 - select S3C2410_PWM + select S3C_PWM select S3C2410_CLOCK help Say Y here if you are using the FIC Neo1973 GSM Phone diff --git a/arch/arm/mach-s3c2442/fiq_c_isr.c b/arch/arm/mach-s3c2442/fiq_c_isr.c index 0decc35a317..e1728300ad0 100644 --- a/arch/arm/mach-s3c2442/fiq_c_isr.c +++ b/arch/arm/mach-s3c2442/fiq_c_isr.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include /* diff --git a/arch/arm/plat-s3c/Kconfig b/arch/arm/plat-s3c/Kconfig index 05537018171..a0ecea9aa4d 100644 --- a/arch/arm/plat-s3c/Kconfig +++ b/arch/arm/plat-s3c/Kconfig @@ -159,6 +159,11 @@ config S3C_GPIO_CFG_S3C64XX Internal configuration to enable S3C64XX style GPIO configuration functions. +config S3C_PWM + bool + help + PWM timer code for the S3C2410, and similar processors + # device definitions to compile in config S3C_DEV_HSMMC diff --git a/arch/arm/plat-s3c/Makefile b/arch/arm/plat-s3c/Makefile index c77fcae5529..cb5ea6cc7dd 100644 --- a/arch/arm/plat-s3c/Makefile +++ b/arch/arm/plat-s3c/Makefile @@ -31,3 +31,5 @@ obj-$(CONFIG_S3C_DEV_HSMMC1) += dev-hsmmc1.o obj-y += dev-i2c0.o obj-$(CONFIG_S3C_DEV_I2C1) += dev-i2c1.o obj-$(CONFIG_S3C_DEV_FB) += dev-fb.o + +obj-$(CONFIG_S3C_PWM) += pwm.o diff --git a/arch/arm/plat-s3c/include/plat/pwm.h b/arch/arm/plat-s3c/include/plat/pwm.h new file mode 100644 index 00000000000..6a41b0ad840 --- /dev/null +++ b/arch/arm/plat-s3c/include/plat/pwm.h @@ -0,0 +1,45 @@ +#ifndef __S3C2410_PWM_H +#define __S3C2410_PWM_H + +#include +#include +#include + +#include +#include +#include +#include + +enum pwm_timer { + PWM0, + PWM1, + PWM2, + PWM3, + PWM4 +}; + +struct s3c2410_pwm { + enum pwm_timer timerid; + struct clk *pclk; + unsigned long pclk_rate; + unsigned long prescaler; + unsigned long divider; + unsigned long counter; + unsigned long comparer; +}; + +struct s3c24xx_pwm_platform_data{ + /* callback to attach platform children (to enforce suspend / resume + * ordering */ + void (*attach_child_devices)(struct device *parent_device); +}; + +int s3c2410_pwm_init(struct s3c2410_pwm *s3c2410_pwm); +int s3c2410_pwm_enable(struct s3c2410_pwm *s3c2410_pwm); +int s3c2410_pwm_disable(struct s3c2410_pwm *s3c2410_pwm); +int s3c2410_pwm_start(struct s3c2410_pwm *s3c2410_pwm); +int s3c2410_pwm_stop(struct s3c2410_pwm *s3c2410_pwm); +int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *s3c2410_pwm); +int s3c2410_pwm_dumpregs(void); + +#endif /* __S3C2410_PWM_H */ diff --git a/arch/arm/plat-s3c/include/plat/regs-timer.h b/arch/arm/plat-s3c/include/plat/regs-timer.h index d097d92f8cc..75527d16f60 100644 --- a/arch/arm/plat-s3c/include/plat/regs-timer.h +++ b/arch/arm/plat-s3c/include/plat/regs-timer.h @@ -10,6 +10,8 @@ * S3C2410 Timer configuration */ +#include + #ifndef __ASM_ARCH_REGS_TIMER_H #define __ASM_ARCH_REGS_TIMER_H diff --git a/arch/arm/plat-s3c/pwm.c b/arch/arm/plat-s3c/pwm.c new file mode 100644 index 00000000000..250bd2bc9b8 --- /dev/null +++ b/arch/arm/plat-s3c/pwm.c @@ -0,0 +1,288 @@ +/* + * arch/arm/plat-s3c/pwm.c + * + * Copyright (c) by Javi Roman + * for the Openmoko Project. + * + * S3C2410A SoC PWM support + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef CONFIG_PM + static unsigned long standby_reg_tcon; + static unsigned long standby_reg_tcfg0; + static unsigned long standby_reg_tcfg1; +#endif + +int s3c2410_pwm_disable(struct s3c2410_pwm *pwm) +{ + unsigned long tcon; + + /* stop timer */ + tcon = __raw_readl(S3C2410_TCON); + tcon &= 0xffffff00; + __raw_writel(tcon, S3C2410_TCON); + + clk_disable(pwm->pclk); + clk_put(pwm->pclk); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_disable); + +int s3c2410_pwm_init(struct s3c2410_pwm *pwm) +{ + pwm->pclk = clk_get(NULL, "timers"); + if (IS_ERR(pwm->pclk)) + return PTR_ERR(pwm->pclk); + + clk_enable(pwm->pclk); + pwm->pclk_rate = clk_get_rate(pwm->pclk); + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_init); + +int s3c2410_pwm_enable(struct s3c2410_pwm *pwm) +{ + unsigned long tcfg0, tcfg1, tcnt, tcmp; + + /* control registers bits */ + tcfg1 = __raw_readl(S3C2410_TCFG1); + tcfg0 = __raw_readl(S3C2410_TCFG0); + + /* divider & scaler slection */ + switch (pwm->timerid) { + case PWM0: + tcfg1 &= ~S3C2410_TCFG1_MUX0_MASK; + tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; + break; + case PWM1: + tcfg1 &= ~S3C2410_TCFG1_MUX1_MASK; + tcfg0 &= ~S3C2410_TCFG_PRESCALER0_MASK; + break; + case PWM2: + tcfg1 &= ~S3C2410_TCFG1_MUX2_MASK; + tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; + break; + case PWM3: + tcfg1 &= ~S3C2410_TCFG1_MUX3_MASK; + tcfg0 &= ~S3C2410_TCFG_PRESCALER1_MASK; + break; + case PWM4: + /* timer four is not capable of doing PWM */ + break; + default: + clk_disable(pwm->pclk); + clk_put(pwm->pclk); + return -1; + } + + /* divider & scaler values */ + tcfg1 |= pwm->divider; + __raw_writel(tcfg1, S3C2410_TCFG1); + + switch (pwm->timerid) { + case PWM0: + case PWM1: + tcfg0 |= pwm->prescaler; + __raw_writel(tcfg0, S3C2410_TCFG0); + break; + default: + if ((tcfg0 | pwm->prescaler) != tcfg0) { + printk(KERN_WARNING "not changing prescaler of PWM %u," + " since it's shared with timer4 (clock tick)\n", + pwm->timerid); + } + break; + } + + /* timer count and compare buffer initial values */ + tcnt = pwm->counter; + tcmp = pwm->comparer; + + __raw_writel(tcnt, S3C2410_TCNTB(pwm->timerid)); + __raw_writel(tcmp, S3C2410_TCMPB(pwm->timerid)); + + /* ensure timer is stopped */ + s3c2410_pwm_stop(pwm); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_enable); + +int s3c2410_pwm_start(struct s3c2410_pwm *pwm) +{ + unsigned long tcon; + + tcon = __raw_readl(S3C2410_TCON); + + switch (pwm->timerid) { + case PWM0: + tcon |= S3C2410_TCON_T0START; + tcon &= ~S3C2410_TCON_T0MANUALUPD; + break; + case PWM1: + tcon |= S3C2410_TCON_T1START; + tcon &= ~S3C2410_TCON_T1MANUALUPD; + break; + case PWM2: + tcon |= S3C2410_TCON_T2START; + tcon &= ~S3C2410_TCON_T2MANUALUPD; + break; + case PWM3: + tcon |= S3C2410_TCON_T3START; + tcon &= ~S3C2410_TCON_T3MANUALUPD; + break; + case PWM4: + /* timer four is not capable of doing PWM */ + default: + return -ENODEV; + } + + __raw_writel(tcon, S3C2410_TCON); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_start); + +int s3c2410_pwm_stop(struct s3c2410_pwm *pwm) +{ + unsigned long tcon; + + tcon = __raw_readl(S3C2410_TCON); + + switch (pwm->timerid) { + case PWM0: + tcon &= ~0x00000000; + tcon |= S3C2410_TCON_T0RELOAD; + tcon |= S3C2410_TCON_T0MANUALUPD; + break; + case PWM1: + tcon &= ~0x00000080; + tcon |= S3C2410_TCON_T1RELOAD; + tcon |= S3C2410_TCON_T1MANUALUPD; + break; + case PWM2: + tcon &= ~0x00000800; + tcon |= S3C2410_TCON_T2RELOAD; + tcon |= S3C2410_TCON_T2MANUALUPD; + break; + case PWM3: + tcon &= ~0x00008000; + tcon |= S3C2410_TCON_T3RELOAD; + tcon |= S3C2410_TCON_T3MANUALUPD; + break; + case PWM4: + /* timer four is not capable of doing PWM */ + default: + return -ENODEV; + } + + __raw_writel(tcon, S3C2410_TCON); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_stop); + +int s3c2410_pwm_duty_cycle(int reg_value, struct s3c2410_pwm *pwm) +{ + __raw_writel(reg_value, S3C2410_TCMPB(pwm->timerid)); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_duty_cycle); + +int s3c2410_pwm_dumpregs(void) +{ + printk(KERN_INFO "TCON: %08lx, TCFG0: %08lx, TCFG1: %08lx\n", + (unsigned long) __raw_readl(S3C2410_TCON), + (unsigned long) __raw_readl(S3C2410_TCFG0), + (unsigned long) __raw_readl(S3C2410_TCFG1)); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c2410_pwm_dumpregs); + +static int __init s3c24xx_pwm_probe(struct platform_device *pdev) +{ + struct s3c24xx_pwm_platform_data *pdata = pdev->dev.platform_data; + + dev_info(&pdev->dev, "s3c24xx_pwm is registered \n"); + + /* if platform was interested, give him a chance to register + * platform devices that switch power with us as the parent + * at registration time -- ensures suspend / resume ordering + */ + if (pdata) + if (pdata->attach_child_devices) + (pdata->attach_child_devices)(&pdev->dev); + + return 0; +} + +#ifdef CONFIG_PM +static int s3c24xx_pwm_suspend(struct platform_device *pdev, pm_message_t state) +{ + /* PWM config should be kept in suspending */ + standby_reg_tcon = __raw_readl(S3C2410_TCON); + standby_reg_tcfg0 = __raw_readl(S3C2410_TCFG0); + standby_reg_tcfg1 = __raw_readl(S3C2410_TCFG1); + + return 0; +} + +static int s3c24xx_pwm_resume(struct platform_device *pdev) +{ + __raw_writel(standby_reg_tcon, S3C2410_TCON); + __raw_writel(standby_reg_tcfg0, S3C2410_TCFG0); + __raw_writel(standby_reg_tcfg1, S3C2410_TCFG1); + + return 0; +} +#else +#define s3c24xx_pwm_suspend NULL +#define s3c24xx_pwm_resume NULL +#endif + +static struct platform_driver s3c24xx_pwm_driver = { + .driver = { + .name = "s3c24xx_pwm", + .owner = THIS_MODULE, + }, + .probe = s3c24xx_pwm_probe, + .suspend = s3c24xx_pwm_suspend, + .resume = s3c24xx_pwm_resume, +}; + +static int __init s3c24xx_pwm_init(void) +{ + return platform_driver_register(&s3c24xx_pwm_driver); +} + +static void __exit s3c24xx_pwm_exit(void) +{ +} + +MODULE_AUTHOR("Javi Roman "); +MODULE_LICENSE("GPL"); + +module_init(s3c24xx_pwm_init); +module_exit(s3c24xx_pwm_exit); -- cgit v1.2.3