aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKim, Milo <Milo.Kim@ti.com>2013-05-20 08:36:07 -0400
committerMark Brown <broonie@opensource.wolfsonmicro.com>2013-05-20 19:13:44 -0400
commit00fd6e6153100ae868975cab67f02df6f16343eb (patch)
tree1e5f7364e9b9fe97342d32ee8cb302ef981f0a14
parentc7788792a5e7b0d5d7f96d0766b4cb6112d47d75 (diff)
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>
-rw-r--r--Documentation/devicetree/bindings/regulator/lp872x.txt160
-rw-r--r--drivers/regulator/lp872x.c116
2 files changed, 274 insertions, 2 deletions
diff --git a/Documentation/devicetree/bindings/regulator/lp872x.txt b/Documentation/devicetree/bindings/regulator/lp872x.txt
new file mode 100644
index 000000000000..78183182dad9
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/lp872x.txt
@@ -0,0 +1,160 @@
1Binding for TI/National Semiconductor LP872x Driver
2
3Required properties:
4 - compatible: "ti,lp8720" or "ti,lp8725"
5 - reg: I2C slave address. 0x7d = LP8720, 0x7a = LP8725
6
7Optional 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
38Datasheet
39 - LP8720: http://www.ti.com/lit/ds/symlink/lp8720.pdf
40 - LP8725: http://www.ti.com/lit/ds/symlink/lp8725.pdf
41
42Example 1) LP8720
43
44lp8720@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
94Example 2) LP8725
95
96lp8725@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};
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c
index f5fc4a142cdf..b16336bcd4d4 100644
--- a/drivers/regulator/lp872x.c
+++ b/drivers/regulator/lp872x.c
@@ -18,6 +18,9 @@
18#include <linux/regulator/lp872x.h> 18#include <linux/regulator/lp872x.h>
19#include <linux/regulator/driver.h> 19#include <linux/regulator/driver.h>
20#include <linux/platform_device.h> 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/* Registers : LP8720/8725 shared */ 25/* Registers : LP8720/8725 shared */
23#define LP872X_GENERAL_CFG 0x00 26#define LP872X_GENERAL_CFG 0x00
@@ -723,8 +726,8 @@ static int lp872x_init_dvs(struct lp872x *lp)
723 726
724 gpio = dvs->gpio; 727 gpio = dvs->gpio;
725 if (!gpio_is_valid(gpio)) { 728 if (!gpio_is_valid(gpio)) {
726 dev_err(lp->dev, "invalid gpio: %d\n", gpio); 729 dev_warn(lp->dev, "invalid gpio: %d\n", gpio);
727 return -EINVAL; 730 goto set_default_dvs_mode;
728 } 731 }
729 732
730 pinstate = dvs->init_state; 733 pinstate = dvs->init_state;
@@ -829,6 +832,103 @@ static const struct regmap_config lp872x_regmap_config = {
829 .max_register = MAX_REGISTERS, 832 .max_register = MAX_REGISTERS,
830}; 833};
831 834
835#ifdef CONFIG_OF
836
837#define LP872X_VALID_OPMODE (REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL)
838
839static struct of_regulator_match lp8720_matches[] = {
840 { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, },
841 { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, },
842 { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, },
843 { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, },
844 { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, },
845 { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, },
846};
847
848static struct of_regulator_match lp8725_matches[] = {
849 { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, },
850 { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, },
851 { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, },
852 { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, },
853 { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, },
854 { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, },
855 { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, },
856 { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, },
857 { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, },
858};
859
860static struct lp872x_platform_data
861*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
862{
863 struct device_node *np = dev->of_node;
864 struct lp872x_platform_data *pdata;
865 struct of_regulator_match *match;
866 struct regulator_init_data *d;
867 int num_matches;
868 int count;
869 int i;
870 u8 dvs_state;
871
872 pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
873 if (!pdata)
874 goto out;
875
876 of_property_read_u8(np, "ti,general-config", &pdata->general_config);
877 if (of_find_property(np, "ti,update-config", NULL))
878 pdata->update_config = true;
879
880 pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL);
881 if (!pdata->dvs)
882 goto out;
883
884 pdata->dvs->gpio = of_get_named_gpio(np, "ti,dvs-gpio", 0);
885 of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel);
886 of_property_read_u8(np, "ti,dvs-state", &dvs_state);
887 pdata->dvs->init_state = dvs_state ? DVS_HIGH : DVS_LOW;
888
889 if (of_get_child_count(np) == 0)
890 goto out;
891
892 switch (which) {
893 case LP8720:
894 match = lp8720_matches;
895 num_matches = ARRAY_SIZE(lp8720_matches);
896 break;
897 case LP8725:
898 match = lp8725_matches;
899 num_matches = ARRAY_SIZE(lp8725_matches);
900 break;
901 default:
902 goto out;
903 }
904
905 count = of_regulator_match(dev, np, match, num_matches);
906 if (count <= 0)
907 goto out;
908
909 for (i = 0; i < num_matches; i++) {
910 pdata->regulator_data[i].id = (int)match[i].driver_data;
911 pdata->regulator_data[i].init_data = match[i].init_data;
912
913 /* Operation mode configuration for buck/buck1/buck2 */
914 if (strncmp(match[i].name, "buck", 4))
915 continue;
916
917 d = pdata->regulator_data[i].init_data;
918 d->constraints.valid_modes_mask |= LP872X_VALID_OPMODE;
919 d->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
920 }
921out:
922 return pdata;
923}
924#else
925static struct lp872x_platform_data
926*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which)
927{
928 return NULL;
929}
930#endif
931
832static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id) 932static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
833{ 933{
834 struct lp872x *lp; 934 struct lp872x *lp;
@@ -838,6 +938,10 @@ static int lp872x_probe(struct i2c_client *cl, const struct i2c_device_id *id)
838 [LP8725] = LP8725_NUM_REGULATORS, 938 [LP8725] = LP8725_NUM_REGULATORS,
839 }; 939 };
840 940
941 if (cl->dev.of_node)
942 cl->dev.platform_data = lp872x_populate_pdata_from_dt(&cl->dev,
943 (enum lp872x_id)id->driver_data);
944
841 lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); 945 lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL);
842 if (!lp) 946 if (!lp)
843 goto err_mem; 947 goto err_mem;
@@ -882,6 +986,13 @@ static int lp872x_remove(struct i2c_client *cl)
882 return 0; 986 return 0;
883} 987}
884 988
989static const struct of_device_id lp872x_dt_ids[] = {
990 { .compatible = "ti,lp8720", },
991 { .compatible = "ti,lp8725", },
992 { }
993};
994MODULE_DEVICE_TABLE(of, lp872x_dt_ids);
995
885static const struct i2c_device_id lp872x_ids[] = { 996static const struct i2c_device_id lp872x_ids[] = {
886 {"lp8720", LP8720}, 997 {"lp8720", LP8720},
887 {"lp8725", LP8725}, 998 {"lp8725", LP8725},
@@ -893,6 +1004,7 @@ static struct i2c_driver lp872x_driver = {
893 .driver = { 1004 .driver = {
894 .name = "lp872x", 1005 .name = "lp872x",
895 .owner = THIS_MODULE, 1006 .owner = THIS_MODULE,
1007 .of_match_table = of_match_ptr(lp872x_dt_ids),
896 }, 1008 },
897 .probe = lp872x_probe, 1009 .probe = lp872x_probe,
898 .remove = lp872x_remove, 1010 .remove = lp872x_remove,