diff options
22 files changed, 1966 insertions, 176 deletions
diff --git a/Documentation/power/regulator/design.txt b/Documentation/power/regulator/design.txt new file mode 100644 index 000000000000..f9b56b72b782 --- /dev/null +++ b/Documentation/power/regulator/design.txt | |||
@@ -0,0 +1,33 @@ | |||
1 | Regulator API design notes | ||
2 | ========================== | ||
3 | |||
4 | This document provides a brief, partially structured, overview of some | ||
5 | of the design considerations which impact the regulator API design. | ||
6 | |||
7 | Safety | ||
8 | ------ | ||
9 | |||
10 | - Errors in regulator configuration can have very serious consequences | ||
11 | for the system, potentially including lasting hardware damage. | ||
12 | - It is not possible to automatically determine the power confugration | ||
13 | of the system - software-equivalent variants of the same chip may | ||
14 | have different power requirments, and not all components with power | ||
15 | requirements are visible to software. | ||
16 | |||
17 | => The API should make no changes to the hardware state unless it has | ||
18 | specific knowledge that these changes are safe to do perform on | ||
19 | this particular system. | ||
20 | |||
21 | Consumer use cases | ||
22 | ------------------ | ||
23 | |||
24 | - The overwhelming majority of devices in a system will have no | ||
25 | requirement to do any runtime configuration of their power beyond | ||
26 | being able to turn it on or off. | ||
27 | |||
28 | - Many of the power supplies in the system will be shared between many | ||
29 | different consumers. | ||
30 | |||
31 | => The consumer API should be structured so that these use cases are | ||
32 | very easy to handle and so that consumers will work with shared | ||
33 | supplies without any additional effort. | ||
diff --git a/Documentation/power/regulator/machine.txt b/Documentation/power/regulator/machine.txt index ce3487d99abe..63728fed620b 100644 --- a/Documentation/power/regulator/machine.txt +++ b/Documentation/power/regulator/machine.txt | |||
@@ -87,7 +87,7 @@ static struct platform_device regulator_devices[] = { | |||
87 | }, | 87 | }, |
88 | }; | 88 | }; |
89 | /* register regulator 1 device */ | 89 | /* register regulator 1 device */ |
90 | platform_device_register(&wm8350_regulator_devices[0]); | 90 | platform_device_register(®ulator_devices[0]); |
91 | 91 | ||
92 | /* register regulator 2 device */ | 92 | /* register regulator 2 device */ |
93 | platform_device_register(&wm8350_regulator_devices[1]); | 93 | platform_device_register(®ulator_devices[1]); |
diff --git a/Documentation/power/regulator/overview.txt b/Documentation/power/regulator/overview.txt index 0cded696ca01..ffd185bb6054 100644 --- a/Documentation/power/regulator/overview.txt +++ b/Documentation/power/regulator/overview.txt | |||
@@ -29,7 +29,7 @@ Some terms used in this document:- | |||
29 | 29 | ||
30 | 30 | ||
31 | o PMIC - Power Management IC. An IC that contains numerous regulators | 31 | o PMIC - Power Management IC. An IC that contains numerous regulators |
32 | and often contains other susbsystems. | 32 | and often contains other subsystems. |
33 | 33 | ||
34 | 34 | ||
35 | o Consumer - Electronic device that is supplied power by a regulator. | 35 | o Consumer - Electronic device that is supplied power by a regulator. |
@@ -168,4 +168,4 @@ relevant to non SoC devices and is split into the following four interfaces:- | |||
168 | userspace via sysfs. This could be used to help monitor device power | 168 | userspace via sysfs. This could be used to help monitor device power |
169 | consumption and status. | 169 | consumption and status. |
170 | 170 | ||
171 | See Documentation/ABI/testing/regulator-sysfs.txt | 171 | See Documentation/ABI/testing/sysfs-class-regulator |
diff --git a/Documentation/power/regulator/regulator.txt b/Documentation/power/regulator/regulator.txt index 4200accb9bba..3f8b528f237e 100644 --- a/Documentation/power/regulator/regulator.txt +++ b/Documentation/power/regulator/regulator.txt | |||
@@ -10,8 +10,9 @@ Registration | |||
10 | 10 | ||
11 | Drivers can register a regulator by calling :- | 11 | Drivers can register a regulator by calling :- |
12 | 12 | ||
13 | struct regulator_dev *regulator_register(struct device *dev, | 13 | struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, |
14 | struct regulator_desc *regulator_desc); | 14 | struct device *dev, struct regulator_init_data *init_data, |
15 | void *driver_data); | ||
15 | 16 | ||
16 | This will register the regulators capabilities and operations to the regulator | 17 | This will register the regulators capabilities and operations to the regulator |
17 | core. | 18 | core. |
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 2dc42bbf6fe9..bcbb161bde0b 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -1,6 +1,5 @@ | |||
1 | menuconfig REGULATOR | 1 | menuconfig REGULATOR |
2 | bool "Voltage and Current Regulator Support" | 2 | bool "Voltage and Current Regulator Support" |
3 | default n | ||
4 | help | 3 | help |
5 | Generic Voltage and Current Regulator support. | 4 | Generic Voltage and Current Regulator support. |
6 | 5 | ||
@@ -30,7 +29,6 @@ config REGULATOR_DEBUG | |||
30 | 29 | ||
31 | config REGULATOR_FIXED_VOLTAGE | 30 | config REGULATOR_FIXED_VOLTAGE |
32 | tristate "Fixed voltage regulator support" | 31 | tristate "Fixed voltage regulator support" |
33 | default n | ||
34 | help | 32 | help |
35 | This driver provides support for fixed voltage regulators, | 33 | This driver provides support for fixed voltage regulators, |
36 | useful for systems which use a combination of software | 34 | useful for systems which use a combination of software |
@@ -38,7 +36,6 @@ config REGULATOR_FIXED_VOLTAGE | |||
38 | 36 | ||
39 | config REGULATOR_VIRTUAL_CONSUMER | 37 | config REGULATOR_VIRTUAL_CONSUMER |
40 | tristate "Virtual regulator consumer support" | 38 | tristate "Virtual regulator consumer support" |
41 | default n | ||
42 | help | 39 | help |
43 | This driver provides a virtual consumer for the voltage and | 40 | This driver provides a virtual consumer for the voltage and |
44 | current regulator API which provides sysfs controls for | 41 | current regulator API which provides sysfs controls for |
@@ -49,17 +46,15 @@ config REGULATOR_VIRTUAL_CONSUMER | |||
49 | 46 | ||
50 | config REGULATOR_USERSPACE_CONSUMER | 47 | config REGULATOR_USERSPACE_CONSUMER |
51 | tristate "Userspace regulator consumer support" | 48 | tristate "Userspace regulator consumer support" |
52 | default n | ||
53 | help | 49 | help |
54 | There are some classes of devices that are controlled entirely | 50 | There are some classes of devices that are controlled entirely |
55 | from user space. Usersapce consumer driver provides ability to | 51 | from user space. Userspace consumer driver provides ability to |
56 | control power supplies for such devices. | 52 | control power supplies for such devices. |
57 | 53 | ||
58 | If unsure, say no. | 54 | If unsure, say no. |
59 | 55 | ||
60 | config REGULATOR_BQ24022 | 56 | config REGULATOR_BQ24022 |
61 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" | 57 | tristate "TI bq24022 Dual Input 1-Cell Li-Ion Charger IC" |
62 | default n | ||
63 | help | 58 | help |
64 | This driver controls a TI bq24022 Charger attached via | 59 | This driver controls a TI bq24022 Charger attached via |
65 | GPIOs. The provided current regulator can enable/disable | 60 | GPIOs. The provided current regulator can enable/disable |
@@ -69,7 +64,6 @@ config REGULATOR_BQ24022 | |||
69 | config REGULATOR_MAX1586 | 64 | config REGULATOR_MAX1586 |
70 | tristate "Maxim 1586/1587 voltage regulator" | 65 | tristate "Maxim 1586/1587 voltage regulator" |
71 | depends on I2C | 66 | depends on I2C |
72 | default n | ||
73 | help | 67 | help |
74 | This driver controls a Maxim 1586 or 1587 voltage output | 68 | This driver controls a Maxim 1586 or 1587 voltage output |
75 | regulator via I2C bus. The provided regulator is suitable | 69 | regulator via I2C bus. The provided regulator is suitable |
@@ -147,5 +141,21 @@ config REGULATOR_AB3100 | |||
147 | AB3100 analog baseband dealing with power regulators | 141 | AB3100 analog baseband dealing with power regulators |
148 | for the system. | 142 | for the system. |
149 | 143 | ||
144 | config REGULATOR_TPS65023 | ||
145 | tristate "TI TPS65023 Power regulators" | ||
146 | depends on I2C | ||
147 | help | ||
148 | This driver supports TPS65023 voltage regulator chips. TPS65023 provides | ||
149 | three step-down converters and two general-purpose LDO voltage regulators. | ||
150 | It supports TI's software based Class-2 SmartReflex implementation. | ||
151 | |||
152 | config REGULATOR_TPS6507X | ||
153 | tristate "TI TPS6507X Power regulators" | ||
154 | depends on I2C | ||
155 | help | ||
156 | This driver supports TPS6507X voltage regulator chips. TPS6507X provides | ||
157 | three step-down converters and two general-purpose LDO voltage regulators. | ||
158 | It supports TI's software based Class-2 SmartReflex implementation. | ||
159 | |||
150 | endif | 160 | endif |
151 | 161 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 768b3316d6eb..4257a8683778 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -23,4 +23,7 @@ obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | |||
23 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o | 23 | obj-$(CONFIG_REGULATOR_MC13783) += mc13783.o |
24 | obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o | 24 | obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o |
25 | 25 | ||
26 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o | ||
27 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o | ||
28 | |||
26 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG | 29 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 91ba9bfaa706..744ea1d0b59b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -37,7 +37,7 @@ static int has_full_constraints; | |||
37 | */ | 37 | */ |
38 | struct regulator_map { | 38 | struct regulator_map { |
39 | struct list_head list; | 39 | struct list_head list; |
40 | struct device *dev; | 40 | const char *dev_name; /* The dev_name() for the consumer */ |
41 | const char *supply; | 41 | const char *supply; |
42 | struct regulator_dev *regulator; | 42 | struct regulator_dev *regulator; |
43 | }; | 43 | }; |
@@ -232,7 +232,7 @@ static ssize_t regulator_name_show(struct device *dev, | |||
232 | struct regulator_dev *rdev = dev_get_drvdata(dev); | 232 | struct regulator_dev *rdev = dev_get_drvdata(dev); |
233 | const char *name; | 233 | const char *name; |
234 | 234 | ||
235 | if (rdev->constraints->name) | 235 | if (rdev->constraints && rdev->constraints->name) |
236 | name = rdev->constraints->name; | 236 | name = rdev->constraints->name; |
237 | else if (rdev->desc->name) | 237 | else if (rdev->desc->name) |
238 | name = rdev->desc->name; | 238 | name = rdev->desc->name; |
@@ -280,8 +280,13 @@ static ssize_t regulator_state_show(struct device *dev, | |||
280 | struct device_attribute *attr, char *buf) | 280 | struct device_attribute *attr, char *buf) |
281 | { | 281 | { |
282 | struct regulator_dev *rdev = dev_get_drvdata(dev); | 282 | struct regulator_dev *rdev = dev_get_drvdata(dev); |
283 | ssize_t ret; | ||
284 | |||
285 | mutex_lock(&rdev->mutex); | ||
286 | ret = regulator_print_state(buf, _regulator_is_enabled(rdev)); | ||
287 | mutex_unlock(&rdev->mutex); | ||
283 | 288 | ||
284 | return regulator_print_state(buf, _regulator_is_enabled(rdev)); | 289 | return ret; |
285 | } | 290 | } |
286 | static DEVICE_ATTR(state, 0444, regulator_state_show, NULL); | 291 | static DEVICE_ATTR(state, 0444, regulator_state_show, NULL); |
287 | 292 | ||
@@ -857,23 +862,39 @@ out: | |||
857 | * set_consumer_device_supply: Bind a regulator to a symbolic supply | 862 | * set_consumer_device_supply: Bind a regulator to a symbolic supply |
858 | * @rdev: regulator source | 863 | * @rdev: regulator source |
859 | * @consumer_dev: device the supply applies to | 864 | * @consumer_dev: device the supply applies to |
865 | * @consumer_dev_name: dev_name() string for device supply applies to | ||
860 | * @supply: symbolic name for supply | 866 | * @supply: symbolic name for supply |
861 | * | 867 | * |
862 | * Allows platform initialisation code to map physical regulator | 868 | * Allows platform initialisation code to map physical regulator |
863 | * sources to symbolic names for supplies for use by devices. Devices | 869 | * sources to symbolic names for supplies for use by devices. Devices |
864 | * should use these symbolic names to request regulators, avoiding the | 870 | * should use these symbolic names to request regulators, avoiding the |
865 | * need to provide board-specific regulator names as platform data. | 871 | * need to provide board-specific regulator names as platform data. |
872 | * | ||
873 | * Only one of consumer_dev and consumer_dev_name may be specified. | ||
866 | */ | 874 | */ |
867 | static int set_consumer_device_supply(struct regulator_dev *rdev, | 875 | static int set_consumer_device_supply(struct regulator_dev *rdev, |
868 | struct device *consumer_dev, const char *supply) | 876 | struct device *consumer_dev, const char *consumer_dev_name, |
877 | const char *supply) | ||
869 | { | 878 | { |
870 | struct regulator_map *node; | 879 | struct regulator_map *node; |
880 | int has_dev; | ||
881 | |||
882 | if (consumer_dev && consumer_dev_name) | ||
883 | return -EINVAL; | ||
884 | |||
885 | if (!consumer_dev_name && consumer_dev) | ||
886 | consumer_dev_name = dev_name(consumer_dev); | ||
871 | 887 | ||
872 | if (supply == NULL) | 888 | if (supply == NULL) |
873 | return -EINVAL; | 889 | return -EINVAL; |
874 | 890 | ||
891 | if (consumer_dev_name != NULL) | ||
892 | has_dev = 1; | ||
893 | else | ||
894 | has_dev = 0; | ||
895 | |||
875 | list_for_each_entry(node, ®ulator_map_list, list) { | 896 | list_for_each_entry(node, ®ulator_map_list, list) { |
876 | if (consumer_dev != node->dev) | 897 | if (consumer_dev_name != node->dev_name) |
877 | continue; | 898 | continue; |
878 | if (strcmp(node->supply, supply) != 0) | 899 | if (strcmp(node->supply, supply) != 0) |
879 | continue; | 900 | continue; |
@@ -886,30 +907,45 @@ static int set_consumer_device_supply(struct regulator_dev *rdev, | |||
886 | return -EBUSY; | 907 | return -EBUSY; |
887 | } | 908 | } |
888 | 909 | ||
889 | node = kmalloc(sizeof(struct regulator_map), GFP_KERNEL); | 910 | node = kzalloc(sizeof(struct regulator_map), GFP_KERNEL); |
890 | if (node == NULL) | 911 | if (node == NULL) |
891 | return -ENOMEM; | 912 | return -ENOMEM; |
892 | 913 | ||
893 | node->regulator = rdev; | 914 | node->regulator = rdev; |
894 | node->dev = consumer_dev; | ||
895 | node->supply = supply; | 915 | node->supply = supply; |
896 | 916 | ||
917 | if (has_dev) { | ||
918 | node->dev_name = kstrdup(consumer_dev_name, GFP_KERNEL); | ||
919 | if (node->dev_name == NULL) { | ||
920 | kfree(node); | ||
921 | return -ENOMEM; | ||
922 | } | ||
923 | } | ||
924 | |||
897 | list_add(&node->list, ®ulator_map_list); | 925 | list_add(&node->list, ®ulator_map_list); |
898 | return 0; | 926 | return 0; |
899 | } | 927 | } |
900 | 928 | ||
901 | static void unset_consumer_device_supply(struct regulator_dev *rdev, | 929 | static void unset_consumer_device_supply(struct regulator_dev *rdev, |
902 | struct device *consumer_dev) | 930 | const char *consumer_dev_name, struct device *consumer_dev) |
903 | { | 931 | { |
904 | struct regulator_map *node, *n; | 932 | struct regulator_map *node, *n; |
905 | 933 | ||
934 | if (consumer_dev && !consumer_dev_name) | ||
935 | consumer_dev_name = dev_name(consumer_dev); | ||
936 | |||
906 | list_for_each_entry_safe(node, n, ®ulator_map_list, list) { | 937 | list_for_each_entry_safe(node, n, ®ulator_map_list, list) { |
907 | if (rdev == node->regulator && | 938 | if (rdev != node->regulator) |
908 | consumer_dev == node->dev) { | 939 | continue; |
909 | list_del(&node->list); | 940 | |
910 | kfree(node); | 941 | if (consumer_dev_name && node->dev_name && |
911 | return; | 942 | strcmp(consumer_dev_name, node->dev_name)) |
912 | } | 943 | continue; |
944 | |||
945 | list_del(&node->list); | ||
946 | kfree(node->dev_name); | ||
947 | kfree(node); | ||
948 | return; | ||
913 | } | 949 | } |
914 | } | 950 | } |
915 | 951 | ||
@@ -920,6 +956,7 @@ static void unset_regulator_supplies(struct regulator_dev *rdev) | |||
920 | list_for_each_entry_safe(node, n, ®ulator_map_list, list) { | 956 | list_for_each_entry_safe(node, n, ®ulator_map_list, list) { |
921 | if (rdev == node->regulator) { | 957 | if (rdev == node->regulator) { |
922 | list_del(&node->list); | 958 | list_del(&node->list); |
959 | kfree(node->dev_name); | ||
923 | kfree(node); | 960 | kfree(node); |
924 | return; | 961 | return; |
925 | } | 962 | } |
@@ -1001,35 +1038,33 @@ overflow_err: | |||
1001 | return NULL; | 1038 | return NULL; |
1002 | } | 1039 | } |
1003 | 1040 | ||
1004 | /** | 1041 | /* Internal regulator request function */ |
1005 | * regulator_get - lookup and obtain a reference to a regulator. | 1042 | static struct regulator *_regulator_get(struct device *dev, const char *id, |
1006 | * @dev: device for regulator "consumer" | 1043 | int exclusive) |
1007 | * @id: Supply name or regulator ID. | ||
1008 | * | ||
1009 | * Returns a struct regulator corresponding to the regulator producer, | ||
1010 | * or IS_ERR() condition containing errno. | ||
1011 | * | ||
1012 | * Use of supply names configured via regulator_set_device_supply() is | ||
1013 | * strongly encouraged. It is recommended that the supply name used | ||
1014 | * should match the name used for the supply and/or the relevant | ||
1015 | * device pins in the datasheet. | ||
1016 | */ | ||
1017 | struct regulator *regulator_get(struct device *dev, const char *id) | ||
1018 | { | 1044 | { |
1019 | struct regulator_dev *rdev; | 1045 | struct regulator_dev *rdev; |
1020 | struct regulator_map *map; | 1046 | struct regulator_map *map; |
1021 | struct regulator *regulator = ERR_PTR(-ENODEV); | 1047 | struct regulator *regulator = ERR_PTR(-ENODEV); |
1048 | const char *devname = NULL; | ||
1049 | int ret; | ||
1022 | 1050 | ||
1023 | if (id == NULL) { | 1051 | if (id == NULL) { |
1024 | printk(KERN_ERR "regulator: get() with no identifier\n"); | 1052 | printk(KERN_ERR "regulator: get() with no identifier\n"); |
1025 | return regulator; | 1053 | return regulator; |
1026 | } | 1054 | } |
1027 | 1055 | ||
1056 | if (dev) | ||
1057 | devname = dev_name(dev); | ||
1058 | |||
1028 | mutex_lock(®ulator_list_mutex); | 1059 | mutex_lock(®ulator_list_mutex); |
1029 | 1060 | ||
1030 | list_for_each_entry(map, ®ulator_map_list, list) { | 1061 | list_for_each_entry(map, ®ulator_map_list, list) { |
1031 | if (dev == map->dev && | 1062 | /* If the mapping has a device set up it must match */ |
1032 | strcmp(map->supply, id) == 0) { | 1063 | if (map->dev_name && |
1064 | (!devname || strcmp(map->dev_name, devname))) | ||
1065 | continue; | ||
1066 | |||
1067 | if (strcmp(map->supply, id) == 0) { | ||
1033 | rdev = map->regulator; | 1068 | rdev = map->regulator; |
1034 | goto found; | 1069 | goto found; |
1035 | } | 1070 | } |
@@ -1038,6 +1073,16 @@ struct regulator *regulator_get(struct device *dev, const char *id) | |||
1038 | return regulator; | 1073 | return regulator; |
1039 | 1074 | ||
1040 | found: | 1075 | found: |
1076 | if (rdev->exclusive) { | ||
1077 | regulator = ERR_PTR(-EPERM); | ||
1078 | goto out; | ||
1079 | } | ||
1080 | |||
1081 | if (exclusive && rdev->open_count) { | ||
1082 | regulator = ERR_PTR(-EBUSY); | ||
1083 | goto out; | ||
1084 | } | ||
1085 | |||
1041 | if (!try_module_get(rdev->owner)) | 1086 | if (!try_module_get(rdev->owner)) |
1042 | goto out; | 1087 | goto out; |
1043 | 1088 | ||
@@ -1047,13 +1092,70 @@ found: | |||
1047 | module_put(rdev->owner); | 1092 | module_put(rdev->owner); |
1048 | } | 1093 | } |
1049 | 1094 | ||
1095 | rdev->open_count++; | ||
1096 | if (exclusive) { | ||
1097 | rdev->exclusive = 1; | ||
1098 | |||
1099 | ret = _regulator_is_enabled(rdev); | ||
1100 | if (ret > 0) | ||
1101 | rdev->use_count = 1; | ||
1102 | else | ||
1103 | rdev->use_count = 0; | ||
1104 | } | ||
1105 | |||
1050 | out: | 1106 | out: |
1051 | mutex_unlock(®ulator_list_mutex); | 1107 | mutex_unlock(®ulator_list_mutex); |
1108 | |||
1052 | return regulator; | 1109 | return regulator; |
1053 | } | 1110 | } |
1111 | |||
1112 | /** | ||
1113 | * regulator_get - lookup and obtain a reference to a regulator. | ||
1114 | * @dev: device for regulator "consumer" | ||
1115 | * @id: Supply name or regulator ID. | ||
1116 | * | ||
1117 | * Returns a struct regulator corresponding to the regulator producer, | ||
1118 | * or IS_ERR() condition containing errno. | ||
1119 | * | ||
1120 | * Use of supply names configured via regulator_set_device_supply() is | ||
1121 | * strongly encouraged. It is recommended that the supply name used | ||
1122 | * should match the name used for the supply and/or the relevant | ||
1123 | * device pins in the datasheet. | ||
1124 | */ | ||
1125 | struct regulator *regulator_get(struct device *dev, const char *id) | ||
1126 | { | ||
1127 | return _regulator_get(dev, id, 0); | ||
1128 | } | ||
1054 | EXPORT_SYMBOL_GPL(regulator_get); | 1129 | EXPORT_SYMBOL_GPL(regulator_get); |
1055 | 1130 | ||
1056 | /** | 1131 | /** |
1132 | * regulator_get_exclusive - obtain exclusive access to a regulator. | ||
1133 | * @dev: device for regulator "consumer" | ||
1134 | * @id: Supply name or regulator ID. | ||
1135 | * | ||
1136 | * Returns a struct regulator corresponding to the regulator producer, | ||
1137 | * or IS_ERR() condition containing errno. Other consumers will be | ||
1138 | * unable to obtain this reference is held and the use count for the | ||
1139 | * regulator will be initialised to reflect the current state of the | ||
1140 | * regulator. | ||
1141 | * | ||
1142 | * This is intended for use by consumers which cannot tolerate shared | ||
1143 | * use of the regulator such as those which need to force the | ||
1144 | * regulator off for correct operation of the hardware they are | ||
1145 | * controlling. | ||
1146 | * | ||
1147 | * Use of supply names configured via regulator_set_device_supply() is | ||
1148 | * strongly encouraged. It is recommended that the supply name used | ||
1149 | * should match the name used for the supply and/or the relevant | ||
1150 | * device pins in the datasheet. | ||
1151 | */ | ||
1152 | struct regulator *regulator_get_exclusive(struct device *dev, const char *id) | ||
1153 | { | ||
1154 | return _regulator_get(dev, id, 1); | ||
1155 | } | ||
1156 | EXPORT_SYMBOL_GPL(regulator_get_exclusive); | ||
1157 | |||
1158 | /** | ||
1057 | * regulator_put - "free" the regulator source | 1159 | * regulator_put - "free" the regulator source |
1058 | * @regulator: regulator source | 1160 | * @regulator: regulator source |
1059 | * | 1161 | * |
@@ -1081,21 +1183,29 @@ void regulator_put(struct regulator *regulator) | |||
1081 | list_del(®ulator->list); | 1183 | list_del(®ulator->list); |
1082 | kfree(regulator); | 1184 | kfree(regulator); |
1083 | 1185 | ||
1186 | rdev->open_count--; | ||
1187 | rdev->exclusive = 0; | ||
1188 | |||
1084 | module_put(rdev->owner); | 1189 | module_put(rdev->owner); |
1085 | mutex_unlock(®ulator_list_mutex); | 1190 | mutex_unlock(®ulator_list_mutex); |
1086 | } | 1191 | } |
1087 | EXPORT_SYMBOL_GPL(regulator_put); | 1192 | EXPORT_SYMBOL_GPL(regulator_put); |
1088 | 1193 | ||
1194 | static int _regulator_can_change_status(struct regulator_dev *rdev) | ||
1195 | { | ||
1196 | if (!rdev->constraints) | ||
1197 | return 0; | ||
1198 | |||
1199 | if (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_STATUS) | ||
1200 | return 1; | ||
1201 | else | ||
1202 | return 0; | ||
1203 | } | ||
1204 | |||
1089 | /* locks held by regulator_enable() */ | 1205 | /* locks held by regulator_enable() */ |
1090 | static int _regulator_enable(struct regulator_dev *rdev) | 1206 | static int _regulator_enable(struct regulator_dev *rdev) |
1091 | { | 1207 | { |
1092 | int ret = -EINVAL; | 1208 | int ret; |
1093 | |||
1094 | if (!rdev->constraints) { | ||
1095 | printk(KERN_ERR "%s: %s has no constraints\n", | ||
1096 | __func__, rdev->desc->name); | ||
1097 | return ret; | ||
1098 | } | ||
1099 | 1209 | ||
1100 | /* do we need to enable the supply regulator first */ | 1210 | /* do we need to enable the supply regulator first */ |
1101 | if (rdev->supply) { | 1211 | if (rdev->supply) { |
@@ -1108,24 +1218,35 @@ static int _regulator_enable(struct regulator_dev *rdev) | |||
1108 | } | 1218 | } |
1109 | 1219 | ||
1110 | /* check voltage and requested load before enabling */ | 1220 | /* check voltage and requested load before enabling */ |
1111 | if (rdev->desc->ops->enable) { | 1221 | if (rdev->constraints && |
1112 | 1222 | (rdev->constraints->valid_ops_mask & REGULATOR_CHANGE_DRMS)) | |
1113 | if (rdev->constraints && | 1223 | drms_uA_update(rdev); |
1114 | (rdev->constraints->valid_ops_mask & | 1224 | |
1115 | REGULATOR_CHANGE_DRMS)) | 1225 | if (rdev->use_count == 0) { |
1116 | drms_uA_update(rdev); | 1226 | /* The regulator may on if it's not switchable or left on */ |
1117 | 1227 | ret = _regulator_is_enabled(rdev); | |
1118 | ret = rdev->desc->ops->enable(rdev); | 1228 | if (ret == -EINVAL || ret == 0) { |
1119 | if (ret < 0) { | 1229 | if (!_regulator_can_change_status(rdev)) |
1120 | printk(KERN_ERR "%s: failed to enable %s: %d\n", | 1230 | return -EPERM; |
1231 | |||
1232 | if (rdev->desc->ops->enable) { | ||
1233 | ret = rdev->desc->ops->enable(rdev); | ||
1234 | if (ret < 0) | ||
1235 | return ret; | ||
1236 | } else { | ||
1237 | return -EINVAL; | ||
1238 | } | ||
1239 | } else if (ret < 0) { | ||
1240 | printk(KERN_ERR "%s: is_enabled() failed for %s: %d\n", | ||
1121 | __func__, rdev->desc->name, ret); | 1241 | __func__, rdev->desc->name, ret); |
1122 | return ret; | 1242 | return ret; |
1123 | } | 1243 | } |
1124 | rdev->use_count++; | 1244 | /* Fallthrough on positive return values - already enabled */ |
1125 | return ret; | ||
1126 | } | 1245 | } |
1127 | 1246 | ||
1128 | return ret; | 1247 | rdev->use_count++; |
1248 | |||
1249 | return 0; | ||
1129 | } | 1250 | } |
1130 | 1251 | ||
1131 | /** | 1252 | /** |
@@ -1165,7 +1286,8 @@ static int _regulator_disable(struct regulator_dev *rdev) | |||
1165 | if (rdev->use_count == 1 && !rdev->constraints->always_on) { | 1286 | if (rdev->use_count == 1 && !rdev->constraints->always_on) { |
1166 | 1287 | ||
1167 | /* we are last user */ | 1288 | /* we are last user */ |
1168 | if (rdev->desc->ops->disable) { | 1289 | if (_regulator_can_change_status(rdev) && |
1290 | rdev->desc->ops->disable) { | ||
1169 | ret = rdev->desc->ops->disable(rdev); | 1291 | ret = rdev->desc->ops->disable(rdev); |
1170 | if (ret < 0) { | 1292 | if (ret < 0) { |
1171 | printk(KERN_ERR "%s: failed to disable %s\n", | 1293 | printk(KERN_ERR "%s: failed to disable %s\n", |
@@ -1265,20 +1387,11 @@ EXPORT_SYMBOL_GPL(regulator_force_disable); | |||
1265 | 1387 | ||
1266 | static int _regulator_is_enabled(struct regulator_dev *rdev) | 1388 | static int _regulator_is_enabled(struct regulator_dev *rdev) |
1267 | { | 1389 | { |
1268 | int ret; | ||
1269 | |||
1270 | mutex_lock(&rdev->mutex); | ||
1271 | |||
1272 | /* sanity check */ | 1390 | /* sanity check */ |
1273 | if (!rdev->desc->ops->is_enabled) { | 1391 | if (!rdev->desc->ops->is_enabled) |
1274 | ret = -EINVAL; | 1392 | return -EINVAL; |
1275 | goto out; | ||
1276 | } | ||
1277 | 1393 | ||
1278 | ret = rdev->desc->ops->is_enabled(rdev); | 1394 | return rdev->desc->ops->is_enabled(rdev); |
1279 | out: | ||
1280 | mutex_unlock(&rdev->mutex); | ||
1281 | return ret; | ||
1282 | } | 1395 | } |
1283 | 1396 | ||
1284 | /** | 1397 | /** |
@@ -1295,7 +1408,13 @@ out: | |||
1295 | */ | 1408 | */ |
1296 | int regulator_is_enabled(struct regulator *regulator) | 1409 | int regulator_is_enabled(struct regulator *regulator) |
1297 | { | 1410 | { |
1298 | return _regulator_is_enabled(regulator->rdev); | 1411 | int ret; |
1412 | |||
1413 | mutex_lock(®ulator->rdev->mutex); | ||
1414 | ret = _regulator_is_enabled(regulator->rdev); | ||
1415 | mutex_unlock(®ulator->rdev->mutex); | ||
1416 | |||
1417 | return ret; | ||
1299 | } | 1418 | } |
1300 | EXPORT_SYMBOL_GPL(regulator_is_enabled); | 1419 | EXPORT_SYMBOL_GPL(regulator_is_enabled); |
1301 | 1420 | ||
@@ -1350,6 +1469,35 @@ int regulator_list_voltage(struct regulator *regulator, unsigned selector) | |||
1350 | EXPORT_SYMBOL_GPL(regulator_list_voltage); | 1469 | EXPORT_SYMBOL_GPL(regulator_list_voltage); |
1351 | 1470 | ||
1352 | /** | 1471 | /** |
1472 | * regulator_is_supported_voltage - check if a voltage range can be supported | ||
1473 | * | ||
1474 | * @regulator: Regulator to check. | ||
1475 | * @min_uV: Minimum required voltage in uV. | ||
1476 | * @max_uV: Maximum required voltage in uV. | ||
1477 | * | ||
1478 | * Returns a boolean or a negative error code. | ||
1479 | */ | ||
1480 | int regulator_is_supported_voltage(struct regulator *regulator, | ||
1481 | int min_uV, int max_uV) | ||
1482 | { | ||
1483 | int i, voltages, ret; | ||
1484 | |||
1485 | ret = regulator_count_voltages(regulator); | ||
1486 | if (ret < 0) | ||
1487 | return ret; | ||
1488 | voltages = ret; | ||
1489 | |||
1490 | for (i = 0; i < voltages; i++) { | ||
1491 | ret = regulator_list_voltage(regulator, i); | ||
1492 | |||
1493 | if (ret >= min_uV && ret <= max_uV) | ||
1494 | return 1; | ||
1495 | } | ||
1496 | |||
1497 | return 0; | ||
1498 | } | ||
1499 | |||
1500 | /** | ||
1353 | * regulator_set_voltage - set regulator output voltage | 1501 | * regulator_set_voltage - set regulator output voltage |
1354 | * @regulator: regulator source | 1502 | * @regulator: regulator source |
1355 | * @min_uV: Minimum required voltage in uV | 1503 | * @min_uV: Minimum required voltage in uV |
@@ -2091,11 +2239,13 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, | |||
2091 | for (i = 0; i < init_data->num_consumer_supplies; i++) { | 2239 | for (i = 0; i < init_data->num_consumer_supplies; i++) { |
2092 | ret = set_consumer_device_supply(rdev, | 2240 | ret = set_consumer_device_supply(rdev, |
2093 | init_data->consumer_supplies[i].dev, | 2241 | init_data->consumer_supplies[i].dev, |
2242 | init_data->consumer_supplies[i].dev_name, | ||
2094 | init_data->consumer_supplies[i].supply); | 2243 | init_data->consumer_supplies[i].supply); |
2095 | if (ret < 0) { | 2244 | if (ret < 0) { |
2096 | for (--i; i >= 0; i--) | 2245 | for (--i; i >= 0; i--) |
2097 | unset_consumer_device_supply(rdev, | 2246 | unset_consumer_device_supply(rdev, |
2098 | init_data->consumer_supplies[i].dev); | 2247 | init_data->consumer_supplies[i].dev_name, |
2248 | init_data->consumer_supplies[i].dev); | ||
2099 | goto scrub; | 2249 | goto scrub; |
2100 | } | 2250 | } |
2101 | } | 2251 | } |
@@ -2130,6 +2280,7 @@ void regulator_unregister(struct regulator_dev *rdev) | |||
2130 | return; | 2280 | return; |
2131 | 2281 | ||
2132 | mutex_lock(®ulator_list_mutex); | 2282 | mutex_lock(®ulator_list_mutex); |
2283 | WARN_ON(rdev->open_count); | ||
2133 | unset_regulator_supplies(rdev); | 2284 | unset_regulator_supplies(rdev); |
2134 | list_del(&rdev->list); | 2285 | list_del(&rdev->list); |
2135 | if (rdev->supply) | 2286 | if (rdev->supply) |
@@ -2277,14 +2428,14 @@ static int __init regulator_init_complete(void) | |||
2277 | ops = rdev->desc->ops; | 2428 | ops = rdev->desc->ops; |
2278 | c = rdev->constraints; | 2429 | c = rdev->constraints; |
2279 | 2430 | ||
2280 | if (c->name) | 2431 | if (c && c->name) |
2281 | name = c->name; | 2432 | name = c->name; |
2282 | else if (rdev->desc->name) | 2433 | else if (rdev->desc->name) |
2283 | name = rdev->desc->name; | 2434 | name = rdev->desc->name; |
2284 | else | 2435 | else |
2285 | name = "regulator"; | 2436 | name = "regulator"; |
2286 | 2437 | ||
2287 | if (!ops->disable || c->always_on) | 2438 | if (!ops->disable || (c && c->always_on)) |
2288 | continue; | 2439 | continue; |
2289 | 2440 | ||
2290 | mutex_lock(&rdev->mutex); | 2441 | mutex_lock(&rdev->mutex); |
diff --git a/drivers/regulator/da903x.c b/drivers/regulator/da903x.c index b8b89ef10a84..aa224d936e0d 100644 --- a/drivers/regulator/da903x.c +++ b/drivers/regulator/da903x.c | |||
@@ -64,6 +64,14 @@ | |||
64 | #define DA9034_MDTV2 (0x33) | 64 | #define DA9034_MDTV2 (0x33) |
65 | #define DA9034_MVRC (0x34) | 65 | #define DA9034_MVRC (0x34) |
66 | 66 | ||
67 | /* DA9035 Registers. DA9034 Registers are comptabile to DA9035. */ | ||
68 | #define DA9035_OVER3 (0x12) | ||
69 | #define DA9035_VCC2 (0x1f) | ||
70 | #define DA9035_3DTV1 (0x2c) | ||
71 | #define DA9035_3DTV2 (0x2d) | ||
72 | #define DA9035_3VRC (0x2e) | ||
73 | #define DA9035_AUTOSKIP (0x2f) | ||
74 | |||
67 | struct da903x_regulator_info { | 75 | struct da903x_regulator_info { |
68 | struct regulator_desc desc; | 76 | struct regulator_desc desc; |
69 | 77 | ||
@@ -79,6 +87,10 @@ struct da903x_regulator_info { | |||
79 | int enable_bit; | 87 | int enable_bit; |
80 | }; | 88 | }; |
81 | 89 | ||
90 | static int da9034_ldo12_data[] = { 1700, 1750, 1800, 1850, 1900, 1950, | ||
91 | 2000, 2050, 2700, 2750, 2800, 2850, | ||
92 | 2900, 2950, 3000, 3050 }; | ||
93 | |||
82 | static inline struct device *to_da903x_dev(struct regulator_dev *rdev) | 94 | static inline struct device *to_da903x_dev(struct regulator_dev *rdev) |
83 | { | 95 | { |
84 | return rdev_get_dev(rdev)->parent->parent; | 96 | return rdev_get_dev(rdev)->parent->parent; |
@@ -162,6 +174,17 @@ static int da903x_is_enabled(struct regulator_dev *rdev) | |||
162 | return !!(reg_val & (1 << info->enable_bit)); | 174 | return !!(reg_val & (1 << info->enable_bit)); |
163 | } | 175 | } |
164 | 176 | ||
177 | static int da903x_list_voltage(struct regulator_dev *rdev, unsigned selector) | ||
178 | { | ||
179 | struct da903x_regulator_info *info = rdev_get_drvdata(rdev); | ||
180 | int ret; | ||
181 | |||
182 | ret = info->min_uV + info->step_uV * selector; | ||
183 | if (ret > info->max_uV) | ||
184 | return -EINVAL; | ||
185 | return ret; | ||
186 | } | ||
187 | |||
165 | /* DA9030 specific operations */ | 188 | /* DA9030 specific operations */ |
166 | static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, | 189 | static int da9030_set_ldo1_15_voltage(struct regulator_dev *rdev, |
167 | int min_uV, int max_uV) | 190 | int min_uV, int max_uV) |
@@ -278,7 +301,7 @@ static int da9034_set_ldo12_voltage(struct regulator_dev *rdev, | |||
278 | } | 301 | } |
279 | 302 | ||
280 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; | 303 | val = (min_uV - info->min_uV + info->step_uV - 1) / info->step_uV; |
281 | val = (val > 7 || val < 20) ? 8 : val - 12; | 304 | val = (val >= 20) ? val - 12 : ((val > 7) ? 8 : val); |
282 | val <<= info->vol_shift; | 305 | val <<= info->vol_shift; |
283 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; | 306 | mask = ((1 << info->vol_nbits) - 1) << info->vol_shift; |
284 | 307 | ||
@@ -305,9 +328,18 @@ static int da9034_get_ldo12_voltage(struct regulator_dev *rdev) | |||
305 | return info->min_uV + info->step_uV * val; | 328 | return info->min_uV + info->step_uV * val; |
306 | } | 329 | } |
307 | 330 | ||
331 | static int da9034_list_ldo12_voltage(struct regulator_dev *rdev, | ||
332 | unsigned selector) | ||
333 | { | ||
334 | if (selector > ARRAY_SIZE(da9034_ldo12_data)) | ||
335 | return -EINVAL; | ||
336 | return da9034_ldo12_data[selector] * 1000; | ||
337 | } | ||
338 | |||
308 | static struct regulator_ops da903x_regulator_ldo_ops = { | 339 | static struct regulator_ops da903x_regulator_ldo_ops = { |
309 | .set_voltage = da903x_set_ldo_voltage, | 340 | .set_voltage = da903x_set_ldo_voltage, |
310 | .get_voltage = da903x_get_voltage, | 341 | .get_voltage = da903x_get_voltage, |
342 | .list_voltage = da903x_list_voltage, | ||
311 | .enable = da903x_enable, | 343 | .enable = da903x_enable, |
312 | .disable = da903x_disable, | 344 | .disable = da903x_disable, |
313 | .is_enabled = da903x_is_enabled, | 345 | .is_enabled = da903x_is_enabled, |
@@ -317,6 +349,7 @@ static struct regulator_ops da903x_regulator_ldo_ops = { | |||
317 | static struct regulator_ops da9030_regulator_ldo14_ops = { | 349 | static struct regulator_ops da9030_regulator_ldo14_ops = { |
318 | .set_voltage = da9030_set_ldo14_voltage, | 350 | .set_voltage = da9030_set_ldo14_voltage, |
319 | .get_voltage = da9030_get_ldo14_voltage, | 351 | .get_voltage = da9030_get_ldo14_voltage, |
352 | .list_voltage = da903x_list_voltage, | ||
320 | .enable = da903x_enable, | 353 | .enable = da903x_enable, |
321 | .disable = da903x_disable, | 354 | .disable = da903x_disable, |
322 | .is_enabled = da903x_is_enabled, | 355 | .is_enabled = da903x_is_enabled, |
@@ -326,6 +359,7 @@ static struct regulator_ops da9030_regulator_ldo14_ops = { | |||
326 | static struct regulator_ops da9030_regulator_ldo1_15_ops = { | 359 | static struct regulator_ops da9030_regulator_ldo1_15_ops = { |
327 | .set_voltage = da9030_set_ldo1_15_voltage, | 360 | .set_voltage = da9030_set_ldo1_15_voltage, |
328 | .get_voltage = da903x_get_voltage, | 361 | .get_voltage = da903x_get_voltage, |
362 | .list_voltage = da903x_list_voltage, | ||
329 | .enable = da903x_enable, | 363 | .enable = da903x_enable, |
330 | .disable = da903x_disable, | 364 | .disable = da903x_disable, |
331 | .is_enabled = da903x_is_enabled, | 365 | .is_enabled = da903x_is_enabled, |
@@ -334,6 +368,7 @@ static struct regulator_ops da9030_regulator_ldo1_15_ops = { | |||
334 | static struct regulator_ops da9034_regulator_dvc_ops = { | 368 | static struct regulator_ops da9034_regulator_dvc_ops = { |
335 | .set_voltage = da9034_set_dvc_voltage, | 369 | .set_voltage = da9034_set_dvc_voltage, |
336 | .get_voltage = da903x_get_voltage, | 370 | .get_voltage = da903x_get_voltage, |
371 | .list_voltage = da903x_list_voltage, | ||
337 | .enable = da903x_enable, | 372 | .enable = da903x_enable, |
338 | .disable = da903x_disable, | 373 | .disable = da903x_disable, |
339 | .is_enabled = da903x_is_enabled, | 374 | .is_enabled = da903x_is_enabled, |
@@ -343,6 +378,7 @@ static struct regulator_ops da9034_regulator_dvc_ops = { | |||
343 | static struct regulator_ops da9034_regulator_ldo12_ops = { | 378 | static struct regulator_ops da9034_regulator_ldo12_ops = { |
344 | .set_voltage = da9034_set_ldo12_voltage, | 379 | .set_voltage = da9034_set_ldo12_voltage, |
345 | .get_voltage = da9034_get_ldo12_voltage, | 380 | .get_voltage = da9034_get_ldo12_voltage, |
381 | .list_voltage = da9034_list_ldo12_voltage, | ||
346 | .enable = da903x_enable, | 382 | .enable = da903x_enable, |
347 | .disable = da903x_disable, | 383 | .disable = da903x_disable, |
348 | .is_enabled = da903x_is_enabled, | 384 | .is_enabled = da903x_is_enabled, |
@@ -355,6 +391,7 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { | |||
355 | .ops = &da903x_regulator_ldo_ops, \ | 391 | .ops = &da903x_regulator_ldo_ops, \ |
356 | .type = REGULATOR_VOLTAGE, \ | 392 | .type = REGULATOR_VOLTAGE, \ |
357 | .id = _pmic##_ID_LDO##_id, \ | 393 | .id = _pmic##_ID_LDO##_id, \ |
394 | .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ | ||
358 | .owner = THIS_MODULE, \ | 395 | .owner = THIS_MODULE, \ |
359 | }, \ | 396 | }, \ |
360 | .min_uV = (min) * 1000, \ | 397 | .min_uV = (min) * 1000, \ |
@@ -367,24 +404,25 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { | |||
367 | .enable_bit = (ebit), \ | 404 | .enable_bit = (ebit), \ |
368 | } | 405 | } |
369 | 406 | ||
370 | #define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ | 407 | #define DA903x_DVC(_pmic, _id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ |
371 | { \ | 408 | { \ |
372 | .desc = { \ | 409 | .desc = { \ |
373 | .name = #_id, \ | 410 | .name = #_id, \ |
374 | .ops = &da9034_regulator_dvc_ops, \ | 411 | .ops = &da9034_regulator_dvc_ops, \ |
375 | .type = REGULATOR_VOLTAGE, \ | 412 | .type = REGULATOR_VOLTAGE, \ |
376 | .id = DA9034_ID_##_id, \ | 413 | .id = _pmic##_ID_##_id, \ |
414 | .n_voltages = (step) ? ((max - min) / step + 1) : 1, \ | ||
377 | .owner = THIS_MODULE, \ | 415 | .owner = THIS_MODULE, \ |
378 | }, \ | 416 | }, \ |
379 | .min_uV = (min) * 1000, \ | 417 | .min_uV = (min) * 1000, \ |
380 | .max_uV = (max) * 1000, \ | 418 | .max_uV = (max) * 1000, \ |
381 | .step_uV = (step) * 1000, \ | 419 | .step_uV = (step) * 1000, \ |
382 | .vol_reg = DA9034_##vreg, \ | 420 | .vol_reg = _pmic##_##vreg, \ |
383 | .vol_shift = (0), \ | 421 | .vol_shift = (0), \ |
384 | .vol_nbits = (nbits), \ | 422 | .vol_nbits = (nbits), \ |
385 | .update_reg = DA9034_##ureg, \ | 423 | .update_reg = _pmic##_##ureg, \ |
386 | .update_bit = (ubit), \ | 424 | .update_bit = (ubit), \ |
387 | .enable_reg = DA9034_##ereg, \ | 425 | .enable_reg = _pmic##_##ereg, \ |
388 | .enable_bit = (ebit), \ | 426 | .enable_bit = (ebit), \ |
389 | } | 427 | } |
390 | 428 | ||
@@ -394,8 +432,22 @@ static struct regulator_ops da9034_regulator_ldo12_ops = { | |||
394 | #define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ | 432 | #define DA9030_LDO(_id, min, max, step, vreg, shift, nbits, ereg, ebit) \ |
395 | DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit) | 433 | DA903x_LDO(DA9030, _id, min, max, step, vreg, shift, nbits, ereg, ebit) |
396 | 434 | ||
435 | #define DA9030_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ | ||
436 | DA903x_DVC(DA9030, _id, min, max, step, vreg, nbits, ureg, ubit, \ | ||
437 | ereg, ebit) | ||
438 | |||
439 | #define DA9034_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ | ||
440 | DA903x_DVC(DA9034, _id, min, max, step, vreg, nbits, ureg, ubit, \ | ||
441 | ereg, ebit) | ||
442 | |||
443 | #define DA9035_DVC(_id, min, max, step, vreg, nbits, ureg, ubit, ereg, ebit) \ | ||
444 | DA903x_DVC(DA9035, _id, min, max, step, vreg, nbits, ureg, ubit, \ | ||
445 | ereg, ebit) | ||
446 | |||
397 | static struct da903x_regulator_info da903x_regulator_info[] = { | 447 | static struct da903x_regulator_info da903x_regulator_info[] = { |
398 | /* DA9030 */ | 448 | /* DA9030 */ |
449 | DA9030_DVC(BUCK2, 850, 1625, 25, BUCK2DVM1, 5, BUCK2DVM1, 7, RCTL11, 0), | ||
450 | |||
399 | DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1), | 451 | DA9030_LDO( 1, 1200, 3200, 100, LDO1, 0, 5, RCTL12, 1), |
400 | DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2), | 452 | DA9030_LDO( 2, 1800, 3200, 100, LDO23, 0, 4, RCTL12, 2), |
401 | DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3), | 453 | DA9030_LDO( 3, 1800, 3200, 100, LDO23, 4, 4, RCTL12, 3), |
@@ -417,9 +469,9 @@ static struct da903x_regulator_info da903x_regulator_info[] = { | |||
417 | DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */ | 469 | DA9030_LDO(13, 2100, 2100, 0, INVAL, 0, 0, RCTL11, 3), /* fixed @2.1V */ |
418 | 470 | ||
419 | /* DA9034 */ | 471 | /* DA9034 */ |
420 | DA9034_DVC(BUCK1, 725, 1500, 25, ADTV1, 5, VCC1, 0, OVER1, 0), | 472 | DA9034_DVC(BUCK1, 725, 1500, 25, ADTV2, 5, VCC1, 0, OVER1, 0), |
421 | DA9034_DVC(BUCK2, 725, 1500, 25, CDTV1, 5, VCC1, 2, OVER1, 1), | 473 | DA9034_DVC(BUCK2, 725, 1500, 25, CDTV2, 5, VCC1, 2, OVER1, 1), |
422 | DA9034_DVC(LDO2, 725, 1500, 25, SDTV1, 5, VCC1, 4, OVER1, 2), | 474 | DA9034_DVC(LDO2, 725, 1500, 25, SDTV2, 5, VCC1, 4, OVER1, 2), |
423 | DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4), | 475 | DA9034_DVC(LDO1, 1700, 2075, 25, MDTV1, 4, VCC1, 6, OVER3, 4), |
424 | 476 | ||
425 | DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5), | 477 | DA9034_LDO( 3, 1800, 3300, 100, LDO643, 0, 4, OVER3, 5), |
@@ -435,6 +487,9 @@ static struct da903x_regulator_info da903x_regulator_info[] = { | |||
435 | DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0), | 487 | DA9034_LDO(14, 1800, 3300, 100, LDO1514, 0, 4, OVER3, 0), |
436 | DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1), | 488 | DA9034_LDO(15, 1800, 3300, 100, LDO1514, 4, 4, OVER3, 1), |
437 | DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */ | 489 | DA9034_LDO(5, 3100, 3100, 0, INVAL, 0, 0, OVER3, 7), /* fixed @3.1V */ |
490 | |||
491 | /* DA9035 */ | ||
492 | DA9035_DVC(BUCK3, 1800, 2200, 100, 3DTV1, 3, VCC2, 0, OVER3, 3), | ||
438 | }; | 493 | }; |
439 | 494 | ||
440 | static inline struct da903x_regulator_info *find_regulator_info(int id) | 495 | static inline struct da903x_regulator_info *find_regulator_info(int id) |
@@ -462,8 +517,10 @@ static int __devinit da903x_regulator_probe(struct platform_device *pdev) | |||
462 | } | 517 | } |
463 | 518 | ||
464 | /* Workaround for the weird LDO12 voltage setting */ | 519 | /* Workaround for the weird LDO12 voltage setting */ |
465 | if (ri->desc.id == DA9034_ID_LDO12) | 520 | if (ri->desc.id == DA9034_ID_LDO12) { |
466 | ri->desc.ops = &da9034_regulator_ldo12_ops; | 521 | ri->desc.ops = &da9034_regulator_ldo12_ops; |
522 | ri->desc.n_voltages = ARRAY_SIZE(da9034_ldo12_data); | ||
523 | } | ||
467 | 524 | ||
468 | if (ri->desc.id == DA9030_ID_LDO14) | 525 | if (ri->desc.id == DA9030_ID_LDO14) |
469 | ri->desc.ops = &da9030_regulator_ldo14_ops; | 526 | ri->desc.ops = &da9030_regulator_ldo14_ops; |
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index cdc674fb46c3..f8b295700d7d 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c | |||
@@ -5,6 +5,9 @@ | |||
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
8 | * Copyright (c) 2009 Nokia Corporation | ||
9 | * Roger Quadros <ext-roger.quadros@nokia.com> | ||
10 | * | ||
8 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
10 | * published by the Free Software Foundation; either version 2 of the | 13 | * published by the Free Software Foundation; either version 2 of the |
@@ -20,20 +23,45 @@ | |||
20 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
21 | #include <linux/regulator/driver.h> | 24 | #include <linux/regulator/driver.h> |
22 | #include <linux/regulator/fixed.h> | 25 | #include <linux/regulator/fixed.h> |
26 | #include <linux/gpio.h> | ||
23 | 27 | ||
24 | struct fixed_voltage_data { | 28 | struct fixed_voltage_data { |
25 | struct regulator_desc desc; | 29 | struct regulator_desc desc; |
26 | struct regulator_dev *dev; | 30 | struct regulator_dev *dev; |
27 | int microvolts; | 31 | int microvolts; |
32 | int gpio; | ||
33 | unsigned enable_high:1; | ||
34 | unsigned is_enabled:1; | ||
28 | }; | 35 | }; |
29 | 36 | ||
30 | static int fixed_voltage_is_enabled(struct regulator_dev *dev) | 37 | static int fixed_voltage_is_enabled(struct regulator_dev *dev) |
31 | { | 38 | { |
32 | return 1; | 39 | struct fixed_voltage_data *data = rdev_get_drvdata(dev); |
40 | |||
41 | return data->is_enabled; | ||
33 | } | 42 | } |
34 | 43 | ||
35 | static int fixed_voltage_enable(struct regulator_dev *dev) | 44 | static int fixed_voltage_enable(struct regulator_dev *dev) |
36 | { | 45 | { |
46 | struct fixed_voltage_data *data = rdev_get_drvdata(dev); | ||
47 | |||
48 | if (gpio_is_valid(data->gpio)) { | ||
49 | gpio_set_value_cansleep(data->gpio, data->enable_high); | ||
50 | data->is_enabled = 1; | ||
51 | } | ||
52 | |||
53 | return 0; | ||
54 | } | ||
55 | |||
56 | static int fixed_voltage_disable(struct regulator_dev *dev) | ||
57 | { | ||
58 | struct fixed_voltage_data *data = rdev_get_drvdata(dev); | ||
59 | |||
60 | if (gpio_is_valid(data->gpio)) { | ||
61 | gpio_set_value_cansleep(data->gpio, !data->enable_high); | ||
62 | data->is_enabled = 0; | ||
63 | } | ||
64 | |||
37 | return 0; | 65 | return 0; |
38 | } | 66 | } |
39 | 67 | ||
@@ -58,6 +86,7 @@ static int fixed_voltage_list_voltage(struct regulator_dev *dev, | |||
58 | static struct regulator_ops fixed_voltage_ops = { | 86 | static struct regulator_ops fixed_voltage_ops = { |
59 | .is_enabled = fixed_voltage_is_enabled, | 87 | .is_enabled = fixed_voltage_is_enabled, |
60 | .enable = fixed_voltage_enable, | 88 | .enable = fixed_voltage_enable, |
89 | .disable = fixed_voltage_disable, | ||
61 | .get_voltage = fixed_voltage_get_voltage, | 90 | .get_voltage = fixed_voltage_get_voltage, |
62 | .list_voltage = fixed_voltage_list_voltage, | 91 | .list_voltage = fixed_voltage_list_voltage, |
63 | }; | 92 | }; |
@@ -70,12 +99,14 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) | |||
70 | 99 | ||
71 | drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL); | 100 | drvdata = kzalloc(sizeof(struct fixed_voltage_data), GFP_KERNEL); |
72 | if (drvdata == NULL) { | 101 | if (drvdata == NULL) { |
102 | dev_err(&pdev->dev, "Failed to allocate device data\n"); | ||
73 | ret = -ENOMEM; | 103 | ret = -ENOMEM; |
74 | goto err; | 104 | goto err; |
75 | } | 105 | } |
76 | 106 | ||
77 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); | 107 | drvdata->desc.name = kstrdup(config->supply_name, GFP_KERNEL); |
78 | if (drvdata->desc.name == NULL) { | 108 | if (drvdata->desc.name == NULL) { |
109 | dev_err(&pdev->dev, "Failed to allocate supply name\n"); | ||
79 | ret = -ENOMEM; | 110 | ret = -ENOMEM; |
80 | goto err; | 111 | goto err; |
81 | } | 112 | } |
@@ -85,12 +116,62 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) | |||
85 | drvdata->desc.n_voltages = 1; | 116 | drvdata->desc.n_voltages = 1; |
86 | 117 | ||
87 | drvdata->microvolts = config->microvolts; | 118 | drvdata->microvolts = config->microvolts; |
119 | drvdata->gpio = config->gpio; | ||
120 | |||
121 | if (gpio_is_valid(config->gpio)) { | ||
122 | drvdata->enable_high = config->enable_high; | ||
123 | |||
124 | /* FIXME: Remove below print warning | ||
125 | * | ||
126 | * config->gpio must be set to -EINVAL by platform code if | ||
127 | * GPIO control is not required. However, early adopters | ||
128 | * not requiring GPIO control may forget to initialize | ||
129 | * config->gpio to -EINVAL. This will cause GPIO 0 to be used | ||
130 | * for GPIO control. | ||
131 | * | ||
132 | * This warning will be removed once there are a couple of users | ||
133 | * for this driver. | ||
134 | */ | ||
135 | if (!config->gpio) | ||
136 | dev_warn(&pdev->dev, | ||
137 | "using GPIO 0 for regulator enable control\n"); | ||
138 | |||
139 | ret = gpio_request(config->gpio, config->supply_name); | ||
140 | if (ret) { | ||
141 | dev_err(&pdev->dev, | ||
142 | "Could not obtain regulator enable GPIO %d: %d\n", | ||
143 | config->gpio, ret); | ||
144 | goto err_name; | ||
145 | } | ||
146 | |||
147 | /* set output direction without changing state | ||
148 | * to prevent glitch | ||
149 | */ | ||
150 | drvdata->is_enabled = config->enabled_at_boot; | ||
151 | ret = drvdata->is_enabled ? | ||
152 | config->enable_high : !config->enable_high; | ||
153 | |||
154 | ret = gpio_direction_output(config->gpio, ret); | ||
155 | if (ret) { | ||
156 | dev_err(&pdev->dev, | ||
157 | "Could not configure regulator enable GPIO %d direction: %d\n", | ||
158 | config->gpio, ret); | ||
159 | goto err_gpio; | ||
160 | } | ||
161 | |||
162 | } else { | ||
163 | /* Regulator without GPIO control is considered | ||
164 | * always enabled | ||
165 | */ | ||
166 | drvdata->is_enabled = 1; | ||
167 | } | ||
88 | 168 | ||
89 | drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, | 169 | drvdata->dev = regulator_register(&drvdata->desc, &pdev->dev, |
90 | config->init_data, drvdata); | 170 | config->init_data, drvdata); |
91 | if (IS_ERR(drvdata->dev)) { | 171 | if (IS_ERR(drvdata->dev)) { |
92 | ret = PTR_ERR(drvdata->dev); | 172 | ret = PTR_ERR(drvdata->dev); |
93 | goto err_name; | 173 | dev_err(&pdev->dev, "Failed to register regulator: %d\n", ret); |
174 | goto err_gpio; | ||
94 | } | 175 | } |
95 | 176 | ||
96 | platform_set_drvdata(pdev, drvdata); | 177 | platform_set_drvdata(pdev, drvdata); |
@@ -100,6 +181,9 @@ static int regulator_fixed_voltage_probe(struct platform_device *pdev) | |||
100 | 181 | ||
101 | return 0; | 182 | return 0; |
102 | 183 | ||
184 | err_gpio: | ||
185 | if (gpio_is_valid(config->gpio)) | ||
186 | gpio_free(config->gpio); | ||
103 | err_name: | 187 | err_name: |
104 | kfree(drvdata->desc.name); | 188 | kfree(drvdata->desc.name); |
105 | err: | 189 | err: |
@@ -115,6 +199,9 @@ static int regulator_fixed_voltage_remove(struct platform_device *pdev) | |||
115 | kfree(drvdata->desc.name); | 199 | kfree(drvdata->desc.name); |
116 | kfree(drvdata); | 200 | kfree(drvdata); |
117 | 201 | ||
202 | if (gpio_is_valid(drvdata->gpio)) | ||
203 | gpio_free(drvdata->gpio); | ||
204 | |||
118 | return 0; | 205 | return 0; |
119 | } | 206 | } |
120 | 207 | ||
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index a61018a27698..7803a320543b 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
@@ -541,7 +541,7 @@ static struct i2c_driver lp3971_i2c_driver = { | |||
541 | 541 | ||
542 | static int __init lp3971_module_init(void) | 542 | static int __init lp3971_module_init(void) |
543 | { | 543 | { |
544 | int ret = -ENODEV; | 544 | int ret; |
545 | 545 | ||
546 | ret = i2c_add_driver(&lp3971_i2c_driver); | 546 | ret = i2c_add_driver(&lp3971_i2c_driver); |
547 | if (ret != 0) | 547 | if (ret != 0) |
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c index 8e14900eb686..0803ffe6236d 100644 --- a/drivers/regulator/pcf50633-regulator.c +++ b/drivers/regulator/pcf50633-regulator.c | |||
@@ -24,11 +24,12 @@ | |||
24 | #include <linux/mfd/pcf50633/core.h> | 24 | #include <linux/mfd/pcf50633/core.h> |
25 | #include <linux/mfd/pcf50633/pmic.h> | 25 | #include <linux/mfd/pcf50633/pmic.h> |
26 | 26 | ||
27 | #define PCF50633_REGULATOR(_name, _id) \ | 27 | #define PCF50633_REGULATOR(_name, _id, _n) \ |
28 | { \ | 28 | { \ |
29 | .name = _name, \ | 29 | .name = _name, \ |
30 | .id = _id, \ | 30 | .id = _id, \ |
31 | .ops = &pcf50633_regulator_ops, \ | 31 | .ops = &pcf50633_regulator_ops, \ |
32 | .n_voltages = _n, \ | ||
32 | .type = REGULATOR_VOLTAGE, \ | 33 | .type = REGULATOR_VOLTAGE, \ |
33 | .owner = THIS_MODULE, \ | 34 | .owner = THIS_MODULE, \ |
34 | } | 35 | } |
@@ -149,33 +150,20 @@ static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev, | |||
149 | return pcf50633_reg_write(pcf, regnr, volt_bits); | 150 | return pcf50633_reg_write(pcf, regnr, volt_bits); |
150 | } | 151 | } |
151 | 152 | ||
152 | static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) | 153 | static int pcf50633_regulator_voltage_value(enum pcf50633_regulator_id id, |
154 | u8 bits) | ||
153 | { | 155 | { |
154 | struct pcf50633 *pcf; | 156 | int millivolts; |
155 | int regulator_id, millivolts, volt_bits; | ||
156 | u8 regnr; | ||
157 | |||
158 | pcf = rdev_get_drvdata(rdev);; | ||
159 | 157 | ||
160 | regulator_id = rdev_get_id(rdev); | 158 | switch (id) { |
161 | if (regulator_id >= PCF50633_NUM_REGULATORS) | ||
162 | return -EINVAL; | ||
163 | |||
164 | regnr = pcf50633_regulator_registers[regulator_id]; | ||
165 | |||
166 | volt_bits = pcf50633_reg_read(pcf, regnr); | ||
167 | if (volt_bits < 0) | ||
168 | return -1; | ||
169 | |||
170 | switch (regulator_id) { | ||
171 | case PCF50633_REGULATOR_AUTO: | 159 | case PCF50633_REGULATOR_AUTO: |
172 | millivolts = auto_voltage_value(volt_bits); | 160 | millivolts = auto_voltage_value(bits); |
173 | break; | 161 | break; |
174 | case PCF50633_REGULATOR_DOWN1: | 162 | case PCF50633_REGULATOR_DOWN1: |
175 | millivolts = down_voltage_value(volt_bits); | 163 | millivolts = down_voltage_value(bits); |
176 | break; | 164 | break; |
177 | case PCF50633_REGULATOR_DOWN2: | 165 | case PCF50633_REGULATOR_DOWN2: |
178 | millivolts = down_voltage_value(volt_bits); | 166 | millivolts = down_voltage_value(bits); |
179 | break; | 167 | break; |
180 | case PCF50633_REGULATOR_LDO1: | 168 | case PCF50633_REGULATOR_LDO1: |
181 | case PCF50633_REGULATOR_LDO2: | 169 | case PCF50633_REGULATOR_LDO2: |
@@ -184,7 +172,7 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) | |||
184 | case PCF50633_REGULATOR_LDO5: | 172 | case PCF50633_REGULATOR_LDO5: |
185 | case PCF50633_REGULATOR_LDO6: | 173 | case PCF50633_REGULATOR_LDO6: |
186 | case PCF50633_REGULATOR_HCLDO: | 174 | case PCF50633_REGULATOR_HCLDO: |
187 | millivolts = ldo_voltage_value(volt_bits); | 175 | millivolts = ldo_voltage_value(bits); |
188 | break; | 176 | break; |
189 | default: | 177 | default: |
190 | return -EINVAL; | 178 | return -EINVAL; |
@@ -193,6 +181,49 @@ static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) | |||
193 | return millivolts * 1000; | 181 | return millivolts * 1000; |
194 | } | 182 | } |
195 | 183 | ||
184 | static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev) | ||
185 | { | ||
186 | struct pcf50633 *pcf; | ||
187 | int regulator_id; | ||
188 | u8 volt_bits, regnr; | ||
189 | |||
190 | pcf = rdev_get_drvdata(rdev); | ||
191 | |||
192 | regulator_id = rdev_get_id(rdev); | ||
193 | if (regulator_id >= PCF50633_NUM_REGULATORS) | ||
194 | return -EINVAL; | ||
195 | |||
196 | regnr = pcf50633_regulator_registers[regulator_id]; | ||
197 | |||
198 | volt_bits = pcf50633_reg_read(pcf, regnr); | ||
199 | |||
200 | return pcf50633_regulator_voltage_value(regulator_id, volt_bits); | ||
201 | } | ||
202 | |||
203 | static int pcf50633_regulator_list_voltage(struct regulator_dev *rdev, | ||
204 | unsigned int index) | ||
205 | { | ||
206 | struct pcf50633 *pcf; | ||
207 | int regulator_id; | ||
208 | |||
209 | pcf = rdev_get_drvdata(rdev); | ||
210 | |||
211 | regulator_id = rdev_get_id(rdev); | ||
212 | |||
213 | switch (regulator_id) { | ||
214 | case PCF50633_REGULATOR_AUTO: | ||
215 | index += 0x2f; | ||
216 | break; | ||
217 | case PCF50633_REGULATOR_HCLDO: | ||
218 | index += 0x01; | ||
219 | break; | ||
220 | default: | ||
221 | break; | ||
222 | } | ||
223 | |||
224 | return pcf50633_regulator_voltage_value(regulator_id, index); | ||
225 | } | ||
226 | |||
196 | static int pcf50633_regulator_enable(struct regulator_dev *rdev) | 227 | static int pcf50633_regulator_enable(struct regulator_dev *rdev) |
197 | { | 228 | { |
198 | struct pcf50633 *pcf = rdev_get_drvdata(rdev); | 229 | struct pcf50633 *pcf = rdev_get_drvdata(rdev); |
@@ -246,6 +277,7 @@ static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev) | |||
246 | static struct regulator_ops pcf50633_regulator_ops = { | 277 | static struct regulator_ops pcf50633_regulator_ops = { |
247 | .set_voltage = pcf50633_regulator_set_voltage, | 278 | .set_voltage = pcf50633_regulator_set_voltage, |
248 | .get_voltage = pcf50633_regulator_get_voltage, | 279 | .get_voltage = pcf50633_regulator_get_voltage, |
280 | .list_voltage = pcf50633_regulator_list_voltage, | ||
249 | .enable = pcf50633_regulator_enable, | 281 | .enable = pcf50633_regulator_enable, |
250 | .disable = pcf50633_regulator_disable, | 282 | .disable = pcf50633_regulator_disable, |
251 | .is_enabled = pcf50633_regulator_is_enabled, | 283 | .is_enabled = pcf50633_regulator_is_enabled, |
@@ -253,27 +285,27 @@ static struct regulator_ops pcf50633_regulator_ops = { | |||
253 | 285 | ||
254 | static struct regulator_desc regulators[] = { | 286 | static struct regulator_desc regulators[] = { |
255 | [PCF50633_REGULATOR_AUTO] = | 287 | [PCF50633_REGULATOR_AUTO] = |
256 | PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO), | 288 | PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO, 80), |
257 | [PCF50633_REGULATOR_DOWN1] = | 289 | [PCF50633_REGULATOR_DOWN1] = |
258 | PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1), | 290 | PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1, 95), |
259 | [PCF50633_REGULATOR_DOWN2] = | 291 | [PCF50633_REGULATOR_DOWN2] = |
260 | PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2), | 292 | PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2, 95), |
261 | [PCF50633_REGULATOR_LDO1] = | 293 | [PCF50633_REGULATOR_LDO1] = |
262 | PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1), | 294 | PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1, 27), |
263 | [PCF50633_REGULATOR_LDO2] = | 295 | [PCF50633_REGULATOR_LDO2] = |
264 | PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2), | 296 | PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2, 27), |
265 | [PCF50633_REGULATOR_LDO3] = | 297 | [PCF50633_REGULATOR_LDO3] = |
266 | PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3), | 298 | PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3, 27), |
267 | [PCF50633_REGULATOR_LDO4] = | 299 | [PCF50633_REGULATOR_LDO4] = |
268 | PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4), | 300 | PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4, 27), |
269 | [PCF50633_REGULATOR_LDO5] = | 301 | [PCF50633_REGULATOR_LDO5] = |
270 | PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5), | 302 | PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5, 27), |
271 | [PCF50633_REGULATOR_LDO6] = | 303 | [PCF50633_REGULATOR_LDO6] = |
272 | PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6), | 304 | PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6, 27), |
273 | [PCF50633_REGULATOR_HCLDO] = | 305 | [PCF50633_REGULATOR_HCLDO] = |
274 | PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO), | 306 | PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO, 26), |
275 | [PCF50633_REGULATOR_MEMLDO] = | 307 | [PCF50633_REGULATOR_MEMLDO] = |
276 | PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO), | 308 | PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO, 0), |
277 | }; | 309 | }; |
278 | 310 | ||
279 | static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) | 311 | static int __devinit pcf50633_regulator_probe(struct platform_device *pdev) |
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c new file mode 100644 index 000000000000..07fda0a75adf --- /dev/null +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -0,0 +1,632 @@ | |||
1 | /* | ||
2 | * tps65023-regulator.c | ||
3 | * | ||
4 | * Supports TPS65023 Regulator | ||
5 | * | ||
6 | * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
13 | * whether express or implied; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/regulator/driver.h> | ||
24 | #include <linux/regulator/machine.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/delay.h> | ||
27 | |||
28 | /* Register definitions */ | ||
29 | #define TPS65023_REG_VERSION 0 | ||
30 | #define TPS65023_REG_PGOODZ 1 | ||
31 | #define TPS65023_REG_MASK 2 | ||
32 | #define TPS65023_REG_REG_CTRL 3 | ||
33 | #define TPS65023_REG_CON_CTRL 4 | ||
34 | #define TPS65023_REG_CON_CTRL2 5 | ||
35 | #define TPS65023_REG_DEF_CORE 6 | ||
36 | #define TPS65023_REG_DEFSLEW 7 | ||
37 | #define TPS65023_REG_LDO_CTRL 8 | ||
38 | |||
39 | /* PGOODZ bitfields */ | ||
40 | #define TPS65023_PGOODZ_PWRFAILZ BIT(7) | ||
41 | #define TPS65023_PGOODZ_LOWBATTZ BIT(6) | ||
42 | #define TPS65023_PGOODZ_VDCDC1 BIT(5) | ||
43 | #define TPS65023_PGOODZ_VDCDC2 BIT(4) | ||
44 | #define TPS65023_PGOODZ_VDCDC3 BIT(3) | ||
45 | #define TPS65023_PGOODZ_LDO2 BIT(2) | ||
46 | #define TPS65023_PGOODZ_LDO1 BIT(1) | ||
47 | |||
48 | /* MASK bitfields */ | ||
49 | #define TPS65023_MASK_PWRFAILZ BIT(7) | ||
50 | #define TPS65023_MASK_LOWBATTZ BIT(6) | ||
51 | #define TPS65023_MASK_VDCDC1 BIT(5) | ||
52 | #define TPS65023_MASK_VDCDC2 BIT(4) | ||
53 | #define TPS65023_MASK_VDCDC3 BIT(3) | ||
54 | #define TPS65023_MASK_LDO2 BIT(2) | ||
55 | #define TPS65023_MASK_LDO1 BIT(1) | ||
56 | |||
57 | /* REG_CTRL bitfields */ | ||
58 | #define TPS65023_REG_CTRL_VDCDC1_EN BIT(5) | ||
59 | #define TPS65023_REG_CTRL_VDCDC2_EN BIT(4) | ||
60 | #define TPS65023_REG_CTRL_VDCDC3_EN BIT(3) | ||
61 | #define TPS65023_REG_CTRL_LDO2_EN BIT(2) | ||
62 | #define TPS65023_REG_CTRL_LDO1_EN BIT(1) | ||
63 | |||
64 | /* LDO_CTRL bitfields */ | ||
65 | #define TPS65023_LDO_CTRL_LDOx_SHIFT(ldo_id) ((ldo_id)*4) | ||
66 | #define TPS65023_LDO_CTRL_LDOx_MASK(ldo_id) (0xF0 >> ((ldo_id)*4)) | ||
67 | |||
68 | /* Number of step-down converters available */ | ||
69 | #define TPS65023_NUM_DCDC 3 | ||
70 | /* Number of LDO voltage regulators available */ | ||
71 | #define TPS65023_NUM_LDO 2 | ||
72 | /* Number of total regulators available */ | ||
73 | #define TPS65023_NUM_REGULATOR (TPS65023_NUM_DCDC + TPS65023_NUM_LDO) | ||
74 | |||
75 | /* DCDCs */ | ||
76 | #define TPS65023_DCDC_1 0 | ||
77 | #define TPS65023_DCDC_2 1 | ||
78 | #define TPS65023_DCDC_3 2 | ||
79 | /* LDOs */ | ||
80 | #define TPS65023_LDO_1 3 | ||
81 | #define TPS65023_LDO_2 4 | ||
82 | |||
83 | #define TPS65023_MAX_REG_ID TPS65023_LDO_2 | ||
84 | |||
85 | /* Supported voltage values for regulators */ | ||
86 | static const u16 VDCDC1_VSEL_table[] = { | ||
87 | 800, 825, 850, 875, | ||
88 | 900, 925, 950, 975, | ||
89 | 1000, 1025, 1050, 1075, | ||
90 | 1100, 1125, 1150, 1175, | ||
91 | 1200, 1225, 1250, 1275, | ||
92 | 1300, 1325, 1350, 1375, | ||
93 | 1400, 1425, 1450, 1475, | ||
94 | 1500, 1525, 1550, 1600, | ||
95 | }; | ||
96 | |||
97 | static const u16 LDO1_VSEL_table[] = { | ||
98 | 1000, 1100, 1300, 1800, | ||
99 | 2200, 2600, 2800, 3150, | ||
100 | }; | ||
101 | |||
102 | static const u16 LDO2_VSEL_table[] = { | ||
103 | 1050, 1200, 1300, 1800, | ||
104 | 2500, 2800, 3000, 3300, | ||
105 | }; | ||
106 | |||
107 | static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDC1_VSEL_table), | ||
108 | 0, 0, ARRAY_SIZE(LDO1_VSEL_table), | ||
109 | ARRAY_SIZE(LDO2_VSEL_table)}; | ||
110 | |||
111 | /* Regulator specific details */ | ||
112 | struct tps_info { | ||
113 | const char *name; | ||
114 | unsigned min_uV; | ||
115 | unsigned max_uV; | ||
116 | bool fixed; | ||
117 | u8 table_len; | ||
118 | const u16 *table; | ||
119 | }; | ||
120 | |||
121 | /* PMIC details */ | ||
122 | struct tps_pmic { | ||
123 | struct regulator_desc desc[TPS65023_NUM_REGULATOR]; | ||
124 | struct i2c_client *client; | ||
125 | struct regulator_dev *rdev[TPS65023_NUM_REGULATOR]; | ||
126 | const struct tps_info *info[TPS65023_NUM_REGULATOR]; | ||
127 | struct mutex io_lock; | ||
128 | }; | ||
129 | |||
130 | static inline int tps_65023_read(struct tps_pmic *tps, u8 reg) | ||
131 | { | ||
132 | return i2c_smbus_read_byte_data(tps->client, reg); | ||
133 | } | ||
134 | |||
135 | static inline int tps_65023_write(struct tps_pmic *tps, u8 reg, u8 val) | ||
136 | { | ||
137 | return i2c_smbus_write_byte_data(tps->client, reg, val); | ||
138 | } | ||
139 | |||
140 | static int tps_65023_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) | ||
141 | { | ||
142 | int err, data; | ||
143 | |||
144 | mutex_lock(&tps->io_lock); | ||
145 | |||
146 | data = tps_65023_read(tps, reg); | ||
147 | if (data < 0) { | ||
148 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
149 | err = data; | ||
150 | goto out; | ||
151 | } | ||
152 | |||
153 | data |= mask; | ||
154 | err = tps_65023_write(tps, reg, data); | ||
155 | if (err) | ||
156 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
157 | |||
158 | out: | ||
159 | mutex_unlock(&tps->io_lock); | ||
160 | return err; | ||
161 | } | ||
162 | |||
163 | static int tps_65023_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) | ||
164 | { | ||
165 | int err, data; | ||
166 | |||
167 | mutex_lock(&tps->io_lock); | ||
168 | |||
169 | data = tps_65023_read(tps, reg); | ||
170 | if (data < 0) { | ||
171 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
172 | err = data; | ||
173 | goto out; | ||
174 | } | ||
175 | |||
176 | data &= ~mask; | ||
177 | |||
178 | err = tps_65023_write(tps, reg, data); | ||
179 | if (err) | ||
180 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
181 | |||
182 | out: | ||
183 | mutex_unlock(&tps->io_lock); | ||
184 | return err; | ||
185 | |||
186 | } | ||
187 | |||
188 | static int tps_65023_reg_read(struct tps_pmic *tps, u8 reg) | ||
189 | { | ||
190 | int data; | ||
191 | |||
192 | mutex_lock(&tps->io_lock); | ||
193 | |||
194 | data = tps_65023_read(tps, reg); | ||
195 | if (data < 0) | ||
196 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
197 | |||
198 | mutex_unlock(&tps->io_lock); | ||
199 | return data; | ||
200 | } | ||
201 | |||
202 | static int tps_65023_reg_write(struct tps_pmic *tps, u8 reg, u8 val) | ||
203 | { | ||
204 | int err; | ||
205 | |||
206 | mutex_lock(&tps->io_lock); | ||
207 | |||
208 | err = tps_65023_write(tps, reg, val); | ||
209 | if (err < 0) | ||
210 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
211 | |||
212 | mutex_unlock(&tps->io_lock); | ||
213 | return err; | ||
214 | } | ||
215 | |||
216 | static int tps65023_dcdc_is_enabled(struct regulator_dev *dev) | ||
217 | { | ||
218 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
219 | int data, dcdc = rdev_get_id(dev); | ||
220 | u8 shift; | ||
221 | |||
222 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | ||
223 | return -EINVAL; | ||
224 | |||
225 | shift = TPS65023_NUM_REGULATOR - dcdc; | ||
226 | data = tps_65023_reg_read(tps, TPS65023_REG_REG_CTRL); | ||
227 | |||
228 | if (data < 0) | ||
229 | return data; | ||
230 | else | ||
231 | return (data & 1<<shift) ? 1 : 0; | ||
232 | } | ||
233 | |||
234 | static int tps65023_ldo_is_enabled(struct regulator_dev *dev) | ||
235 | { | ||
236 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
237 | int data, ldo = rdev_get_id(dev); | ||
238 | u8 shift; | ||
239 | |||
240 | if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) | ||
241 | return -EINVAL; | ||
242 | |||
243 | shift = (ldo == TPS65023_LDO_1 ? 1 : 2); | ||
244 | data = tps_65023_reg_read(tps, TPS65023_REG_REG_CTRL); | ||
245 | |||
246 | if (data < 0) | ||
247 | return data; | ||
248 | else | ||
249 | return (data & 1<<shift) ? 1 : 0; | ||
250 | } | ||
251 | |||
252 | static int tps65023_dcdc_enable(struct regulator_dev *dev) | ||
253 | { | ||
254 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
255 | int dcdc = rdev_get_id(dev); | ||
256 | u8 shift; | ||
257 | |||
258 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | ||
259 | return -EINVAL; | ||
260 | |||
261 | shift = TPS65023_NUM_REGULATOR - dcdc; | ||
262 | return tps_65023_set_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift); | ||
263 | } | ||
264 | |||
265 | static int tps65023_dcdc_disable(struct regulator_dev *dev) | ||
266 | { | ||
267 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
268 | int dcdc = rdev_get_id(dev); | ||
269 | u8 shift; | ||
270 | |||
271 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | ||
272 | return -EINVAL; | ||
273 | |||
274 | shift = TPS65023_NUM_REGULATOR - dcdc; | ||
275 | return tps_65023_clear_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift); | ||
276 | } | ||
277 | |||
278 | static int tps65023_ldo_enable(struct regulator_dev *dev) | ||
279 | { | ||
280 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
281 | int ldo = rdev_get_id(dev); | ||
282 | u8 shift; | ||
283 | |||
284 | if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) | ||
285 | return -EINVAL; | ||
286 | |||
287 | shift = (ldo == TPS65023_LDO_1 ? 1 : 2); | ||
288 | return tps_65023_set_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift); | ||
289 | } | ||
290 | |||
291 | static int tps65023_ldo_disable(struct regulator_dev *dev) | ||
292 | { | ||
293 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
294 | int ldo = rdev_get_id(dev); | ||
295 | u8 shift; | ||
296 | |||
297 | if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) | ||
298 | return -EINVAL; | ||
299 | |||
300 | shift = (ldo == TPS65023_LDO_1 ? 1 : 2); | ||
301 | return tps_65023_clear_bits(tps, TPS65023_REG_REG_CTRL, 1 << shift); | ||
302 | } | ||
303 | |||
304 | static int tps65023_dcdc_get_voltage(struct regulator_dev *dev) | ||
305 | { | ||
306 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
307 | int data, dcdc = rdev_get_id(dev); | ||
308 | |||
309 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | ||
310 | return -EINVAL; | ||
311 | |||
312 | if (dcdc == TPS65023_DCDC_1) { | ||
313 | data = tps_65023_reg_read(tps, TPS65023_REG_DEF_CORE); | ||
314 | if (data < 0) | ||
315 | return data; | ||
316 | data &= (tps->info[dcdc]->table_len - 1); | ||
317 | return tps->info[dcdc]->table[data] * 1000; | ||
318 | } else | ||
319 | return tps->info[dcdc]->min_uV; | ||
320 | } | ||
321 | |||
322 | static int tps65023_dcdc_set_voltage(struct regulator_dev *dev, | ||
323 | int min_uV, int max_uV) | ||
324 | { | ||
325 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
326 | int dcdc = rdev_get_id(dev); | ||
327 | int vsel; | ||
328 | |||
329 | if (dcdc != TPS65023_DCDC_1) | ||
330 | return -EINVAL; | ||
331 | |||
332 | if (min_uV < tps->info[dcdc]->min_uV | ||
333 | || min_uV > tps->info[dcdc]->max_uV) | ||
334 | return -EINVAL; | ||
335 | if (max_uV < tps->info[dcdc]->min_uV | ||
336 | || max_uV > tps->info[dcdc]->max_uV) | ||
337 | return -EINVAL; | ||
338 | |||
339 | for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { | ||
340 | int mV = tps->info[dcdc]->table[vsel]; | ||
341 | int uV = mV * 1000; | ||
342 | |||
343 | /* Break at the first in-range value */ | ||
344 | if (min_uV <= uV && uV <= max_uV) | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | /* write to the register in case we found a match */ | ||
349 | if (vsel == tps->info[dcdc]->table_len) | ||
350 | return -EINVAL; | ||
351 | else | ||
352 | return tps_65023_reg_write(tps, TPS65023_REG_DEF_CORE, vsel); | ||
353 | } | ||
354 | |||
355 | static int tps65023_ldo_get_voltage(struct regulator_dev *dev) | ||
356 | { | ||
357 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
358 | int data, ldo = rdev_get_id(dev); | ||
359 | |||
360 | if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) | ||
361 | return -EINVAL; | ||
362 | |||
363 | data = tps_65023_reg_read(tps, TPS65023_REG_LDO_CTRL); | ||
364 | if (data < 0) | ||
365 | return data; | ||
366 | |||
367 | data >>= (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1)); | ||
368 | data &= (tps->info[ldo]->table_len - 1); | ||
369 | return tps->info[ldo]->table[data] * 1000; | ||
370 | } | ||
371 | |||
372 | static int tps65023_ldo_set_voltage(struct regulator_dev *dev, | ||
373 | int min_uV, int max_uV) | ||
374 | { | ||
375 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
376 | int data, vsel, ldo = rdev_get_id(dev); | ||
377 | |||
378 | if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) | ||
379 | return -EINVAL; | ||
380 | |||
381 | if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV) | ||
382 | return -EINVAL; | ||
383 | if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV) | ||
384 | return -EINVAL; | ||
385 | |||
386 | for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) { | ||
387 | int mV = tps->info[ldo]->table[vsel]; | ||
388 | int uV = mV * 1000; | ||
389 | |||
390 | /* Break at the first in-range value */ | ||
391 | if (min_uV <= uV && uV <= max_uV) | ||
392 | break; | ||
393 | } | ||
394 | |||
395 | if (vsel == tps->info[ldo]->table_len) | ||
396 | return -EINVAL; | ||
397 | |||
398 | data = tps_65023_reg_read(tps, TPS65023_REG_LDO_CTRL); | ||
399 | if (data < 0) | ||
400 | return data; | ||
401 | |||
402 | data &= TPS65023_LDO_CTRL_LDOx_MASK(ldo - TPS65023_LDO_1); | ||
403 | data |= (vsel << (TPS65023_LDO_CTRL_LDOx_SHIFT(ldo - TPS65023_LDO_1))); | ||
404 | return tps_65023_reg_write(tps, TPS65023_REG_LDO_CTRL, data); | ||
405 | } | ||
406 | |||
407 | static int tps65023_dcdc_list_voltage(struct regulator_dev *dev, | ||
408 | unsigned selector) | ||
409 | { | ||
410 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
411 | int dcdc = rdev_get_id(dev); | ||
412 | |||
413 | if (dcdc < TPS65023_DCDC_1 || dcdc > TPS65023_DCDC_3) | ||
414 | return -EINVAL; | ||
415 | |||
416 | if (dcdc == TPS65023_DCDC_1) { | ||
417 | if (selector >= tps->info[dcdc]->table_len) | ||
418 | return -EINVAL; | ||
419 | else | ||
420 | return tps->info[dcdc]->table[selector] * 1000; | ||
421 | } else | ||
422 | return tps->info[dcdc]->min_uV; | ||
423 | } | ||
424 | |||
425 | static int tps65023_ldo_list_voltage(struct regulator_dev *dev, | ||
426 | unsigned selector) | ||
427 | { | ||
428 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
429 | int ldo = rdev_get_id(dev); | ||
430 | |||
431 | if (ldo < TPS65023_LDO_1 || ldo > TPS65023_LDO_2) | ||
432 | return -EINVAL; | ||
433 | |||
434 | if (selector >= tps->info[ldo]->table_len) | ||
435 | return -EINVAL; | ||
436 | else | ||
437 | return tps->info[ldo]->table[selector] * 1000; | ||
438 | } | ||
439 | |||
440 | /* Operations permitted on VDCDCx */ | ||
441 | static struct regulator_ops tps65023_dcdc_ops = { | ||
442 | .is_enabled = tps65023_dcdc_is_enabled, | ||
443 | .enable = tps65023_dcdc_enable, | ||
444 | .disable = tps65023_dcdc_disable, | ||
445 | .get_voltage = tps65023_dcdc_get_voltage, | ||
446 | .set_voltage = tps65023_dcdc_set_voltage, | ||
447 | .list_voltage = tps65023_dcdc_list_voltage, | ||
448 | }; | ||
449 | |||
450 | /* Operations permitted on LDOx */ | ||
451 | static struct regulator_ops tps65023_ldo_ops = { | ||
452 | .is_enabled = tps65023_ldo_is_enabled, | ||
453 | .enable = tps65023_ldo_enable, | ||
454 | .disable = tps65023_ldo_disable, | ||
455 | .get_voltage = tps65023_ldo_get_voltage, | ||
456 | .set_voltage = tps65023_ldo_set_voltage, | ||
457 | .list_voltage = tps65023_ldo_list_voltage, | ||
458 | }; | ||
459 | |||
460 | static | ||
461 | int tps_65023_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
462 | { | ||
463 | static int desc_id; | ||
464 | const struct tps_info *info = (void *)id->driver_data; | ||
465 | struct regulator_init_data *init_data; | ||
466 | struct regulator_dev *rdev; | ||
467 | struct tps_pmic *tps; | ||
468 | int i; | ||
469 | |||
470 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
471 | return -EIO; | ||
472 | |||
473 | /** | ||
474 | * init_data points to array of regulator_init structures | ||
475 | * coming from the board-evm file. | ||
476 | */ | ||
477 | init_data = client->dev.platform_data; | ||
478 | |||
479 | if (!init_data) | ||
480 | return -EIO; | ||
481 | |||
482 | tps = kzalloc(sizeof(*tps), GFP_KERNEL); | ||
483 | if (!tps) | ||
484 | return -ENOMEM; | ||
485 | |||
486 | mutex_init(&tps->io_lock); | ||
487 | |||
488 | /* common for all regulators */ | ||
489 | tps->client = client; | ||
490 | |||
491 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++, info++, init_data++) { | ||
492 | /* Store regulator specific information */ | ||
493 | tps->info[i] = info; | ||
494 | |||
495 | tps->desc[i].name = info->name; | ||
496 | tps->desc[i].id = desc_id++; | ||
497 | tps->desc[i].n_voltages = num_voltages[i]; | ||
498 | tps->desc[i].ops = (i > TPS65023_DCDC_3 ? | ||
499 | &tps65023_ldo_ops : &tps65023_dcdc_ops); | ||
500 | tps->desc[i].type = REGULATOR_VOLTAGE; | ||
501 | tps->desc[i].owner = THIS_MODULE; | ||
502 | |||
503 | /* Register the regulators */ | ||
504 | rdev = regulator_register(&tps->desc[i], &client->dev, | ||
505 | init_data, tps); | ||
506 | if (IS_ERR(rdev)) { | ||
507 | dev_err(&client->dev, "failed to register %s\n", | ||
508 | id->name); | ||
509 | |||
510 | /* Unregister */ | ||
511 | while (i) | ||
512 | regulator_unregister(tps->rdev[--i]); | ||
513 | |||
514 | tps->client = NULL; | ||
515 | |||
516 | /* clear the client data in i2c */ | ||
517 | i2c_set_clientdata(client, NULL); | ||
518 | kfree(tps); | ||
519 | return PTR_ERR(rdev); | ||
520 | } | ||
521 | |||
522 | /* Save regulator for cleanup */ | ||
523 | tps->rdev[i] = rdev; | ||
524 | } | ||
525 | |||
526 | i2c_set_clientdata(client, tps); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * tps_65023_remove - TPS65023 driver i2c remove handler | ||
533 | * @client: i2c driver client device structure | ||
534 | * | ||
535 | * Unregister TPS driver as an i2c client device driver | ||
536 | */ | ||
537 | static int __devexit tps_65023_remove(struct i2c_client *client) | ||
538 | { | ||
539 | struct tps_pmic *tps = i2c_get_clientdata(client); | ||
540 | int i; | ||
541 | |||
542 | for (i = 0; i < TPS65023_NUM_REGULATOR; i++) | ||
543 | regulator_unregister(tps->rdev[i]); | ||
544 | |||
545 | tps->client = NULL; | ||
546 | |||
547 | /* clear the client data in i2c */ | ||
548 | i2c_set_clientdata(client, NULL); | ||
549 | kfree(tps); | ||
550 | |||
551 | return 0; | ||
552 | } | ||
553 | |||
554 | static const struct tps_info tps65023_regs[] = { | ||
555 | { | ||
556 | .name = "VDCDC1", | ||
557 | .min_uV = 800000, | ||
558 | .max_uV = 1600000, | ||
559 | .table_len = ARRAY_SIZE(VDCDC1_VSEL_table), | ||
560 | .table = VDCDC1_VSEL_table, | ||
561 | }, | ||
562 | { | ||
563 | .name = "VDCDC2", | ||
564 | .min_uV = 3300000, | ||
565 | .max_uV = 3300000, | ||
566 | .fixed = 1, | ||
567 | }, | ||
568 | { | ||
569 | .name = "VDCDC3", | ||
570 | .min_uV = 1800000, | ||
571 | .max_uV = 1800000, | ||
572 | .fixed = 1, | ||
573 | }, | ||
574 | { | ||
575 | .name = "LDO1", | ||
576 | .min_uV = 1000000, | ||
577 | .max_uV = 3150000, | ||
578 | .table_len = ARRAY_SIZE(LDO1_VSEL_table), | ||
579 | .table = LDO1_VSEL_table, | ||
580 | }, | ||
581 | { | ||
582 | .name = "LDO2", | ||
583 | .min_uV = 1050000, | ||
584 | .max_uV = 3300000, | ||
585 | .table_len = ARRAY_SIZE(LDO2_VSEL_table), | ||
586 | .table = LDO2_VSEL_table, | ||
587 | }, | ||
588 | }; | ||
589 | |||
590 | static const struct i2c_device_id tps_65023_id[] = { | ||
591 | {.name = "tps65023", | ||
592 | .driver_data = (unsigned long) tps65023_regs,}, | ||
593 | { }, | ||
594 | }; | ||
595 | |||
596 | MODULE_DEVICE_TABLE(i2c, tps_65023_id); | ||
597 | |||
598 | static struct i2c_driver tps_65023_i2c_driver = { | ||
599 | .driver = { | ||
600 | .name = "tps65023", | ||
601 | .owner = THIS_MODULE, | ||
602 | }, | ||
603 | .probe = tps_65023_probe, | ||
604 | .remove = __devexit_p(tps_65023_remove), | ||
605 | .id_table = tps_65023_id, | ||
606 | }; | ||
607 | |||
608 | /** | ||
609 | * tps_65023_init | ||
610 | * | ||
611 | * Module init function | ||
612 | */ | ||
613 | static int __init tps_65023_init(void) | ||
614 | { | ||
615 | return i2c_add_driver(&tps_65023_i2c_driver); | ||
616 | } | ||
617 | subsys_initcall(tps_65023_init); | ||
618 | |||
619 | /** | ||
620 | * tps_65023_cleanup | ||
621 | * | ||
622 | * Module exit function | ||
623 | */ | ||
624 | static void __exit tps_65023_cleanup(void) | ||
625 | { | ||
626 | i2c_del_driver(&tps_65023_i2c_driver); | ||
627 | } | ||
628 | module_exit(tps_65023_cleanup); | ||
629 | |||
630 | MODULE_AUTHOR("Texas Instruments"); | ||
631 | MODULE_DESCRIPTION("TPS65023 voltage regulator driver"); | ||
632 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c new file mode 100644 index 000000000000..f8a6dfbef751 --- /dev/null +++ b/drivers/regulator/tps6507x-regulator.c | |||
@@ -0,0 +1,714 @@ | |||
1 | /* | ||
2 | * tps6507x-regulator.c | ||
3 | * | ||
4 | * Regulator driver for TPS65073 PMIC | ||
5 | * | ||
6 | * Copyright (C) 2009 Texas Instrument Incorporated - http://www.ti.com/ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
13 | * whether express or implied; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/regulator/driver.h> | ||
24 | #include <linux/regulator/machine.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/delay.h> | ||
27 | |||
28 | /* Register definitions */ | ||
29 | #define TPS6507X_REG_PPATH1 0X01 | ||
30 | #define TPS6507X_REG_INT 0X02 | ||
31 | #define TPS6507X_REG_CHGCONFIG0 0X03 | ||
32 | #define TPS6507X_REG_CHGCONFIG1 0X04 | ||
33 | #define TPS6507X_REG_CHGCONFIG2 0X05 | ||
34 | #define TPS6507X_REG_CHGCONFIG3 0X06 | ||
35 | #define TPS6507X_REG_REG_ADCONFIG 0X07 | ||
36 | #define TPS6507X_REG_TSCMODE 0X08 | ||
37 | #define TPS6507X_REG_ADRESULT_1 0X09 | ||
38 | #define TPS6507X_REG_ADRESULT_2 0X0A | ||
39 | #define TPS6507X_REG_PGOOD 0X0B | ||
40 | #define TPS6507X_REG_PGOODMASK 0X0C | ||
41 | #define TPS6507X_REG_CON_CTRL1 0X0D | ||
42 | #define TPS6507X_REG_CON_CTRL2 0X0E | ||
43 | #define TPS6507X_REG_CON_CTRL3 0X0F | ||
44 | #define TPS6507X_REG_DEFDCDC1 0X10 | ||
45 | #define TPS6507X_REG_DEFDCDC2_LOW 0X11 | ||
46 | #define TPS6507X_REG_DEFDCDC2_HIGH 0X12 | ||
47 | #define TPS6507X_REG_DEFDCDC3_LOW 0X13 | ||
48 | #define TPS6507X_REG_DEFDCDC3_HIGH 0X14 | ||
49 | #define TPS6507X_REG_DEFSLEW 0X15 | ||
50 | #define TPS6507X_REG_LDO_CTRL1 0X16 | ||
51 | #define TPS6507X_REG_DEFLDO2 0X17 | ||
52 | #define TPS6507X_REG_WLED_CTRL1 0X18 | ||
53 | #define TPS6507X_REG_WLED_CTRL2 0X19 | ||
54 | |||
55 | /* CON_CTRL1 bitfields */ | ||
56 | #define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) | ||
57 | #define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) | ||
58 | #define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) | ||
59 | #define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) | ||
60 | #define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) | ||
61 | |||
62 | /* DEFDCDC1 bitfields */ | ||
63 | #define TPS6507X_DEFDCDC1_DCDC1_EXT_ADJ_EN BIT(7) | ||
64 | #define TPS6507X_DEFDCDC1_DCDC1_MASK 0X3F | ||
65 | |||
66 | /* DEFDCDC2_LOW bitfields */ | ||
67 | #define TPS6507X_DEFDCDC2_LOW_DCDC2_MASK 0X3F | ||
68 | |||
69 | /* DEFDCDC2_HIGH bitfields */ | ||
70 | #define TPS6507X_DEFDCDC2_HIGH_DCDC2_MASK 0X3F | ||
71 | |||
72 | /* DEFDCDC3_LOW bitfields */ | ||
73 | #define TPS6507X_DEFDCDC3_LOW_DCDC3_MASK 0X3F | ||
74 | |||
75 | /* DEFDCDC3_HIGH bitfields */ | ||
76 | #define TPS6507X_DEFDCDC3_HIGH_DCDC3_MASK 0X3F | ||
77 | |||
78 | /* TPS6507X_REG_LDO_CTRL1 bitfields */ | ||
79 | #define TPS6507X_REG_LDO_CTRL1_LDO1_MASK 0X0F | ||
80 | |||
81 | /* TPS6507X_REG_DEFLDO2 bitfields */ | ||
82 | #define TPS6507X_REG_DEFLDO2_LDO2_MASK 0X3F | ||
83 | |||
84 | /* VDCDC MASK */ | ||
85 | #define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F | ||
86 | |||
87 | /* DCDC's */ | ||
88 | #define TPS6507X_DCDC_1 0 | ||
89 | #define TPS6507X_DCDC_2 1 | ||
90 | #define TPS6507X_DCDC_3 2 | ||
91 | /* LDOs */ | ||
92 | #define TPS6507X_LDO_1 3 | ||
93 | #define TPS6507X_LDO_2 4 | ||
94 | |||
95 | #define TPS6507X_MAX_REG_ID TPS6507X_LDO_2 | ||
96 | |||
97 | /* Number of step-down converters available */ | ||
98 | #define TPS6507X_NUM_DCDC 3 | ||
99 | /* Number of LDO voltage regulators available */ | ||
100 | #define TPS6507X_NUM_LDO 2 | ||
101 | /* Number of total regulators available */ | ||
102 | #define TPS6507X_NUM_REGULATOR (TPS6507X_NUM_DCDC + TPS6507X_NUM_LDO) | ||
103 | |||
104 | /* Supported voltage values for regulators (in milliVolts) */ | ||
105 | static const u16 VDCDCx_VSEL_table[] = { | ||
106 | 725, 750, 775, 800, | ||
107 | 825, 850, 875, 900, | ||
108 | 925, 950, 975, 1000, | ||
109 | 1025, 1050, 1075, 1100, | ||
110 | 1125, 1150, 1175, 1200, | ||
111 | 1225, 1250, 1275, 1300, | ||
112 | 1325, 1350, 1375, 1400, | ||
113 | 1425, 1450, 1475, 1500, | ||
114 | 1550, 1600, 1650, 1700, | ||
115 | 1750, 1800, 1850, 1900, | ||
116 | 1950, 2000, 2050, 2100, | ||
117 | 2150, 2200, 2250, 2300, | ||
118 | 2350, 2400, 2450, 2500, | ||
119 | 2550, 2600, 2650, 2700, | ||
120 | 2750, 2800, 2850, 2900, | ||
121 | 3000, 3100, 3200, 3300, | ||
122 | }; | ||
123 | |||
124 | static const u16 LDO1_VSEL_table[] = { | ||
125 | 1000, 1100, 1200, 1250, | ||
126 | 1300, 1350, 1400, 1500, | ||
127 | 1600, 1800, 2500, 2750, | ||
128 | 2800, 3000, 3100, 3300, | ||
129 | }; | ||
130 | |||
131 | static const u16 LDO2_VSEL_table[] = { | ||
132 | 725, 750, 775, 800, | ||
133 | 825, 850, 875, 900, | ||
134 | 925, 950, 975, 1000, | ||
135 | 1025, 1050, 1075, 1100, | ||
136 | 1125, 1150, 1175, 1200, | ||
137 | 1225, 1250, 1275, 1300, | ||
138 | 1325, 1350, 1375, 1400, | ||
139 | 1425, 1450, 1475, 1500, | ||
140 | 1550, 1600, 1650, 1700, | ||
141 | 1750, 1800, 1850, 1900, | ||
142 | 1950, 2000, 2050, 2100, | ||
143 | 2150, 2200, 2250, 2300, | ||
144 | 2350, 2400, 2450, 2500, | ||
145 | 2550, 2600, 2650, 2700, | ||
146 | 2750, 2800, 2850, 2900, | ||
147 | 3000, 3100, 3200, 3300, | ||
148 | }; | ||
149 | |||
150 | static unsigned int num_voltages[] = {ARRAY_SIZE(VDCDCx_VSEL_table), | ||
151 | ARRAY_SIZE(VDCDCx_VSEL_table), | ||
152 | ARRAY_SIZE(VDCDCx_VSEL_table), | ||
153 | ARRAY_SIZE(LDO1_VSEL_table), | ||
154 | ARRAY_SIZE(LDO2_VSEL_table)}; | ||
155 | |||
156 | struct tps_info { | ||
157 | const char *name; | ||
158 | unsigned min_uV; | ||
159 | unsigned max_uV; | ||
160 | u8 table_len; | ||
161 | const u16 *table; | ||
162 | }; | ||
163 | |||
164 | struct tps_pmic { | ||
165 | struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; | ||
166 | struct i2c_client *client; | ||
167 | struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; | ||
168 | const struct tps_info *info[TPS6507X_NUM_REGULATOR]; | ||
169 | struct mutex io_lock; | ||
170 | }; | ||
171 | |||
172 | static inline int tps_6507x_read(struct tps_pmic *tps, u8 reg) | ||
173 | { | ||
174 | return i2c_smbus_read_byte_data(tps->client, reg); | ||
175 | } | ||
176 | |||
177 | static inline int tps_6507x_write(struct tps_pmic *tps, u8 reg, u8 val) | ||
178 | { | ||
179 | return i2c_smbus_write_byte_data(tps->client, reg, val); | ||
180 | } | ||
181 | |||
182 | static int tps_6507x_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) | ||
183 | { | ||
184 | int err, data; | ||
185 | |||
186 | mutex_lock(&tps->io_lock); | ||
187 | |||
188 | data = tps_6507x_read(tps, reg); | ||
189 | if (data < 0) { | ||
190 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
191 | err = data; | ||
192 | goto out; | ||
193 | } | ||
194 | |||
195 | data |= mask; | ||
196 | err = tps_6507x_write(tps, reg, data); | ||
197 | if (err) | ||
198 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
199 | |||
200 | out: | ||
201 | mutex_unlock(&tps->io_lock); | ||
202 | return err; | ||
203 | } | ||
204 | |||
205 | static int tps_6507x_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) | ||
206 | { | ||
207 | int err, data; | ||
208 | |||
209 | mutex_lock(&tps->io_lock); | ||
210 | |||
211 | data = tps_6507x_read(tps, reg); | ||
212 | if (data < 0) { | ||
213 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
214 | err = data; | ||
215 | goto out; | ||
216 | } | ||
217 | |||
218 | data &= ~mask; | ||
219 | err = tps_6507x_write(tps, reg, data); | ||
220 | if (err) | ||
221 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
222 | |||
223 | out: | ||
224 | mutex_unlock(&tps->io_lock); | ||
225 | return err; | ||
226 | } | ||
227 | |||
228 | static int tps_6507x_reg_read(struct tps_pmic *tps, u8 reg) | ||
229 | { | ||
230 | int data; | ||
231 | |||
232 | mutex_lock(&tps->io_lock); | ||
233 | |||
234 | data = tps_6507x_read(tps, reg); | ||
235 | if (data < 0) | ||
236 | dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); | ||
237 | |||
238 | mutex_unlock(&tps->io_lock); | ||
239 | return data; | ||
240 | } | ||
241 | |||
242 | static int tps_6507x_reg_write(struct tps_pmic *tps, u8 reg, u8 val) | ||
243 | { | ||
244 | int err; | ||
245 | |||
246 | mutex_lock(&tps->io_lock); | ||
247 | |||
248 | err = tps_6507x_write(tps, reg, val); | ||
249 | if (err < 0) | ||
250 | dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); | ||
251 | |||
252 | mutex_unlock(&tps->io_lock); | ||
253 | return err; | ||
254 | } | ||
255 | |||
256 | static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) | ||
257 | { | ||
258 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
259 | int data, dcdc = rdev_get_id(dev); | ||
260 | u8 shift; | ||
261 | |||
262 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | ||
263 | return -EINVAL; | ||
264 | |||
265 | shift = TPS6507X_MAX_REG_ID - dcdc; | ||
266 | data = tps_6507x_reg_read(tps, TPS6507X_REG_CON_CTRL1); | ||
267 | |||
268 | if (data < 0) | ||
269 | return data; | ||
270 | else | ||
271 | return (data & 1<<shift) ? 1 : 0; | ||
272 | } | ||
273 | |||
274 | static int tps6507x_ldo_is_enabled(struct regulator_dev *dev) | ||
275 | { | ||
276 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
277 | int data, ldo = rdev_get_id(dev); | ||
278 | u8 shift; | ||
279 | |||
280 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
281 | return -EINVAL; | ||
282 | |||
283 | shift = TPS6507X_MAX_REG_ID - ldo; | ||
284 | data = tps_6507x_reg_read(tps, TPS6507X_REG_CON_CTRL1); | ||
285 | |||
286 | if (data < 0) | ||
287 | return data; | ||
288 | else | ||
289 | return (data & 1<<shift) ? 1 : 0; | ||
290 | } | ||
291 | |||
292 | static int tps6507x_dcdc_enable(struct regulator_dev *dev) | ||
293 | { | ||
294 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
295 | int dcdc = rdev_get_id(dev); | ||
296 | u8 shift; | ||
297 | |||
298 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | ||
299 | return -EINVAL; | ||
300 | |||
301 | shift = TPS6507X_MAX_REG_ID - dcdc; | ||
302 | return tps_6507x_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); | ||
303 | } | ||
304 | |||
305 | static int tps6507x_dcdc_disable(struct regulator_dev *dev) | ||
306 | { | ||
307 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
308 | int dcdc = rdev_get_id(dev); | ||
309 | u8 shift; | ||
310 | |||
311 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | ||
312 | return -EINVAL; | ||
313 | |||
314 | shift = TPS6507X_MAX_REG_ID - dcdc; | ||
315 | return tps_6507x_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); | ||
316 | } | ||
317 | |||
318 | static int tps6507x_ldo_enable(struct regulator_dev *dev) | ||
319 | { | ||
320 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
321 | int ldo = rdev_get_id(dev); | ||
322 | u8 shift; | ||
323 | |||
324 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
325 | return -EINVAL; | ||
326 | |||
327 | shift = TPS6507X_MAX_REG_ID - ldo; | ||
328 | return tps_6507x_set_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); | ||
329 | } | ||
330 | |||
331 | static int tps6507x_ldo_disable(struct regulator_dev *dev) | ||
332 | { | ||
333 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
334 | int ldo = rdev_get_id(dev); | ||
335 | u8 shift; | ||
336 | |||
337 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
338 | return -EINVAL; | ||
339 | |||
340 | shift = TPS6507X_MAX_REG_ID - ldo; | ||
341 | return tps_6507x_clear_bits(tps, TPS6507X_REG_CON_CTRL1, 1 << shift); | ||
342 | } | ||
343 | |||
344 | static int tps6507x_dcdc_get_voltage(struct regulator_dev *dev) | ||
345 | { | ||
346 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
347 | int data, dcdc = rdev_get_id(dev); | ||
348 | u8 reg; | ||
349 | |||
350 | switch (dcdc) { | ||
351 | case TPS6507X_DCDC_1: | ||
352 | reg = TPS6507X_REG_DEFDCDC1; | ||
353 | break; | ||
354 | case TPS6507X_DCDC_2: | ||
355 | reg = TPS6507X_REG_DEFDCDC2_LOW; | ||
356 | break; | ||
357 | case TPS6507X_DCDC_3: | ||
358 | reg = TPS6507X_REG_DEFDCDC3_LOW; | ||
359 | break; | ||
360 | default: | ||
361 | return -EINVAL; | ||
362 | } | ||
363 | |||
364 | data = tps_6507x_reg_read(tps, reg); | ||
365 | if (data < 0) | ||
366 | return data; | ||
367 | |||
368 | data &= TPS6507X_DEFDCDCX_DCDC_MASK; | ||
369 | return tps->info[dcdc]->table[data] * 1000; | ||
370 | } | ||
371 | |||
372 | static int tps6507x_dcdc_set_voltage(struct regulator_dev *dev, | ||
373 | int min_uV, int max_uV) | ||
374 | { | ||
375 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
376 | int data, vsel, dcdc = rdev_get_id(dev); | ||
377 | u8 reg; | ||
378 | |||
379 | switch (dcdc) { | ||
380 | case TPS6507X_DCDC_1: | ||
381 | reg = TPS6507X_REG_DEFDCDC1; | ||
382 | break; | ||
383 | case TPS6507X_DCDC_2: | ||
384 | reg = TPS6507X_REG_DEFDCDC2_LOW; | ||
385 | break; | ||
386 | case TPS6507X_DCDC_3: | ||
387 | reg = TPS6507X_REG_DEFDCDC3_LOW; | ||
388 | break; | ||
389 | default: | ||
390 | return -EINVAL; | ||
391 | } | ||
392 | |||
393 | if (min_uV < tps->info[dcdc]->min_uV | ||
394 | || min_uV > tps->info[dcdc]->max_uV) | ||
395 | return -EINVAL; | ||
396 | if (max_uV < tps->info[dcdc]->min_uV | ||
397 | || max_uV > tps->info[dcdc]->max_uV) | ||
398 | return -EINVAL; | ||
399 | |||
400 | for (vsel = 0; vsel < tps->info[dcdc]->table_len; vsel++) { | ||
401 | int mV = tps->info[dcdc]->table[vsel]; | ||
402 | int uV = mV * 1000; | ||
403 | |||
404 | /* Break at the first in-range value */ | ||
405 | if (min_uV <= uV && uV <= max_uV) | ||
406 | break; | ||
407 | } | ||
408 | |||
409 | /* write to the register in case we found a match */ | ||
410 | if (vsel == tps->info[dcdc]->table_len) | ||
411 | return -EINVAL; | ||
412 | |||
413 | data = tps_6507x_reg_read(tps, reg); | ||
414 | if (data < 0) | ||
415 | return data; | ||
416 | |||
417 | data &= ~TPS6507X_DEFDCDCX_DCDC_MASK; | ||
418 | data |= vsel; | ||
419 | |||
420 | return tps_6507x_reg_write(tps, reg, data); | ||
421 | } | ||
422 | |||
423 | static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) | ||
424 | { | ||
425 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
426 | int data, ldo = rdev_get_id(dev); | ||
427 | u8 reg, mask; | ||
428 | |||
429 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
430 | return -EINVAL; | ||
431 | else { | ||
432 | reg = (ldo == TPS6507X_LDO_1 ? | ||
433 | TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); | ||
434 | mask = (ldo == TPS6507X_LDO_1 ? | ||
435 | TPS6507X_REG_LDO_CTRL1_LDO1_MASK : | ||
436 | TPS6507X_REG_DEFLDO2_LDO2_MASK); | ||
437 | } | ||
438 | |||
439 | data = tps_6507x_reg_read(tps, reg); | ||
440 | if (data < 0) | ||
441 | return data; | ||
442 | |||
443 | data &= mask; | ||
444 | return tps->info[ldo]->table[data] * 1000; | ||
445 | } | ||
446 | |||
447 | static int tps6507x_ldo_set_voltage(struct regulator_dev *dev, | ||
448 | int min_uV, int max_uV) | ||
449 | { | ||
450 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
451 | int data, vsel, ldo = rdev_get_id(dev); | ||
452 | u8 reg, mask; | ||
453 | |||
454 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
455 | return -EINVAL; | ||
456 | else { | ||
457 | reg = (ldo == TPS6507X_LDO_1 ? | ||
458 | TPS6507X_REG_LDO_CTRL1 : TPS6507X_REG_DEFLDO2); | ||
459 | mask = (ldo == TPS6507X_LDO_1 ? | ||
460 | TPS6507X_REG_LDO_CTRL1_LDO1_MASK : | ||
461 | TPS6507X_REG_DEFLDO2_LDO2_MASK); | ||
462 | } | ||
463 | |||
464 | if (min_uV < tps->info[ldo]->min_uV || min_uV > tps->info[ldo]->max_uV) | ||
465 | return -EINVAL; | ||
466 | if (max_uV < tps->info[ldo]->min_uV || max_uV > tps->info[ldo]->max_uV) | ||
467 | return -EINVAL; | ||
468 | |||
469 | for (vsel = 0; vsel < tps->info[ldo]->table_len; vsel++) { | ||
470 | int mV = tps->info[ldo]->table[vsel]; | ||
471 | int uV = mV * 1000; | ||
472 | |||
473 | /* Break at the first in-range value */ | ||
474 | if (min_uV <= uV && uV <= max_uV) | ||
475 | break; | ||
476 | } | ||
477 | |||
478 | if (vsel == tps->info[ldo]->table_len) | ||
479 | return -EINVAL; | ||
480 | |||
481 | data = tps_6507x_reg_read(tps, reg); | ||
482 | if (data < 0) | ||
483 | return data; | ||
484 | |||
485 | data &= ~mask; | ||
486 | data |= vsel; | ||
487 | |||
488 | return tps_6507x_reg_write(tps, reg, data); | ||
489 | } | ||
490 | |||
491 | static int tps6507x_dcdc_list_voltage(struct regulator_dev *dev, | ||
492 | unsigned selector) | ||
493 | { | ||
494 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
495 | int dcdc = rdev_get_id(dev); | ||
496 | |||
497 | if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) | ||
498 | return -EINVAL; | ||
499 | |||
500 | if (selector >= tps->info[dcdc]->table_len) | ||
501 | return -EINVAL; | ||
502 | else | ||
503 | return tps->info[dcdc]->table[selector] * 1000; | ||
504 | } | ||
505 | |||
506 | static int tps6507x_ldo_list_voltage(struct regulator_dev *dev, | ||
507 | unsigned selector) | ||
508 | { | ||
509 | struct tps_pmic *tps = rdev_get_drvdata(dev); | ||
510 | int ldo = rdev_get_id(dev); | ||
511 | |||
512 | if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) | ||
513 | return -EINVAL; | ||
514 | |||
515 | if (selector >= tps->info[ldo]->table_len) | ||
516 | return -EINVAL; | ||
517 | else | ||
518 | return tps->info[ldo]->table[selector] * 1000; | ||
519 | } | ||
520 | |||
521 | /* Operations permitted on VDCDCx */ | ||
522 | static struct regulator_ops tps6507x_dcdc_ops = { | ||
523 | .is_enabled = tps6507x_dcdc_is_enabled, | ||
524 | .enable = tps6507x_dcdc_enable, | ||
525 | .disable = tps6507x_dcdc_disable, | ||
526 | .get_voltage = tps6507x_dcdc_get_voltage, | ||
527 | .set_voltage = tps6507x_dcdc_set_voltage, | ||
528 | .list_voltage = tps6507x_dcdc_list_voltage, | ||
529 | }; | ||
530 | |||
531 | /* Operations permitted on LDOx */ | ||
532 | static struct regulator_ops tps6507x_ldo_ops = { | ||
533 | .is_enabled = tps6507x_ldo_is_enabled, | ||
534 | .enable = tps6507x_ldo_enable, | ||
535 | .disable = tps6507x_ldo_disable, | ||
536 | .get_voltage = tps6507x_ldo_get_voltage, | ||
537 | .set_voltage = tps6507x_ldo_set_voltage, | ||
538 | .list_voltage = tps6507x_ldo_list_voltage, | ||
539 | }; | ||
540 | |||
541 | static | ||
542 | int tps_6507x_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
543 | { | ||
544 | static int desc_id; | ||
545 | const struct tps_info *info = (void *)id->driver_data; | ||
546 | struct regulator_init_data *init_data; | ||
547 | struct regulator_dev *rdev; | ||
548 | struct tps_pmic *tps; | ||
549 | int i; | ||
550 | |||
551 | if (!i2c_check_functionality(client->adapter, | ||
552 | I2C_FUNC_SMBUS_BYTE_DATA)) | ||
553 | return -EIO; | ||
554 | |||
555 | /** | ||
556 | * init_data points to array of regulator_init structures | ||
557 | * coming from the board-evm file. | ||
558 | */ | ||
559 | init_data = client->dev.platform_data; | ||
560 | |||
561 | if (!init_data) | ||
562 | return -EIO; | ||
563 | |||
564 | tps = kzalloc(sizeof(*tps), GFP_KERNEL); | ||
565 | if (!tps) | ||
566 | return -ENOMEM; | ||
567 | |||
568 | mutex_init(&tps->io_lock); | ||
569 | |||
570 | /* common for all regulators */ | ||
571 | tps->client = client; | ||
572 | |||
573 | for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { | ||
574 | /* Register the regulators */ | ||
575 | tps->info[i] = info; | ||
576 | tps->desc[i].name = info->name; | ||
577 | tps->desc[i].id = desc_id++; | ||
578 | tps->desc[i].n_voltages = num_voltages[i]; | ||
579 | tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? | ||
580 | &tps6507x_ldo_ops : &tps6507x_dcdc_ops); | ||
581 | tps->desc[i].type = REGULATOR_VOLTAGE; | ||
582 | tps->desc[i].owner = THIS_MODULE; | ||
583 | |||
584 | rdev = regulator_register(&tps->desc[i], | ||
585 | &client->dev, init_data, tps); | ||
586 | if (IS_ERR(rdev)) { | ||
587 | dev_err(&client->dev, "failed to register %s\n", | ||
588 | id->name); | ||
589 | |||
590 | /* Unregister */ | ||
591 | while (i) | ||
592 | regulator_unregister(tps->rdev[--i]); | ||
593 | |||
594 | tps->client = NULL; | ||
595 | |||
596 | /* clear the client data in i2c */ | ||
597 | i2c_set_clientdata(client, NULL); | ||
598 | |||
599 | kfree(tps); | ||
600 | return PTR_ERR(rdev); | ||
601 | } | ||
602 | |||
603 | /* Save regulator for cleanup */ | ||
604 | tps->rdev[i] = rdev; | ||
605 | } | ||
606 | |||
607 | i2c_set_clientdata(client, tps); | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * tps_6507x_remove - TPS6507x driver i2c remove handler | ||
614 | * @client: i2c driver client device structure | ||
615 | * | ||
616 | * Unregister TPS driver as an i2c client device driver | ||
617 | */ | ||
618 | static int __devexit tps_6507x_remove(struct i2c_client *client) | ||
619 | { | ||
620 | struct tps_pmic *tps = i2c_get_clientdata(client); | ||
621 | int i; | ||
622 | |||
623 | for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) | ||
624 | regulator_unregister(tps->rdev[i]); | ||
625 | |||
626 | tps->client = NULL; | ||
627 | |||
628 | /* clear the client data in i2c */ | ||
629 | i2c_set_clientdata(client, NULL); | ||
630 | kfree(tps); | ||
631 | |||
632 | return 0; | ||
633 | } | ||
634 | |||
635 | static const struct tps_info tps6507x_regs[] = { | ||
636 | { | ||
637 | .name = "VDCDC1", | ||
638 | .min_uV = 725000, | ||
639 | .max_uV = 3300000, | ||
640 | .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), | ||
641 | .table = VDCDCx_VSEL_table, | ||
642 | }, | ||
643 | { | ||
644 | .name = "VDCDC2", | ||
645 | .min_uV = 725000, | ||
646 | .max_uV = 3300000, | ||
647 | .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), | ||
648 | .table = VDCDCx_VSEL_table, | ||
649 | }, | ||
650 | { | ||
651 | .name = "VDCDC3", | ||
652 | .min_uV = 725000, | ||
653 | .max_uV = 3300000, | ||
654 | .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), | ||
655 | .table = VDCDCx_VSEL_table, | ||
656 | }, | ||
657 | { | ||
658 | .name = "LDO1", | ||
659 | .min_uV = 1000000, | ||
660 | .max_uV = 3300000, | ||
661 | .table_len = ARRAY_SIZE(LDO1_VSEL_table), | ||
662 | .table = LDO1_VSEL_table, | ||
663 | }, | ||
664 | { | ||
665 | .name = "LDO2", | ||
666 | .min_uV = 725000, | ||
667 | .max_uV = 3300000, | ||
668 | .table_len = ARRAY_SIZE(LDO2_VSEL_table), | ||
669 | .table = LDO2_VSEL_table, | ||
670 | }, | ||
671 | }; | ||
672 | |||
673 | static const struct i2c_device_id tps_6507x_id[] = { | ||
674 | {.name = "tps6507x", | ||
675 | .driver_data = (unsigned long) tps6507x_regs,}, | ||
676 | { }, | ||
677 | }; | ||
678 | MODULE_DEVICE_TABLE(i2c, tps_6507x_id); | ||
679 | |||
680 | static struct i2c_driver tps_6507x_i2c_driver = { | ||
681 | .driver = { | ||
682 | .name = "tps6507x", | ||
683 | .owner = THIS_MODULE, | ||
684 | }, | ||
685 | .probe = tps_6507x_probe, | ||
686 | .remove = __devexit_p(tps_6507x_remove), | ||
687 | .id_table = tps_6507x_id, | ||
688 | }; | ||
689 | |||
690 | /** | ||
691 | * tps_6507x_init | ||
692 | * | ||
693 | * Module init function | ||
694 | */ | ||
695 | static int __init tps_6507x_init(void) | ||
696 | { | ||
697 | return i2c_add_driver(&tps_6507x_i2c_driver); | ||
698 | } | ||
699 | subsys_initcall(tps_6507x_init); | ||
700 | |||
701 | /** | ||
702 | * tps_6507x_cleanup | ||
703 | * | ||
704 | * Module exit function | ||
705 | */ | ||
706 | static void __exit tps_6507x_cleanup(void) | ||
707 | { | ||
708 | i2c_del_driver(&tps_6507x_i2c_driver); | ||
709 | } | ||
710 | module_exit(tps_6507x_cleanup); | ||
711 | |||
712 | MODULE_AUTHOR("Texas Instruments"); | ||
713 | MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); | ||
714 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/userspace-consumer.c b/drivers/regulator/userspace-consumer.c index 06d2fa96a8b4..44917da4ac97 100644 --- a/drivers/regulator/userspace-consumer.c +++ b/drivers/regulator/userspace-consumer.c | |||
@@ -93,16 +93,21 @@ static ssize_t reg_set_state(struct device *dev, struct device_attribute *attr, | |||
93 | static DEVICE_ATTR(name, 0444, reg_show_name, NULL); | 93 | static DEVICE_ATTR(name, 0444, reg_show_name, NULL); |
94 | static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state); | 94 | static DEVICE_ATTR(state, 0644, reg_show_state, reg_set_state); |
95 | 95 | ||
96 | static struct device_attribute *attributes[] = { | 96 | static struct attribute *attributes[] = { |
97 | &dev_attr_name, | 97 | &dev_attr_name.attr, |
98 | &dev_attr_state, | 98 | &dev_attr_state.attr, |
99 | NULL, | ||
100 | }; | ||
101 | |||
102 | static const struct attribute_group attr_group = { | ||
103 | .attrs = attributes, | ||
99 | }; | 104 | }; |
100 | 105 | ||
101 | static int regulator_userspace_consumer_probe(struct platform_device *pdev) | 106 | static int regulator_userspace_consumer_probe(struct platform_device *pdev) |
102 | { | 107 | { |
103 | struct regulator_userspace_consumer_data *pdata; | 108 | struct regulator_userspace_consumer_data *pdata; |
104 | struct userspace_consumer_data *drvdata; | 109 | struct userspace_consumer_data *drvdata; |
105 | int ret, i; | 110 | int ret; |
106 | 111 | ||
107 | pdata = pdev->dev.platform_data; | 112 | pdata = pdev->dev.platform_data; |
108 | if (!pdata) | 113 | if (!pdata) |
@@ -125,31 +130,29 @@ static int regulator_userspace_consumer_probe(struct platform_device *pdev) | |||
125 | goto err_alloc_supplies; | 130 | goto err_alloc_supplies; |
126 | } | 131 | } |
127 | 132 | ||
128 | for (i = 0; i < ARRAY_SIZE(attributes); i++) { | 133 | ret = sysfs_create_group(&pdev->dev.kobj, &attr_group); |
129 | ret = device_create_file(&pdev->dev, attributes[i]); | 134 | if (ret != 0) |
130 | if (ret != 0) | 135 | goto err_create_attrs; |
131 | goto err_create_attrs; | ||
132 | } | ||
133 | 136 | ||
134 | if (pdata->init_on) | 137 | if (pdata->init_on) { |
135 | ret = regulator_bulk_enable(drvdata->num_supplies, | 138 | ret = regulator_bulk_enable(drvdata->num_supplies, |
136 | drvdata->supplies); | 139 | drvdata->supplies); |
137 | 140 | if (ret) { | |
138 | drvdata->enabled = pdata->init_on; | 141 | dev_err(&pdev->dev, |
139 | 142 | "Failed to set initial state: %d\n", ret); | |
140 | if (ret) { | 143 | goto err_enable; |
141 | dev_err(&pdev->dev, "Failed to set initial state: %d\n", ret); | 144 | } |
142 | goto err_create_attrs; | ||
143 | } | 145 | } |
144 | 146 | ||
147 | drvdata->enabled = pdata->init_on; | ||
145 | platform_set_drvdata(pdev, drvdata); | 148 | platform_set_drvdata(pdev, drvdata); |
146 | 149 | ||
147 | return 0; | 150 | return 0; |
148 | 151 | ||
149 | err_create_attrs: | 152 | err_enable: |
150 | for (i = 0; i < ARRAY_SIZE(attributes); i++) | 153 | sysfs_remove_group(&pdev->dev.kobj, &attr_group); |
151 | device_remove_file(&pdev->dev, attributes[i]); | ||
152 | 154 | ||
155 | err_create_attrs: | ||
153 | regulator_bulk_free(drvdata->num_supplies, drvdata->supplies); | 156 | regulator_bulk_free(drvdata->num_supplies, drvdata->supplies); |
154 | 157 | ||
155 | err_alloc_supplies: | 158 | err_alloc_supplies: |
@@ -160,10 +163,8 @@ err_alloc_supplies: | |||
160 | static int regulator_userspace_consumer_remove(struct platform_device *pdev) | 163 | static int regulator_userspace_consumer_remove(struct platform_device *pdev) |
161 | { | 164 | { |
162 | struct userspace_consumer_data *data = platform_get_drvdata(pdev); | 165 | struct userspace_consumer_data *data = platform_get_drvdata(pdev); |
163 | int i; | ||
164 | 166 | ||
165 | for (i = 0; i < ARRAY_SIZE(attributes); i++) | 167 | sysfs_remove_group(&pdev->dev.kobj, &attr_group); |
166 | device_remove_file(&pdev->dev, attributes[i]); | ||
167 | 168 | ||
168 | if (data->enabled) | 169 | if (data->enabled) |
169 | regulator_bulk_disable(data->num_supplies, data->supplies); | 170 | regulator_bulk_disable(data->num_supplies, data->supplies); |
diff --git a/drivers/regulator/virtual.c b/drivers/regulator/virtual.c index e7db5664722e..addc032c84bf 100644 --- a/drivers/regulator/virtual.c +++ b/drivers/regulator/virtual.c | |||
@@ -27,71 +27,81 @@ struct virtual_consumer_data { | |||
27 | unsigned int mode; | 27 | unsigned int mode; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static void update_voltage_constraints(struct virtual_consumer_data *data) | 30 | static void update_voltage_constraints(struct device *dev, |
31 | struct virtual_consumer_data *data) | ||
31 | { | 32 | { |
32 | int ret; | 33 | int ret; |
33 | 34 | ||
34 | if (data->min_uV && data->max_uV | 35 | if (data->min_uV && data->max_uV |
35 | && data->min_uV <= data->max_uV) { | 36 | && data->min_uV <= data->max_uV) { |
37 | dev_dbg(dev, "Requesting %d-%duV\n", | ||
38 | data->min_uV, data->max_uV); | ||
36 | ret = regulator_set_voltage(data->regulator, | 39 | ret = regulator_set_voltage(data->regulator, |
37 | data->min_uV, data->max_uV); | 40 | data->min_uV, data->max_uV); |
38 | if (ret != 0) { | 41 | if (ret != 0) { |
39 | printk(KERN_ERR "regulator_set_voltage() failed: %d\n", | 42 | dev_err(dev, |
40 | ret); | 43 | "regulator_set_voltage() failed: %d\n", ret); |
41 | return; | 44 | return; |
42 | } | 45 | } |
43 | } | 46 | } |
44 | 47 | ||
45 | if (data->min_uV && data->max_uV && !data->enabled) { | 48 | if (data->min_uV && data->max_uV && !data->enabled) { |
49 | dev_dbg(dev, "Enabling regulator\n"); | ||
46 | ret = regulator_enable(data->regulator); | 50 | ret = regulator_enable(data->regulator); |
47 | if (ret == 0) | 51 | if (ret == 0) |
48 | data->enabled = 1; | 52 | data->enabled = 1; |
49 | else | 53 | else |
50 | printk(KERN_ERR "regulator_enable() failed: %d\n", | 54 | dev_err(dev, "regulator_enable() failed: %d\n", |
51 | ret); | 55 | ret); |
52 | } | 56 | } |
53 | 57 | ||
54 | if (!(data->min_uV && data->max_uV) && data->enabled) { | 58 | if (!(data->min_uV && data->max_uV) && data->enabled) { |
59 | dev_dbg(dev, "Disabling regulator\n"); | ||
55 | ret = regulator_disable(data->regulator); | 60 | ret = regulator_disable(data->regulator); |
56 | if (ret == 0) | 61 | if (ret == 0) |
57 | data->enabled = 0; | 62 | data->enabled = 0; |
58 | else | 63 | else |
59 | printk(KERN_ERR "regulator_disable() failed: %d\n", | 64 | dev_err(dev, "regulator_disable() failed: %d\n", |
60 | ret); | 65 | ret); |
61 | } | 66 | } |
62 | } | 67 | } |
63 | 68 | ||
64 | static void update_current_limit_constraints(struct virtual_consumer_data | 69 | static void update_current_limit_constraints(struct device *dev, |
65 | *data) | 70 | struct virtual_consumer_data *data) |
66 | { | 71 | { |
67 | int ret; | 72 | int ret; |
68 | 73 | ||
69 | if (data->max_uA | 74 | if (data->max_uA |
70 | && data->min_uA <= data->max_uA) { | 75 | && data->min_uA <= data->max_uA) { |
76 | dev_dbg(dev, "Requesting %d-%duA\n", | ||
77 | data->min_uA, data->max_uA); | ||
71 | ret = regulator_set_current_limit(data->regulator, | 78 | ret = regulator_set_current_limit(data->regulator, |
72 | data->min_uA, data->max_uA); | 79 | data->min_uA, data->max_uA); |
73 | if (ret != 0) { | 80 | if (ret != 0) { |
74 | pr_err("regulator_set_current_limit() failed: %d\n", | 81 | dev_err(dev, |
75 | ret); | 82 | "regulator_set_current_limit() failed: %d\n", |
83 | ret); | ||
76 | return; | 84 | return; |
77 | } | 85 | } |
78 | } | 86 | } |
79 | 87 | ||
80 | if (data->max_uA && !data->enabled) { | 88 | if (data->max_uA && !data->enabled) { |
89 | dev_dbg(dev, "Enabling regulator\n"); | ||
81 | ret = regulator_enable(data->regulator); | 90 | ret = regulator_enable(data->regulator); |
82 | if (ret == 0) | 91 | if (ret == 0) |
83 | data->enabled = 1; | 92 | data->enabled = 1; |
84 | else | 93 | else |
85 | printk(KERN_ERR "regulator_enable() failed: %d\n", | 94 | dev_err(dev, "regulator_enable() failed: %d\n", |
86 | ret); | 95 | ret); |
87 | } | 96 | } |
88 | 97 | ||
89 | if (!(data->min_uA && data->max_uA) && data->enabled) { | 98 | if (!(data->min_uA && data->max_uA) && data->enabled) { |
99 | dev_dbg(dev, "Disabling regulator\n"); | ||
90 | ret = regulator_disable(data->regulator); | 100 | ret = regulator_disable(data->regulator); |
91 | if (ret == 0) | 101 | if (ret == 0) |
92 | data->enabled = 0; | 102 | data->enabled = 0; |
93 | else | 103 | else |
94 | printk(KERN_ERR "regulator_disable() failed: %d\n", | 104 | dev_err(dev, "regulator_disable() failed: %d\n", |
95 | ret); | 105 | ret); |
96 | } | 106 | } |
97 | } | 107 | } |
@@ -115,7 +125,7 @@ static ssize_t set_min_uV(struct device *dev, struct device_attribute *attr, | |||
115 | mutex_lock(&data->lock); | 125 | mutex_lock(&data->lock); |
116 | 126 | ||
117 | data->min_uV = val; | 127 | data->min_uV = val; |
118 | update_voltage_constraints(data); | 128 | update_voltage_constraints(dev, data); |
119 | 129 | ||
120 | mutex_unlock(&data->lock); | 130 | mutex_unlock(&data->lock); |
121 | 131 | ||
@@ -141,7 +151,7 @@ static ssize_t set_max_uV(struct device *dev, struct device_attribute *attr, | |||
141 | mutex_lock(&data->lock); | 151 | mutex_lock(&data->lock); |
142 | 152 | ||
143 | data->max_uV = val; | 153 | data->max_uV = val; |
144 | update_voltage_constraints(data); | 154 | update_voltage_constraints(dev, data); |
145 | 155 | ||
146 | mutex_unlock(&data->lock); | 156 | mutex_unlock(&data->lock); |
147 | 157 | ||
@@ -167,7 +177,7 @@ static ssize_t set_min_uA(struct device *dev, struct device_attribute *attr, | |||
167 | mutex_lock(&data->lock); | 177 | mutex_lock(&data->lock); |
168 | 178 | ||
169 | data->min_uA = val; | 179 | data->min_uA = val; |
170 | update_current_limit_constraints(data); | 180 | update_current_limit_constraints(dev, data); |
171 | 181 | ||
172 | mutex_unlock(&data->lock); | 182 | mutex_unlock(&data->lock); |
173 | 183 | ||
@@ -193,7 +203,7 @@ static ssize_t set_max_uA(struct device *dev, struct device_attribute *attr, | |||
193 | mutex_lock(&data->lock); | 203 | mutex_lock(&data->lock); |
194 | 204 | ||
195 | data->max_uA = val; | 205 | data->max_uA = val; |
196 | update_current_limit_constraints(data); | 206 | update_current_limit_constraints(dev, data); |
197 | 207 | ||
198 | mutex_unlock(&data->lock); | 208 | mutex_unlock(&data->lock); |
199 | 209 | ||
@@ -276,8 +286,7 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev) | |||
276 | 286 | ||
277 | drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL); | 287 | drvdata = kzalloc(sizeof(struct virtual_consumer_data), GFP_KERNEL); |
278 | if (drvdata == NULL) { | 288 | if (drvdata == NULL) { |
279 | ret = -ENOMEM; | 289 | return -ENOMEM; |
280 | goto err; | ||
281 | } | 290 | } |
282 | 291 | ||
283 | mutex_init(&drvdata->lock); | 292 | mutex_init(&drvdata->lock); |
@@ -285,13 +294,18 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev) | |||
285 | drvdata->regulator = regulator_get(&pdev->dev, reg_id); | 294 | drvdata->regulator = regulator_get(&pdev->dev, reg_id); |
286 | if (IS_ERR(drvdata->regulator)) { | 295 | if (IS_ERR(drvdata->regulator)) { |
287 | ret = PTR_ERR(drvdata->regulator); | 296 | ret = PTR_ERR(drvdata->regulator); |
297 | dev_err(&pdev->dev, "Failed to obtain supply '%s': %d\n", | ||
298 | reg_id, ret); | ||
288 | goto err; | 299 | goto err; |
289 | } | 300 | } |
290 | 301 | ||
291 | for (i = 0; i < ARRAY_SIZE(attributes); i++) { | 302 | for (i = 0; i < ARRAY_SIZE(attributes); i++) { |
292 | ret = device_create_file(&pdev->dev, attributes[i]); | 303 | ret = device_create_file(&pdev->dev, attributes[i]); |
293 | if (ret != 0) | 304 | if (ret != 0) { |
294 | goto err; | 305 | dev_err(&pdev->dev, "Failed to create attr %d: %d\n", |
306 | i, ret); | ||
307 | goto err_regulator; | ||
308 | } | ||
295 | } | 309 | } |
296 | 310 | ||
297 | drvdata->mode = regulator_get_mode(drvdata->regulator); | 311 | drvdata->mode = regulator_get_mode(drvdata->regulator); |
@@ -300,6 +314,8 @@ static int regulator_virtual_consumer_probe(struct platform_device *pdev) | |||
300 | 314 | ||
301 | return 0; | 315 | return 0; |
302 | 316 | ||
317 | err_regulator: | ||
318 | regulator_put(drvdata->regulator); | ||
303 | err: | 319 | err: |
304 | for (i = 0; i < ARRAY_SIZE(attributes); i++) | 320 | for (i = 0; i < ARRAY_SIZE(attributes); i++) |
305 | device_remove_file(&pdev->dev, attributes[i]); | 321 | device_remove_file(&pdev->dev, attributes[i]); |
diff --git a/drivers/regulator/wm8350-regulator.c b/drivers/regulator/wm8350-regulator.c index 17a00b0fafd1..768bd0e5b48b 100644 --- a/drivers/regulator/wm8350-regulator.c +++ b/drivers/regulator/wm8350-regulator.c | |||
@@ -1419,6 +1419,8 @@ int wm8350_register_regulator(struct wm8350 *wm8350, int reg, | |||
1419 | { | 1419 | { |
1420 | struct platform_device *pdev; | 1420 | struct platform_device *pdev; |
1421 | int ret; | 1421 | int ret; |
1422 | if (reg < 0 || reg >= NUM_WM8350_REGULATORS) | ||
1423 | return -EINVAL; | ||
1422 | 1424 | ||
1423 | if (wm8350->pmic.pdev[reg]) | 1425 | if (wm8350->pmic.pdev[reg]) |
1424 | return -EBUSY; | 1426 | return -EBUSY; |
diff --git a/include/linux/mfd/da903x.h b/include/linux/mfd/da903x.h index 115dbe965082..c63b65c94429 100644 --- a/include/linux/mfd/da903x.h +++ b/include/linux/mfd/da903x.h | |||
@@ -1,7 +1,7 @@ | |||
1 | #ifndef __LINUX_PMIC_DA903X_H | 1 | #ifndef __LINUX_PMIC_DA903X_H |
2 | #define __LINUX_PMIC_DA903X_H | 2 | #define __LINUX_PMIC_DA903X_H |
3 | 3 | ||
4 | /* Unified sub device IDs for DA9030/DA9034 */ | 4 | /* Unified sub device IDs for DA9030/DA9034/DA9035 */ |
5 | enum { | 5 | enum { |
6 | DA9030_ID_LED_1, | 6 | DA9030_ID_LED_1, |
7 | DA9030_ID_LED_2, | 7 | DA9030_ID_LED_2, |
@@ -57,6 +57,8 @@ enum { | |||
57 | DA9034_ID_LDO13, | 57 | DA9034_ID_LDO13, |
58 | DA9034_ID_LDO14, | 58 | DA9034_ID_LDO14, |
59 | DA9034_ID_LDO15, | 59 | DA9034_ID_LDO15, |
60 | |||
61 | DA9035_ID_BUCK3, | ||
60 | }; | 62 | }; |
61 | 63 | ||
62 | /* | 64 | /* |
diff --git a/include/linux/regulator/consumer.h b/include/linux/regulator/consumer.h index 277f4b964df5..490c5b37b6d7 100644 --- a/include/linux/regulator/consumer.h +++ b/include/linux/regulator/consumer.h | |||
@@ -125,6 +125,8 @@ struct regulator_bulk_data { | |||
125 | /* regulator get and put */ | 125 | /* regulator get and put */ |
126 | struct regulator *__must_check regulator_get(struct device *dev, | 126 | struct regulator *__must_check regulator_get(struct device *dev, |
127 | const char *id); | 127 | const char *id); |
128 | struct regulator *__must_check regulator_get_exclusive(struct device *dev, | ||
129 | const char *id); | ||
128 | void regulator_put(struct regulator *regulator); | 130 | void regulator_put(struct regulator *regulator); |
129 | 131 | ||
130 | /* regulator output control and status */ | 132 | /* regulator output control and status */ |
@@ -144,6 +146,8 @@ void regulator_bulk_free(int num_consumers, | |||
144 | 146 | ||
145 | int regulator_count_voltages(struct regulator *regulator); | 147 | int regulator_count_voltages(struct regulator *regulator); |
146 | int regulator_list_voltage(struct regulator *regulator, unsigned selector); | 148 | int regulator_list_voltage(struct regulator *regulator, unsigned selector); |
149 | int regulator_is_supported_voltage(struct regulator *regulator, | ||
150 | int min_uV, int max_uV); | ||
147 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); | 151 | int regulator_set_voltage(struct regulator *regulator, int min_uV, int max_uV); |
148 | int regulator_get_voltage(struct regulator *regulator); | 152 | int regulator_get_voltage(struct regulator *regulator); |
149 | int regulator_set_current_limit(struct regulator *regulator, | 153 | int regulator_set_current_limit(struct regulator *regulator, |
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index ce1be708ca16..31f2055eae28 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h | |||
@@ -37,7 +37,8 @@ enum regulator_status { | |||
37 | * | 37 | * |
38 | * @enable: Configure the regulator as enabled. | 38 | * @enable: Configure the regulator as enabled. |
39 | * @disable: Configure the regulator as disabled. | 39 | * @disable: Configure the regulator as disabled. |
40 | * @is_enabled: Return 1 if the regulator is enabled, 0 otherwise. | 40 | * @is_enabled: Return 1 if the regulator is enabled, 0 if not. |
41 | * May also return negative errno. | ||
41 | * | 42 | * |
42 | * @set_voltage: Set the voltage for the regulator within the range specified. | 43 | * @set_voltage: Set the voltage for the regulator within the range specified. |
43 | * The driver should select the voltage closest to min_uV. | 44 | * The driver should select the voltage closest to min_uV. |
@@ -162,6 +163,8 @@ struct regulator_desc { | |||
162 | struct regulator_dev { | 163 | struct regulator_dev { |
163 | struct regulator_desc *desc; | 164 | struct regulator_desc *desc; |
164 | int use_count; | 165 | int use_count; |
166 | int open_count; | ||
167 | int exclusive; | ||
165 | 168 | ||
166 | /* lists we belong to */ | 169 | /* lists we belong to */ |
167 | struct list_head list; /* list of all regulators */ | 170 | struct list_head list; /* list of all regulators */ |
diff --git a/include/linux/regulator/fixed.h b/include/linux/regulator/fixed.h index 91b4da31f1b5..e94a4a1c7c8a 100644 --- a/include/linux/regulator/fixed.h +++ b/include/linux/regulator/fixed.h | |||
@@ -5,6 +5,9 @@ | |||
5 | * | 5 | * |
6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> | 6 | * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> |
7 | * | 7 | * |
8 | * Copyright (c) 2009 Nokia Corporation | ||
9 | * Roger Quadros <ext-roger.quadros@nokia.com> | ||
10 | * | ||
8 | * This program is free software; you can redistribute it and/or | 11 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License as | 12 | * modify it under the terms of the GNU General Public License as |
10 | * published by the Free Software Foundation; either version 2 of the | 13 | * published by the Free Software Foundation; either version 2 of the |
@@ -16,9 +19,30 @@ | |||
16 | 19 | ||
17 | struct regulator_init_data; | 20 | struct regulator_init_data; |
18 | 21 | ||
22 | /** | ||
23 | * struct fixed_voltage_config - fixed_voltage_config structure | ||
24 | * @supply_name: Name of the regulator supply | ||
25 | * @microvolts: Output voltage of regulator | ||
26 | * @gpio: GPIO to use for enable control | ||
27 | * set to -EINVAL if not used | ||
28 | * @enable_high: Polarity of enable GPIO | ||
29 | * 1 = Active high, 0 = Active low | ||
30 | * @enabled_at_boot: Whether regulator has been enabled at | ||
31 | * boot or not. 1 = Yes, 0 = No | ||
32 | * This is used to keep the regulator at | ||
33 | * the default state | ||
34 | * @init_data: regulator_init_data | ||
35 | * | ||
36 | * This structure contains fixed voltage regulator configuration | ||
37 | * information that must be passed by platform code to the fixed | ||
38 | * voltage regulator driver. | ||
39 | */ | ||
19 | struct fixed_voltage_config { | 40 | struct fixed_voltage_config { |
20 | const char *supply_name; | 41 | const char *supply_name; |
21 | int microvolts; | 42 | int microvolts; |
43 | int gpio; | ||
44 | unsigned enable_high:1; | ||
45 | unsigned enabled_at_boot:1; | ||
22 | struct regulator_init_data *init_data; | 46 | struct regulator_init_data *init_data; |
23 | }; | 47 | }; |
24 | 48 | ||
diff --git a/include/linux/regulator/machine.h b/include/linux/regulator/machine.h index bac64fa390f2..87f5f176d4ef 100644 --- a/include/linux/regulator/machine.h +++ b/include/linux/regulator/machine.h | |||
@@ -41,7 +41,7 @@ struct regulator; | |||
41 | #define REGULATOR_CHANGE_DRMS 0x10 | 41 | #define REGULATOR_CHANGE_DRMS 0x10 |
42 | 42 | ||
43 | /** | 43 | /** |
44 | * struct regulator_state - regulator state during low power syatem states | 44 | * struct regulator_state - regulator state during low power system states |
45 | * | 45 | * |
46 | * This describes a regulators state during a system wide low power state. | 46 | * This describes a regulators state during a system wide low power state. |
47 | * | 47 | * |
@@ -117,25 +117,37 @@ struct regulation_constraints { | |||
117 | /* mode to set on startup */ | 117 | /* mode to set on startup */ |
118 | unsigned int initial_mode; | 118 | unsigned int initial_mode; |
119 | 119 | ||
120 | /* constriant flags */ | 120 | /* constraint flags */ |
121 | unsigned always_on:1; /* regulator never off when system is on */ | 121 | unsigned always_on:1; /* regulator never off when system is on */ |
122 | unsigned boot_on:1; /* bootloader/firmware enabled regulator */ | 122 | unsigned boot_on:1; /* bootloader/firmware enabled regulator */ |
123 | unsigned apply_uV:1; /* apply uV constraint iff min == max */ | 123 | unsigned apply_uV:1; /* apply uV constraint if min == max */ |
124 | }; | 124 | }; |
125 | 125 | ||
126 | /** | 126 | /** |
127 | * struct regulator_consumer_supply - supply -> device mapping | 127 | * struct regulator_consumer_supply - supply -> device mapping |
128 | * | 128 | * |
129 | * This maps a supply name to a device. | 129 | * This maps a supply name to a device. Only one of dev or dev_name |
130 | * can be specified. Use of dev_name allows support for buses which | ||
131 | * make struct device available late such as I2C and is the preferred | ||
132 | * form. | ||
130 | * | 133 | * |
131 | * @dev: Device structure for the consumer. | 134 | * @dev: Device structure for the consumer. |
135 | * @dev_name: Result of dev_name() for the consumer. | ||
132 | * @supply: Name for the supply. | 136 | * @supply: Name for the supply. |
133 | */ | 137 | */ |
134 | struct regulator_consumer_supply { | 138 | struct regulator_consumer_supply { |
135 | struct device *dev; /* consumer */ | 139 | struct device *dev; /* consumer */ |
140 | const char *dev_name; /* dev_name() for consumer */ | ||
136 | const char *supply; /* consumer supply - e.g. "vcc" */ | 141 | const char *supply; /* consumer supply - e.g. "vcc" */ |
137 | }; | 142 | }; |
138 | 143 | ||
144 | /* Initialize struct regulator_consumer_supply */ | ||
145 | #define REGULATOR_SUPPLY(_name, _dev_name) \ | ||
146 | { \ | ||
147 | .supply = _name, \ | ||
148 | .dev_name = _dev_name, \ | ||
149 | } | ||
150 | |||
139 | /** | 151 | /** |
140 | * struct regulator_init_data - regulator platform initialisation data. | 152 | * struct regulator_init_data - regulator platform initialisation data. |
141 | * | 153 | * |
@@ -166,6 +178,12 @@ struct regulator_init_data { | |||
166 | 178 | ||
167 | int regulator_suspend_prepare(suspend_state_t state); | 179 | int regulator_suspend_prepare(suspend_state_t state); |
168 | 180 | ||
181 | #ifdef CONFIG_REGULATOR | ||
169 | void regulator_has_full_constraints(void); | 182 | void regulator_has_full_constraints(void); |
183 | #else | ||
184 | static inline void regulator_has_full_constraints(void) | ||
185 | { | ||
186 | } | ||
187 | #endif | ||
170 | 188 | ||
171 | #endif | 189 | #endif |
diff --git a/include/linux/regulator/max1586.h b/include/linux/regulator/max1586.h index 44563192bf16..de9a7fae20be 100644 --- a/include/linux/regulator/max1586.h +++ b/include/linux/regulator/max1586.h | |||
@@ -36,7 +36,7 @@ | |||
36 | * max1586_subdev_data - regulator data | 36 | * max1586_subdev_data - regulator data |
37 | * @id: regulator Id (either MAX1586_V3 or MAX1586_V6) | 37 | * @id: regulator Id (either MAX1586_V3 or MAX1586_V6) |
38 | * @name: regulator cute name (example for V3: "vcc_core") | 38 | * @name: regulator cute name (example for V3: "vcc_core") |
39 | * @platform_data: regulator init data (contraints, supplies, ...) | 39 | * @platform_data: regulator init data (constraints, supplies, ...) |
40 | */ | 40 | */ |
41 | struct max1586_subdev_data { | 41 | struct max1586_subdev_data { |
42 | int id; | 42 | int id; |
@@ -46,7 +46,7 @@ struct max1586_subdev_data { | |||
46 | 46 | ||
47 | /** | 47 | /** |
48 | * max1586_platform_data - platform data for max1586 | 48 | * max1586_platform_data - platform data for max1586 |
49 | * @num_subdevs: number of regultors used (may be 1 or 2) | 49 | * @num_subdevs: number of regulators used (may be 1 or 2) |
50 | * @subdevs: regulator used | 50 | * @subdevs: regulator used |
51 | * At most, there will be a regulator for V3 and one for V6 voltages. | 51 | * At most, there will be a regulator for V3 and one for V6 voltages. |
52 | * @v3_gain: gain on the V3 voltage output multiplied by 1e6. | 52 | * @v3_gain: gain on the V3 voltage output multiplied by 1e6. |