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/regulator/of_regulator.h> 22 #include <linux/platform_device.h> 23 #include <linux/kernel.h> 24 #include <linux/slab.h> 25 #include <linux/init.h> 26 #include <linux/err.h> 27 #include <linux/module.h> 28 #include <linux/of.h> 29 #include "mc13xxx.h" 30 31 static int mc13xxx_regulator_enable(struct regulator_dev *rdev) 32 { 33 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 34 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 35 int id = rdev_get_id(rdev); 36 int ret; 37 38 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 39 40 mc13xxx_lock(priv->mc13xxx); 41 ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, 42 mc13xxx_regulators[id].enable_bit, 43 mc13xxx_regulators[id].enable_bit); 44 mc13xxx_unlock(priv->mc13xxx); 45 46 return ret; 47 } 48 49 static int mc13xxx_regulator_disable(struct regulator_dev *rdev) 50 { 51 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 52 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 53 int id = rdev_get_id(rdev); 54 int ret; 55 56 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 57 58 mc13xxx_lock(priv->mc13xxx); 59 ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].reg, 60 mc13xxx_regulators[id].enable_bit, 0); 61 mc13xxx_unlock(priv->mc13xxx); 62 63 return ret; 64 } 65 66 static int mc13xxx_regulator_is_enabled(struct regulator_dev *rdev) 67 { 68 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 69 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 70 int ret, id = rdev_get_id(rdev); 71 unsigned int val; 72 73 mc13xxx_lock(priv->mc13xxx); 74 ret = mc13xxx_reg_read(priv->mc13xxx, mc13xxx_regulators[id].reg, &val); 75 mc13xxx_unlock(priv->mc13xxx); 76 77 if (ret) 78 return ret; 79 80 return (val & mc13xxx_regulators[id].enable_bit) != 0; 81 } 82 83 int mc13xxx_regulator_list_voltage(struct regulator_dev *rdev, 84 unsigned selector) 85 { 86 int id = rdev_get_id(rdev); 87 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 88 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 89 90 if (selector >= mc13xxx_regulators[id].desc.n_voltages) 91 return -EINVAL; 92 93 return mc13xxx_regulators[id].voltages[selector]; 94 } 95 EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage); 96 97 int mc13xxx_get_best_voltage_index(struct regulator_dev *rdev, 98 int min_uV, int max_uV) 99 { 100 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 101 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 102 int reg_id = rdev_get_id(rdev); 103 int i; 104 int bestmatch; 105 int bestindex; 106 107 /* 108 * Locate the minimum voltage fitting the criteria on 109 * this regulator. The switchable voltages are not 110 * in strict falling order so we need to check them 111 * all for the best match. 112 */ 113 bestmatch = INT_MAX; 114 bestindex = -1; 115 for (i = 0; i < mc13xxx_regulators[reg_id].desc.n_voltages; i++) { 116 if (mc13xxx_regulators[reg_id].voltages[i] >= min_uV && 117 mc13xxx_regulators[reg_id].voltages[i] < bestmatch) { 118 bestmatch = mc13xxx_regulators[reg_id].voltages[i]; 119 bestindex = i; 120 } 121 } 122 123 if (bestindex < 0 || bestmatch > max_uV) { 124 dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n", 125 min_uV, max_uV); 126 return -EINVAL; 127 } 128 return bestindex; 129 } 130 EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index); 131 132 static int mc13xxx_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, 133 int max_uV, unsigned *selector) 134 { 135 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 136 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 137 int value, id = rdev_get_id(rdev); 138 int ret; 139 140 dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", 141 __func__, id, min_uV, max_uV); 142 143 /* Find the best index */ 144 value = mc13xxx_get_best_voltage_index(rdev, min_uV, max_uV); 145 dev_dbg(rdev_get_dev(rdev), "%s best value: %d\n", __func__, value); 146 if (value < 0) 147 return value; 148 149 mc13xxx_lock(priv->mc13xxx); 150 ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13xxx_regulators[id].vsel_reg, 151 mc13xxx_regulators[id].vsel_mask, 152 value << mc13xxx_regulators[id].vsel_shift); 153 mc13xxx_unlock(priv->mc13xxx); 154 155 return ret; 156 } 157 158 static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) 159 { 160 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 161 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 162 int ret, id = rdev_get_id(rdev); 163 unsigned int val; 164 165 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 166 167 mc13xxx_lock(priv->mc13xxx); 168 ret = mc13xxx_reg_read(priv->mc13xxx, 169 mc13xxx_regulators[id].vsel_reg, &val); 170 mc13xxx_unlock(priv->mc13xxx); 171 172 if (ret) 173 return ret; 174 175 val = (val & mc13xxx_regulators[id].vsel_mask) 176 >> mc13xxx_regulators[id].vsel_shift; 177 178 dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); 179 180 BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages); 181 182 return mc13xxx_regulators[id].voltages[val]; 183 } 184 185 struct regulator_ops mc13xxx_regulator_ops = { 186 .enable = mc13xxx_regulator_enable, 187 .disable = mc13xxx_regulator_disable, 188 .is_enabled = mc13xxx_regulator_is_enabled, 189 .list_voltage = mc13xxx_regulator_list_voltage, 190 .set_voltage = mc13xxx_regulator_set_voltage, 191 .get_voltage = mc13xxx_regulator_get_voltage, 192 }; 193 EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops); 194 195 int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, 196 int max_uV, unsigned *selector) 197 { 198 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 199 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 200 int id = rdev_get_id(rdev); 201 202 dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", 203 __func__, id, min_uV, max_uV); 204 205 if (min_uV >= mc13xxx_regulators[id].voltages[0] && 206 max_uV <= mc13xxx_regulators[id].voltages[0]) 207 return 0; 208 else 209 return -EINVAL; 210 } 211 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage); 212 213 int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev *rdev) 214 { 215 struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); 216 struct mc13xxx_regulator *mc13xxx_regulators = priv->mc13xxx_regulators; 217 int id = rdev_get_id(rdev); 218 219 dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); 220 221 return mc13xxx_regulators[id].voltages[0]; 222 } 223 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage); 224 225 struct regulator_ops mc13xxx_fixed_regulator_ops = { 226 .enable = mc13xxx_regulator_enable, 227 .disable = mc13xxx_regulator_disable, 228 .is_enabled = mc13xxx_regulator_is_enabled, 229 .list_voltage = mc13xxx_regulator_list_voltage, 230 .set_voltage = mc13xxx_fixed_regulator_set_voltage, 231 .get_voltage = mc13xxx_fixed_regulator_get_voltage, 232 }; 233 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops); 234 235 int mc13xxx_sw_regulator_is_enabled(struct regulator_dev *rdev) 236 { 237 return 1; 238 } 239 EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled); 240 241 #ifdef CONFIG_OF 242 int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) 243 { 244 struct device_node *parent, *child; 245 int num = 0; 246 247 of_node_get(pdev->dev.parent->of_node); 248 parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); 249 if (!parent) 250 return -ENODEV; 251 252 for_each_child_of_node(parent, child) 253 num++; 254 255 return num; 256 } 257 258 struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( 259 struct platform_device *pdev, struct mc13xxx_regulator *regulators, 260 int num_regulators) 261 { 262 struct mc13xxx_regulator_priv *priv = platform_get_drvdata(pdev); 263 struct mc13xxx_regulator_init_data *data, *p; 264 struct device_node *parent, *child; 265 int i; 266 267 of_node_get(pdev->dev.parent->of_node); 268 parent = of_find_node_by_name(pdev->dev.parent->of_node, "regulators"); 269 if (!parent) 270 return NULL; 271 272 data = devm_kzalloc(&pdev->dev, sizeof(*data) * priv->num_regulators, 273 GFP_KERNEL); 274 if (!data) 275 return NULL; 276 p = data; 277 278 for_each_child_of_node(parent, child) { 279 for (i = 0; i < num_regulators; i++) { 280 if (!of_node_cmp(child->name, 281 regulators[i].desc.name)) { 282 p->id = i; 283 p->init_data = of_get_regulator_init_data( 284 &pdev->dev, child); 285 p->node = child; 286 p++; 287 break; 288 } 289 } 290 } 291 292 return data; 293 } 294 #endif 295 296 MODULE_LICENSE("GPL v2"); 297 MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>"); 298 MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC"); 299 MODULE_ALIAS("mc13xxx-regulator-core"); 300