aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/regulator/tps65910-regulator.c206
-rw-r--r--include/linux/mfd/tps65910.h8
2 files changed, 214 insertions, 0 deletions
diff --git a/drivers/regulator/tps65910-regulator.c b/drivers/regulator/tps65910-regulator.c
index 1d13cf997afb..9092b7f998c1 100644
--- a/drivers/regulator/tps65910-regulator.c
+++ b/drivers/regulator/tps65910-regulator.c
@@ -26,6 +26,9 @@
26#include <linux/mfd/tps65910.h> 26#include <linux/mfd/tps65910.h>
27 27
28#define TPS65910_SUPPLY_STATE_ENABLED 0x1 28#define TPS65910_SUPPLY_STATE_ENABLED 0x1
29#define EXT_SLEEP_CONTROL (TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 | \
30 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 | \
31 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
29 32
30/* supported VIO voltages in milivolts */ 33/* supported VIO voltages in milivolts */
31static const u16 VIO_VSEL_table[] = { 34static const u16 VIO_VSEL_table[] = {
@@ -252,6 +255,39 @@ static struct tps_info tps65911_regs[] = {
252 }, 255 },
253}; 256};
254 257
258#define EXT_CONTROL_REG_BITS(id, regs_offs, bits) (((regs_offs) << 8) | (bits))
259static unsigned int tps65910_ext_sleep_control[] = {
260 0,
261 EXT_CONTROL_REG_BITS(VIO, 1, 0),
262 EXT_CONTROL_REG_BITS(VDD1, 1, 1),
263 EXT_CONTROL_REG_BITS(VDD2, 1, 2),
264 EXT_CONTROL_REG_BITS(VDD3, 1, 3),
265 EXT_CONTROL_REG_BITS(VDIG1, 0, 1),
266 EXT_CONTROL_REG_BITS(VDIG2, 0, 2),
267 EXT_CONTROL_REG_BITS(VPLL, 0, 6),
268 EXT_CONTROL_REG_BITS(VDAC, 0, 7),
269 EXT_CONTROL_REG_BITS(VAUX1, 0, 3),
270 EXT_CONTROL_REG_BITS(VAUX2, 0, 4),
271 EXT_CONTROL_REG_BITS(VAUX33, 0, 5),
272 EXT_CONTROL_REG_BITS(VMMC, 0, 0),
273};
274
275static unsigned int tps65911_ext_sleep_control[] = {
276 0,
277 EXT_CONTROL_REG_BITS(VIO, 1, 0),
278 EXT_CONTROL_REG_BITS(VDD1, 1, 1),
279 EXT_CONTROL_REG_BITS(VDD2, 1, 2),
280 EXT_CONTROL_REG_BITS(VDDCTRL, 1, 3),
281 EXT_CONTROL_REG_BITS(LDO1, 0, 1),
282 EXT_CONTROL_REG_BITS(LDO2, 0, 2),
283 EXT_CONTROL_REG_BITS(LDO3, 0, 7),
284 EXT_CONTROL_REG_BITS(LDO4, 0, 6),
285 EXT_CONTROL_REG_BITS(LDO5, 0, 3),
286 EXT_CONTROL_REG_BITS(LDO6, 0, 0),
287 EXT_CONTROL_REG_BITS(LDO7, 0, 5),
288 EXT_CONTROL_REG_BITS(LDO8, 0, 4),
289};
290
255struct tps65910_reg { 291struct tps65910_reg {
256 struct regulator_desc *desc; 292 struct regulator_desc *desc;
257 struct tps65910 *mfd; 293 struct tps65910 *mfd;
@@ -261,6 +297,8 @@ struct tps65910_reg {
261 int num_regulators; 297 int num_regulators;
262 int mode; 298 int mode;
263 int (*get_ctrl_reg)(int); 299 int (*get_ctrl_reg)(int);
300 unsigned int *ext_sleep_control;
301 unsigned int board_ext_control[TPS65910_NUM_REGS];
264}; 302};
265 303
266static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg) 304static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
@@ -861,6 +899,131 @@ static struct regulator_ops tps65911_ops = {
861 .list_voltage = tps65911_list_voltage, 899 .list_voltage = tps65911_list_voltage,
862}; 900};
863 901
902static int tps65910_set_ext_sleep_config(struct tps65910_reg *pmic,
903 int id, int ext_sleep_config)
904{
905 struct tps65910 *mfd = pmic->mfd;
906 u8 regoffs = (pmic->ext_sleep_control[id] >> 8) & 0xFF;
907 u8 bit_pos = (1 << pmic->ext_sleep_control[id] & 0xFF);
908 int ret;
909
910 /*
911 * Regulator can not be control from multiple external input EN1, EN2
912 * and EN3 together.
913 */
914 if (ext_sleep_config & EXT_SLEEP_CONTROL) {
915 int en_count;
916 en_count = ((ext_sleep_config &
917 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1) != 0);
918 en_count += ((ext_sleep_config &
919 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2) != 0);
920 en_count += ((ext_sleep_config &
921 TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3) != 0);
922 if (en_count > 1) {
923 dev_err(mfd->dev,
924 "External sleep control flag is not proper\n");
925 return -EINVAL;
926 }
927 }
928
929 pmic->board_ext_control[id] = ext_sleep_config;
930
931 /* External EN1 control */
932 if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1)
933 ret = tps65910_set_bits(mfd,
934 TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
935 else
936 ret = tps65910_clear_bits(mfd,
937 TPS65910_EN1_LDO_ASS + regoffs, bit_pos);
938 if (ret < 0) {
939 dev_err(mfd->dev,
940 "Error in configuring external control EN1\n");
941 return ret;
942 }
943
944 /* External EN2 control */
945 if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2)
946 ret = tps65910_set_bits(mfd,
947 TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
948 else
949 ret = tps65910_clear_bits(mfd,
950 TPS65910_EN2_LDO_ASS + regoffs, bit_pos);
951 if (ret < 0) {
952 dev_err(mfd->dev,
953 "Error in configuring external control EN2\n");
954 return ret;
955 }
956
957 /* External EN3 control for TPS65910 LDO only */
958 if ((tps65910_chip_id(mfd) == TPS65910) &&
959 (id >= TPS65910_REG_VDIG1)) {
960 if (ext_sleep_config & TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3)
961 ret = tps65910_set_bits(mfd,
962 TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
963 else
964 ret = tps65910_clear_bits(mfd,
965 TPS65910_EN3_LDO_ASS + regoffs, bit_pos);
966 if (ret < 0) {
967 dev_err(mfd->dev,
968 "Error in configuring external control EN3\n");
969 return ret;
970 }
971 }
972
973 /* Return if no external control is selected */
974 if (!(ext_sleep_config & EXT_SLEEP_CONTROL)) {
975 /* Clear all sleep controls */
976 ret = tps65910_clear_bits(mfd,
977 TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
978 if (!ret)
979 ret = tps65910_clear_bits(mfd,
980 TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
981 if (ret < 0)
982 dev_err(mfd->dev,
983 "Error in configuring SLEEP register\n");
984 return ret;
985 }
986
987 /*
988 * For regulator that has separate operational and sleep register make
989 * sure that operational is used and clear sleep register to turn
990 * regulator off when external control is inactive
991 */
992 if ((id == TPS65910_REG_VDD1) ||
993 (id == TPS65910_REG_VDD2) ||
994 ((id == TPS65911_REG_VDDCTRL) &&
995 (tps65910_chip_id(mfd) == TPS65911))) {
996 int op_reg_add = pmic->get_ctrl_reg(id) + 1;
997 int sr_reg_add = pmic->get_ctrl_reg(id) + 2;
998 int opvsel = tps65910_reg_read(pmic, op_reg_add);
999 int srvsel = tps65910_reg_read(pmic, sr_reg_add);
1000 if (opvsel & VDD1_OP_CMD_MASK) {
1001 u8 reg_val = srvsel & VDD1_OP_SEL_MASK;
1002 ret = tps65910_reg_write(pmic, op_reg_add, reg_val);
1003 if (ret < 0) {
1004 dev_err(mfd->dev,
1005 "Error in configuring op register\n");
1006 return ret;
1007 }
1008 }
1009 ret = tps65910_reg_write(pmic, sr_reg_add, 0);
1010 if (ret < 0) {
1011 dev_err(mfd->dev, "Error in settting sr register\n");
1012 return ret;
1013 }
1014 }
1015
1016 ret = tps65910_clear_bits(mfd,
1017 TPS65910_SLEEP_KEEP_LDO_ON + regoffs, bit_pos);
1018 if (!ret)
1019 ret = tps65910_set_bits(mfd,
1020 TPS65910_SLEEP_SET_LDO_OFF + regoffs, bit_pos);
1021 if (ret < 0)
1022 dev_err(mfd->dev,
1023 "Error in configuring SLEEP register\n");
1024 return ret;
1025}
1026
864static __devinit int tps65910_probe(struct platform_device *pdev) 1027static __devinit int tps65910_probe(struct platform_device *pdev)
865{ 1028{
866 struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent); 1029 struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
@@ -891,11 +1054,13 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
891 case TPS65910: 1054 case TPS65910:
892 pmic->get_ctrl_reg = &tps65910_get_ctrl_register; 1055 pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
893 pmic->num_regulators = ARRAY_SIZE(tps65910_regs); 1056 pmic->num_regulators = ARRAY_SIZE(tps65910_regs);
1057 pmic->ext_sleep_control = tps65910_ext_sleep_control;
894 info = tps65910_regs; 1058 info = tps65910_regs;
895 break; 1059 break;
896 case TPS65911: 1060 case TPS65911:
897 pmic->get_ctrl_reg = &tps65911_get_ctrl_register; 1061 pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
898 pmic->num_regulators = ARRAY_SIZE(tps65911_regs); 1062 pmic->num_regulators = ARRAY_SIZE(tps65911_regs);
1063 pmic->ext_sleep_control = tps65911_ext_sleep_control;
899 info = tps65911_regs; 1064 info = tps65911_regs;
900 break; 1065 break;
901 default: 1066 default:
@@ -958,6 +1123,16 @@ static __devinit int tps65910_probe(struct platform_device *pdev)
958 pmic->desc[i].ops = &tps65911_ops; 1123 pmic->desc[i].ops = &tps65911_ops;
959 } 1124 }
960 1125
1126 err = tps65910_set_ext_sleep_config(pmic, i,
1127 pmic_plat_data->regulator_ext_sleep_control[i]);
1128 /*
1129 * Failing on regulator for configuring externally control
1130 * is not a serious issue, just throw warning.
1131 */
1132 if (err < 0)
1133 dev_warn(tps65910->dev,
1134 "Failed to initialise ext control config\n");
1135
961 pmic->desc[i].type = REGULATOR_VOLTAGE; 1136 pmic->desc[i].type = REGULATOR_VOLTAGE;
962 pmic->desc[i].owner = THIS_MODULE; 1137 pmic->desc[i].owner = THIS_MODULE;
963 1138
@@ -1004,6 +1179,36 @@ static int __devexit tps65910_remove(struct platform_device *pdev)
1004 return 0; 1179 return 0;
1005} 1180}
1006 1181
1182static void tps65910_shutdown(struct platform_device *pdev)
1183{
1184 struct tps65910_reg *pmic = platform_get_drvdata(pdev);
1185 int i;
1186
1187 /*
1188 * Before bootloader jumps to kernel, it makes sure that required
1189 * external control signals are in desired state so that given rails
1190 * can be configure accordingly.
1191 * If rails are configured to be controlled from external control
1192 * then before shutting down/rebooting the system, the external
1193 * control configuration need to be remove from the rails so that
1194 * its output will be available as per register programming even
1195 * if external controls are removed. This is require when the POR
1196 * value of the control signals are not in active state and before
1197 * bootloader initializes it, the system requires the rail output
1198 * to be active for booting.
1199 */
1200 for (i = 0; i < pmic->num_regulators; i++) {
1201 int err;
1202 if (!pmic->rdev[i])
1203 continue;
1204
1205 err = tps65910_set_ext_sleep_config(pmic, i, 0);
1206 if (err < 0)
1207 dev_err(&pdev->dev,
1208 "Error in clearing external control\n");
1209 }
1210}
1211
1007static struct platform_driver tps65910_driver = { 1212static struct platform_driver tps65910_driver = {
1008 .driver = { 1213 .driver = {
1009 .name = "tps65910-pmic", 1214 .name = "tps65910-pmic",
@@ -1011,6 +1216,7 @@ static struct platform_driver tps65910_driver = {
1011 }, 1216 },
1012 .probe = tps65910_probe, 1217 .probe = tps65910_probe,
1013 .remove = __devexit_p(tps65910_remove), 1218 .remove = __devexit_p(tps65910_remove),
1219 .shutdown = tps65910_shutdown,
1014}; 1220};
1015 1221
1016static int __init tps65910_init(void) 1222static int __init tps65910_init(void)
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index d0cb12eba402..fa6c6bf7a54d 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -768,6 +768,13 @@
768/* Max number of TPS65910/11 regulators */ 768/* Max number of TPS65910/11 regulators */
769#define TPS65910_NUM_REGS 13 769#define TPS65910_NUM_REGS 13
770 770
771/* External sleep controls through EN1/EN2/EN3 inputs*/
772#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN1 0x1
773#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN2 0x2
774#define TPS65910_SLEEP_CONTROL_EXT_INPUT_EN3 0x4
775/* TPS65911 names the EN3 signal as SLEEP */
776#define TPS65911_SLEEP_CONTROL_EXT_INPUT_SLEEP 0x4
777
771/** 778/**
772 * struct tps65910_board 779 * struct tps65910_board
773 * Board platform data may be used to initialize regulators. 780 * Board platform data may be used to initialize regulators.
@@ -779,6 +786,7 @@ struct tps65910_board {
779 int irq_base; 786 int irq_base;
780 int vmbch_threshold; 787 int vmbch_threshold;
781 int vmbch2_threshold; 788 int vmbch2_threshold;
789 unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
782 struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS]; 790 struct regulator_init_data *tps65910_pmic_init_data[TPS65910_NUM_REGS];
783}; 791};
784 792