diff options
author | Peter Meerwald <pmeerw@pmeerw.net> | 2014-12-06 00:54:00 -0500 |
---|---|---|
committer | Jonathan Cameron <jic23@kernel.org> | 2014-07-13 16:56:14 -0400 |
commit | 91556c69394d08ad32525b76436a8deab6155cbd (patch) | |
tree | 68e4d2fb490a8c3cc818b42af32837c488e36ce3 /drivers/iio/adc/ad799x.c | |
parent | e1c6e2a2173c88c1be6a43df407567ae1c11cc22 (diff) |
iio:adc:ad799x: Only expose event interface when IRQ is available
an IRQ is necessary to handle the ALERT condition; without
IRQ, the IIO event interface serves no purpose
Signed-off-by: Peter Meerwald <pmeerw@pmeerw.net>
Acked-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Jonathan Cameron <jic23@kernel.org>
Diffstat (limited to 'drivers/iio/adc/ad799x.c')
-rw-r--r-- | drivers/iio/adc/ad799x.c | 265 |
1 files changed, 179 insertions, 86 deletions
diff --git a/drivers/iio/adc/ad799x.c b/drivers/iio/adc/ad799x.c index b3799a8056c8..b8a811726d2f 100644 --- a/drivers/iio/adc/ad799x.c +++ b/drivers/iio/adc/ad799x.c | |||
@@ -101,22 +101,32 @@ enum { | |||
101 | }; | 101 | }; |
102 | 102 | ||
103 | /** | 103 | /** |
104 | * struct ad799x_chip_info - chip specific information | 104 | * struct ad799x_chip_config - chip specific information |
105 | * @channel: channel specification | 105 | * @channel: channel specification |
106 | * @num_channels: number of channels | ||
107 | * @default_config: device default configuration | 106 | * @default_config: device default configuration |
108 | * @info: pointer to iio_info struct | 107 | * @info: pointer to iio_info struct |
109 | */ | 108 | */ |
110 | struct ad799x_chip_info { | 109 | struct ad799x_chip_config { |
111 | struct iio_chan_spec channel[9]; | 110 | struct iio_chan_spec channel[9]; |
112 | int num_channels; | ||
113 | u16 default_config; | 111 | u16 default_config; |
114 | const struct iio_info *info; | 112 | const struct iio_info *info; |
115 | }; | 113 | }; |
116 | 114 | ||
115 | /** | ||
116 | * struct ad799x_chip_info - chip specific information | ||
117 | * @num_channels: number of channels | ||
118 | * @noirq_config: device configuration w/o IRQ | ||
119 | * @irq_config: device configuration w/IRQ | ||
120 | */ | ||
121 | struct ad799x_chip_info { | ||
122 | int num_channels; | ||
123 | const struct ad799x_chip_config noirq_config; | ||
124 | const struct ad799x_chip_config irq_config; | ||
125 | }; | ||
126 | |||
117 | struct ad799x_state { | 127 | struct ad799x_state { |
118 | struct i2c_client *client; | 128 | struct i2c_client *client; |
119 | const struct ad799x_chip_info *chip_info; | 129 | const struct ad799x_chip_config *chip_config; |
120 | struct regulator *reg; | 130 | struct regulator *reg; |
121 | struct regulator *vref; | 131 | struct regulator *vref; |
122 | unsigned id; | 132 | unsigned id; |
@@ -446,7 +456,13 @@ static const struct iio_info ad7991_info = { | |||
446 | .driver_module = THIS_MODULE, | 456 | .driver_module = THIS_MODULE, |
447 | }; | 457 | }; |
448 | 458 | ||
449 | static const struct iio_info ad7993_4_7_8_info = { | 459 | static const struct iio_info ad7993_4_7_8_noirq_info = { |
460 | .read_raw = &ad799x_read_raw, | ||
461 | .driver_module = THIS_MODULE, | ||
462 | .update_scan_mode = ad7997_8_update_scan_mode, | ||
463 | }; | ||
464 | |||
465 | static const struct iio_info ad7993_4_7_8_irq_info = { | ||
450 | .read_raw = &ad799x_read_raw, | 466 | .read_raw = &ad799x_read_raw, |
451 | .event_attrs = &ad799x_event_attrs_group, | 467 | .event_attrs = &ad799x_event_attrs_group, |
452 | .read_event_config = &ad799x_read_event_config, | 468 | .read_event_config = &ad799x_read_event_config, |
@@ -501,103 +517,175 @@ static const struct iio_event_spec ad799x_events[] = { | |||
501 | 517 | ||
502 | static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { | 518 | static const struct ad799x_chip_info ad799x_chip_info_tbl[] = { |
503 | [ad7991] = { | 519 | [ad7991] = { |
504 | .channel = { | ||
505 | AD799X_CHANNEL(0, 12), | ||
506 | AD799X_CHANNEL(1, 12), | ||
507 | AD799X_CHANNEL(2, 12), | ||
508 | AD799X_CHANNEL(3, 12), | ||
509 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
510 | }, | ||
511 | .num_channels = 5, | 520 | .num_channels = 5, |
512 | .info = &ad7991_info, | 521 | .noirq_config = { |
522 | .channel = { | ||
523 | AD799X_CHANNEL(0, 12), | ||
524 | AD799X_CHANNEL(1, 12), | ||
525 | AD799X_CHANNEL(2, 12), | ||
526 | AD799X_CHANNEL(3, 12), | ||
527 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
528 | }, | ||
529 | .info = &ad7991_info, | ||
530 | }, | ||
513 | }, | 531 | }, |
514 | [ad7995] = { | 532 | [ad7995] = { |
515 | .channel = { | ||
516 | AD799X_CHANNEL(0, 10), | ||
517 | AD799X_CHANNEL(1, 10), | ||
518 | AD799X_CHANNEL(2, 10), | ||
519 | AD799X_CHANNEL(3, 10), | ||
520 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
521 | }, | ||
522 | .num_channels = 5, | 533 | .num_channels = 5, |
523 | .info = &ad7991_info, | 534 | .noirq_config = { |
535 | .channel = { | ||
536 | AD799X_CHANNEL(0, 10), | ||
537 | AD799X_CHANNEL(1, 10), | ||
538 | AD799X_CHANNEL(2, 10), | ||
539 | AD799X_CHANNEL(3, 10), | ||
540 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
541 | }, | ||
542 | .info = &ad7991_info, | ||
543 | }, | ||
524 | }, | 544 | }, |
525 | [ad7999] = { | 545 | [ad7999] = { |
526 | .channel = { | ||
527 | AD799X_CHANNEL(0, 8), | ||
528 | AD799X_CHANNEL(1, 8), | ||
529 | AD799X_CHANNEL(2, 8), | ||
530 | AD799X_CHANNEL(3, 8), | ||
531 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
532 | }, | ||
533 | .num_channels = 5, | 546 | .num_channels = 5, |
534 | .info = &ad7991_info, | 547 | .noirq_config = { |
548 | .channel = { | ||
549 | AD799X_CHANNEL(0, 8), | ||
550 | AD799X_CHANNEL(1, 8), | ||
551 | AD799X_CHANNEL(2, 8), | ||
552 | AD799X_CHANNEL(3, 8), | ||
553 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
554 | }, | ||
555 | .info = &ad7991_info, | ||
556 | }, | ||
535 | }, | 557 | }, |
536 | [ad7992] = { | 558 | [ad7992] = { |
537 | .channel = { | ||
538 | AD799X_CHANNEL_WITH_EVENTS(0, 12), | ||
539 | AD799X_CHANNEL_WITH_EVENTS(1, 12), | ||
540 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
541 | }, | ||
542 | .num_channels = 3, | 559 | .num_channels = 3, |
543 | .default_config = AD7998_ALERT_EN, | 560 | .noirq_config = { |
544 | .info = &ad7993_4_7_8_info, | 561 | .channel = { |
562 | AD799X_CHANNEL(0, 12), | ||
563 | AD799X_CHANNEL(1, 12), | ||
564 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
565 | }, | ||
566 | .info = &ad7993_4_7_8_noirq_info, | ||
567 | }, | ||
568 | .irq_config = { | ||
569 | .channel = { | ||
570 | AD799X_CHANNEL_WITH_EVENTS(0, 12), | ||
571 | AD799X_CHANNEL_WITH_EVENTS(1, 12), | ||
572 | IIO_CHAN_SOFT_TIMESTAMP(3), | ||
573 | }, | ||
574 | .default_config = AD7998_ALERT_EN, | ||
575 | .info = &ad7993_4_7_8_irq_info, | ||
576 | }, | ||
545 | }, | 577 | }, |
546 | [ad7993] = { | 578 | [ad7993] = { |
547 | .channel = { | ||
548 | AD799X_CHANNEL_WITH_EVENTS(0, 10), | ||
549 | AD799X_CHANNEL_WITH_EVENTS(1, 10), | ||
550 | AD799X_CHANNEL_WITH_EVENTS(2, 10), | ||
551 | AD799X_CHANNEL_WITH_EVENTS(3, 10), | ||
552 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
553 | }, | ||
554 | .num_channels = 5, | 579 | .num_channels = 5, |
555 | .default_config = AD7998_ALERT_EN, | 580 | .noirq_config = { |
556 | .info = &ad7993_4_7_8_info, | 581 | .channel = { |
582 | AD799X_CHANNEL(0, 10), | ||
583 | AD799X_CHANNEL(1, 10), | ||
584 | AD799X_CHANNEL(2, 10), | ||
585 | AD799X_CHANNEL(3, 10), | ||
586 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
587 | }, | ||
588 | .info = &ad7993_4_7_8_noirq_info, | ||
589 | }, | ||
590 | .irq_config = { | ||
591 | .channel = { | ||
592 | AD799X_CHANNEL_WITH_EVENTS(0, 10), | ||
593 | AD799X_CHANNEL_WITH_EVENTS(1, 10), | ||
594 | AD799X_CHANNEL_WITH_EVENTS(2, 10), | ||
595 | AD799X_CHANNEL_WITH_EVENTS(3, 10), | ||
596 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
597 | }, | ||
598 | .default_config = AD7998_ALERT_EN, | ||
599 | .info = &ad7993_4_7_8_irq_info, | ||
600 | }, | ||
557 | }, | 601 | }, |
558 | [ad7994] = { | 602 | [ad7994] = { |
559 | .channel = { | ||
560 | AD799X_CHANNEL_WITH_EVENTS(0, 12), | ||
561 | AD799X_CHANNEL_WITH_EVENTS(1, 12), | ||
562 | AD799X_CHANNEL_WITH_EVENTS(2, 12), | ||
563 | AD799X_CHANNEL_WITH_EVENTS(3, 12), | ||
564 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
565 | }, | ||
566 | .num_channels = 5, | 603 | .num_channels = 5, |
567 | .default_config = AD7998_ALERT_EN, | 604 | .noirq_config = { |
568 | .info = &ad7993_4_7_8_info, | 605 | .channel = { |
606 | AD799X_CHANNEL(0, 12), | ||
607 | AD799X_CHANNEL(1, 12), | ||
608 | AD799X_CHANNEL(2, 12), | ||
609 | AD799X_CHANNEL(3, 12), | ||
610 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
611 | }, | ||
612 | .info = &ad7993_4_7_8_noirq_info, | ||
613 | }, | ||
614 | .irq_config = { | ||
615 | .channel = { | ||
616 | AD799X_CHANNEL_WITH_EVENTS(0, 12), | ||
617 | AD799X_CHANNEL_WITH_EVENTS(1, 12), | ||
618 | AD799X_CHANNEL_WITH_EVENTS(2, 12), | ||
619 | AD799X_CHANNEL_WITH_EVENTS(3, 12), | ||
620 | IIO_CHAN_SOFT_TIMESTAMP(4), | ||
621 | }, | ||
622 | .default_config = AD7998_ALERT_EN, | ||
623 | .info = &ad7993_4_7_8_irq_info, | ||
624 | }, | ||
569 | }, | 625 | }, |
570 | [ad7997] = { | 626 | [ad7997] = { |
571 | .channel = { | ||
572 | AD799X_CHANNEL_WITH_EVENTS(0, 10), | ||
573 | AD799X_CHANNEL_WITH_EVENTS(1, 10), | ||
574 | AD799X_CHANNEL_WITH_EVENTS(2, 10), | ||
575 | AD799X_CHANNEL_WITH_EVENTS(3, 10), | ||
576 | AD799X_CHANNEL(4, 10), | ||
577 | AD799X_CHANNEL(5, 10), | ||
578 | AD799X_CHANNEL(6, 10), | ||
579 | AD799X_CHANNEL(7, 10), | ||
580 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
581 | }, | ||
582 | .num_channels = 9, | 627 | .num_channels = 9, |
583 | .default_config = AD7998_ALERT_EN, | 628 | .noirq_config = { |
584 | .info = &ad7993_4_7_8_info, | 629 | .channel = { |
630 | AD799X_CHANNEL(0, 10), | ||
631 | AD799X_CHANNEL(1, 10), | ||
632 | AD799X_CHANNEL(2, 10), | ||
633 | AD799X_CHANNEL(3, 10), | ||
634 | AD799X_CHANNEL(4, 10), | ||
635 | AD799X_CHANNEL(5, 10), | ||
636 | AD799X_CHANNEL(6, 10), | ||
637 | AD799X_CHANNEL(7, 10), | ||
638 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
639 | }, | ||
640 | .info = &ad7993_4_7_8_noirq_info, | ||
641 | }, | ||
642 | .irq_config = { | ||
643 | .channel = { | ||
644 | AD799X_CHANNEL_WITH_EVENTS(0, 10), | ||
645 | AD799X_CHANNEL_WITH_EVENTS(1, 10), | ||
646 | AD799X_CHANNEL_WITH_EVENTS(2, 10), | ||
647 | AD799X_CHANNEL_WITH_EVENTS(3, 10), | ||
648 | AD799X_CHANNEL(4, 10), | ||
649 | AD799X_CHANNEL(5, 10), | ||
650 | AD799X_CHANNEL(6, 10), | ||
651 | AD799X_CHANNEL(7, 10), | ||
652 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
653 | }, | ||
654 | .default_config = AD7998_ALERT_EN, | ||
655 | .info = &ad7993_4_7_8_irq_info, | ||
656 | }, | ||
585 | }, | 657 | }, |
586 | [ad7998] = { | 658 | [ad7998] = { |
587 | .channel = { | ||
588 | AD799X_CHANNEL_WITH_EVENTS(0, 12), | ||
589 | AD799X_CHANNEL_WITH_EVENTS(1, 12), | ||
590 | AD799X_CHANNEL_WITH_EVENTS(2, 12), | ||
591 | AD799X_CHANNEL_WITH_EVENTS(3, 12), | ||
592 | AD799X_CHANNEL(4, 12), | ||
593 | AD799X_CHANNEL(5, 12), | ||
594 | AD799X_CHANNEL(6, 12), | ||
595 | AD799X_CHANNEL(7, 12), | ||
596 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
597 | }, | ||
598 | .num_channels = 9, | 659 | .num_channels = 9, |
599 | .default_config = AD7998_ALERT_EN, | 660 | .noirq_config = { |
600 | .info = &ad7993_4_7_8_info, | 661 | .channel = { |
662 | AD799X_CHANNEL(0, 12), | ||
663 | AD799X_CHANNEL(1, 12), | ||
664 | AD799X_CHANNEL(2, 12), | ||
665 | AD799X_CHANNEL(3, 12), | ||
666 | AD799X_CHANNEL(4, 12), | ||
667 | AD799X_CHANNEL(5, 12), | ||
668 | AD799X_CHANNEL(6, 12), | ||
669 | AD799X_CHANNEL(7, 12), | ||
670 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
671 | }, | ||
672 | .info = &ad7993_4_7_8_noirq_info, | ||
673 | }, | ||
674 | .irq_config = { | ||
675 | .channel = { | ||
676 | AD799X_CHANNEL_WITH_EVENTS(0, 12), | ||
677 | AD799X_CHANNEL_WITH_EVENTS(1, 12), | ||
678 | AD799X_CHANNEL_WITH_EVENTS(2, 12), | ||
679 | AD799X_CHANNEL_WITH_EVENTS(3, 12), | ||
680 | AD799X_CHANNEL(4, 12), | ||
681 | AD799X_CHANNEL(5, 12), | ||
682 | AD799X_CHANNEL(6, 12), | ||
683 | AD799X_CHANNEL(7, 12), | ||
684 | IIO_CHAN_SOFT_TIMESTAMP(8), | ||
685 | }, | ||
686 | .default_config = AD7998_ALERT_EN, | ||
687 | .info = &ad7993_4_7_8_irq_info, | ||
688 | }, | ||
601 | }, | 689 | }, |
602 | }; | 690 | }; |
603 | 691 | ||
@@ -607,6 +695,8 @@ static int ad799x_probe(struct i2c_client *client, | |||
607 | int ret; | 695 | int ret; |
608 | struct ad799x_state *st; | 696 | struct ad799x_state *st; |
609 | struct iio_dev *indio_dev; | 697 | struct iio_dev *indio_dev; |
698 | const struct ad799x_chip_info *chip_info = | ||
699 | &ad799x_chip_info_tbl[id->driver_data]; | ||
610 | 700 | ||
611 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); | 701 | indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st)); |
612 | if (indio_dev == NULL) | 702 | if (indio_dev == NULL) |
@@ -617,8 +707,11 @@ static int ad799x_probe(struct i2c_client *client, | |||
617 | i2c_set_clientdata(client, indio_dev); | 707 | i2c_set_clientdata(client, indio_dev); |
618 | 708 | ||
619 | st->id = id->driver_data; | 709 | st->id = id->driver_data; |
620 | st->chip_info = &ad799x_chip_info_tbl[st->id]; | 710 | if (client->irq > 0 && chip_info->irq_config.info) |
621 | st->config = st->chip_info->default_config; | 711 | st->chip_config = &chip_info->irq_config; |
712 | else | ||
713 | st->chip_config = &chip_info->noirq_config; | ||
714 | st->config = st->chip_config->default_config; | ||
622 | 715 | ||
623 | /* TODO: Add pdata options for filtering and bit delay */ | 716 | /* TODO: Add pdata options for filtering and bit delay */ |
624 | 717 | ||
@@ -641,11 +734,11 @@ static int ad799x_probe(struct i2c_client *client, | |||
641 | 734 | ||
642 | indio_dev->dev.parent = &client->dev; | 735 | indio_dev->dev.parent = &client->dev; |
643 | indio_dev->name = id->name; | 736 | indio_dev->name = id->name; |
644 | indio_dev->info = st->chip_info->info; | 737 | indio_dev->info = st->chip_config->info; |
645 | 738 | ||
646 | indio_dev->modes = INDIO_DIRECT_MODE; | 739 | indio_dev->modes = INDIO_DIRECT_MODE; |
647 | indio_dev->channels = st->chip_info->channel; | 740 | indio_dev->channels = st->chip_config->channel; |
648 | indio_dev->num_channels = st->chip_info->num_channels; | 741 | indio_dev->num_channels = chip_info->num_channels; |
649 | 742 | ||
650 | ret = iio_triggered_buffer_setup(indio_dev, NULL, | 743 | ret = iio_triggered_buffer_setup(indio_dev, NULL, |
651 | &ad799x_trigger_handler, NULL); | 744 | &ad799x_trigger_handler, NULL); |