aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 07:15:24 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2012-10-10 07:15:24 -0400
commit2474542f64432398f503373f53bdf620491bcfa8 (patch)
tree3c9744b138c2158757530814b35c23eed31cf6ce /arch/mips
parentc7a6ced9d8e8411bdafe83998474d185a79badc3 (diff)
parent85f8879ca4f3d26a7f473522101fb74a79bda3f2 (diff)
Merge tag 'for-3.7-rc1' of git://gitorious.org/linux-pwm/linux-pwm
Pull pwm changes from Thierry Reding: "All legacy PWM providers have now been moved to the PWM subsystem. The plan for 3.8 is to adapt all board files to provide a lookup table for PWM devices in order to get rid of the global namespace. Subsequently, users of the legacy pwm_request() and pwm_free() functions can be migrated to the new pwm_get() and pwm_put() functions. Once this has been completed, the legacy API and the compatibility code in the core can be removed. In addition to the above, these changes also add support for configuring the polarity of a PWM signal (currently only supported on ECAP and EHRPWM) and include a much needed rework of the i.MX driver. Managed functions to obtain and release a PWM device (devm_pwm_get() and devm_pwm_put()) have been added and the pwm-backlight driver has been updated to use them. If the PWM subsystem hasn't been enabled, dummy functions are provided that allow the subsystem to safely compile out. Some common checks on input parameters have been moved to the core and removed from the drivers. Finally, a small fix corrects the description of the PWM specifier's second cell in the device tree representation." * tag 'for-3.7-rc1' of git://gitorious.org/linux-pwm/linux-pwm: (23 commits) pwm: dt: Fix description of second PWM cell pwm: Check for negative duty-cycle and period pwm: Add Ingenic JZ4740 support MIPS: JZ4740: Export timer API pwm: Move PUV3 PWM driver to PWM framework unicore32: pwm: Use managed resource allocations unicore32: pwm: Remove unnecessary indirection unicore32: pwm: Use module_platform_driver() unicore32: pwm: Properly remap memory-mapped registers pwm-backlight: Use devm_pwm_get() instead of pwm_get() pwm: Move AB8500 PWM driver to PWM framework pwm: Fix compilation error when CONFIG_PWM is not defined pwm: i.MX: fix clock lookup pwm: i.MX: use per clock unconditionally pwm: i.MX: add devicetree support pwm: i.MX: Use module_platform_driver pwm: i.MX: add functions to enable/disable pwm. pwm: i.MX: remove unnecessary if in pwm_[en|dis]able pwm: i.MX: factor out SoC specific functions pwm: pwm-tiehrpwm: Add support for configuring polarity of PWM ...
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/mach-jz4740/platform.h1
-rw-r--r--arch/mips/include/asm/mach-jz4740/timer.h113
-rw-r--r--arch/mips/jz4740/Kconfig3
-rw-r--r--arch/mips/jz4740/Makefile2
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c1
-rw-r--r--arch/mips/jz4740/platform.c6
-rw-r--r--arch/mips/jz4740/pwm.c177
-rw-r--r--arch/mips/jz4740/time.c2
-rw-r--r--arch/mips/jz4740/timer.c4
-rw-r--r--arch/mips/jz4740/timer.h136
10 files changed, 125 insertions, 320 deletions
diff --git a/arch/mips/include/asm/mach-jz4740/platform.h b/arch/mips/include/asm/mach-jz4740/platform.h
index 564ab81d6cdc..163e81db880d 100644
--- a/arch/mips/include/asm/mach-jz4740/platform.h
+++ b/arch/mips/include/asm/mach-jz4740/platform.h
@@ -31,6 +31,7 @@ extern struct platform_device jz4740_pcm_device;
31extern struct platform_device jz4740_codec_device; 31extern struct platform_device jz4740_codec_device;
32extern struct platform_device jz4740_adc_device; 32extern struct platform_device jz4740_adc_device;
33extern struct platform_device jz4740_wdt_device; 33extern struct platform_device jz4740_wdt_device;
34extern struct platform_device jz4740_pwm_device;
34 35
35void jz4740_serial_device_register(void); 36void jz4740_serial_device_register(void);
36 37
diff --git a/arch/mips/include/asm/mach-jz4740/timer.h b/arch/mips/include/asm/mach-jz4740/timer.h
index 9baa03ce748c..a7759fb1f73d 100644
--- a/arch/mips/include/asm/mach-jz4740/timer.h
+++ b/arch/mips/include/asm/mach-jz4740/timer.h
@@ -16,7 +16,120 @@
16#ifndef __ASM_MACH_JZ4740_TIMER 16#ifndef __ASM_MACH_JZ4740_TIMER
17#define __ASM_MACH_JZ4740_TIMER 17#define __ASM_MACH_JZ4740_TIMER
18 18
19#define JZ_REG_TIMER_STOP 0x0C
20#define JZ_REG_TIMER_STOP_SET 0x1C
21#define JZ_REG_TIMER_STOP_CLEAR 0x2C
22#define JZ_REG_TIMER_ENABLE 0x00
23#define JZ_REG_TIMER_ENABLE_SET 0x04
24#define JZ_REG_TIMER_ENABLE_CLEAR 0x08
25#define JZ_REG_TIMER_FLAG 0x10
26#define JZ_REG_TIMER_FLAG_SET 0x14
27#define JZ_REG_TIMER_FLAG_CLEAR 0x18
28#define JZ_REG_TIMER_MASK 0x20
29#define JZ_REG_TIMER_MASK_SET 0x24
30#define JZ_REG_TIMER_MASK_CLEAR 0x28
31
32#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
33#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
34#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
35#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
36
37#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
38#define JZ_TIMER_IRQ_FULL(x) BIT(x)
39
40#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN BIT(9)
41#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
42#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
43#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
44#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
45#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
46#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
47#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
48#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
49#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
50#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
51
52#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
53
54#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
55#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
56#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
57
58extern void __iomem *jz4740_timer_base;
59void __init jz4740_timer_init(void);
60
19void jz4740_timer_enable_watchdog(void); 61void jz4740_timer_enable_watchdog(void);
20void jz4740_timer_disable_watchdog(void); 62void jz4740_timer_disable_watchdog(void);
21 63
64static inline void jz4740_timer_stop(unsigned int timer)
65{
66 writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
67}
68
69static inline void jz4740_timer_start(unsigned int timer)
70{
71 writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
72}
73
74static inline bool jz4740_timer_is_enabled(unsigned int timer)
75{
76 return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
77}
78
79static inline void jz4740_timer_enable(unsigned int timer)
80{
81 writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
82}
83
84static inline void jz4740_timer_disable(unsigned int timer)
85{
86 writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
87}
88
89static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
90{
91 writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
92}
93
94static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
95{
96 writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
97}
98
99static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
100{
101 writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
102}
103
104static inline uint16_t jz4740_timer_get_count(unsigned int timer)
105{
106 return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
107}
108
109static inline void jz4740_timer_ack_full(unsigned int timer)
110{
111 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
112}
113
114static inline void jz4740_timer_irq_full_enable(unsigned int timer)
115{
116 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
117 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
118}
119
120static inline void jz4740_timer_irq_full_disable(unsigned int timer)
121{
122 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
123}
124
125static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
126{
127 writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
128}
129
130static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
131{
132 return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
133}
134
22#endif 135#endif
diff --git a/arch/mips/jz4740/Kconfig b/arch/mips/jz4740/Kconfig
index 3e7141f0746c..468903053883 100644
--- a/arch/mips/jz4740/Kconfig
+++ b/arch/mips/jz4740/Kconfig
@@ -7,6 +7,3 @@ config JZ4740_QI_LB60
7 bool "Qi Hardware Ben NanoNote" 7 bool "Qi Hardware Ben NanoNote"
8 8
9endchoice 9endchoice
10
11config HAVE_PWM
12 bool
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile
index e44abea9c209..63bad0e491d0 100644
--- a/arch/mips/jz4740/Makefile
+++ b/arch/mips/jz4740/Makefile
@@ -5,7 +5,7 @@
5# Object file lists. 5# Object file lists.
6 6
7obj-y += prom.o irq.o time.o reset.o setup.o dma.o \ 7obj-y += prom.o irq.o time.o reset.o setup.o dma.o \
8 gpio.o clock.o platform.o timer.o pwm.o serial.o 8 gpio.o clock.o platform.o timer.o serial.o
9 9
10obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o 10obj-$(CONFIG_DEBUG_FS) += clock-debugfs.o
11 11
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 9a3d9de4d04e..43d964d36288 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -437,6 +437,7 @@ static struct platform_device *jz_platform_devices[] __initdata = {
437 &jz4740_codec_device, 437 &jz4740_codec_device,
438 &jz4740_rtc_device, 438 &jz4740_rtc_device,
439 &jz4740_adc_device, 439 &jz4740_adc_device,
440 &jz4740_pwm_device,
440 &qi_lb60_gpio_keys, 441 &qi_lb60_gpio_keys,
441 &qi_lb60_pwm_beeper, 442 &qi_lb60_pwm_beeper,
442 &qi_lb60_charger_device, 443 &qi_lb60_charger_device,
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index e342ed4cbd43..6d14dcdbd908 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -323,3 +323,9 @@ struct platform_device jz4740_wdt_device = {
323 .num_resources = ARRAY_SIZE(jz4740_wdt_resources), 323 .num_resources = ARRAY_SIZE(jz4740_wdt_resources),
324 .resource = jz4740_wdt_resources, 324 .resource = jz4740_wdt_resources,
325}; 325};
326
327/* PWM */
328struct platform_device jz4740_pwm_device = {
329 .name = "jz4740-pwm",
330 .id = -1,
331};
diff --git a/arch/mips/jz4740/pwm.c b/arch/mips/jz4740/pwm.c
deleted file mode 100644
index a26a6faec9a6..000000000000
--- a/arch/mips/jz4740/pwm.c
+++ /dev/null
@@ -1,177 +0,0 @@
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform PWM support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#include <linux/kernel.h>
17
18#include <linux/clk.h>
19#include <linux/err.h>
20#include <linux/pwm.h>
21#include <linux/gpio.h>
22
23#include <asm/mach-jz4740/gpio.h>
24#include "timer.h"
25
26static struct clk *jz4740_pwm_clk;
27
28DEFINE_MUTEX(jz4740_pwm_mutex);
29
30struct pwm_device {
31 unsigned int id;
32 unsigned int gpio;
33 bool used;
34};
35
36static struct pwm_device jz4740_pwm_list[] = {
37 { 2, JZ_GPIO_PWM2, false },
38 { 3, JZ_GPIO_PWM3, false },
39 { 4, JZ_GPIO_PWM4, false },
40 { 5, JZ_GPIO_PWM5, false },
41 { 6, JZ_GPIO_PWM6, false },
42 { 7, JZ_GPIO_PWM7, false },
43};
44
45struct pwm_device *pwm_request(int id, const char *label)
46{
47 int ret = 0;
48 struct pwm_device *pwm;
49
50 if (id < 2 || id > 7 || !jz4740_pwm_clk)
51 return ERR_PTR(-ENODEV);
52
53 mutex_lock(&jz4740_pwm_mutex);
54
55 pwm = &jz4740_pwm_list[id - 2];
56 if (pwm->used)
57 ret = -EBUSY;
58 else
59 pwm->used = true;
60
61 mutex_unlock(&jz4740_pwm_mutex);
62
63 if (ret)
64 return ERR_PTR(ret);
65
66 ret = gpio_request(pwm->gpio, label);
67
68 if (ret) {
69 printk(KERN_ERR "Failed to request pwm gpio: %d\n", ret);
70 pwm->used = false;
71 return ERR_PTR(ret);
72 }
73
74 jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_PWM);
75
76 jz4740_timer_start(id);
77
78 return pwm;
79}
80
81void pwm_free(struct pwm_device *pwm)
82{
83 pwm_disable(pwm);
84 jz4740_timer_set_ctrl(pwm->id, 0);
85
86 jz_gpio_set_function(pwm->gpio, JZ_GPIO_FUNC_NONE);
87 gpio_free(pwm->gpio);
88
89 jz4740_timer_stop(pwm->id);
90
91 pwm->used = false;
92}
93
94int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
95{
96 unsigned long long tmp;
97 unsigned long period, duty;
98 unsigned int prescaler = 0;
99 unsigned int id = pwm->id;
100 uint16_t ctrl;
101 bool is_enabled;
102
103 if (duty_ns < 0 || duty_ns > period_ns)
104 return -EINVAL;
105
106 tmp = (unsigned long long)clk_get_rate(jz4740_pwm_clk) * period_ns;
107 do_div(tmp, 1000000000);
108 period = tmp;
109
110 while (period > 0xffff && prescaler < 6) {
111 period >>= 2;
112 ++prescaler;
113 }
114
115 if (prescaler == 6)
116 return -EINVAL;
117
118 tmp = (unsigned long long)period * duty_ns;
119 do_div(tmp, period_ns);
120 duty = period - tmp;
121
122 if (duty >= period)
123 duty = period - 1;
124
125 is_enabled = jz4740_timer_is_enabled(id);
126 if (is_enabled)
127 pwm_disable(pwm);
128
129 jz4740_timer_set_count(id, 0);
130 jz4740_timer_set_duty(id, duty);
131 jz4740_timer_set_period(id, period);
132
133 ctrl = JZ_TIMER_CTRL_PRESCALER(prescaler) | JZ_TIMER_CTRL_SRC_EXT |
134 JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN;
135
136 jz4740_timer_set_ctrl(id, ctrl);
137
138 if (is_enabled)
139 pwm_enable(pwm);
140
141 return 0;
142}
143
144int pwm_enable(struct pwm_device *pwm)
145{
146 uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
147
148 ctrl |= JZ_TIMER_CTRL_PWM_ENABLE;
149 jz4740_timer_set_ctrl(pwm->id, ctrl);
150 jz4740_timer_enable(pwm->id);
151
152 return 0;
153}
154
155void pwm_disable(struct pwm_device *pwm)
156{
157 uint32_t ctrl = jz4740_timer_get_ctrl(pwm->id);
158
159 ctrl &= ~JZ_TIMER_CTRL_PWM_ENABLE;
160 jz4740_timer_disable(pwm->id);
161 jz4740_timer_set_ctrl(pwm->id, ctrl);
162}
163
164static int __init jz4740_pwm_init(void)
165{
166 int ret = 0;
167
168 jz4740_pwm_clk = clk_get(NULL, "ext");
169
170 if (IS_ERR(jz4740_pwm_clk)) {
171 ret = PTR_ERR(jz4740_pwm_clk);
172 jz4740_pwm_clk = NULL;
173 }
174
175 return ret;
176}
177subsys_initcall(jz4740_pwm_init);
diff --git a/arch/mips/jz4740/time.c b/arch/mips/jz4740/time.c
index f83c2dd07a27..39bb4bbf43e7 100644
--- a/arch/mips/jz4740/time.c
+++ b/arch/mips/jz4740/time.c
@@ -20,10 +20,10 @@
20#include <linux/clockchips.h> 20#include <linux/clockchips.h>
21 21
22#include <asm/mach-jz4740/irq.h> 22#include <asm/mach-jz4740/irq.h>
23#include <asm/mach-jz4740/timer.h>
23#include <asm/time.h> 24#include <asm/time.h>
24 25
25#include "clock.h" 26#include "clock.h"
26#include "timer.h"
27 27
28#define TIMER_CLOCKEVENT 0 28#define TIMER_CLOCKEVENT 0
29#define TIMER_CLOCKSOURCE 1 29#define TIMER_CLOCKSOURCE 1
diff --git a/arch/mips/jz4740/timer.c b/arch/mips/jz4740/timer.c
index 654d5c3900b6..22f11d73a17d 100644
--- a/arch/mips/jz4740/timer.c
+++ b/arch/mips/jz4740/timer.c
@@ -17,11 +17,11 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19 19
20#include "timer.h"
21
22#include <asm/mach-jz4740/base.h> 20#include <asm/mach-jz4740/base.h>
21#include <asm/mach-jz4740/timer.h>
23 22
24void __iomem *jz4740_timer_base; 23void __iomem *jz4740_timer_base;
24EXPORT_SYMBOL_GPL(jz4740_timer_base);
25 25
26void jz4740_timer_enable_watchdog(void) 26void jz4740_timer_enable_watchdog(void)
27{ 27{
diff --git a/arch/mips/jz4740/timer.h b/arch/mips/jz4740/timer.h
deleted file mode 100644
index fca3994f2e6d..000000000000
--- a/arch/mips/jz4740/timer.h
+++ /dev/null
@@ -1,136 +0,0 @@
1/*
2 * Copyright (C) 2010, Lars-Peter Clausen <lars@metafoo.de>
3 * JZ4740 platform timer support
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 * You should have received a copy of the GNU General Public License along
11 * with this program; if not, write to the Free Software Foundation, Inc.,
12 * 675 Mass Ave, Cambridge, MA 02139, USA.
13 *
14 */
15
16#ifndef __MIPS_JZ4740_TIMER_H__
17#define __MIPS_JZ4740_TIMER_H__
18
19#include <linux/module.h>
20#include <linux/io.h>
21
22#define JZ_REG_TIMER_STOP 0x0C
23#define JZ_REG_TIMER_STOP_SET 0x1C
24#define JZ_REG_TIMER_STOP_CLEAR 0x2C
25#define JZ_REG_TIMER_ENABLE 0x00
26#define JZ_REG_TIMER_ENABLE_SET 0x04
27#define JZ_REG_TIMER_ENABLE_CLEAR 0x08
28#define JZ_REG_TIMER_FLAG 0x10
29#define JZ_REG_TIMER_FLAG_SET 0x14
30#define JZ_REG_TIMER_FLAG_CLEAR 0x18
31#define JZ_REG_TIMER_MASK 0x20
32#define JZ_REG_TIMER_MASK_SET 0x24
33#define JZ_REG_TIMER_MASK_CLEAR 0x28
34
35#define JZ_REG_TIMER_DFR(x) (((x) * 0x10) + 0x30)
36#define JZ_REG_TIMER_DHR(x) (((x) * 0x10) + 0x34)
37#define JZ_REG_TIMER_CNT(x) (((x) * 0x10) + 0x38)
38#define JZ_REG_TIMER_CTRL(x) (((x) * 0x10) + 0x3C)
39
40#define JZ_TIMER_IRQ_HALF(x) BIT((x) + 0x10)
41#define JZ_TIMER_IRQ_FULL(x) BIT(x)
42
43#define JZ_TIMER_CTRL_PWM_ABBRUPT_SHUTDOWN BIT(9)
44#define JZ_TIMER_CTRL_PWM_ACTIVE_LOW BIT(8)
45#define JZ_TIMER_CTRL_PWM_ENABLE BIT(7)
46#define JZ_TIMER_CTRL_PRESCALE_MASK 0x1c
47#define JZ_TIMER_CTRL_PRESCALE_OFFSET 0x3
48#define JZ_TIMER_CTRL_PRESCALE_1 (0 << 3)
49#define JZ_TIMER_CTRL_PRESCALE_4 (1 << 3)
50#define JZ_TIMER_CTRL_PRESCALE_16 (2 << 3)
51#define JZ_TIMER_CTRL_PRESCALE_64 (3 << 3)
52#define JZ_TIMER_CTRL_PRESCALE_256 (4 << 3)
53#define JZ_TIMER_CTRL_PRESCALE_1024 (5 << 3)
54
55#define JZ_TIMER_CTRL_PRESCALER(x) ((x) << JZ_TIMER_CTRL_PRESCALE_OFFSET)
56
57#define JZ_TIMER_CTRL_SRC_EXT BIT(2)
58#define JZ_TIMER_CTRL_SRC_RTC BIT(1)
59#define JZ_TIMER_CTRL_SRC_PCLK BIT(0)
60
61extern void __iomem *jz4740_timer_base;
62void __init jz4740_timer_init(void);
63
64static inline void jz4740_timer_stop(unsigned int timer)
65{
66 writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_SET);
67}
68
69static inline void jz4740_timer_start(unsigned int timer)
70{
71 writel(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_STOP_CLEAR);
72}
73
74static inline bool jz4740_timer_is_enabled(unsigned int timer)
75{
76 return readb(jz4740_timer_base + JZ_REG_TIMER_ENABLE) & BIT(timer);
77}
78
79static inline void jz4740_timer_enable(unsigned int timer)
80{
81 writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_SET);
82}
83
84static inline void jz4740_timer_disable(unsigned int timer)
85{
86 writeb(BIT(timer), jz4740_timer_base + JZ_REG_TIMER_ENABLE_CLEAR);
87}
88
89
90static inline void jz4740_timer_set_period(unsigned int timer, uint16_t period)
91{
92 writew(period, jz4740_timer_base + JZ_REG_TIMER_DFR(timer));
93}
94
95static inline void jz4740_timer_set_duty(unsigned int timer, uint16_t duty)
96{
97 writew(duty, jz4740_timer_base + JZ_REG_TIMER_DHR(timer));
98}
99
100static inline void jz4740_timer_set_count(unsigned int timer, uint16_t count)
101{
102 writew(count, jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
103}
104
105static inline uint16_t jz4740_timer_get_count(unsigned int timer)
106{
107 return readw(jz4740_timer_base + JZ_REG_TIMER_CNT(timer));
108}
109
110static inline void jz4740_timer_ack_full(unsigned int timer)
111{
112 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
113}
114
115static inline void jz4740_timer_irq_full_enable(unsigned int timer)
116{
117 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_FLAG_CLEAR);
118 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_CLEAR);
119}
120
121static inline void jz4740_timer_irq_full_disable(unsigned int timer)
122{
123 writel(JZ_TIMER_IRQ_FULL(timer), jz4740_timer_base + JZ_REG_TIMER_MASK_SET);
124}
125
126static inline void jz4740_timer_set_ctrl(unsigned int timer, uint16_t ctrl)
127{
128 writew(ctrl, jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
129}
130
131static inline uint16_t jz4740_timer_get_ctrl(unsigned int timer)
132{
133 return readw(jz4740_timer_base + JZ_REG_TIMER_CTRL(timer));
134}
135
136#endif