diff options
| -rw-r--r-- | drivers/regulator/palmas-regulator.c | 822 |
1 files changed, 822 insertions, 0 deletions
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c new file mode 100644 index 000000000000..c4435f608df7 --- /dev/null +++ b/drivers/regulator/palmas-regulator.c | |||
| @@ -0,0 +1,822 @@ | |||
| 1 | /* | ||
| 2 | * Driver for Regulator part of Palmas PMIC Chips | ||
| 3 | * | ||
| 4 | * Copyright 2011-2012 Texas Instruments Inc. | ||
| 5 | * | ||
| 6 | * Author: Graeme Gregory <gg@slimlogic.co.uk> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify it | ||
| 9 | * under the terms of the GNU General Public License as published by the | ||
| 10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
| 11 | * option) any later version. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | |||
| 15 | #include <linux/kernel.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/init.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/regulator/driver.h> | ||
| 21 | #include <linux/regulator/machine.h> | ||
| 22 | #include <linux/slab.h> | ||
| 23 | #include <linux/regmap.h> | ||
| 24 | #include <linux/mfd/palmas.h> | ||
| 25 | |||
| 26 | struct regs_info { | ||
| 27 | char *name; | ||
| 28 | u8 vsel_addr; | ||
| 29 | u8 ctrl_addr; | ||
| 30 | u8 tstep_addr; | ||
| 31 | }; | ||
| 32 | |||
| 33 | static const struct regs_info palmas_regs_info[] = { | ||
| 34 | { | ||
| 35 | .name = "SMPS12", | ||
| 36 | .vsel_addr = PALMAS_SMPS12_VOLTAGE, | ||
| 37 | .ctrl_addr = PALMAS_SMPS12_CTRL, | ||
| 38 | .tstep_addr = PALMAS_SMPS12_TSTEP, | ||
| 39 | }, | ||
| 40 | { | ||
| 41 | .name = "SMPS123", | ||
| 42 | .vsel_addr = PALMAS_SMPS12_VOLTAGE, | ||
| 43 | .ctrl_addr = PALMAS_SMPS12_CTRL, | ||
| 44 | .tstep_addr = PALMAS_SMPS12_TSTEP, | ||
| 45 | }, | ||
| 46 | { | ||
| 47 | .name = "SMPS3", | ||
| 48 | .vsel_addr = PALMAS_SMPS3_VOLTAGE, | ||
| 49 | .ctrl_addr = PALMAS_SMPS3_CTRL, | ||
| 50 | }, | ||
| 51 | { | ||
| 52 | .name = "SMPS45", | ||
| 53 | .vsel_addr = PALMAS_SMPS45_VOLTAGE, | ||
| 54 | .ctrl_addr = PALMAS_SMPS45_CTRL, | ||
| 55 | .tstep_addr = PALMAS_SMPS45_TSTEP, | ||
| 56 | }, | ||
| 57 | { | ||
| 58 | .name = "SMPS457", | ||
| 59 | .vsel_addr = PALMAS_SMPS45_VOLTAGE, | ||
| 60 | .ctrl_addr = PALMAS_SMPS45_CTRL, | ||
| 61 | .tstep_addr = PALMAS_SMPS45_TSTEP, | ||
| 62 | }, | ||
| 63 | { | ||
| 64 | .name = "SMPS6", | ||
| 65 | .vsel_addr = PALMAS_SMPS6_VOLTAGE, | ||
| 66 | .ctrl_addr = PALMAS_SMPS6_CTRL, | ||
| 67 | .tstep_addr = PALMAS_SMPS6_TSTEP, | ||
| 68 | }, | ||
| 69 | { | ||
| 70 | .name = "SMPS7", | ||
| 71 | .vsel_addr = PALMAS_SMPS7_VOLTAGE, | ||
| 72 | .ctrl_addr = PALMAS_SMPS7_CTRL, | ||
| 73 | }, | ||
| 74 | { | ||
| 75 | .name = "SMPS8", | ||
| 76 | .vsel_addr = PALMAS_SMPS8_VOLTAGE, | ||
| 77 | .ctrl_addr = PALMAS_SMPS8_CTRL, | ||
| 78 | .tstep_addr = PALMAS_SMPS8_TSTEP, | ||
| 79 | }, | ||
| 80 | { | ||
| 81 | .name = "SMPS9", | ||
| 82 | .vsel_addr = PALMAS_SMPS9_VOLTAGE, | ||
| 83 | .ctrl_addr = PALMAS_SMPS9_CTRL, | ||
| 84 | }, | ||
| 85 | { | ||
| 86 | .name = "SMPS10", | ||
| 87 | }, | ||
| 88 | { | ||
| 89 | .name = "LDO1", | ||
| 90 | .vsel_addr = PALMAS_LDO1_VOLTAGE, | ||
| 91 | .ctrl_addr = PALMAS_LDO1_CTRL, | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | .name = "LDO2", | ||
| 95 | .vsel_addr = PALMAS_LDO2_VOLTAGE, | ||
| 96 | .ctrl_addr = PALMAS_LDO2_CTRL, | ||
| 97 | }, | ||
| 98 | { | ||
| 99 | .name = "LDO3", | ||
| 100 | .vsel_addr = PALMAS_LDO3_VOLTAGE, | ||
| 101 | .ctrl_addr = PALMAS_LDO3_CTRL, | ||
| 102 | }, | ||
| 103 | { | ||
| 104 | .name = "LDO4", | ||
| 105 | .vsel_addr = PALMAS_LDO4_VOLTAGE, | ||
| 106 | .ctrl_addr = PALMAS_LDO4_CTRL, | ||
| 107 | }, | ||
| 108 | { | ||
| 109 | .name = "LDO5", | ||
| 110 | .vsel_addr = PALMAS_LDO5_VOLTAGE, | ||
| 111 | .ctrl_addr = PALMAS_LDO5_CTRL, | ||
| 112 | }, | ||
| 113 | { | ||
| 114 | .name = "LDO6", | ||
| 115 | .vsel_addr = PALMAS_LDO6_VOLTAGE, | ||
| 116 | .ctrl_addr = PALMAS_LDO6_CTRL, | ||
| 117 | }, | ||
| 118 | { | ||
| 119 | .name = "LDO7", | ||
| 120 | .vsel_addr = PALMAS_LDO7_VOLTAGE, | ||
| 121 | .ctrl_addr = PALMAS_LDO7_CTRL, | ||
| 122 | }, | ||
| 123 | { | ||
| 124 | .name = "LDO8", | ||
| 125 | .vsel_addr = PALMAS_LDO8_VOLTAGE, | ||
| 126 | .ctrl_addr = PALMAS_LDO8_CTRL, | ||
| 127 | }, | ||
| 128 | { | ||
| 129 | .name = "LDO9", | ||
| 130 | .vsel_addr = PALMAS_LDO9_VOLTAGE, | ||
| 131 | .ctrl_addr = PALMAS_LDO9_CTRL, | ||
| 132 | }, | ||
| 133 | { | ||
| 134 | .name = "LDOLN", | ||
| 135 | .vsel_addr = PALMAS_LDOLN_VOLTAGE, | ||
| 136 | .ctrl_addr = PALMAS_LDOLN_CTRL, | ||
| 137 | }, | ||
| 138 | { | ||
| 139 | .name = "LDOUSB", | ||
| 140 | .vsel_addr = PALMAS_LDOUSB_VOLTAGE, | ||
| 141 | .ctrl_addr = PALMAS_LDOUSB_CTRL, | ||
| 142 | }, | ||
| 143 | }; | ||
| 144 | |||
| 145 | #define SMPS_CTRL_MODE_OFF 0x00 | ||
| 146 | #define SMPS_CTRL_MODE_ON 0x01 | ||
| 147 | #define SMPS_CTRL_MODE_ECO 0x02 | ||
| 148 | #define SMPS_CTRL_MODE_PWM 0x03 | ||
| 149 | |||
| 150 | /* These values are derived from the data sheet. And are the number of steps | ||
| 151 | * where there is a voltage change, the ranges at beginning and end of register | ||
| 152 | * max/min values where there are no change are ommitted. | ||
| 153 | * | ||
| 154 | * So they are basically (maxV-minV)/stepV | ||
| 155 | */ | ||
| 156 | #define PALMAS_SMPS_NUM_VOLTAGES 116 | ||
| 157 | #define PALMAS_SMPS10_NUM_VOLTAGES 2 | ||
| 158 | #define PALMAS_LDO_NUM_VOLTAGES 50 | ||
| 159 | |||
| 160 | #define SMPS10_VSEL (1<<3) | ||
| 161 | #define SMPS10_BOOST_EN (1<<2) | ||
| 162 | #define SMPS10_BYPASS_EN (1<<1) | ||
| 163 | #define SMPS10_SWITCH_EN (1<<0) | ||
| 164 | |||
| 165 | #define REGULATOR_SLAVE 0 | ||
| 166 | |||
| 167 | static int palmas_smps_read(struct palmas *palmas, unsigned int reg, | ||
| 168 | unsigned int *dest) | ||
| 169 | { | ||
| 170 | unsigned int addr; | ||
| 171 | |||
| 172 | addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg); | ||
| 173 | |||
| 174 | return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest); | ||
| 175 | } | ||
| 176 | |||
| 177 | static int palmas_smps_write(struct palmas *palmas, unsigned int reg, | ||
| 178 | unsigned int value) | ||
| 179 | { | ||
| 180 | unsigned int addr; | ||
| 181 | |||
| 182 | addr = PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, reg); | ||
| 183 | |||
| 184 | return regmap_write(palmas->regmap[REGULATOR_SLAVE], addr, value); | ||
| 185 | } | ||
| 186 | |||
| 187 | static int palmas_ldo_read(struct palmas *palmas, unsigned int reg, | ||
| 188 | unsigned int *dest) | ||
| 189 | { | ||
| 190 | unsigned int addr; | ||
| 191 | |||
| 192 | addr = PALMAS_BASE_TO_REG(PALMAS_LDO_BASE, reg); | ||
| 193 | |||
| 194 | return regmap_read(palmas->regmap[REGULATOR_SLAVE], addr, dest); | ||
| 195 | } | ||
| 196 | |||
| 197 | static int palmas_ldo_write(struct palmas *palmas, unsigned int reg, | ||
