diff options
Diffstat (limited to 'drivers/iio/trigger/stm32-timer-trigger.c')
-rw-r--r-- | drivers/iio/trigger/stm32-timer-trigger.c | 244 |
1 files changed, 238 insertions, 6 deletions
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index 994b96d19750..7db904cae926 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/platform_device.h> | 15 | #include <linux/platform_device.h> |
16 | 16 | ||
17 | #define MAX_TRIGGERS 6 | 17 | #define MAX_TRIGGERS 6 |
18 | #define MAX_VALIDS 5 | ||
18 | 19 | ||
19 | /* List the triggers created by each timer */ | 20 | /* List the triggers created by each timer */ |
20 | static const void *triggers_table[][MAX_TRIGGERS] = { | 21 | static const void *triggers_table[][MAX_TRIGGERS] = { |
@@ -32,12 +33,29 @@ static const void *triggers_table[][MAX_TRIGGERS] = { | |||
32 | { TIM12_TRGO, TIM12_CH1, TIM12_CH2,}, | 33 | { TIM12_TRGO, TIM12_CH1, TIM12_CH2,}, |
33 | }; | 34 | }; |
34 | 35 | ||
36 | /* List the triggers accepted by each timer */ | ||
37 | static const void *valids_table[][MAX_VALIDS] = { | ||
38 | { TIM5_TRGO, TIM2_TRGO, TIM3_TRGO, TIM4_TRGO,}, | ||
39 | { TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO,}, | ||
40 | { TIM1_TRGO, TIM2_TRGO, TIM5_TRGO, TIM4_TRGO,}, | ||
41 | { TIM1_TRGO, TIM2_TRGO, TIM3_TRGO, TIM8_TRGO,}, | ||
42 | { TIM2_TRGO, TIM3_TRGO, TIM4_TRGO, TIM8_TRGO,}, | ||
43 | { }, /* timer 6 */ | ||
44 | { }, /* timer 7 */ | ||
45 | { TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO,}, | ||
46 | { TIM2_TRGO, TIM3_TRGO,}, | ||
47 | { }, /* timer 10 */ | ||
48 | { }, /* timer 11 */ | ||
49 | { TIM4_TRGO, TIM5_TRGO,}, | ||
50 | }; | ||
51 | |||
35 | struct stm32_timer_trigger { | 52 | struct stm32_timer_trigger { |
36 | struct device *dev; | 53 | struct device *dev; |
37 | struct regmap *regmap; | 54 | struct regmap *regmap; |
38 | struct clk *clk; | 55 | struct clk *clk; |
39 | u32 max_arr; | 56 | u32 max_arr; |
40 | const void *triggers; | 57 | const void *triggers; |
58 | const void *valids; | ||
41 | }; | 59 | }; |
42 | 60 | ||
43 | static int stm32_timer_start(struct stm32_timer_trigger *priv, | 61 | static int stm32_timer_start(struct stm32_timer_trigger *priv, |
@@ -180,8 +198,7 @@ static ssize_t stm32_tt_show_master_mode(struct device *dev, | |||
180 | struct device_attribute *attr, | 198 | struct device_attribute *attr, |
181 | char *buf) | 199 | char *buf) |
182 | { | 200 | { |
183 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 201 | struct stm32_timer_trigger *priv = dev_get_drvdata(dev); |
184 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
185 | u32 cr2; | 202 | u32 cr2; |
186 | 203 | ||
187 | regmap_read(priv->regmap, TIM_CR2, &cr2); | 204 | regmap_read(priv->regmap, TIM_CR2, &cr2); |
@@ -194,8 +211,7 @@ static ssize_t stm32_tt_store_master_mode(struct device *dev, | |||
194 | struct device_attribute *attr, | 211 | struct device_attribute *attr, |
195 | const char *buf, size_t len) | 212 | const char *buf, size_t len) |
196 | { | 213 | { |
197 | struct iio_dev *indio_dev = dev_to_iio_dev(dev); | 214 | struct stm32_timer_trigger *priv = dev_get_drvdata(dev); |
198 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
199 | int i; | 215 | int i; |
200 | 216 | ||
201 | for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) { | 217 | for (i = 0; i < ARRAY_SIZE(master_mode_table); i++) { |
@@ -275,6 +291,216 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) | |||
275 | return 0; | 291 | return 0; |
276 | } | 292 | } |
277 | 293 | ||
294 | static int stm32_counter_read_raw(struct iio_dev *indio_dev, | ||
295 | struct iio_chan_spec const *chan, | ||
296 | int *val, int *val2, long mask) | ||
297 | { | ||
298 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
299 | |||
300 | switch (mask) { | ||
301 | case IIO_CHAN_INFO_RAW: | ||
302 | { | ||
303 | u32 cnt; | ||
304 | |||
305 | regmap_read(priv->regmap, TIM_CNT, &cnt); | ||
306 | *val = cnt; | ||
307 | |||
308 | return IIO_VAL_INT; | ||
309 | } | ||
310 | case IIO_CHAN_INFO_SCALE: | ||
311 | { | ||
312 | u32 smcr; | ||
313 | |||
314 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | ||
315 | smcr &= TIM_SMCR_SMS; | ||
316 | |||
317 | *val = 1; | ||
318 | *val2 = 0; | ||
319 | |||
320 | /* in quadrature case scale = 0.25 */ | ||
321 | if (smcr == 3) | ||
322 | *val2 = 2; | ||
323 | |||
324 | return IIO_VAL_FRACTIONAL_LOG2; | ||
325 | } | ||
326 | } | ||
327 | |||
328 | return -EINVAL; | ||
329 | } | ||
330 | |||
331 | static int stm32_counter_write_raw(struct iio_dev *indio_dev, | ||
332 | struct iio_chan_spec const *chan, | ||
333 | int val, int val2, long mask) | ||
334 | { | ||
335 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
336 | |||
337 | switch (mask) { | ||
338 | case IIO_CHAN_INFO_RAW: | ||
339 | regmap_write(priv->regmap, TIM_CNT, val); | ||
340 | |||
341 | return IIO_VAL_INT; | ||
342 | case IIO_CHAN_INFO_SCALE: | ||
343 | /* fixed scale */ | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | |||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | static const struct iio_info stm32_trigger_info = { | ||
351 | .driver_module = THIS_MODULE, | ||
352 | .read_raw = stm32_counter_read_raw, | ||
353 | .write_raw = stm32_counter_write_raw | ||
354 | }; | ||
355 | |||
356 | static const char *const stm32_quadrature_modes[] = { | ||
357 | "channel_A", | ||
358 | "channel_B", | ||
359 | "quadrature", | ||
360 | }; | ||
361 | |||
362 | static int stm32_set_quadrature_mode(struct iio_dev *indio_dev, | ||
363 | const struct iio_chan_spec *chan, | ||
364 | unsigned int mode) | ||
365 | { | ||
366 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
367 | |||
368 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, mode + 1); | ||
369 | |||
370 | return 0; | ||
371 | } | ||
372 | |||
373 | static int stm32_get_quadrature_mode(struct iio_dev *indio_dev, | ||
374 | const struct iio_chan_spec *chan) | ||
375 | { | ||
376 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
377 | u32 smcr; | ||
378 | |||
379 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | ||
380 | smcr &= TIM_SMCR_SMS; | ||
381 | |||
382 | return smcr - 1; | ||
383 | } | ||
384 | |||
385 | static const struct iio_enum stm32_quadrature_mode_enum = { | ||
386 | .items = stm32_quadrature_modes, | ||
387 | .num_items = ARRAY_SIZE(stm32_quadrature_modes), | ||
388 | .set = stm32_set_quadrature_mode, | ||
389 | .get = stm32_get_quadrature_mode | ||
390 | }; | ||
391 | |||
392 | static const char *const stm32_count_direction_states[] = { | ||
393 | "up", | ||
394 | "down" | ||
395 | }; | ||
396 | |||
397 | static int stm32_set_count_direction(struct iio_dev *indio_dev, | ||
398 | const struct iio_chan_spec *chan, | ||
399 | unsigned int mode) | ||
400 | { | ||
401 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
402 | |||
403 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_DIR, mode); | ||
404 | |||
405 | return 0; | ||
406 | } | ||
407 | |||
408 | static int stm32_get_count_direction(struct iio_dev *indio_dev, | ||
409 | const struct iio_chan_spec *chan) | ||
410 | { | ||
411 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
412 | u32 cr1; | ||
413 | |||
414 | regmap_read(priv->regmap, TIM_CR1, &cr1); | ||
415 | |||
416 | return (cr1 & TIM_CR1_DIR); | ||
417 | } | ||
418 | |||
419 | static const struct iio_enum stm32_count_direction_enum = { | ||
420 | .items = stm32_count_direction_states, | ||
421 | .num_items = ARRAY_SIZE(stm32_count_direction_states), | ||
422 | .set = stm32_set_count_direction, | ||
423 | .get = stm32_get_count_direction | ||
424 | }; | ||
425 | |||
426 | static ssize_t stm32_count_get_preset(struct iio_dev *indio_dev, | ||
427 | uintptr_t private, | ||
428 | const struct iio_chan_spec *chan, | ||
429 | char *buf) | ||
430 | { | ||
431 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
432 | u32 arr; | ||
433 | |||
434 | regmap_read(priv->regmap, TIM_ARR, &arr); | ||
435 | |||
436 | return snprintf(buf, PAGE_SIZE, "%u\n", arr); | ||
437 | } | ||
438 | |||
439 | static ssize_t stm32_count_set_preset(struct iio_dev *indio_dev, | ||
440 | uintptr_t private, | ||
441 | const struct iio_chan_spec *chan, | ||
442 | const char *buf, size_t len) | ||
443 | { | ||
444 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
445 | unsigned int preset; | ||
446 | int ret; | ||
447 | |||
448 | ret = kstrtouint(buf, 0, &preset); | ||
449 | if (ret) | ||
450 | return ret; | ||
451 | |||
452 | regmap_write(priv->regmap, TIM_ARR, preset); | ||
453 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); | ||
454 | |||
455 | return len; | ||
456 | } | ||
457 | |||
458 | static const struct iio_chan_spec_ext_info stm32_trigger_count_info[] = { | ||
459 | { | ||
460 | .name = "preset", | ||
461 | .shared = IIO_SEPARATE, | ||
462 | .read = stm32_count_get_preset, | ||
463 | .write = stm32_count_set_preset | ||
464 | }, | ||
465 | IIO_ENUM("count_direction", IIO_SEPARATE, &stm32_count_direction_enum), | ||
466 | IIO_ENUM_AVAILABLE("count_direction", &stm32_count_direction_enum), | ||
467 | IIO_ENUM("quadrature_mode", IIO_SEPARATE, &stm32_quadrature_mode_enum), | ||
468 | IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_quadrature_mode_enum), | ||
469 | {} | ||
470 | }; | ||
471 | |||
472 | static const struct iio_chan_spec stm32_trigger_channel = { | ||
473 | .type = IIO_COUNT, | ||
474 | .channel = 0, | ||
475 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | ||
476 | .ext_info = stm32_trigger_count_info, | ||
477 | .indexed = 1 | ||
478 | }; | ||
479 | |||
480 | static struct stm32_timer_trigger *stm32_setup_counter_device(struct device *dev) | ||
481 | { | ||
482 | struct iio_dev *indio_dev; | ||
483 | int ret; | ||
484 | |||
485 | indio_dev = devm_iio_device_alloc(dev, | ||
486 | sizeof(struct stm32_timer_trigger)); | ||
487 | if (!indio_dev) | ||
488 | return NULL; | ||
489 | |||
490 | indio_dev->name = dev_name(dev); | ||
491 | indio_dev->dev.parent = dev; | ||
492 | indio_dev->info = &stm32_trigger_info; | ||
493 | indio_dev->num_channels = 1; | ||
494 | indio_dev->channels = &stm32_trigger_channel; | ||
495 | indio_dev->dev.of_node = dev->of_node; | ||
496 | |||
497 | ret = devm_iio_device_register(dev, indio_dev); | ||
498 | if (ret) | ||
499 | return NULL; | ||
500 | |||
501 | return iio_priv(indio_dev); | ||
502 | } | ||
503 | |||
278 | /** | 504 | /** |
279 | * is_stm32_timer_trigger | 505 | * is_stm32_timer_trigger |
280 | * @trig: trigger to be checked | 506 | * @trig: trigger to be checked |
@@ -299,10 +525,15 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) | |||
299 | if (of_property_read_u32(dev->of_node, "reg", &index)) | 525 | if (of_property_read_u32(dev->of_node, "reg", &index)) |
300 | return -EINVAL; | 526 | return -EINVAL; |
301 | 527 | ||
302 | if (index >= ARRAY_SIZE(triggers_table)) | 528 | if (index >= ARRAY_SIZE(triggers_table) || |
529 | index >= ARRAY_SIZE(valids_table)) | ||
303 | return -EINVAL; | 530 | return -EINVAL; |
304 | 531 | ||
305 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 532 | /* Create an IIO device only if we have triggers to be validated */ |
533 | if (*valids_table[index]) | ||
534 | priv = stm32_setup_counter_device(dev); | ||
535 | else | ||
536 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
306 | 537 | ||
307 | if (!priv) | 538 | if (!priv) |
308 | return -ENOMEM; | 539 | return -ENOMEM; |
@@ -312,6 +543,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) | |||
312 | priv->clk = ddata->clk; | 543 | priv->clk = ddata->clk; |
313 | priv->max_arr = ddata->max_arr; | 544 | priv->max_arr = ddata->max_arr; |
314 | priv->triggers = triggers_table[index]; | 545 | priv->triggers = triggers_table[index]; |
546 | priv->valids = valids_table[index]; | ||
315 | 547 | ||
316 | ret = stm32_setup_iio_triggers(priv); | 548 | ret = stm32_setup_iio_triggers(priv); |
317 | if (ret) | 549 | if (ret) |