diff options
Diffstat (limited to 'drivers/iio/trigger/stm32-timer-trigger.c')
-rw-r--r-- | drivers/iio/trigger/stm32-timer-trigger.c | 314 |
1 files changed, 308 insertions, 6 deletions
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index 994b96d19750..0f1a2cf334bf 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,286 @@ 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_enable_modes[] = { | ||
357 | "always", | ||
358 | "gated", | ||
359 | "triggered", | ||
360 | }; | ||
361 | |||
362 | static int stm32_enable_mode2sms(int mode) | ||
363 | { | ||
364 | switch (mode) { | ||
365 | case 0: | ||
366 | return 0; | ||
367 | case 1: | ||
368 | return 5; | ||
369 | case 2: | ||
370 | return 6; | ||
371 | } | ||
372 | |||
373 | return -EINVAL; | ||
374 | } | ||
375 | |||
376 | static int stm32_set_enable_mode(struct iio_dev *indio_dev, | ||
377 | const struct iio_chan_spec *chan, | ||
378 | unsigned int mode) | ||
379 | { | ||
380 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
381 | int sms = stm32_enable_mode2sms(mode); | ||
382 | |||
383 | if (sms < 0) | ||
384 | return sms; | ||
385 | |||
386 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); | ||
387 | |||
388 | return 0; | ||
389 | } | ||
390 | |||
391 | static int stm32_sms2enable_mode(int mode) | ||
392 | { | ||
393 | switch (mode) { | ||
394 | case 0: | ||
395 | return 0; | ||
396 | case 5: | ||
397 | return 1; | ||
398 | case 6: | ||
399 | return 2; | ||
400 | } | ||
401 | |||
402 | return -EINVAL; | ||
403 | } | ||
404 | |||
405 | static int stm32_get_enable_mode(struct iio_dev *indio_dev, | ||
406 | const struct iio_chan_spec *chan) | ||
407 | { | ||
408 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
409 | u32 smcr; | ||
410 | |||
411 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | ||
412 | smcr &= TIM_SMCR_SMS; | ||
413 | |||
414 | return stm32_sms2enable_mode(smcr); | ||
415 | } | ||
416 | |||
417 | static const struct iio_enum stm32_enable_mode_enum = { | ||
418 | .items = stm32_enable_modes, | ||
419 | .num_items = ARRAY_SIZE(stm32_enable_modes), | ||
420 | .set = stm32_set_enable_mode, | ||
421 | .get = stm32_get_enable_mode | ||
422 | }; | ||
423 | |||
424 | static const char *const stm32_quadrature_modes[] = { | ||
425 | "channel_A", | ||
426 | "channel_B", | ||
427 | "quadrature", | ||
428 | }; | ||
429 | |||
430 | static int stm32_set_quadrature_mode(struct iio_dev *indio_dev, | ||
431 | const struct iio_chan_spec *chan, | ||
432 | unsigned int mode) | ||
433 | { | ||
434 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
435 | |||
436 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, mode + 1); | ||
437 | |||
438 | return 0; | ||
439 | } | ||
440 | |||
441 | static int stm32_get_quadrature_mode(struct iio_dev *indio_dev, | ||
442 | const struct iio_chan_spec *chan) | ||
443 | { | ||
444 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
445 | u32 smcr; | ||
446 | |||
447 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | ||
448 | smcr &= TIM_SMCR_SMS; | ||
449 | |||
450 | return smcr - 1; | ||
451 | } | ||
452 | |||
453 | static const struct iio_enum stm32_quadrature_mode_enum = { | ||
454 | .items = stm32_quadrature_modes, | ||
455 | .num_items = ARRAY_SIZE(stm32_quadrature_modes), | ||
456 | .set = stm32_set_quadrature_mode, | ||
457 | .get = stm32_get_quadrature_mode | ||
458 | }; | ||
459 | |||
460 | static const char *const stm32_count_direction_states[] = { | ||
461 | "up", | ||
462 | "down" | ||
463 | }; | ||
464 | |||
465 | static int stm32_set_count_direction(struct iio_dev *indio_dev, | ||
466 | const struct iio_chan_spec *chan, | ||
467 | unsigned int mode) | ||
468 | { | ||
469 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
470 | |||
471 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_DIR, mode); | ||
472 | |||
473 | return 0; | ||
474 | } | ||
475 | |||
476 | static int stm32_get_count_direction(struct iio_dev *indio_dev, | ||
477 | const struct iio_chan_spec *chan) | ||
478 | { | ||
479 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
480 | u32 cr1; | ||
481 | |||
482 | regmap_read(priv->regmap, TIM_CR1, &cr1); | ||
483 | |||
484 | return (cr1 & TIM_CR1_DIR); | ||
485 | } | ||
486 | |||
487 | static const struct iio_enum stm32_count_direction_enum = { | ||
488 | .items = stm32_count_direction_states, | ||
489 | .num_items = ARRAY_SIZE(stm32_count_direction_states), | ||
490 | .set = stm32_set_count_direction, | ||
491 | .get = stm32_get_count_direction | ||
492 | }; | ||
493 | |||
494 | static ssize_t stm32_count_get_preset(struct iio_dev *indio_dev, | ||
495 | uintptr_t private, | ||
496 | const struct iio_chan_spec *chan, | ||
497 | char *buf) | ||
498 | { | ||
499 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
500 | u32 arr; | ||
501 | |||
502 | regmap_read(priv->regmap, TIM_ARR, &arr); | ||
503 | |||
504 | return snprintf(buf, PAGE_SIZE, "%u\n", arr); | ||
505 | } | ||
506 | |||
507 | static ssize_t stm32_count_set_preset(struct iio_dev *indio_dev, | ||
508 | uintptr_t private, | ||
509 | const struct iio_chan_spec *chan, | ||
510 | const char *buf, size_t len) | ||
511 | { | ||
512 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | ||
513 | unsigned int preset; | ||
514 | int ret; | ||
515 | |||
516 | ret = kstrtouint(buf, 0, &preset); | ||
517 | if (ret) | ||
518 | return ret; | ||
519 | |||
520 | regmap_write(priv->regmap, TIM_ARR, preset); | ||
521 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_ARPE, TIM_CR1_ARPE); | ||
522 | |||
523 | return len; | ||
524 | } | ||
525 | |||
526 | static const struct iio_chan_spec_ext_info stm32_trigger_count_info[] = { | ||
527 | { | ||
528 | .name = "preset", | ||
529 | .shared = IIO_SEPARATE, | ||
530 | .read = stm32_count_get_preset, | ||
531 | .write = stm32_count_set_preset | ||
532 | }, | ||
533 | IIO_ENUM("count_direction", IIO_SEPARATE, &stm32_count_direction_enum), | ||
534 | IIO_ENUM_AVAILABLE("count_direction", &stm32_count_direction_enum), | ||
535 | IIO_ENUM("quadrature_mode", IIO_SEPARATE, &stm32_quadrature_mode_enum), | ||
536 | IIO_ENUM_AVAILABLE("quadrature_mode", &stm32_quadrature_mode_enum), | ||
537 | IIO_ENUM("enable_mode", IIO_SEPARATE, &stm32_enable_mode_enum), | ||
538 | IIO_ENUM_AVAILABLE("enable_mode", &stm32_enable_mode_enum), | ||
539 | {} | ||
540 | }; | ||
541 | |||
542 | static const struct iio_chan_spec stm32_trigger_channel = { | ||
543 | .type = IIO_COUNT, | ||
544 | .channel = 0, | ||
545 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | ||
546 | .ext_info = stm32_trigger_count_info, | ||
547 | .indexed = 1 | ||
548 | }; | ||
549 | |||
550 | static struct stm32_timer_trigger *stm32_setup_counter_device(struct device *dev) | ||
551 | { | ||
552 | struct iio_dev *indio_dev; | ||
553 | int ret; | ||
554 | |||
555 | indio_dev = devm_iio_device_alloc(dev, | ||
556 | sizeof(struct stm32_timer_trigger)); | ||
557 | if (!indio_dev) | ||
558 | return NULL; | ||
559 | |||
560 | indio_dev->name = dev_name(dev); | ||
561 | indio_dev->dev.parent = dev; | ||
562 | indio_dev->info = &stm32_trigger_info; | ||
563 | indio_dev->num_channels = 1; | ||
564 | indio_dev->channels = &stm32_trigger_channel; | ||
565 | indio_dev->dev.of_node = dev->of_node; | ||
566 | |||
567 | ret = devm_iio_device_register(dev, indio_dev); | ||
568 | if (ret) | ||
569 | return NULL; | ||
570 | |||
571 | return iio_priv(indio_dev); | ||
572 | } | ||
573 | |||
278 | /** | 574 | /** |
279 | * is_stm32_timer_trigger | 575 | * is_stm32_timer_trigger |
280 | * @trig: trigger to be checked | 576 | * @trig: trigger to be checked |
@@ -299,10 +595,15 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) | |||
299 | if (of_property_read_u32(dev->of_node, "reg", &index)) | 595 | if (of_property_read_u32(dev->of_node, "reg", &index)) |
300 | return -EINVAL; | 596 | return -EINVAL; |
301 | 597 | ||
302 | if (index >= ARRAY_SIZE(triggers_table)) | 598 | if (index >= ARRAY_SIZE(triggers_table) || |
599 | index >= ARRAY_SIZE(valids_table)) | ||
303 | return -EINVAL; | 600 | return -EINVAL; |
304 | 601 | ||
305 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | 602 | /* Create an IIO device only if we have triggers to be validated */ |
603 | if (*valids_table[index]) | ||
604 | priv = stm32_setup_counter_device(dev); | ||
605 | else | ||
606 | priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); | ||
306 | 607 | ||
307 | if (!priv) | 608 | if (!priv) |
308 | return -ENOMEM; | 609 | return -ENOMEM; |
@@ -312,6 +613,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) | |||
312 | priv->clk = ddata->clk; | 613 | priv->clk = ddata->clk; |
313 | priv->max_arr = ddata->max_arr; | 614 | priv->max_arr = ddata->max_arr; |
314 | priv->triggers = triggers_table[index]; | 615 | priv->triggers = triggers_table[index]; |
616 | priv->valids = valids_table[index]; | ||
315 | 617 | ||
316 | ret = stm32_setup_iio_triggers(priv); | 618 | ret = stm32_setup_iio_triggers(priv); |
317 | if (ret) | 619 | if (ret) |