diff options
Diffstat (limited to 'drivers/regulator/ab8500.c')
-rw-r--r-- | drivers/regulator/ab8500.c | 150 |
1 files changed, 87 insertions, 63 deletions
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index d1563907d3c8..3571b5425b36 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c | |||
@@ -708,11 +708,92 @@ static struct ab8500_reg_init ab8500_reg_init[] = { | |||
708 | REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), | 708 | REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16), |
709 | }; | 709 | }; |
710 | 710 | ||
711 | static __devinit int | ||
712 | ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value) | ||
713 | { | ||
714 | int err; | ||
715 | |||
716 | if (value & ~ab8500_reg_init[id].mask) { | ||
717 | dev_err(&pdev->dev, | ||
718 | "Configuration error: value outside mask.\n"); | ||
719 | return -EINVAL; | ||
720 | } | ||
721 | |||
722 | err = abx500_mask_and_set_register_interruptible( | ||
723 | &pdev->dev, | ||
724 | ab8500_reg_init[id].bank, | ||
725 | ab8500_reg_init[id].addr, | ||
726 | ab8500_reg_init[id].mask, | ||
727 | value); | ||
728 | if (err < 0) { | ||
729 | dev_err(&pdev->dev, | ||
730 | "Failed to initialize 0x%02x, 0x%02x.\n", | ||
731 | ab8500_reg_init[id].bank, | ||
732 | ab8500_reg_init[id].addr); | ||
733 | return err; | ||
734 | } | ||
735 | |||
736 | dev_vdbg(&pdev->dev, | ||
737 | "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", | ||
738 | ab8500_reg_init[id].bank, | ||
739 | ab8500_reg_init[id].addr, | ||
740 | ab8500_reg_init[id].mask, | ||
741 | value); | ||
742 | |||
743 | return 0; | ||
744 | } | ||
745 | |||
746 | static __devinit int ab8500_regulator_register(struct platform_device *pdev, | ||
747 | struct regulator_init_data *init_data, | ||
748 | int id, | ||
749 | struct device_node *np) | ||
750 | { | ||
751 | struct ab8500_regulator_info *info = NULL; | ||
752 | struct regulator_config config = { }; | ||
753 | int err; | ||
754 | |||
755 | /* assign per-regulator data */ | ||
756 | info = &ab8500_regulator_info[id]; | ||
757 | info->dev = &pdev->dev; | ||
758 | |||
759 | config.dev = &pdev->dev; | ||
760 | config.init_data = init_data; | ||
761 | config.driver_data = info; | ||
762 | config.of_node = np; | ||
763 | |||
764 | /* fix for hardware before ab8500v2.0 */ | ||
765 | if (abx500_get_chip_id(info->dev) < 0x20) { | ||
766 | if (info->desc.id == AB8500_LDO_AUX3) { | ||
767 | info->desc.n_voltages = | ||
768 | ARRAY_SIZE(ldo_vauxn_voltages); | ||
769 | info->voltages = ldo_vauxn_voltages; | ||
770 | info->voltages_len = | ||
771 | ARRAY_SIZE(ldo_vauxn_voltages); | ||
772 | info->voltage_mask = 0xf; | ||
773 | } | ||
774 | } | ||
775 | |||
776 | /* register regulator with framework */ | ||
777 | info->regulator = regulator_register(&info->desc, &config); | ||
778 | if (IS_ERR(info->regulator)) { | ||
779 | err = PTR_ERR(info->regulator); | ||
780 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
781 | info->desc.name); | ||
782 | /* when we fail, un-register all earlier regulators */ | ||
783 | while (--id >= 0) { | ||
784 | info = &ab8500_regulator_info[id]; | ||
785 | regulator_unregister(info->regulator); | ||
786 | } | ||
787 | return err; | ||
788 | } | ||
789 | |||
790 | return 0; | ||
791 | } | ||
792 | |||
711 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | 793 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) |
712 | { | 794 | { |
713 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | 795 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); |
714 | struct ab8500_platform_data *pdata; | 796 | struct ab8500_platform_data *pdata; |
715 | struct regulator_config config = { }; | ||
716 | int i, err; | 797 | int i, err; |
717 | 798 | ||
718 | if (!ab8500) { | 799 | if (!ab8500) { |
@@ -733,8 +814,7 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
733 | 814 | ||
734 | /* initialize registers */ | 815 | /* initialize registers */ |
735 | for (i = 0; i < pdata->num_regulator_reg_init; i++) { | 816 | for (i = 0; i < pdata->num_regulator_reg_init; i++) { |
736 | int id; | 817 | int id, value; |
737 | u8 value; | ||
738 | 818 | ||
739 | id = pdata->regulator_reg_init[i].id; | 819 | id = pdata->regulator_reg_init[i].id; |
740 | value = pdata->regulator_reg_init[i].value; | 820 | value = pdata->regulator_reg_init[i].value; |
@@ -745,73 +825,17 @@ static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | |||
745 | "Configuration error: id outside range.\n"); | 825 | "Configuration error: id outside range.\n"); |
746 | return -EINVAL; | 826 | return -EINVAL; |
747 | } | 827 | } |
748 | if (value & ~ab8500_reg_init[id].mask) { | ||
749 | dev_err(&pdev->dev, | ||
750 | "Configuration error: value outside mask.\n"); | ||
751 | return -EINVAL; | ||
752 | } | ||
753 | 828 | ||
754 | /* initialize register */ | 829 | err = ab8500_regulator_init_registers(pdev, id, value); |
755 | err = abx500_mask_and_set_register_interruptible(&pdev->dev, | 830 | if (err < 0) |
756 | ab8500_reg_init[id].bank, | ||
757 | ab8500_reg_init[id].addr, | ||
758 | ab8500_reg_init[id].mask, | ||
759 | value); | ||
760 | if (err < 0) { | ||
761 | dev_err(&pdev->dev, | ||
762 | "Failed to initialize 0x%02x, 0x%02x.\n", | ||
763 | ab8500_reg_init[id].bank, | ||
764 | ab8500_reg_init[id].addr); | ||
765 | return err; | 831 | return err; |
766 | } | ||
767 | dev_vdbg(&pdev->dev, | ||
768 | " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n", | ||
769 | ab8500_reg_init[id].bank, | ||
770 | ab8500_reg_init[id].addr, | ||
771 | ab8500_reg_init[id].mask, | ||
772 | value); | ||
773 | } | 832 | } |
774 | 833 | ||
775 | /* register all regulators */ | 834 | /* register all regulators */ |
776 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | 835 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { |
777 | struct ab8500_regulator_info *info = NULL; | 836 | err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL); |
778 | 837 | if (err < 0) | |
779 | /* assign per-regulator data */ | ||
780 | info = &ab8500_regulator_info[i]; | ||
781 | info->dev = &pdev->dev; | ||
782 | |||
783 | config.dev = &pdev->dev; | ||
784 | config.init_data = &pdata->regulator[i]; | ||
785 | config.driver_data = info; | ||
786 | |||
787 | /* fix for hardware before ab8500v2.0 */ | ||
788 | if (abx500_get_chip_id(info->dev) < 0x20) { | ||
789 | if (info->desc.id == AB8500_LDO_AUX3) { | ||
790 | info->desc.n_voltages = | ||
791 | ARRAY_SIZE(ldo_vauxn_voltages); | ||
792 | info->voltages = ldo_vauxn_voltages; | ||
793 | info->voltages_len = | ||
794 | ARRAY_SIZE(ldo_vauxn_voltages); | ||
795 | info->voltage_mask = 0xf; | ||
796 | } | ||
797 | } | ||
798 | |||
799 | /* register regulator with framework */ | ||
800 | info->regulator = regulator_register(&info->desc, &config); | ||
801 | if (IS_ERR(info->regulator)) { | ||
802 | err = PTR_ERR(info->regulator); | ||
803 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
804 | info->desc.name); | ||
805 | /* when we fail, un-register all earlier regulators */ | ||
806 | while (--i >= 0) { | ||
807 | info = &ab8500_regulator_info[i]; | ||
808 | regulator_unregister(info->regulator); | ||
809 | } | ||
810 | return err; | 838 | return err; |
811 | } | ||
812 | |||
813 | dev_vdbg(rdev_get_dev(info->regulator), | ||
814 | "%s-probed\n", info->desc.name); | ||
815 | } | 839 | } |
816 | 840 | ||
817 | return 0; | 841 | return 0; |