diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-08-28 05:39:25 -0400 |
---|---|---|
committer | Thierry Reding <thierry.reding@avionic-design.de> | 2012-09-12 08:25:05 -0400 |
commit | 66ad6a613abeeeabc5217a0498fae63205e8ddb8 (patch) | |
tree | 10990eefe667348983b32b0894a94cdbb7b1ba26 /drivers/pwm | |
parent | 140827c148f2f3a95fdcec5310f6cd980139b383 (diff) |
pwm: i.MX: add functions to enable/disable pwm.
We used to enable/disable the PWM only by switching the
clock on or off. Instead, use the dedicated register bits.
These differ on different SoCs, so introduce a SoC specific
function for this.
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Reviewed-by: Shawn Guo <shawn.guo@linaro.org>
Reviewed-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com>
Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
Diffstat (limited to 'drivers/pwm')
-rw-r--r-- | drivers/pwm/pwm-imx.c | 48 |
1 files changed, 44 insertions, 4 deletions
diff --git a/drivers/pwm/pwm-imx.c b/drivers/pwm/pwm-imx.c index 5d426ffe6a31..13d4d22f12cf 100644 --- a/drivers/pwm/pwm-imx.c +++ b/drivers/pwm/pwm-imx.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #define MX1_PWMS 0x04 /* PWM Sample Register */ | 25 | #define MX1_PWMS 0x04 /* PWM Sample Register */ |
26 | #define MX1_PWMP 0x08 /* PWM Period Register */ | 26 | #define MX1_PWMP 0x08 /* PWM Period Register */ |
27 | 27 | ||
28 | #define MX1_PWMC_EN (1 << 4) | ||
28 | 29 | ||
29 | /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ | 30 | /* i.MX27, i.MX31, i.MX35 share the same PWM function block: */ |
30 | 31 | ||
@@ -49,6 +50,7 @@ struct imx_chip { | |||
49 | 50 | ||
50 | int (*config)(struct pwm_chip *chip, | 51 | int (*config)(struct pwm_chip *chip, |
51 | struct pwm_device *pwm, int duty_ns, int period_ns); | 52 | struct pwm_device *pwm, int duty_ns, int period_ns); |
53 | void (*set_enable)(struct pwm_chip *chip, bool enable); | ||
52 | }; | 54 | }; |
53 | 55 | ||
54 | #define to_imx_chip(chip) container_of(chip, struct imx_chip, chip) | 56 | #define to_imx_chip(chip) container_of(chip, struct imx_chip, chip) |
@@ -82,6 +84,21 @@ static int imx_pwm_config_v1(struct pwm_chip *chip, | |||
82 | return 0; | 84 | return 0; |
83 | } | 85 | } |
84 | 86 | ||
87 | static void imx_pwm_set_enable_v1(struct pwm_chip *chip, bool enable) | ||
88 | { | ||
89 | struct imx_chip *imx = to_imx_chip(chip); | ||
90 | u32 val; | ||
91 | |||
92 | val = readl(imx->mmio_base + MX1_PWMC); | ||
93 | |||
94 | if (enable) | ||
95 | val |= MX1_PWMC_EN; | ||
96 | else | ||
97 | val &= ~MX1_PWMC_EN; | ||
98 | |||
99 | writel(val, imx->mmio_base + MX1_PWMC); | ||
100 | } | ||
101 | |||
85 | static int imx_pwm_config_v2(struct pwm_chip *chip, | 102 | static int imx_pwm_config_v2(struct pwm_chip *chip, |
86 | struct pwm_device *pwm, int duty_ns, int period_ns) | 103 | struct pwm_device *pwm, int duty_ns, int period_ns) |
87 | { | 104 | { |
@@ -116,7 +133,10 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, | |||
116 | 133 | ||
117 | cr = MX3_PWMCR_PRESCALER(prescale) | | 134 | cr = MX3_PWMCR_PRESCALER(prescale) | |
118 | MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | | 135 | MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN | |
119 | MX3_PWMCR_DBGEN | MX3_PWMCR_EN; | 136 | MX3_PWMCR_DBGEN; |
137 | |||
138 | if (imx->enabled) | ||
139 | cr |= MX3_PWMCR_EN; | ||
120 | 140 | ||
121 | if (cpu_is_mx25()) | 141 | if (cpu_is_mx25()) |
122 | cr |= MX3_PWMCR_CLKSRC_IPG; | 142 | cr |= MX3_PWMCR_CLKSRC_IPG; |
@@ -128,6 +148,21 @@ static int imx_pwm_config_v2(struct pwm_chip *chip, | |||
128 | return 0; | 148 | return 0; |
129 | } | 149 | } |
130 | 150 | ||
151 | static void imx_pwm_set_enable_v2(struct pwm_chip *chip, bool enable) | ||
152 | { | ||
153 | struct imx_chip *imx = to_imx_chip(chip); | ||
154 | u32 val; | ||
155 | |||
156 | val = readl(imx->mmio_base + MX3_PWMCR); | ||
157 | |||
158 | if (enable) | ||
159 | val |= MX3_PWMCR_EN; | ||
160 | else | ||
161 | val &= ~MX3_PWMCR_EN; | ||
162 | |||
163 | writel(val, imx->mmio_base + MX3_PWMCR); | ||
164 | } | ||
165 | |||
131 | static int imx_pwm_config(struct pwm_chip *chip, | 166 | static int imx_pwm_config(struct pwm_chip *chip, |
132 | struct pwm_device *pwm, int duty_ns, int period_ns) | 167 | struct pwm_device *pwm, int duty_ns, int period_ns) |
133 | { | 168 | { |
@@ -145,6 +180,8 @@ static int imx_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
145 | if (ret) | 180 | if (ret) |
146 | return ret; | 181 | return ret; |
147 | 182 | ||
183 | imx->set_enable(chip, true); | ||
184 | |||
148 | imx->enabled = 1; | 185 | imx->enabled = 1; |
149 | 186 | ||
150 | return 0; | 187 | return 0; |
@@ -154,7 +191,7 @@ static void imx_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
154 | { | 191 | { |
155 | struct imx_chip *imx = to_imx_chip(chip); | 192 | struct imx_chip *imx = to_imx_chip(chip); |
156 | 193 | ||
157 | writel(0, imx->mmio_base + MX3_PWMCR); | 194 | imx->set_enable(chip, false); |
158 | 195 | ||
159 | clk_disable_unprepare(imx->clk); | 196 | clk_disable_unprepare(imx->clk); |
160 | imx->enabled = 0; | 197 | imx->enabled = 0; |
@@ -199,10 +236,13 @@ static int __devinit imx_pwm_probe(struct platform_device *pdev) | |||
199 | if (imx->mmio_base == NULL) | 236 | if (imx->mmio_base == NULL) |
200 | return -EADDRNOTAVAIL; | 237 | return -EADDRNOTAVAIL; |
201 | 238 | ||
202 | if (cpu_is_mx1() || cpu_is_mx21()) | 239 | if (cpu_is_mx1() || cpu_is_mx21()) { |
203 | imx->config = imx_pwm_config_v1; | 240 | imx->config = imx_pwm_config_v1; |
204 | else | 241 | imx->set_enable = imx_pwm_set_enable_v1; |
242 | } else { | ||
205 | imx->config = imx_pwm_config_v2; | 243 | imx->config = imx_pwm_config_v2; |
244 | imx->set_enable = imx_pwm_set_enable_v2; | ||
245 | } | ||
206 | 246 | ||
207 | ret = pwmchip_add(&imx->chip); | 247 | ret = pwmchip_add(&imx->chip); |
208 | if (ret < 0) | 248 | if (ret < 0) |