diff options
author | Shawn Guo <shawn.guo@linaro.org> | 2011-12-12 12:52:57 -0500 |
---|---|---|
committer | Samuel Ortiz <sameo@linux.intel.com> | 2012-01-08 18:37:35 -0500 |
commit | 876989d58658858f27a461f0b4b43fa750a208f4 (patch) | |
tree | 6ccd9e3d9cf0c190083a1dcb1d192c91ab616261 /drivers/mfd | |
parent | af9081ae64b941d32239b947882cd59ba855c5db (diff) |
mfd: Add device tree probe support for mc13xxx
This adds device tree probe support for mc13xxx mfd driver.
Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
Diffstat (limited to 'drivers/mfd')
-rw-r--r-- | drivers/mfd/mc13xxx-core.c | 106 |
1 files changed, 75 insertions, 31 deletions
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c index d0d3dfafba5c..7122386b4e3c 100644 --- a/drivers/mfd/mc13xxx-core.c +++ b/drivers/mfd/mc13xxx-core.c | |||
@@ -18,11 +18,15 @@ | |||
18 | #include <linux/spi/spi.h> | 18 | #include <linux/spi/spi.h> |
19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
20 | #include <linux/mfd/mc13xxx.h> | 20 | #include <linux/mfd/mc13xxx.h> |
21 | #include <linux/of.h> | ||
22 | #include <linux/of_device.h> | ||
23 | #include <linux/of_gpio.h> | ||
21 | 24 | ||
22 | struct mc13xxx { | 25 | struct mc13xxx { |
23 | struct spi_device *spidev; | 26 | struct spi_device *spidev; |
24 | struct mutex lock; | 27 | struct mutex lock; |
25 | int irq; | 28 | int irq; |
29 | int flags; | ||
26 | 30 | ||
27 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; | 31 | irq_handler_t irqhandler[MC13XXX_NUM_IRQ]; |
28 | void *irqdata[MC13XXX_NUM_IRQ]; | 32 | void *irqdata[MC13XXX_NUM_IRQ]; |
@@ -550,10 +554,7 @@ static const char *mc13xxx_get_chipname(struct mc13xxx *mc13xxx) | |||
550 | 554 | ||
551 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) | 555 | int mc13xxx_get_flags(struct mc13xxx *mc13xxx) |
552 | { | 556 | { |
553 | struct mc13xxx_platform_data *pdata = | 557 | return mc13xxx->flags; |
554 | dev_get_platdata(&mc13xxx->spidev->dev); | ||
555 | |||
556 | return pdata->flags; | ||
557 | } | 558 | } |
558 | EXPORT_SYMBOL(mc13xxx_get_flags); | 559 | EXPORT_SYMBOL(mc13xxx_get_flags); |
559 | 560 | ||
@@ -696,17 +697,67 @@ static int mc13xxx_add_subdevice(struct mc13xxx *mc13xxx, const char *format) | |||
696 | return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); | 697 | return mc13xxx_add_subdevice_pdata(mc13xxx, format, NULL, 0); |
697 | } | 698 | } |
698 | 699 | ||
700 | #ifdef CONFIG_OF | ||
701 | static int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | ||
702 | { | ||
703 | struct device_node *np = mc13xxx->spidev->dev.of_node; | ||
704 | |||
705 | if (!np) | ||
706 | return -ENODEV; | ||
707 | |||
708 | if (of_get_property(np, "fsl,mc13xxx-uses-adc", NULL)) | ||
709 | mc13xxx->flags |= MC13XXX_USE_ADC; | ||
710 | |||
711 | if (of_get_property(np, "fsl,mc13xxx-uses-codec", NULL)) | ||
712 | mc13xxx->flags |= MC13XXX_USE_CODEC; | ||
713 | |||
714 | if (of_get_property(np, "fsl,mc13xxx-uses-rtc", NULL)) | ||
715 | mc13xxx->flags |= MC13XXX_USE_RTC; | ||
716 | |||
717 | if (of_get_property(np, "fsl,mc13xxx-uses-touch", NULL)) | ||
718 | mc13xxx->flags |= MC13XXX_USE_TOUCHSCREEN; | ||
719 | |||
720 | return 0; | ||
721 | } | ||
722 | #else | ||
723 | static inline int mc13xxx_probe_flags_dt(struct mc13xxx *mc13xxx) | ||
724 | { | ||
725 | return -ENODEV; | ||
726 | } | ||
727 | #endif | ||
728 | |||
729 | static const struct spi_device_id mc13xxx_device_id[] = { | ||
730 | { | ||
731 | .name = "mc13783", | ||
732 | .driver_data = MC13XXX_ID_MC13783, | ||
733 | }, { | ||
734 | .name = "mc13892", | ||
735 | .driver_data = MC13XXX_ID_MC13892, | ||
736 | }, { | ||
737 | /* sentinel */ | ||
738 | } | ||
739 | }; | ||
740 | MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); | ||
741 | |||
742 | static const struct of_device_id mc13xxx_dt_ids[] = { | ||
743 | { .compatible = "fsl,mc13783", .data = (void *) MC13XXX_ID_MC13783, }, | ||
744 | { .compatible = "fsl,mc13892", .data = (void *) MC13XXX_ID_MC13892, }, | ||
745 | { /* sentinel */ } | ||
746 | }; | ||
747 | MODULE_DEVICE_TABLE(of, mc13xxx_dt_ids); | ||
748 | |||
699 | static int mc13xxx_probe(struct spi_device *spi) | 749 | static int mc13xxx_probe(struct spi_device *spi) |
700 | { | 750 | { |
751 | const struct of_device_id *of_id; | ||
752 | struct spi_driver *sdrv = to_spi_driver(spi->dev.driver); | ||
701 | struct mc13xxx *mc13xxx; | 753 | struct mc13xxx *mc13xxx; |
702 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); | 754 | struct mc13xxx_platform_data *pdata = dev_get_platdata(&spi->dev); |
703 | enum mc13xxx_id id; | 755 | enum mc13xxx_id id; |
704 | int ret; | 756 | int ret; |
705 | 757 | ||
706 | if (!pdata) { | 758 | of_id = of_match_device(mc13xxx_dt_ids, &spi->dev); |
707 | dev_err(&spi->dev, "invalid platform data\n"); | 759 | if (of_id) |
708 | return -EINVAL; | 760 | sdrv->id_table = &mc13xxx_device_id[(enum mc13xxx_id) of_id->data]; |
709 | } | ||
710 | 761 | ||
711 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); | 762 | mc13xxx = kzalloc(sizeof(*mc13xxx), GFP_KERNEL); |
712 | if (!mc13xxx) | 763 | if (!mc13xxx) |
@@ -749,28 +800,33 @@ err_revision: | |||
749 | 800 | ||
750 | mc13xxx_unlock(mc13xxx); | 801 | mc13xxx_unlock(mc13xxx); |
751 | 802 | ||
752 | if (pdata->flags & MC13XXX_USE_ADC) | 803 | if (mc13xxx_probe_flags_dt(mc13xxx) < 0 && pdata) |
804 | mc13xxx->flags = pdata->flags; | ||
805 | |||
806 | if (mc13xxx->flags & MC13XXX_USE_ADC) | ||
753 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); | 807 | mc13xxx_add_subdevice(mc13xxx, "%s-adc"); |
754 | 808 | ||
755 | if (pdata->flags & MC13XXX_USE_CODEC) | 809 | if (mc13xxx->flags & MC13XXX_USE_CODEC) |
756 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); | 810 | mc13xxx_add_subdevice(mc13xxx, "%s-codec"); |
757 | 811 | ||
758 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | 812 | if (mc13xxx->flags & MC13XXX_USE_RTC) |
759 | &pdata->regulators, sizeof(pdata->regulators)); | ||
760 | |||
761 | if (pdata->flags & MC13XXX_USE_RTC) | ||
762 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); | 813 | mc13xxx_add_subdevice(mc13xxx, "%s-rtc"); |
763 | 814 | ||
764 | if (pdata->flags & MC13XXX_USE_TOUCHSCREEN) | 815 | if (mc13xxx->flags & MC13XXX_USE_TOUCHSCREEN) |
765 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); | 816 | mc13xxx_add_subdevice(mc13xxx, "%s-ts"); |
766 | 817 | ||
767 | if (pdata->leds) | 818 | if (pdata) { |
819 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-regulator", | ||
820 | &pdata->regulators, sizeof(pdata->regulators)); | ||
768 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", | 821 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-led", |
769 | pdata->leds, sizeof(*pdata->leds)); | 822 | pdata->leds, sizeof(*pdata->leds)); |
770 | |||
771 | if (pdata->buttons) | ||
772 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", | 823 | mc13xxx_add_subdevice_pdata(mc13xxx, "%s-pwrbutton", |
773 | pdata->buttons, sizeof(*pdata->buttons)); | 824 | pdata->buttons, sizeof(*pdata->buttons)); |
825 | } else { | ||
826 | mc13xxx_add_subdevice(mc13xxx, "%s-regulator"); | ||
827 | mc13xxx_add_subdevice(mc13xxx, "%s-led"); | ||
828 | mc13xxx_add_subdevice(mc13xxx, "%s-pwrbutton"); | ||
829 | } | ||
774 | 830 | ||
775 | return 0; | 831 | return 0; |
776 | } | 832 | } |
@@ -788,24 +844,12 @@ static int __devexit mc13xxx_remove(struct spi_device *spi) | |||
788 | return 0; | 844 | return 0; |
789 | } | 845 | } |
790 | 846 | ||
791 | static const struct spi_device_id mc13xxx_device_id[] = { | ||
792 | { | ||
793 | .name = "mc13783", | ||
794 | .driver_data = MC13XXX_ID_MC13783, | ||
795 | }, { | ||
796 | .name = "mc13892", | ||
797 | .driver_data = MC13XXX_ID_MC13892, | ||
798 | }, { | ||
799 | /* sentinel */ | ||
800 | } | ||
801 | }; | ||
802 | MODULE_DEVICE_TABLE(spi, mc13xxx_device_id); | ||
803 | |||
804 | static struct spi_driver mc13xxx_driver = { | 847 | static struct spi_driver mc13xxx_driver = { |
805 | .id_table = mc13xxx_device_id, | 848 | .id_table = mc13xxx_device_id, |
806 | .driver = { | 849 | .driver = { |
807 | .name = "mc13xxx", | 850 | .name = "mc13xxx", |
808 | .owner = THIS_MODULE, | 851 | .owner = THIS_MODULE, |
852 | .of_match_table = mc13xxx_dt_ids, | ||
809 | }, | 853 | }, |
810 | .probe = mc13xxx_probe, | 854 | .probe = mc13xxx_probe, |
811 | .remove = __devexit_p(mc13xxx_remove), | 855 | .remove = __devexit_p(mc13xxx_remove), |