GNU Linux-libre 4.14.328-gnu1
[releases.git] / drivers / iio / counter / stm32-lptimer-cnt.c
1 /*
2  * STM32 Low-Power Timer Encoder and Counter driver
3  *
4  * Copyright (C) STMicroelectronics 2017
5  *
6  * Author: Fabrice Gasnier <fabrice.gasnier@st.com>
7  *
8  * Inspired by 104-quad-8 and stm32-timer-trigger drivers.
9  *
10  * License terms:  GNU General Public License (GPL), version 2
11  */
12
13 #include <linux/bitfield.h>
14 #include <linux/iio/iio.h>
15 #include <linux/mfd/stm32-lptimer.h>
16 #include <linux/module.h>
17 #include <linux/platform_device.h>
18
19 struct stm32_lptim_cnt {
20         struct device *dev;
21         struct regmap *regmap;
22         struct clk *clk;
23         u32 preset;
24         u32 polarity;
25         u32 quadrature_mode;
26 };
27
28 static int stm32_lptim_is_enabled(struct stm32_lptim_cnt *priv)
29 {
30         u32 val;
31         int ret;
32
33         ret = regmap_read(priv->regmap, STM32_LPTIM_CR, &val);
34         if (ret)
35                 return ret;
36
37         return FIELD_GET(STM32_LPTIM_ENABLE, val);
38 }
39
40 static int stm32_lptim_set_enable_state(struct stm32_lptim_cnt *priv,
41                                         int enable)
42 {
43         int ret;
44         u32 val;
45
46         val = FIELD_PREP(STM32_LPTIM_ENABLE, enable);
47         ret = regmap_write(priv->regmap, STM32_LPTIM_CR, val);
48         if (ret)
49                 return ret;
50
51         if (!enable) {
52                 clk_disable(priv->clk);
53                 return 0;
54         }
55
56         /* LP timer must be enabled before writing CMP & ARR */
57         ret = regmap_write(priv->regmap, STM32_LPTIM_ARR, priv->preset);
58         if (ret)
59                 return ret;
60
61         ret = regmap_write(priv->regmap, STM32_LPTIM_CMP, 0);
62         if (ret)
63                 return ret;
64
65         /* ensure CMP & ARR registers are properly written */
66         ret = regmap_read_poll_timeout(priv->regmap, STM32_LPTIM_ISR, val,
67                                        (val & STM32_LPTIM_CMPOK_ARROK),
68                                        100, 1000);
69         if (ret)
70                 return ret;
71
72         ret = regmap_write(priv->regmap, STM32_LPTIM_ICR,
73                            STM32_LPTIM_CMPOKCF_ARROKCF);
74         if (ret)
75                 return ret;
76
77         ret = clk_enable(priv->clk);
78         if (ret) {
79                 regmap_write(priv->regmap, STM32_LPTIM_CR, 0);
80                 return ret;
81         }
82
83         /* Start LP timer in continuous mode */
84         return regmap_update_bits(priv->regmap, STM32_LPTIM_CR,
85                                   STM32_LPTIM_CNTSTRT, STM32_LPTIM_CNTSTRT);
86 }
87
88 static int stm32_lptim_setup(struct stm32_lptim_cnt *priv, int enable)
89 {
90         u32 mask = STM32_LPTIM_ENC | STM32_LPTIM_COUNTMODE |
91                    STM32_LPTIM_CKPOL | STM32_LPTIM_PRESC;
92         u32 val;
93
94         /* Setup LP timer encoder/counter and polarity, without prescaler */
95         if (priv->quadrature_mode)
96                 val = enable ? STM32_LPTIM_ENC : 0;
97         else
98                 val = enable ? STM32_LPTIM_COUNTMODE : 0;
99         val |= FIELD_PREP(STM32_LPTIM_CKPOL, enable ? priv->polarity : 0);
100
101         return regmap_update_bits(priv->regmap, STM32_LPTIM_CFGR, mask, val);
102 }
103
104 static int stm32_lptim_write_raw(struct iio_dev *indio_dev,
105                                  struct iio_chan_spec const *chan,
106                                  int val, int val2, long mask)
107 {
108         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
109         int ret;
110
111         switch (mask) {
112         case IIO_CHAN_INFO_ENABLE:
113                 if (val < 0 || val > 1)
114                         return -EINVAL;
115
116                 /* Check nobody uses the timer, or already disabled/enabled */
117                 ret = stm32_lptim_is_enabled(priv);
118                 if ((ret < 0) || (!ret && !val))
119                         return ret;
120                 if (val && ret)
121                         return -EBUSY;
122
123                 ret = stm32_lptim_setup(priv, val);
124                 if (ret)
125                         return ret;
126                 return stm32_lptim_set_enable_state(priv, val);
127
128         default:
129                 return -EINVAL;
130         }
131 }
132
133 static int stm32_lptim_read_raw(struct iio_dev *indio_dev,
134                                 struct iio_chan_spec const *chan,
135                                 int *val, int *val2, long mask)
136 {
137         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
138         u32 dat;
139         int ret;
140
141         switch (mask) {
142         case IIO_CHAN_INFO_RAW:
143                 ret = regmap_read(priv->regmap, STM32_LPTIM_CNT, &dat);
144                 if (ret)
145                         return ret;
146                 *val = dat;
147                 return IIO_VAL_INT;
148
149         case IIO_CHAN_INFO_ENABLE:
150                 ret = stm32_lptim_is_enabled(priv);
151                 if (ret < 0)
152                         return ret;
153                 *val = ret;
154                 return IIO_VAL_INT;
155
156         case IIO_CHAN_INFO_SCALE:
157                 /* Non-quadrature mode: scale = 1 */
158                 *val = 1;
159                 *val2 = 0;
160                 if (priv->quadrature_mode) {
161                         /*
162                          * Quadrature encoder mode:
163                          * - both edges, quarter cycle, scale is 0.25
164                          * - either rising/falling edge scale is 0.5
165                          */
166                         if (priv->polarity > 1)
167                                 *val2 = 2;
168                         else
169                                 *val2 = 1;
170                 }
171                 return IIO_VAL_FRACTIONAL_LOG2;
172
173         default:
174                 return -EINVAL;
175         }
176 }
177
178 static const struct iio_info stm32_lptim_cnt_iio_info = {
179         .read_raw = stm32_lptim_read_raw,
180         .write_raw = stm32_lptim_write_raw,
181         .driver_module = THIS_MODULE,
182 };
183
184 static const char *const stm32_lptim_quadrature_modes[] = {
185         "non-quadrature",
186         "quadrature",
187 };
188
189 static int stm32_lptim_get_quadrature_mode(struct iio_dev *indio_dev,
190                                            const struct iio_chan_spec *chan)
191 {
192         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
193
194         return priv->quadrature_mode;
195 }
196
197 static int stm32_lptim_set_quadrature_mode(struct iio_dev *indio_dev,
198                                            const struct iio_chan_spec *chan,
199                                            unsigned int type)
200 {
201         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
202
203         if (stm32_lptim_is_enabled(priv))
204                 return -EBUSY;
205
206         priv->quadrature_mode = type;
207
208         return 0;
209 }
210
211 static const struct iio_enum stm32_lptim_quadrature_mode_en = {
212         .items = stm32_lptim_quadrature_modes,
213         .num_items = ARRAY_SIZE(stm32_lptim_quadrature_modes),
214         .get = stm32_lptim_get_quadrature_mode,
215         .set = stm32_lptim_set_quadrature_mode,
216 };
217
218 static const char * const stm32_lptim_cnt_polarity[] = {
219         "rising-edge", "falling-edge", "both-edges",
220 };
221
222 static int stm32_lptim_cnt_get_polarity(struct iio_dev *indio_dev,
223                                         const struct iio_chan_spec *chan)
224 {
225         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
226
227         return priv->polarity;
228 }
229
230 static int stm32_lptim_cnt_set_polarity(struct iio_dev *indio_dev,
231                                         const struct iio_chan_spec *chan,
232                                         unsigned int type)
233 {
234         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
235
236         if (stm32_lptim_is_enabled(priv))
237                 return -EBUSY;
238
239         priv->polarity = type;
240
241         return 0;
242 }
243
244 static const struct iio_enum stm32_lptim_cnt_polarity_en = {
245         .items = stm32_lptim_cnt_polarity,
246         .num_items = ARRAY_SIZE(stm32_lptim_cnt_polarity),
247         .get = stm32_lptim_cnt_get_polarity,
248         .set = stm32_lptim_cnt_set_polarity,
249 };
250
251 static ssize_t stm32_lptim_cnt_get_preset(struct iio_dev *indio_dev,
252                                           uintptr_t private,
253                                           const struct iio_chan_spec *chan,
254                                           char *buf)
255 {
256         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
257
258         return snprintf(buf, PAGE_SIZE, "%u\n", priv->preset);
259 }
260
261 static ssize_t stm32_lptim_cnt_set_preset(struct iio_dev *indio_dev,
262                                           uintptr_t private,
263                                           const struct iio_chan_spec *chan,
264                                           const char *buf, size_t len)
265 {
266         struct stm32_lptim_cnt *priv = iio_priv(indio_dev);
267         int ret;
268
269         if (stm32_lptim_is_enabled(priv))
270                 return -EBUSY;
271
272         ret = kstrtouint(buf, 0, &priv->preset);
273         if (ret)
274                 return ret;
275
276         if (priv->preset > STM32_LPTIM_MAX_ARR)
277                 return -EINVAL;
278
279         return len;
280 }
281
282 /* LP timer with encoder */
283 static const struct iio_chan_spec_ext_info stm32_lptim_enc_ext_info[] = {
284         {
285                 .name = "preset",
286                 .shared = IIO_SEPARATE,
287                 .read = stm32_lptim_cnt_get_preset,
288                 .write = stm32_lptim_cnt_set_preset,
289         },
290         IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
291         IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
292         IIO_ENUM("quadrature_mode", IIO_SEPARATE,
293                  &stm32_lptim_quadrature_mode_en),
294         IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_lptim_quadrature_mode_en),
295         {}
296 };
297
298 static const struct iio_chan_spec stm32_lptim_enc_channels = {
299         .type = IIO_COUNT,
300         .channel = 0,
301         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
302                               BIT(IIO_CHAN_INFO_ENABLE) |
303                               BIT(IIO_CHAN_INFO_SCALE),
304         .ext_info = stm32_lptim_enc_ext_info,
305         .indexed = 1,
306 };
307
308 /* LP timer without encoder (counter only) */
309 static const struct iio_chan_spec_ext_info stm32_lptim_cnt_ext_info[] = {
310         {
311                 .name = "preset",
312                 .shared = IIO_SEPARATE,
313                 .read = stm32_lptim_cnt_get_preset,
314                 .write = stm32_lptim_cnt_set_preset,
315         },
316         IIO_ENUM("polarity", IIO_SEPARATE, &stm32_lptim_cnt_polarity_en),
317         IIO_ENUM_AVAILABLE("polarity", &stm32_lptim_cnt_polarity_en),
318         {}
319 };
320
321 static const struct iio_chan_spec stm32_lptim_cnt_channels = {
322         .type = IIO_COUNT,
323         .channel = 0,
324         .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
325                               BIT(IIO_CHAN_INFO_ENABLE) |
326                               BIT(IIO_CHAN_INFO_SCALE),
327         .ext_info = stm32_lptim_cnt_ext_info,
328         .indexed = 1,
329 };
330
331 static int stm32_lptim_cnt_probe(struct platform_device *pdev)
332 {
333         struct stm32_lptimer *ddata = dev_get_drvdata(pdev->dev.parent);
334         struct stm32_lptim_cnt *priv;
335         struct iio_dev *indio_dev;
336
337         if (IS_ERR_OR_NULL(ddata))
338                 return -EINVAL;
339
340         indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*priv));
341         if (!indio_dev)
342                 return -ENOMEM;
343
344         priv = iio_priv(indio_dev);
345         priv->dev = &pdev->dev;
346         priv->regmap = ddata->regmap;
347         priv->clk = ddata->clk;
348         priv->preset = STM32_LPTIM_MAX_ARR;
349
350         indio_dev->name = dev_name(&pdev->dev);
351         indio_dev->dev.parent = &pdev->dev;
352         indio_dev->dev.of_node = pdev->dev.of_node;
353         indio_dev->info = &stm32_lptim_cnt_iio_info;
354         if (ddata->has_encoder)
355                 indio_dev->channels = &stm32_lptim_enc_channels;
356         else
357                 indio_dev->channels = &stm32_lptim_cnt_channels;
358         indio_dev->num_channels = 1;
359
360         platform_set_drvdata(pdev, priv);
361
362         return devm_iio_device_register(&pdev->dev, indio_dev);
363 }
364
365 static const struct of_device_id stm32_lptim_cnt_of_match[] = {
366         { .compatible = "st,stm32-lptimer-counter", },
367         {},
368 };
369 MODULE_DEVICE_TABLE(of, stm32_lptim_cnt_of_match);
370
371 static struct platform_driver stm32_lptim_cnt_driver = {
372         .probe = stm32_lptim_cnt_probe,
373         .driver = {
374                 .name = "stm32-lptimer-counter",
375                 .of_match_table = stm32_lptim_cnt_of_match,
376         },
377 };
378 module_platform_driver(stm32_lptim_cnt_driver);
379
380 MODULE_AUTHOR("Fabrice Gasnier <fabrice.gasnier@st.com>");
381 MODULE_ALIAS("platform:stm32-lptimer-counter");
382 MODULE_DESCRIPTION("STMicroelectronics STM32 LPTIM counter driver");
383 MODULE_LICENSE("GPL v2");