Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.13 301 lines 8.0 kB view raw
1/* 2 * max77693.c - Regulator driver for the Maxim 77693 3 * 4 * Copyright (C) 2013 Samsung Electronics 5 * Jonghwa Lee <jonghwa3.lee@samsung.com> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * 21 * This driver is based on max77686.c 22 */ 23 24#include <linux/err.h> 25#include <linux/slab.h> 26#include <linux/platform_device.h> 27#include <linux/module.h> 28#include <linux/export.h> 29#include <linux/regulator/driver.h> 30#include <linux/regulator/machine.h> 31#include <linux/mfd/max77693.h> 32#include <linux/mfd/max77693-private.h> 33#include <linux/regulator/of_regulator.h> 34 35#define CHGIN_ILIM_STEP_20mA 20000 36 37struct max77693_pmic_dev { 38 struct device *dev; 39 struct max77693_dev *iodev; 40 int num_regulators; 41 struct regulator_dev **rdev; 42}; 43 44/* CHARGER regulator ops */ 45/* CHARGER regulator uses two bits for enabling */ 46static int max77693_chg_is_enabled(struct regulator_dev *rdev) 47{ 48 int ret; 49 u8 val; 50 51 ret = max77693_read_reg(rdev->regmap, rdev->desc->enable_reg, &val); 52 if (ret) 53 return ret; 54 55 return (val & rdev->desc->enable_mask) == rdev->desc->enable_mask; 56} 57 58/* 59 * CHARGER regulator - Min : 20mA, Max : 2580mA, step : 20mA 60 * 0x00, 0x01, 0x2, 0x03 = 60 mA 61 * 0x04 ~ 0x7E = (60 + (X - 3) * 20) mA 62 */ 63static int max77693_chg_get_current_limit(struct regulator_dev *rdev) 64{ 65 unsigned int chg_min_uA = rdev->constraints->min_uA; 66 unsigned int chg_max_uA = rdev->constraints->max_uA; 67 u8 reg, sel; 68 unsigned int val; 69 int ret; 70 71 ret = max77693_read_reg(rdev->regmap, 72 MAX77693_CHG_REG_CHG_CNFG_09, &reg); 73 if (ret < 0) 74 return ret; 75 76 sel = reg & CHG_CNFG_09_CHGIN_ILIM_MASK; 77 78 /* the first four codes for charger current are all 60mA */ 79 if (sel <= 3) 80 sel = 0; 81 else 82 sel -= 3; 83 84 val = chg_min_uA + CHGIN_ILIM_STEP_20mA * sel; 85 if (val > chg_max_uA) 86 return -EINVAL; 87 88 return val; 89} 90 91static int max77693_chg_set_current_limit(struct regulator_dev *rdev, 92 int min_uA, int max_uA) 93{ 94 unsigned int chg_min_uA = rdev->constraints->min_uA; 95 int sel = 0; 96 97 while (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel < min_uA) 98 sel++; 99 100 if (chg_min_uA + CHGIN_ILIM_STEP_20mA * sel > max_uA) 101 return -EINVAL; 102 103 /* the first four codes for charger current are all 60mA */ 104 sel += 3; 105 106 return max77693_write_reg(rdev->regmap, 107 MAX77693_CHG_REG_CHG_CNFG_09, sel); 108} 109/* end of CHARGER regulator ops */ 110 111static const unsigned int max77693_safeout_table[] = { 112 4850000, 113 4900000, 114 4950000, 115 3300000, 116}; 117 118static struct regulator_ops max77693_safeout_ops = { 119 .list_voltage = regulator_list_voltage_table, 120 .is_enabled = regulator_is_enabled_regmap, 121 .enable = regulator_enable_regmap, 122 .disable = regulator_disable_regmap, 123 .get_voltage_sel = regulator_get_voltage_sel_regmap, 124 .set_voltage_sel = regulator_set_voltage_sel_regmap, 125}; 126 127static struct regulator_ops max77693_charger_ops = { 128 .is_enabled = max77693_chg_is_enabled, 129 .enable = regulator_enable_regmap, 130 .disable = regulator_disable_regmap, 131 .get_current_limit = max77693_chg_get_current_limit, 132 .set_current_limit = max77693_chg_set_current_limit, 133}; 134 135#define regulator_desc_esafeout(_num) { \ 136 .name = "ESAFEOUT"#_num, \ 137 .id = MAX77693_ESAFEOUT##_num, \ 138 .n_voltages = 4, \ 139 .ops = &max77693_safeout_ops, \ 140 .type = REGULATOR_VOLTAGE, \ 141 .volt_table = max77693_safeout_table, \ 142 .vsel_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \ 143 .vsel_mask = SAFEOUT_CTRL_SAFEOUT##_num##_MASK, \ 144 .enable_reg = MAX77693_CHG_REG_SAFEOUT_CTRL, \ 145 .enable_mask = SAFEOUT_CTRL_ENSAFEOUT##_num##_MASK , \ 146} 147 148static struct regulator_desc regulators[] = { 149 regulator_desc_esafeout(1), 150 regulator_desc_esafeout(2), 151 { 152 .name = "CHARGER", 153 .id = MAX77693_CHARGER, 154 .ops = &max77693_charger_ops, 155 .type = REGULATOR_CURRENT, 156 .owner = THIS_MODULE, 157 .enable_reg = MAX77693_CHG_REG_CHG_CNFG_00, 158 .enable_mask = CHG_CNFG_00_CHG_MASK | 159 CHG_CNFG_00_BUCK_MASK, 160 }, 161}; 162 163#ifdef CONFIG_OF 164static int max77693_pmic_dt_parse_rdata(struct device *dev, 165 struct max77693_regulator_data **rdata) 166{ 167 struct device_node *np; 168 struct of_regulator_match *rmatch; 169 struct max77693_regulator_data *tmp; 170 int i, matched = 0; 171 172 np = of_find_node_by_name(dev->parent->of_node, "regulators"); 173 if (!np) 174 return -EINVAL; 175 176 rmatch = devm_kzalloc(dev, 177 sizeof(*rmatch) * ARRAY_SIZE(regulators), GFP_KERNEL); 178 if (!rmatch) 179 return -ENOMEM; 180 181 for (i = 0; i < ARRAY_SIZE(regulators); i++) 182 rmatch[i].name = regulators[i].name; 183 184 matched = of_regulator_match(dev, np, rmatch, ARRAY_SIZE(regulators)); 185 if (matched <= 0) 186 return matched; 187 *rdata = devm_kzalloc(dev, sizeof(**rdata) * matched, GFP_KERNEL); 188 if (!(*rdata)) 189 return -ENOMEM; 190 191 tmp = *rdata; 192 193 for (i = 0; i < matched; i++) { 194 tmp->initdata = rmatch[i].init_data; 195 tmp->of_node = rmatch[i].of_node; 196 tmp->id = regulators[i].id; 197 tmp++; 198 } 199 200 return matched; 201} 202#else 203static int max77693_pmic_dt_parse_rdata(struct device *dev, 204 struct max77693_regulator_data **rdata) 205{ 206 return 0; 207} 208#endif /* CONFIG_OF */ 209 210static int max77693_pmic_init_rdata(struct device *dev, 211 struct max77693_regulator_data **rdata) 212{ 213 struct max77693_platform_data *pdata; 214 int num_regulators = 0; 215 216 pdata = dev_get_platdata(dev->parent); 217 if (pdata) { 218 *rdata = pdata->regulators; 219 num_regulators = pdata->num_regulators; 220 } 221 222 if (!(*rdata) && dev->parent->of_node) 223 num_regulators = max77693_pmic_dt_parse_rdata(dev, rdata); 224 225 return num_regulators; 226} 227 228static int max77693_pmic_probe(struct platform_device *pdev) 229{ 230 struct max77693_dev *iodev = dev_get_drvdata(pdev->dev.parent); 231 struct max77693_pmic_dev *max77693_pmic; 232 struct max77693_regulator_data *rdata = NULL; 233 int num_rdata, i; 234 struct regulator_config config; 235 236 num_rdata = max77693_pmic_init_rdata(&pdev->dev, &rdata); 237 if (!rdata || num_rdata <= 0) { 238 dev_err(&pdev->dev, "No init data supplied.\n"); 239 return -ENODEV; 240 } 241 242 max77693_pmic = devm_kzalloc(&pdev->dev, 243 sizeof(struct max77693_pmic_dev), 244 GFP_KERNEL); 245 if (!max77693_pmic) 246 return -ENOMEM; 247 248 max77693_pmic->rdev = devm_kzalloc(&pdev->dev, 249 sizeof(struct regulator_dev *) * num_rdata, 250 GFP_KERNEL); 251 if (!max77693_pmic->rdev) 252 return -ENOMEM; 253 254 max77693_pmic->dev = &pdev->dev; 255 max77693_pmic->iodev = iodev; 256 max77693_pmic->num_regulators = num_rdata; 257 258 config.dev = &pdev->dev; 259 config.regmap = iodev->regmap; 260 config.driver_data = max77693_pmic; 261 platform_set_drvdata(pdev, max77693_pmic); 262 263 for (i = 0; i < max77693_pmic->num_regulators; i++) { 264 int id = rdata[i].id; 265 266 config.init_data = rdata[i].initdata; 267 config.of_node = rdata[i].of_node; 268 269 max77693_pmic->rdev[i] = devm_regulator_register(&pdev->dev, 270 &regulators[id], &config); 271 if (IS_ERR(max77693_pmic->rdev[i])) { 272 dev_err(max77693_pmic->dev, 273 "Failed to initialize regulator-%d\n", id); 274 return PTR_ERR(max77693_pmic->rdev[i]); 275 } 276 } 277 278 return 0; 279} 280 281static const struct platform_device_id max77693_pmic_id[] = { 282 {"max77693-pmic", 0}, 283 {}, 284}; 285 286MODULE_DEVICE_TABLE(platform, max77693_pmic_id); 287 288static struct platform_driver max77693_pmic_driver = { 289 .driver = { 290 .name = "max77693-pmic", 291 .owner = THIS_MODULE, 292 }, 293 .probe = max77693_pmic_probe, 294 .id_table = max77693_pmic_id, 295}; 296 297module_platform_driver(max77693_pmic_driver); 298 299MODULE_DESCRIPTION("MAXIM MAX77693 regulator driver"); 300MODULE_AUTHOR("Jonghwa Lee <jonghwa3.lee@samsung.com>"); 301MODULE_LICENSE("GPL");