aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pwm
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-08-28 05:39:25 -0400
committerThierry Reding <thierry.reding@avionic-design.de>2012-09-12 08:25:05 -0400
commit66ad6a613abeeeabc5217a0498fae63205e8ddb8 (patch)
tree10990eefe667348983b32b0894a94cdbb7b1ba26 /drivers/pwm
parent140827c148f2f3a95fdcec5310f6cd980139b383 (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.c48
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
87static 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
85static int imx_pwm_config_v2(struct pwm_chip *chip, 102static 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
151static 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
131static int imx_pwm_config(struct pwm_chip *chip, 166static 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)