Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

regulator: lp872x: support the device tree feature

This patch enables the DT structure of the LP8720 and LP8725 device.
The LP872x platform data is generated when the device tree is configured.
Even if the platform data is NULL, it is no issue at all because the driver is
configured with the default mode.

Signed-off-by: Milo(Woogyom) Kim <milo.kim@ti.com>
Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>

authored by

Kim, Milo and committed by
Mark Brown
00fd6e61 c7788792

+274 -2
+160
Documentation/devicetree/bindings/regulator/lp872x.txt
··· 1 + Binding for TI/National Semiconductor LP872x Driver 2 + 3 + Required properties: 4 + - compatible: "ti,lp8720" or "ti,lp8725" 5 + - reg: I2C slave address. 0x7d = LP8720, 0x7a = LP8725 6 + 7 + Optional properties: 8 + - ti,general-config: the value of LP872X_GENERAL_CFG register (u8) 9 + (LP8720) 10 + bit[2]: BUCK output voltage control by external DVS pin or register 11 + 1 = external pin, 0 = bit7 of register 08h 12 + bit[1]: sleep control by external DVS pin or register 13 + 1 = external pin, 0 = bit6 of register 08h 14 + bit[0]: time step unit(usec). 1 = 25, 0 = 50 15 + 16 + (LP8725) 17 + bit[7:6]: time step unit(usec). 00 = 32, 01 = 64, 10 = 128, 11 = 256 18 + bit[4]: BUCK2 enable control. 1 = enable, 0 = disable 19 + bit[3]: BUCK2 output voltage register address. 1 = 0Ah, 0 = 0Bh 20 + bit[2]: BUCK1 output voltage control by external DVS pin or register 21 + 1 = register 08h, 0 = DVS 22 + bit[1]: LDO sleep control. 1 = sleep mode, 0 = normal 23 + bit[0]: BUCK1 enable control, 1 = enable, 0 = disable 24 + 25 + For more details, please see the datasheet. 26 + 27 + - ti,update-config: define it when LP872X_GENERAL_CFG register should be set 28 + - ti,dvs-gpio: GPIO specifier for external DVS pin control of LP872x devices. 29 + - ti,dvs-vsel: DVS selector. 0 = SEL_V1, 1 = SEL_V2. 30 + - ti,dvs-state: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH. 31 + 32 + Sub nodes for regulator_init_data 33 + LP8720 has maximum 6 nodes. (child name: ldo1 ~ 5 and buck) 34 + LP8725 has maximum 9 nodes. (child name: ldo1 ~ 5, lilo1,2 and buck1,2) 35 + For more details, please see the following binding document. 36 + (Documentation/devicetree/bindings/regulator/regulator.txt) 37 + 38 + Datasheet 39 + - LP8720: http://www.ti.com/lit/ds/symlink/lp8720.pdf 40 + - LP8725: http://www.ti.com/lit/ds/symlink/lp8725.pdf 41 + 42 + Example 1) LP8720 43 + 44 + lp8720@7d { 45 + compatible = "ti,lp8720"; 46 + reg = <0x7d>; 47 + 48 + /* external DVS pin used, timestep is 25usec */ 49 + ti,general-config = /bits/ 8 <0x03>; 50 + ti,update-config; 51 + 52 + /* 53 + * The dvs-gpio depends on the processor environment. 54 + * For example, following GPIO specifier means GPIO134 in OMAP4. 55 + */ 56 + ti,dvs-gpio = <&gpio5 6 0>; 57 + ti,dvs-vsel = /bits/ 8 <1>; /* SEL_V2 */ 58 + ti,dvs-state = /bits/ 8 <1>; /* DVS_HIGH */ 59 + 60 + vaf: ldo1 { 61 + regulator-min-microvolt = <1200000>; 62 + regulator-max-microvolt = <3300000>; 63 + }; 64 + 65 + vmmc: ldo2 { 66 + regulator-min-microvolt = <1200000>; 67 + regulator-max-microvolt = <3300000>; 68 + }; 69 + 70 + vcam_io: ldo3 { 71 + regulator-min-microvolt = <1200000>; 72 + regulator-max-microvolt = <3300000>; 73 + regulator-boot-on; 74 + }; 75 + 76 + vcam_core: ldo4 { 77 + regulator-min-microvolt = <800000>; 78 + regulator-max-microvolt = <2850000>; 79 + regulator-boot-on; 80 + }; 81 + 82 + vcam: ldo5 { 83 + regulator-min-microvolt = <1200000>; 84 + regulator-max-microvolt = <3300000>; 85 + }; 86 + 87 + vcc: buck { 88 + regulator-name = "VBUCK"; 89 + regulator-min-microvolt = <800000>; 90 + regulator-max-microvolt = <2300000>; 91 + }; 92 + }; 93 + 94 + Example 2) LP8725 95 + 96 + lp8725@7a { 97 + compatible = "ti,lp8725"; 98 + reg = <0x7a>; 99 + 100 + /* Enable BUCK1,2, no DVS, normal LDO mode, timestep is 256usec */ 101 + ti,general-config = /bits/ 8 <0xdd>; 102 + ti,update-config; 103 + 104 + vcam_io: ldo1 { 105 + regulator-min-microvolt = <1200000>; 106 + regulator-max-microvolt = <3300000>; 107 + }; 108 + 109 + vcam_core: ldo2 { 110 + regulator-min-microvolt = <1200000>; 111 + regulator-max-microvolt = <3300000>; 112 + }; 113 + 114 + vcam: ldo3 { 115 + regulator-min-microvolt = <1200000>; 116 + regulator-max-microvolt = <3300000>; 117 + }; 118 + 119 + vcmmb_io: ldo4 { 120 + regulator-min-microvolt = <1200000>; 121 + regulator-max-microvolt = <3300000>; 122 + regulator-boot-on; 123 + }; 124 + 125 + vcmmb_core: ldo5 { 126 + regulator-min-microvolt = <1200000>; 127 + regulator-max-microvolt = <3300000>; 128 + regulator-boot-on; 129 + }; 130 + 131 + vaux1: lilo1 { 132 + regulator-name = "VAUX1"; 133 + regulator-min-microvolt = <800000>; 134 + regulator-max-microvolt = <3300000>; 135 + }; 136 + 137 + vaux2: lilo2 { 138 + regulator-name = "VAUX2"; 139 + regulator-min-microvolt = <800000>; 140 + regulator-max-microvolt = <3300000>; 141 + }; 142 + 143 + vcc1: buck1 { 144 + regulator-name = "VBUCK1"; 145 + regulator-min-microvolt = <800000>; 146 + regulator-max-microvolt = <3000000>; 147 + regulator-min-microamp = <460000>; 148 + regulator-max-microamp = <1370000>; 149 + regulator-boot-on; 150 + }; 151 + 152 + vcc2: buck2 { 153 + regulator-name = "VBUCK2"; 154 + regulator-min-microvolt = <800000>; 155 + regulator-max-microvolt = <3000000>; 156 + regulator-min-microamp = <460000>; 157 + regulator-max-microamp = <1370000>; 158 + regulator-boot-on; 159 + }; 160 + };
+114 -2
drivers/regulator/lp872x.c
··· 18 18 #include <linux/regulator/lp872x.h> 19 19 #include <linux/regulator/driver.h> 20 20 #include <linux/platform_device.h> 21 + #include <linux/of.h> 22 + #include <linux/of_gpio.h> 23 + #include <linux/regulator/of_regulator.h> 21 24 22 25 /* Registers : LP8720/8725 shared */ 23 26 #define LP872X_GENERAL_CFG 0x00 ··· 726 723 727 724 gpio = dvs->gpio; 728 725 if (!gpio_is_valid(gpio)) { 729 - dev_err(lp->dev, "invalid gpio: %d\n", gpio); 730 - return -EINVAL; 726 + dev_warn(lp->dev, "invalid gpio: %d\n", gpio); 727 + goto set_default_dvs_mode; 731 728 } 732 729 733 730 pinstate = dvs->init_state; ··· 832 829 .max_register = MAX_REGISTERS, 833 830 }; 834 831 832 + #ifdef CONFIG_OF 833 + 834 + #define LP872X_VALID_OPMODE (REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL) 835 + 836 + static struct of_regulator_match lp8720_matches[] = { 837 + { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, }, 838 + { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, }, 839 + { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, }, 840 + { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, }, 841 + { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, }, 842 + { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, }, 843 + }; 844 + 845 + static struct of_regulator_match lp8725_matches[] = { 846 + { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, }, 847 + { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, }, 848 + { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, }, 849 + { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, }, 850 + { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, }, 851 + { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, }, 852 + { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, }, 853 + { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, }, 854 + { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, }, 855 + }; 856 + 857 + static struct lp872x_platform_data 858 + *lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which) 859 + { 860 + struct device_node *np = dev->of_node; 861 + struct lp872x_platform_data *pdata; 862 + struct of_regulator_match *match; 863 + struct regulator_init_data *d; 864 + int num_matches; 865 + int count; 866 + int i; 867 + u8 dvs_state; 868 + 869 + pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); 870 + if (!pdata) 871 + goto out; 872 + 873 + of_property_read_u8(np, "ti,general-config", &pdata->general_config); 874 + if (of_find_property(np, "ti,update-config", NULL)) 875 + pdata->update_config = true; 876 + 877 + pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL); 878 + if (!pdata->dvs) 879 + goto out; 880 + 881 + pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0); 882 + of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel); 883 + of_property_read_u8(np, "ti,dvs-state", &dvs_state); 884 + pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW; 885 + 886 + if (of_get_child_count(np) == 0) 887 + goto out; 888 + 889 + switch (which) { 890 + case LP8720: 891 + match = lp8720_matches; 892 + num_matches = ARRAY_SIZE(lp8720_matches); 893 + break; 894 + case LP8725: 895 + match = lp8725_matches; 896 + num_matches = ARRAY_SIZE(lp8725_matches); 897 + break; 898 + default: 899 + goto out; 900 + } 901 + 902 + count = of_regulator_match(dev, np, match, num_matches); 903 + if (count <= 0) 904 + goto out; 905 + 906 + for (i = 0; i < num_matches; i++) { 907 + pdata->regulator_data[i].id = (int)match[i].driver_data; 908 + pdata->regulator_data[i].init_data = match[i].init_data; 909 + 910 + /* Operation mode configuration for buck/buck1/buck2 */ 911 + if (strncmp(match[i].name, "buck", 4)) 912 + continue; 913 + 914 + d = pdata->regulator_data[i].init_data; 915 + d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE; 916 + d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE; 917 + } 918 + out: 919 + return pdata; 920 + } 921 + #else 922 + static struct lp872x_platform_data 923 + *lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which) 924 + { 925 + return NULL; 926 + } 927 + #endif 928 + 835 929 static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 836 930 { 837 931 struct lp872x *lp; ··· 937 837 [LP8720] = LP8720_NUM_REGULATORS, 938 838 [LP8725] = LP8725_NUM_REGULATORS, 939 839 }; 840 + 841 + if (cl->dev.of_node) 842 + cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev, 843 + (enum lp872x_id)id->driver_data); 940 844 941 845 lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); 942 846 if (!lp) ··· 986 882 return 0; 987 883 } 988 884 885 + static const struct of_device_id lp872x_dt_ids[] = { 886 + { .compatible = "ti,lp8720", }, 887 + { .compatible = "ti,lp8725", }, 888 + { } 889 + }; 890 + MODULE_DEVICE_TABLE(of, lp872x_dt_ids); 891 + 989 892 static const struct i2c_device_id lp872x_ids[] = { 990 893 {"lp8720", LP8720}, 991 894 {"lp8725", LP8725}, ··· 1004 893 .driver = { 1005 894 .name = "lp872x", 1006 895 .owner = THIS_MODULE, 896 + .of_match_table = of_match_ptr(lp872x_dt_ids), 1007 897 }, 1008 898 .probe = lp872x_probe, 1009 899 .remove = lp872x_remove,