1 /* 2 * Regulator Driver for Freescale MC13xxx PMIC 3 * 4 * Copyright 2010 Yong Shen <yong.shen@linaro.org> 5 * 6 * Based on mc13783 regulator driver : 7 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> 8 * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * Regs infos taken from mc13xxx drivers from freescale and mc13xxx.pdf file 15 * from freescale 16 */ 17 18 #include <linux/mfd/mc13xxx.h> 19 #include <linux/regulator/machine.h> 20 #include <linux/regulator/driver.h> 21 #include <linux/platform_device.h> 22 #include <linux/kernel.h> 23 #include <linux/slab.h> 24 #include <linux/init.h> 25 #include <linux/err.h> 26 #include <linux/module.h> 27 #include "mc13xxx.h" 28 29 static int mc13xxx_regulator_enable(struct regulator_dev *rdev) 30 { 31 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 32 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 33 int id = rdev_get_id(rdev); 34 int ret; 35 36 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 37 38 mc13xxx_lock(priv->mc13xxx); 39 ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, 40 mc13xxx_regulators[id].enable_bit, 41 mc13xxx_regulators[id].enable_bit); 42 mc13xxx_unlock(priv->mc13xxx); 43 44 return ret; 45 } 46 47 static int mc13xxx_regulator_disable(struct regulator_dev *rdev) 48 { 49 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 50 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 51 int id = rdev_get_id(rdev); 52 int ret; 53 54 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 55 56 mc13xxx_lock(priv->mc13xxx); 57 ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, 58 mc13xxx_regulators[id].enable_bit, 0); 59 mc13xxx_unlock(priv->mc13xxx); 60 61 return ret; 62 } 63 64 static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) 65 { 66 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 67 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 68 int ret, id = rdev_get_id(rdev); 69 unsigned int val; 70 71 mc13xxx_lock(priv->mc13xxx); 72 ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val); 73 mc13xxx_unlock(priv->mc13xxx); 74 75 if (ret) 76 return ret; 77 78 return (val & mc13xxx_regulators[id].enable_bit) != 0; 79 } 80 81 int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, 82 unsigned selector) 83 { 84 int id = rdev_get_id(rdev); 85 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 86 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 87 88 if (selector >= mc13xxx_regulators[id].desc.n_voltages) 89 return -EINVAL; 90 91 return mc13xxx_regulators[id].voltages[selector]; 92 } 93 EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage); 94 95 int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev, 96 int min_uV, int max_uV) 97 { 98 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 99 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 100 int reg_id = rdev_get_id(rdev); 101 int i; 102 int bestmatch; 103 int bestindex; 104 105 /* 106 * Locate the minimum voltage fitting the criteria on 107 * this regulator. The switchable voltages are not 108 * in strict falling order so we need to check them 109 * all for the best match. 110 */ 111 bestmatch = INT_MAX; 112 bestindex = -1; 113 for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) { 114 if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV && 115 mc13xxx_regulators[reg_id].voltages[i] < bestmatch) { 116 bestmatch = mc13xxx_regulators[reg_id].voltages[i]; 117 bestindex = i; 118 } 119 } 120 121 if (bestindex < 0 || bestmatch > max_uV) { 122 dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n", 123 min_uV, max_uV); 124 return -EINVAL; 125 } 126 return bestindex; 127 } 128 EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index); 129 130 static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, 131 int max_uV, unsigned *selector) 132 { 133 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 134 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 135 int value, id = rdev_get_id(rdev); 136 int ret; 137 138 dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", 139 __func__, id, min_uV, max_uV); 140 141 /* Find the best index */ 142 value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); 143 dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); 144 if (value < 0) 145 return value; 146 147 mc13xxx_lock(priv->mc13xxx); 148 ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, 149 mc13xxx_regulators[id].vsel_mask, 150 value << mc13xxx_regulators[id].vsel_shift); 151 mc13xxx_unlock(priv->mc13xxx); 152 153 return ret; 154 } 155 156 static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) 157 { 158 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 159 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 160 int ret, id = rdev_get_id(rdev); 161 unsigned int val; 162 163 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 164 165 mc13xxx_lock(priv->mc13xxx); 166 ret = mc13xxx_reg_read(priv->mc13xxx, 167 mc13xxx_regulators[id].vsel_reg, &val); 168 mc13xxx_unlock(priv->mc13xxx); 169 170 if (ret) 171 return ret; 172 173 val = (val & mc13xxx_regulators[id].vsel_mask) 174 >> mc13xxx_regulators[id].vsel_shift; 175 176 dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); 177 178 BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages); 179 180 return mc13xxx_regulators[id].voltages[val]; 181 } 182 183 struct regulator_ops mc13xxx_regulator_ops = { 184 .enable = mc13xxx_regulator_enable, 185 .disable = mc13xxx_regulator_disable, 186 .is_enabled = mc13xxx_regulator_is_enabled, 187 .list_voltage = mc13xxx_regulator_list_voltage, 188 .set_voltage = mc13xxx_regulator_set_voltage, 189 .get_voltage = mc13xxx_regulator_get_voltage, 190 }; 191 EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops); 192 193 int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, 194 int max_uV, unsigned *selector) 195 { 196 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 197 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 198 int id = rdev_get_id(rdev); 199 200 dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", 201 __func__, id, min_uV, max_uV); 202 203 if (min_uV >= mc13xxx_regulators[id].voltages[0] && 204 max_uV <= mc13xxx_regulators[id].voltages[0]) 205 return 0; 206 else 207 return -EINVAL; 208 } 209 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); 210 211 int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev) 212 { 213 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 214 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 215 int id = rdev_get_id(rdev); 216 217 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 218 219 return mc13xxx_regulators[id].voltages[0]; 220 } 221 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage); 222 223 struct regulator_ops mc13xxx_fixed_regulator_ops = { 224 .enable = mc13xxx_regulator_enable, 225 .disable = mc13xxx_regulator_disable, 226 .is_enabled = mc13xxx_regulator_is_enabled, 227 .list_voltage = mc13xxx_regulator_list_voltage, 228 .set_voltage = mc13xxx_fixed_regulator_set_voltage, 229 .get_voltage = mc13xxx_fixed_regulator_get_voltage, 230 }; 231 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); 232 233 int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev) 234 { 235 return 1; 236 } 237 EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled); 238 239 MODULE_LICENSE("GPL v2"); 240 MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>"); 241 MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC"); 242 MODULE_ALIAS("mc13xxx-regulator-core"); 243