diff options
Diffstat (limited to 'drivers/pwm/pwm-sti.c')
-rw-r--r-- | drivers/pwm/pwm-sti.c | 483 |
1 files changed, 385 insertions, 98 deletions
diff --git a/drivers/pwm/pwm-sti.c b/drivers/pwm/pwm-sti.c index 92abbd56b9f7..dd82dc840af9 100644 --- a/drivers/pwm/pwm-sti.c +++ b/drivers/pwm/pwm-sti.c | |||
@@ -1,8 +1,10 @@ | |||
1 | /* | 1 | /* |
2 | * PWM device driver for ST SoCs. | 2 | * PWM device driver for ST SoCs |
3 | * Author: Ajit Pal Singh <ajitpal.singh@st.com> | 3 | * |
4 | * Copyright (C) 2013-2016 STMicroelectronics (R&D) Limited | ||
4 | * | 5 | * |
5 | * Copyright (C) 2013-2014 STMicroelectronics (R&D) Limited | 6 | * Author: Ajit Pal Singh <ajitpal.singh@st.com> |
7 | * Lee Jones <lee.jones@linaro.org> | ||
6 | * | 8 | * |
7 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 10 | * it under the terms of the GNU General Public License as published by |
@@ -11,6 +13,7 @@ | |||
11 | */ | 13 | */ |
12 | 14 | ||
13 | #include <linux/clk.h> | 15 | #include <linux/clk.h> |
16 | #include <linux/interrupt.h> | ||
14 | #include <linux/math64.h> | 17 | #include <linux/math64.h> |
15 | #include <linux/mfd/syscon.h> | 18 | #include <linux/mfd/syscon.h> |
16 | #include <linux/module.h> | 19 | #include <linux/module.h> |
@@ -18,43 +21,82 @@ | |||
18 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
19 | #include <linux/pwm.h> | 22 | #include <linux/pwm.h> |
20 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
24 | #include <linux/sched.h> | ||
21 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
22 | #include <linux/time.h> | 26 | #include <linux/time.h> |
27 | #include <linux/wait.h> | ||
28 | |||
29 | #define PWM_OUT_VAL(x) (0x00 + (4 * (x))) /* Device's Duty Cycle register */ | ||
30 | #define PWM_CPT_VAL(x) (0x10 + (4 * (x))) /* Capture value */ | ||
31 | #define PWM_CPT_EDGE(x) (0x30 + (4 * (x))) /* Edge to capture on */ | ||
23 | 32 | ||
24 | #define STI_DS_REG(ch) (4 * (ch)) /* Channel's Duty Cycle register */ | 33 | #define STI_PWM_CTRL 0x50 /* Control/Config register */ |
25 | #define STI_PWMCR 0x50 /* Control/Config register */ | 34 | #define STI_INT_EN 0x54 /* Interrupt Enable/Disable register */ |
26 | #define STI_INTEN 0x54 /* Interrupt Enable/Disable register */ | 35 | #define STI_INT_STA 0x58 /* Interrupt Status register */ |
27 | #define PWM_PRESCALE_LOW_MASK 0x0f | 36 | #define PWM_INT_ACK 0x5c |
28 | #define PWM_PRESCALE_HIGH_MASK 0xf0 | 37 | #define PWM_PRESCALE_LOW_MASK 0x0f |
38 | #define PWM_PRESCALE_HIGH_MASK 0xf0 | ||
39 | #define PWM_CPT_EDGE_MASK 0x03 | ||
40 | #define PWM_INT_ACK_MASK 0x1ff | ||
41 | |||
42 | #define STI_MAX_CPT_DEVS 4 | ||
43 | #define CPT_DC_MAX 0xff | ||
29 | 44 | ||
30 | /* Regfield IDs */ | 45 | /* Regfield IDs */ |
31 | enum { | 46 | enum { |
47 | /* Bits in PWM_CTRL*/ | ||
32 | PWMCLK_PRESCALE_LOW, | 48 | PWMCLK_PRESCALE_LOW, |
33 | PWMCLK_PRESCALE_HIGH, | 49 | PWMCLK_PRESCALE_HIGH, |
34 | PWM_EN, | 50 | CPTCLK_PRESCALE, |
35 | PWM_INT_EN, | 51 | |
52 | PWM_OUT_EN, | ||
53 | PWM_CPT_EN, | ||
54 | |||
55 | PWM_CPT_INT_EN, | ||
56 | PWM_CPT_INT_STAT, | ||
36 | 57 | ||
37 | /* Keep last */ | 58 | /* Keep last */ |
38 | MAX_REGFIELDS | 59 | MAX_REGFIELDS |
39 | }; | 60 | }; |
40 | 61 | ||
62 | /* | ||
63 | * Each capture input can be programmed to detect rising-edge, falling-edge, | ||
64 | * either edge or neither egde. | ||
65 | */ | ||
66 | enum sti_cpt_edge { | ||
67 | CPT_EDGE_DISABLED, | ||
68 | CPT_EDGE_RISING, | ||
69 | CPT_EDGE_FALLING, | ||
70 | CPT_EDGE_BOTH, | ||
71 | }; | ||
72 | |||
73 | struct sti_cpt_ddata { | ||
74 | u32 snapshot[3]; | ||
75 | unsigned int index; | ||
76 | struct mutex lock; | ||
77 | wait_queue_head_t wait; | ||
78 | }; | ||
79 | |||
41 | struct sti_pwm_compat_data { | 80 | struct sti_pwm_compat_data { |
42 | const struct reg_field *reg_fields; | 81 | const struct reg_field *reg_fields; |
43 | unsigned int num_chan; | 82 | unsigned int pwm_num_devs; |
83 | unsigned int cpt_num_devs; | ||
44 | unsigned int max_pwm_cnt; | 84 | unsigned int max_pwm_cnt; |
45 | unsigned int max_prescale; | 85 | unsigned int max_prescale; |
46 | }; | 86 | }; |
47 | 87 | ||
48 | struct sti_pwm_chip { | 88 | struct sti_pwm_chip { |
49 | struct device *dev; | 89 | struct device *dev; |
50 | struct clk *clk; | 90 | struct clk *pwm_clk; |
51 | unsigned long clk_rate; | 91 | struct clk *cpt_clk; |
52 | struct regmap *regmap; | 92 | struct regmap *regmap; |
53 | struct sti_pwm_compat_data *cdata; | 93 | struct sti_pwm_compat_data *cdata; |
54 | struct regmap_field *prescale_low; | 94 | struct regmap_field *prescale_low; |
55 | struct regmap_field *prescale_high; | 95 | struct regmap_field *prescale_high; |
56 | struct regmap_field *pwm_en; | 96 | struct regmap_field *pwm_out_en; |
57 | struct regmap_field *pwm_int_en; | 97 | struct regmap_field *pwm_cpt_en; |
98 | struct regmap_field *pwm_cpt_int_en; | ||
99 | struct regmap_field *pwm_cpt_int_stat; | ||
58 | struct pwm_chip chip; | 100 | struct pwm_chip chip; |
59 | struct pwm_device *cur; | 101 | struct pwm_device *cur; |
60 | unsigned long configured; | 102 | unsigned long configured; |
@@ -64,10 +106,13 @@ struct sti_pwm_chip { | |||
64 | }; | 106 | }; |
65 | 107 | ||
66 | static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { | 108 | static const struct reg_field sti_pwm_regfields[MAX_REGFIELDS] = { |
67 | [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWMCR, 0, 3), | 109 | [PWMCLK_PRESCALE_LOW] = REG_FIELD(STI_PWM_CTRL, 0, 3), |
68 | [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWMCR, 11, 14), | 110 | [PWMCLK_PRESCALE_HIGH] = REG_FIELD(STI_PWM_CTRL, 11, 14), |
69 | [PWM_EN] = REG_FIELD(STI_PWMCR, 9, 9), | 111 | [CPTCLK_PRESCALE] = REG_FIELD(STI_PWM_CTRL, 4, 8), |
70 | [PWM_INT_EN] = REG_FIELD(STI_INTEN, 0, 0), | 112 | [PWM_OUT_EN] = REG_FIELD(STI_PWM_CTRL, 9, 9), |
113 | [PWM_CPT_EN] = REG_FIELD(STI_PWM_CTRL, 10, 10), | ||
114 | [PWM_CPT_INT_EN] = REG_FIELD(STI_INT_EN, 1, 4), | ||
115 | [PWM_CPT_INT_STAT] = REG_FIELD(STI_INT_STA, 1, 4), | ||
71 | }; | 116 | }; |
72 | 117 | ||
73 | static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) | 118 | static inline struct sti_pwm_chip *to_sti_pwmchip(struct pwm_chip *chip) |
@@ -82,61 +127,68 @@ static int sti_pwm_get_prescale(struct sti_pwm_chip *pc, unsigned long period, | |||
82 | unsigned int *prescale) | 127 | unsigned int *prescale) |
83 | { | 128 | { |
84 | struct sti_pwm_compat_data *cdata = pc->cdata; | 129 | struct sti_pwm_compat_data *cdata = pc->cdata; |
85 | unsigned long val; | 130 | unsigned long clk_rate; |
131 | unsigned long value; | ||
86 | unsigned int ps; | 132 | unsigned int ps; |
87 | 133 | ||
134 | clk_rate = clk_get_rate(pc->pwm_clk); | ||
135 | if (!clk_rate) { | ||
136 | dev_err(pc->dev, "failed to get clock rate\n"); | ||
137 | return -EINVAL; | ||
138 | } | ||
139 | |||
88 | /* | 140 | /* |
89 | * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_count + 1)) - 1 | 141 | * prescale = ((period_ns * clk_rate) / (10^9 * (max_pwm_cnt + 1)) - 1 |
90 | */ | 142 | */ |
91 | val = NSEC_PER_SEC / pc->clk_rate; | 143 | value = NSEC_PER_SEC / clk_rate; |
92 | val *= cdata->max_pwm_cnt + 1; | 144 | value *= cdata->max_pwm_cnt + 1; |
93 | 145 | ||
94 | if (period % val) { | 146 | if (period % value) |
95 | return -EINVAL; | 147 | return -EINVAL; |
96 | } else { | 148 | |
97 | ps = period / val - 1; | 149 | ps = period / value - 1; |
98 | if (ps > cdata->max_prescale) | 150 | if (ps > cdata->max_prescale) |
99 | return -EINVAL; | 151 | return -EINVAL; |
100 | } | 152 | |
101 | *prescale = ps; | 153 | *prescale = ps; |
102 | 154 | ||
103 | return 0; | 155 | return 0; |
104 | } | 156 | } |
105 | 157 | ||
106 | /* | 158 | /* |
107 | * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. | 159 | * For STiH4xx PWM IP, the PWM period is fixed to 256 local clock cycles. The |
108 | * The only way to change the period (apart from changing the PWM input clock) | 160 | * only way to change the period (apart from changing the PWM input clock) is |
109 | * is to change the PWM clock prescaler. | 161 | * to change the PWM clock prescaler. |
110 | * The prescaler is of 8 bits, so 256 prescaler values and hence | 162 | * |
111 | * 256 possible period values are supported (for a particular clock rate). | 163 | * The prescaler is of 8 bits, so 256 prescaler values and hence 256 possible |
112 | * The requested period will be applied only if it matches one of these | 164 | * period values are supported (for a particular clock rate). The requested |
113 | * 256 values. | 165 | * period will be applied only if it matches one of these 256 values. |
114 | */ | 166 | */ |
115 | static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | 167 | static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, |
116 | int duty_ns, int period_ns) | 168 | int duty_ns, int period_ns) |
117 | { | 169 | { |
118 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); | 170 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
119 | struct sti_pwm_compat_data *cdata = pc->cdata; | 171 | struct sti_pwm_compat_data *cdata = pc->cdata; |
172 | unsigned int ncfg, value, prescale = 0; | ||
120 | struct pwm_device *cur = pc->cur; | 173 | struct pwm_device *cur = pc->cur; |
121 | struct device *dev = pc->dev; | 174 | struct device *dev = pc->dev; |
122 | unsigned int prescale = 0, pwmvalx; | ||
123 | int ret; | ||
124 | unsigned int ncfg; | ||
125 | bool period_same = false; | 175 | bool period_same = false; |
176 | int ret; | ||
126 | 177 | ||
127 | ncfg = hweight_long(pc->configured); | 178 | ncfg = hweight_long(pc->configured); |
128 | if (ncfg) | 179 | if (ncfg) |
129 | period_same = (period_ns == pwm_get_period(cur)); | 180 | period_same = (period_ns == pwm_get_period(cur)); |
130 | 181 | ||
131 | /* Allow configuration changes if one of the | 182 | /* |
132 | * following conditions satisfy. | 183 | * Allow configuration changes if one of the following conditions |
133 | * 1. No channels have been configured. | 184 | * satisfy. |
134 | * 2. Only one channel has been configured and the new request | 185 | * 1. No devices have been configured. |
135 | * is for the same channel. | 186 | * 2. Only one device has been configured and the new request is for |
136 | * 3. Only one channel has been configured and the new request is | 187 | * the same device. |
137 | * for a new channel and period of the new channel is same as | 188 | * 3. Only one device has been configured and the new request is for |
138 | * the current configured period. | 189 | * a new device and period of the new device is same as the current |
139 | * 4. More than one channels are configured and period of the new | 190 | * configured period. |
191 | * 4. More than one devices are configured and period of the new | ||
140 | * requestis the same as the current period. | 192 | * requestis the same as the current period. |
141 | */ | 193 | */ |
142 | if (!ncfg || | 194 | if (!ncfg || |
@@ -144,7 +196,11 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
144 | ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) || | 196 | ((ncfg == 1) && (pwm->hwpwm != cur->hwpwm) && period_same) || |
145 | ((ncfg > 1) && period_same)) { | 197 | ((ncfg > 1) && period_same)) { |
146 | /* Enable clock before writing to PWM registers. */ | 198 | /* Enable clock before writing to PWM registers. */ |
147 | ret = clk_enable(pc->clk); | 199 | ret = clk_enable(pc->pwm_clk); |
200 | if (ret) | ||
201 | return ret; | ||
202 | |||
203 | ret = clk_enable(pc->cpt_clk); | ||
148 | if (ret) | 204 | if (ret) |
149 | return ret; | 205 | return ret; |
150 | 206 | ||
@@ -153,15 +209,15 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
153 | if (ret) | 209 | if (ret) |
154 | goto clk_dis; | 210 | goto clk_dis; |
155 | 211 | ||
156 | ret = | 212 | value = prescale & PWM_PRESCALE_LOW_MASK; |
157 | regmap_field_write(pc->prescale_low, | 213 | |
158 | prescale & PWM_PRESCALE_LOW_MASK); | 214 | ret = regmap_field_write(pc->prescale_low, value); |
159 | if (ret) | 215 | if (ret) |
160 | goto clk_dis; | 216 | goto clk_dis; |
161 | 217 | ||
162 | ret = | 218 | value = (prescale & PWM_PRESCALE_HIGH_MASK) >> 4; |
163 | regmap_field_write(pc->prescale_high, | 219 | |
164 | (prescale & PWM_PRESCALE_HIGH_MASK) >> 4); | 220 | ret = regmap_field_write(pc->prescale_high, value); |
165 | if (ret) | 221 | if (ret) |
166 | goto clk_dis; | 222 | goto clk_dis; |
167 | } | 223 | } |
@@ -172,25 +228,26 @@ static int sti_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, | |||
172 | * PWM pulse = (max_pwm_count + 1) local cycles, | 228 | * PWM pulse = (max_pwm_count + 1) local cycles, |
173 | * that is continuous pulse: signal never goes low. | 229 | * that is continuous pulse: signal never goes low. |
174 | */ | 230 | */ |
175 | pwmvalx = cdata->max_pwm_cnt * duty_ns / period_ns; | 231 | value = cdata->max_pwm_cnt * duty_ns / period_ns; |
176 | 232 | ||
177 | ret = regmap_write(pc->regmap, STI_DS_REG(pwm->hwpwm), pwmvalx); | 233 | ret = regmap_write(pc->regmap, PWM_OUT_VAL(pwm->hwpwm), value); |
178 | if (ret) | 234 | if (ret) |
179 | goto clk_dis; | 235 | goto clk_dis; |
180 | 236 | ||
181 | ret = regmap_field_write(pc->pwm_int_en, 0); | 237 | ret = regmap_field_write(pc->pwm_cpt_int_en, 0); |
182 | 238 | ||
183 | set_bit(pwm->hwpwm, &pc->configured); | 239 | set_bit(pwm->hwpwm, &pc->configured); |
184 | pc->cur = pwm; | 240 | pc->cur = pwm; |
185 | 241 | ||
186 | dev_dbg(dev, "prescale:%u, period:%i, duty:%i, pwmvalx:%u\n", | 242 | dev_dbg(dev, "prescale:%u, period:%i, duty:%i, value:%u\n", |
187 | prescale, period_ns, duty_ns, pwmvalx); | 243 | prescale, period_ns, duty_ns, value); |
188 | } else { | 244 | } else { |
189 | return -EINVAL; | 245 | return -EINVAL; |
190 | } | 246 | } |
191 | 247 | ||
192 | clk_dis: | 248 | clk_dis: |
193 | clk_disable(pc->clk); | 249 | clk_disable(pc->pwm_clk); |
250 | clk_disable(pc->cpt_clk); | ||
194 | return ret; | 251 | return ret; |
195 | } | 252 | } |
196 | 253 | ||
@@ -201,23 +258,30 @@ static int sti_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
201 | int ret = 0; | 258 | int ret = 0; |
202 | 259 | ||
203 | /* | 260 | /* |
204 | * Since we have a common enable for all PWM channels, | 261 | * Since we have a common enable for all PWM devices, do not enable if |
205 | * do not enable if already enabled. | 262 | * already enabled. |
206 | */ | 263 | */ |
207 | mutex_lock(&pc->sti_pwm_lock); | 264 | mutex_lock(&pc->sti_pwm_lock); |
265 | |||
208 | if (!pc->en_count) { | 266 | if (!pc->en_count) { |
209 | ret = clk_enable(pc->clk); | 267 | ret = clk_enable(pc->pwm_clk); |
268 | if (ret) | ||
269 | goto out; | ||
270 | |||
271 | ret = clk_enable(pc->cpt_clk); | ||
210 | if (ret) | 272 | if (ret) |
211 | goto out; | 273 | goto out; |
212 | 274 | ||
213 | ret = regmap_field_write(pc->pwm_en, 1); | 275 | ret = regmap_field_write(pc->pwm_out_en, 1); |
214 | if (ret) { | 276 | if (ret) { |
215 | dev_err(dev, "failed to enable PWM device:%d\n", | 277 | dev_err(dev, "failed to enable PWM device %u: %d\n", |
216 | pwm->hwpwm); | 278 | pwm->hwpwm, ret); |
217 | goto out; | 279 | goto out; |
218 | } | 280 | } |
219 | } | 281 | } |
282 | |||
220 | pc->en_count++; | 283 | pc->en_count++; |
284 | |||
221 | out: | 285 | out: |
222 | mutex_unlock(&pc->sti_pwm_lock); | 286 | mutex_unlock(&pc->sti_pwm_lock); |
223 | return ret; | 287 | return ret; |
@@ -228,13 +292,17 @@ static void sti_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) | |||
228 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); | 292 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); |
229 | 293 | ||
230 | mutex_lock(&pc->sti_pwm_lock); | 294 | mutex_lock(&pc->sti_pwm_lock); |
295 | |||
231 | if (--pc->en_count) { | 296 | if (--pc->en_count) { |
232 | mutex_unlock(&pc->sti_pwm_lock); | 297 | mutex_unlock(&pc->sti_pwm_lock); |
233 | return; | 298 | return; |
234 | } | 299 | } |
235 | regmap_field_write(pc->pwm_en, 0); | ||
236 | 300 | ||
237 | clk_disable(pc->clk); | 301 | regmap_field_write(pc->pwm_out_en, 0); |
302 | |||
303 | clk_disable(pc->pwm_clk); | ||
304 | clk_disable(pc->cpt_clk); | ||
305 | |||
238 | mutex_unlock(&pc->sti_pwm_lock); | 306 | mutex_unlock(&pc->sti_pwm_lock); |
239 | } | 307 | } |
240 | 308 | ||
@@ -245,7 +313,90 @@ static void sti_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm) | |||
245 | clear_bit(pwm->hwpwm, &pc->configured); | 313 | clear_bit(pwm->hwpwm, &pc->configured); |
246 | } | 314 | } |
247 | 315 | ||
316 | static int sti_pwm_capture(struct pwm_chip *chip, struct pwm_device *pwm, | ||
317 | struct pwm_capture *result, unsigned long timeout) | ||
318 | { | ||
319 | struct sti_pwm_chip *pc = to_sti_pwmchip(chip); | ||
320 | struct sti_pwm_compat_data *cdata = pc->cdata; | ||
321 | struct sti_cpt_ddata *ddata = pwm_get_chip_data(pwm); | ||
322 | struct device *dev = pc->dev; | ||
323 | unsigned int effective_ticks; | ||
324 | unsigned long long high, low; | ||
325 | int ret; | ||
326 | |||
327 | if (pwm->hwpwm >= cdata->cpt_num_devs) { | ||
328 | dev_err(dev, "device %u is not valid\n", pwm->hwpwm); | ||
329 | return -EINVAL; | ||
330 | } | ||
331 | |||
332 | mutex_lock(&ddata->lock); | ||
333 | ddata->index = 0; | ||
334 | |||
335 | /* Prepare capture measurement */ | ||
336 | regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_RISING); | ||
337 | regmap_field_write(pc->pwm_cpt_int_en, BIT(pwm->hwpwm)); | ||
338 | |||
339 | /* Enable capture */ | ||
340 | ret = regmap_field_write(pc->pwm_cpt_en, 1); | ||
341 | if (ret) { | ||
342 | dev_err(dev, "failed to enable PWM capture %u: %d\n", | ||
343 | pwm->hwpwm, ret); | ||
344 | goto out; | ||
345 | } | ||
346 | |||
347 | ret = wait_event_interruptible_timeout(ddata->wait, ddata->index > 1, | ||
348 | msecs_to_jiffies(timeout)); | ||
349 | |||
350 | regmap_write(pc->regmap, PWM_CPT_EDGE(pwm->hwpwm), CPT_EDGE_DISABLED); | ||
351 | |||
352 | if (ret == -ERESTARTSYS) | ||
353 | goto out; | ||
354 | |||
355 | switch (ddata->index) { | ||
356 | case 0: | ||
357 | case 1: | ||
358 | /* | ||
359 | * Getting here could mean: | ||
360 | * - input signal is constant of less than 1 Hz | ||
361 | * - there is no input signal at all | ||
362 | * | ||
363 | * In such case the frequency is rounded down to 0 | ||
364 | */ | ||
365 | result->period = 0; | ||
366 | result->duty_cycle = 0; | ||
367 | |||
368 | break; | ||
369 | |||
370 | case 2: | ||
371 | /* We have everying we need */ | ||
372 | high = ddata->snapshot[1] - ddata->snapshot[0]; | ||
373 | low = ddata->snapshot[2] - ddata->snapshot[1]; | ||
374 | |||
375 | effective_ticks = clk_get_rate(pc->cpt_clk); | ||
376 | |||
377 | result->period = (high + low) * NSEC_PER_SEC; | ||
378 | result->period /= effective_ticks; | ||
379 | |||
380 | result->duty_cycle = high * NSEC_PER_SEC; | ||
381 | result->duty_cycle /= effective_ticks; | ||
382 | |||
383 | break; | ||
384 | |||
385 | default: | ||
386 | dev_err(dev, "internal error\n"); | ||
387 | break; | ||
388 | } | ||
389 | |||
390 | out: | ||
391 | /* Disable capture */ | ||
392 | regmap_field_write(pc->pwm_cpt_en, 0); | ||
393 | |||
394 | mutex_unlock(&ddata->lock); | ||
395 | return ret; | ||
396 | } | ||
397 | |||
248 | static const struct pwm_ops sti_pwm_ops = { | 398 | static const struct pwm_ops sti_pwm_ops = { |
399 | .capture = sti_pwm_capture, | ||
249 | .config = sti_pwm_config, | 400 | .config = sti_pwm_config, |
250 | .enable = sti_pwm_enable, | 401 | .enable = sti_pwm_enable, |
251 | .disable = sti_pwm_disable, | 402 | .disable = sti_pwm_disable, |
@@ -253,17 +404,98 @@ static const struct pwm_ops sti_pwm_ops = { | |||
253 | .owner = THIS_MODULE, | 404 | .owner = THIS_MODULE, |
254 | }; | 405 | }; |
255 | 406 | ||
407 | static irqreturn_t sti_pwm_interrupt(int irq, void *data) | ||
408 | { | ||
409 | struct sti_pwm_chip *pc = data; | ||
410 | struct device *dev = pc->dev; | ||
411 | struct sti_cpt_ddata *ddata; | ||
412 | int devicenum; | ||
413 | unsigned int cpt_int_stat; | ||
414 | unsigned int reg; | ||
415 | int ret = IRQ_NONE; | ||
416 | |||
417 | ret = regmap_field_read(pc->pwm_cpt_int_stat, &cpt_int_stat); | ||
418 | if (ret) | ||
419 | return ret; | ||
420 | |||
421 | while (cpt_int_stat) { | ||
422 | devicenum = ffs(cpt_int_stat) - 1; | ||
423 | |||
424 | ddata = pwm_get_chip_data(&pc->chip.pwms[devicenum]); | ||
425 | |||
426 | /* | ||
427 | * Capture input: | ||
428 | * _______ _______ | ||
429 | * | | | | | ||
430 | * __| |_________________| |________ | ||
431 | * ^0 ^1 ^2 | ||
432 | * | ||
433 | * Capture start by the first available rising edge. When a | ||
434 | * capture event occurs, capture value (CPT_VALx) is stored, | ||
435 | * index incremented, capture edge changed. | ||
436 | * | ||
437 | * After the capture, if the index > 1, we have collected the | ||
438 | * necessary data so we signal the thread waiting for it and | ||
439 | * disable the capture by setting capture edge to none | ||
440 | */ | ||
441 | |||
442 | regmap_read(pc->regmap, | ||
443 | PWM_CPT_VAL(devicenum), | ||
444 | &ddata->snapshot[ddata->index]); | ||
445 | |||
446 | switch (ddata->index) { | ||
447 | case 0: | ||
448 | case 1: | ||
449 | regmap_read(pc->regmap, PWM_CPT_EDGE(devicenum), ®); | ||
450 | reg ^= PWM_CPT_EDGE_MASK; | ||
451 | regmap_write(pc->regmap, PWM_CPT_EDGE(devicenum), reg); | ||
452 | |||
453 | ddata->index++; | ||
454 | break; | ||
455 | |||
456 | case 2: | ||
457 | regmap_write(pc->regmap, | ||
458 | PWM_CPT_EDGE(devicenum), | ||
459 | CPT_EDGE_DISABLED); | ||
460 | wake_up(&ddata->wait); | ||
461 | break; | ||
462 | |||
463 | default: | ||
464 | dev_err(dev, "Internal error\n"); | ||
465 | } | ||
466 | |||
467 | cpt_int_stat &= ~BIT_MASK(devicenum); | ||
468 | |||
469 | ret = IRQ_HANDLED; | ||
470 | } | ||
471 | |||
472 | /* Just ACK everything */ | ||
473 | regmap_write(pc->regmap, PWM_INT_ACK, PWM_INT_ACK_MASK); | ||
474 | |||
475 | return ret; | ||
476 | } | ||
477 | |||
256 | static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) | 478 | static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) |
257 | { | 479 | { |
258 | struct device *dev = pc->dev; | 480 | struct device *dev = pc->dev; |
259 | const struct reg_field *reg_fields; | 481 | const struct reg_field *reg_fields; |
260 | struct device_node *np = dev->of_node; | 482 | struct device_node *np = dev->of_node; |
261 | struct sti_pwm_compat_data *cdata = pc->cdata; | 483 | struct sti_pwm_compat_data *cdata = pc->cdata; |
262 | u32 num_chan; | 484 | u32 num_devs; |
485 | int ret; | ||
486 | |||
487 | ret = of_property_read_u32(np, "st,pwm-num-chan", &num_devs); | ||
488 | if (!ret) | ||
489 | cdata->pwm_num_devs = num_devs; | ||
490 | |||
491 | ret = of_property_read_u32(np, "st,capture-num-chan", &num_devs); | ||
492 | if (!ret) | ||
493 | cdata->cpt_num_devs = num_devs; | ||
263 | 494 | ||
264 | of_property_read_u32(np, "st,pwm-num-chan", &num_chan); | 495 | if (!cdata->pwm_num_devs && !cdata->cpt_num_devs) { |
265 | if (num_chan) | 496 | dev_err(dev, "No channels configured\n"); |
266 | cdata->num_chan = num_chan; | 497 | return -EINVAL; |
498 | } | ||
267 | 499 | ||
268 | reg_fields = cdata->reg_fields; | 500 | reg_fields = cdata->reg_fields; |
269 | 501 | ||
@@ -277,15 +509,26 @@ static int sti_pwm_probe_dt(struct sti_pwm_chip *pc) | |||
277 | if (IS_ERR(pc->prescale_high)) | 509 | if (IS_ERR(pc->prescale_high)) |
278 | return PTR_ERR(pc->prescale_high); | 510 | return PTR_ERR(pc->prescale_high); |
279 | 511 | ||
280 | pc->pwm_en = devm_regmap_field_alloc(dev, pc->regmap, | ||
281 | reg_fields[PWM_EN]); | ||
282 | if (IS_ERR(pc->pwm_en)) | ||
283 | return PTR_ERR(pc->pwm_en); | ||
284 | 512 | ||
285 | pc->pwm_int_en = devm_regmap_field_alloc(dev, pc->regmap, | 513 | pc->pwm_out_en = devm_regmap_field_alloc(dev, pc->regmap, |
286 | reg_fields[PWM_INT_EN]); | 514 | reg_fields[PWM_OUT_EN]); |
287 | if (IS_ERR(pc->pwm_int_en)) | 515 | if (IS_ERR(pc->pwm_out_en)) |
288 | return PTR_ERR(pc->pwm_int_en); | 516 | return PTR_ERR(pc->pwm_out_en); |
517 | |||
518 | pc->pwm_cpt_en = devm_regmap_field_alloc(dev, pc->regmap, | ||
519 | reg_fields[PWM_CPT_EN]); | ||
520 | if (IS_ERR(pc->pwm_cpt_en)) | ||
521 | return PTR_ERR(pc->pwm_cpt_en); | ||
522 | |||
523 | pc->pwm_cpt_int_en = devm_regmap_field_alloc(dev, pc->regmap, | ||
524 | reg_fields[PWM_CPT_INT_EN]); | ||
525 | if (IS_ERR(pc->pwm_cpt_int_en)) | ||
526 | return PTR_ERR(pc->pwm_cpt_int_en); | ||
527 | |||
528 | pc->pwm_cpt_int_stat = devm_regmap_field_alloc(dev, pc->regmap, | ||
529 | reg_fields[PWM_CPT_INT_STAT]); | ||
530 | if (PTR_ERR_OR_ZERO(pc->pwm_cpt_int_stat)) | ||
531 | return PTR_ERR(pc->pwm_cpt_int_stat); | ||
289 | 532 | ||
290 | return 0; | 533 | return 0; |
291 | } | 534 | } |
@@ -302,7 +545,8 @@ static int sti_pwm_probe(struct platform_device *pdev) | |||
302 | struct sti_pwm_compat_data *cdata; | 545 | struct sti_pwm_compat_data *cdata; |
303 | struct sti_pwm_chip *pc; | 546 | struct sti_pwm_chip *pc; |
304 | struct resource *res; | 547 | struct resource *res; |
305 | int ret; | 548 | unsigned int i; |
549 | int irq, ret; | ||
306 | 550 | ||
307 | pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); | 551 | pc = devm_kzalloc(dev, sizeof(*pc), GFP_KERNEL); |
308 | if (!pc) | 552 | if (!pc) |
@@ -323,14 +567,28 @@ static int sti_pwm_probe(struct platform_device *pdev) | |||
323 | if (IS_ERR(pc->regmap)) | 567 | if (IS_ERR(pc->regmap)) |
324 | return PTR_ERR(pc->regmap); | 568 | return PTR_ERR(pc->regmap); |
325 | 569 | ||
570 | irq = platform_get_irq(pdev, 0); | ||
571 | if (irq < 0) { | ||
572 | dev_err(&pdev->dev, "Failed to obtain IRQ\n"); | ||
573 | return irq; | ||
574 | } | ||
575 | |||
576 | ret = devm_request_irq(&pdev->dev, irq, sti_pwm_interrupt, 0, | ||
577 | pdev->name, pc); | ||
578 | if (ret < 0) { | ||
579 | dev_err(&pdev->dev, "Failed to request IRQ\n"); | ||
580 | return ret; | ||
581 | } | ||
582 | |||
326 | /* | 583 | /* |
327 | * Setup PWM data with default values: some values could be replaced | 584 | * Setup PWM data with default values: some values could be replaced |
328 | * with specific ones provided from Device Tree. | 585 | * with specific ones provided from Device Tree. |
329 | */ | 586 | */ |
330 | cdata->reg_fields = &sti_pwm_regfields[0]; | 587 | cdata->reg_fields = sti_pwm_regfields; |
331 | cdata->max_prescale = 0xff; | 588 | cdata->max_prescale = 0xff; |
332 | cdata->max_pwm_cnt = 255; | 589 | cdata->max_pwm_cnt = 255; |
333 | cdata->num_chan = 1; | 590 | cdata->pwm_num_devs = 0; |
591 | cdata->cpt_num_devs = 0; | ||
334 | 592 | ||
335 | pc->cdata = cdata; | 593 | pc->cdata = cdata; |
336 | pc->dev = dev; | 594 | pc->dev = dev; |
@@ -341,36 +599,64 @@ static int sti_pwm_probe(struct platform_device *pdev) | |||
341 | if (ret) | 599 | if (ret) |
342 | return ret; | 600 | return ret; |
343 | 601 | ||
344 | pc->clk = of_clk_get_by_name(dev->of_node, "pwm"); | 602 | if (!cdata->pwm_num_devs) |
345 | if (IS_ERR(pc->clk)) { | 603 | goto skip_pwm; |
604 | |||
605 | pc->pwm_clk = of_clk_get_by_name(dev->of_node, "pwm"); | ||
606 | if (IS_ERR(pc->pwm_clk)) { | ||
346 | dev_err(dev, "failed to get PWM clock\n"); | 607 | dev_err(dev, "failed to get PWM clock\n"); |
347 | return PTR_ERR(pc->clk); | 608 | return PTR_ERR(pc->pwm_clk); |
348 | } | 609 | } |
349 | 610 | ||
350 | pc->clk_rate = clk_get_rate(pc->clk); | 611 | ret = clk_prepare(pc->pwm_clk); |
351 | if (!pc->clk_rate) { | 612 | if (ret) { |
352 | dev_err(dev, "failed to get clock rate\n"); | 613 | dev_err(dev, "failed to prepare clock\n"); |
353 | return -EINVAL; | 614 | return ret; |
354 | } | 615 | } |
355 | 616 | ||
356 | ret = clk_prepare(pc->clk); | 617 | skip_pwm: |
618 | if (!cdata->cpt_num_devs) | ||
619 | goto skip_cpt; | ||
620 | |||
621 | pc->cpt_clk = of_clk_get_by_name(dev->of_node, "capture"); | ||
622 | if (IS_ERR(pc->cpt_clk)) { | ||
623 | dev_err(dev, "failed to get PWM capture clock\n"); | ||
624 | return PTR_ERR(pc->cpt_clk); | ||
625 | } | ||
626 | |||
627 | ret = clk_prepare(pc->cpt_clk); | ||
357 | if (ret) { | 628 | if (ret) { |
358 | dev_err(dev, "failed to prepare clock\n"); | 629 | dev_err(dev, "failed to prepare clock\n"); |
359 | return ret; | 630 | return ret; |
360 | } | 631 | } |
361 | 632 | ||
633 | skip_cpt: | ||
362 | pc->chip.dev = dev; | 634 | pc->chip.dev = dev; |
363 | pc->chip.ops = &sti_pwm_ops; | 635 | pc->chip.ops = &sti_pwm_ops; |
364 | pc->chip.base = -1; | 636 | pc->chip.base = -1; |
365 | pc->chip.npwm = pc->cdata->num_chan; | 637 | pc->chip.npwm = pc->cdata->pwm_num_devs; |
366 | pc->chip.can_sleep = true; | 638 | pc->chip.can_sleep = true; |
367 | 639 | ||
368 | ret = pwmchip_add(&pc->chip); | 640 | ret = pwmchip_add(&pc->chip); |
369 | if (ret < 0) { | 641 | if (ret < 0) { |
370 | clk_unprepare(pc->clk); | 642 | clk_unprepare(pc->pwm_clk); |
643 | clk_unprepare(pc->cpt_clk); | ||
371 | return ret; | 644 | return ret; |
372 | } | 645 | } |
373 | 646 | ||
647 | for (i = 0; i < cdata->cpt_num_devs; i++) { | ||
648 | struct sti_cpt_ddata *ddata; | ||
649 | |||
650 | ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL); | ||
651 | if (!ddata) | ||
652 | return -ENOMEM; | ||
653 | |||
654 | init_waitqueue_head(&ddata->wait); | ||
655 | mutex_init(&ddata->lock); | ||
656 | |||
657 | pwm_set_chip_data(&pc->chip.pwms[i], ddata); | ||
658 | } | ||
659 | |||
374 | platform_set_drvdata(pdev, pc); | 660 | platform_set_drvdata(pdev, pc); |
375 | 661 | ||
376 | return 0; | 662 | return 0; |
@@ -381,10 +667,11 @@ static int sti_pwm_remove(struct platform_device *pdev) | |||
381 | struct sti_pwm_chip *pc = platform_get_drvdata(pdev); | 667 | struct sti_pwm_chip *pc = platform_get_drvdata(pdev); |
382 | unsigned int i; | 668 | unsigned int i; |
383 | 669 | ||
384 | for (i = 0; i < pc->cdata->num_chan; i++) | 670 | for (i = 0; i < pc->cdata->pwm_num_devs; i++) |
385 | pwm_disable(&pc->chip.pwms[i]); | 671 | pwm_disable(&pc->chip.pwms[i]); |
386 | 672 | ||
387 | clk_unprepare(pc->clk); | 673 | clk_unprepare(pc->pwm_clk); |
674 | clk_unprepare(pc->cpt_clk); | ||
388 | 675 | ||
389 | return pwmchip_remove(&pc->chip); | 676 | return pwmchip_remove(&pc->chip); |
390 | } | 677 | } |