1b59320ccSDaniel Jeong /* 2b59320ccSDaniel Jeong * LP8755 High Performance Power Management Unit : System Interface Driver 3b59320ccSDaniel Jeong * (based on rev. 0.26) 4b59320ccSDaniel Jeong * Copyright 2012 Texas Instruments 5b59320ccSDaniel Jeong * 6b59320ccSDaniel Jeong * Author: Daniel(Geon Si) Jeong <daniel.jeong@ti.com> 7b59320ccSDaniel Jeong * 8b59320ccSDaniel Jeong * This program is free software; you can redistribute it and/or modify 9b59320ccSDaniel Jeong * it under the terms of the GNU General Public License version 2 as 10b59320ccSDaniel Jeong * published by the Free Software Foundation. 11b59320ccSDaniel Jeong * 12b59320ccSDaniel Jeong */ 13b59320ccSDaniel Jeong 14b59320ccSDaniel Jeong #include <linux/module.h> 15b59320ccSDaniel Jeong #include <linux/slab.h> 16b59320ccSDaniel Jeong #include <linux/i2c.h> 17b59320ccSDaniel Jeong #include <linux/err.h> 18b59320ccSDaniel Jeong #include <linux/irq.h> 19b59320ccSDaniel Jeong #include <linux/interrupt.h> 20b59320ccSDaniel Jeong #include <linux/gpio.h> 21b59320ccSDaniel Jeong #include <linux/regmap.h> 22b59320ccSDaniel Jeong #include <linux/delay.h> 23b59320ccSDaniel Jeong #include <linux/uaccess.h> 24b59320ccSDaniel Jeong #include <linux/regulator/driver.h> 25b59320ccSDaniel Jeong #include <linux/regulator/machine.h> 26b59320ccSDaniel Jeong #include <linux/platform_data/lp8755.h> 27b59320ccSDaniel Jeong 28b59320ccSDaniel Jeong #define LP8755_REG_BUCK0 0x00 29b59320ccSDaniel Jeong #define LP8755_REG_BUCK1 0x03 30b59320ccSDaniel Jeong #define LP8755_REG_BUCK2 0x04 31b59320ccSDaniel Jeong #define LP8755_REG_BUCK3 0x01 32b59320ccSDaniel Jeong #define LP8755_REG_BUCK4 0x05 33b59320ccSDaniel Jeong #define LP8755_REG_BUCK5 0x02 34b59320ccSDaniel Jeong #define LP8755_REG_MAX 0xFF 35b59320ccSDaniel Jeong 36b59320ccSDaniel Jeong #define LP8755_BUCK_EN_M BIT(7) 37b59320ccSDaniel Jeong #define LP8755_BUCK_LINEAR_OUT_MAX 0x76 38b59320ccSDaniel Jeong #define LP8755_BUCK_VOUT_M 0x7F 39b59320ccSDaniel Jeong 40b59320ccSDaniel Jeong struct lp8755_mphase { 41b59320ccSDaniel Jeong int nreg; 42b59320ccSDaniel Jeong int buck_num[LP8755_BUCK_MAX]; 43b59320ccSDaniel Jeong }; 44b59320ccSDaniel Jeong 45b59320ccSDaniel Jeong struct lp8755_chip { 46b59320ccSDaniel Jeong struct device *dev; 47b59320ccSDaniel Jeong struct regmap *regmap; 48b59320ccSDaniel Jeong struct lp8755_platform_data *pdata; 49b59320ccSDaniel Jeong 50b59320ccSDaniel Jeong int irq; 51b59320ccSDaniel Jeong unsigned int irqmask; 52b59320ccSDaniel Jeong 53b59320ccSDaniel Jeong int mphase; 54b59320ccSDaniel Jeong struct regulator_dev *rdev[LP8755_BUCK_MAX]; 55b59320ccSDaniel Jeong }; 56b59320ccSDaniel Jeong 57b59320ccSDaniel Jeong /** 58b59320ccSDaniel Jeong *lp8755_read : read a single register value from lp8755. 59b59320ccSDaniel Jeong *@pchip : device to read from 60b59320ccSDaniel Jeong *@reg : register to read from 61b59320ccSDaniel Jeong *@val : pointer to store read value 62b59320ccSDaniel Jeong */ 63b59320ccSDaniel Jeong static int lp8755_read(struct lp8755_chip *pchip, unsigned int reg, 64b59320ccSDaniel Jeong unsigned int *val) 65b59320ccSDaniel Jeong { 66b59320ccSDaniel Jeong return regmap_read(pchip->regmap, reg, val); 67b59320ccSDaniel Jeong } 68b59320ccSDaniel Jeong 69b59320ccSDaniel Jeong /** 70b59320ccSDaniel Jeong *lp8755_write : write a single register value to lp8755. 71b59320ccSDaniel Jeong *@pchip : device to write to 72b59320ccSDaniel Jeong *@reg : register to write to 73b59320ccSDaniel Jeong *@val : value to be written 74b59320ccSDaniel Jeong */ 75b59320ccSDaniel Jeong static int lp8755_write(struct lp8755_chip *pchip, unsigned int reg, 76b59320ccSDaniel Jeong unsigned int val) 77b59320ccSDaniel Jeong { 78b59320ccSDaniel Jeong return regmap_write(pchip->regmap, reg, val); 79b59320ccSDaniel Jeong } 80b59320ccSDaniel Jeong 81b59320ccSDaniel Jeong /** 82b59320ccSDaniel Jeong *lp8755_update_bits : set the values of bit fields in lp8755 register. 83b59320ccSDaniel Jeong *@pchip : device to read from 84b59320ccSDaniel Jeong *@reg : register to update 85b59320ccSDaniel Jeong *@mask : bitmask to be changed 86b59320ccSDaniel Jeong *@val : value for bitmask 87b59320ccSDaniel Jeong */ 88b59320ccSDaniel Jeong static int lp8755_update_bits(struct lp8755_chip *pchip, unsigned int reg, 89b59320ccSDaniel Jeong unsigned int mask, unsigned int val) 90b59320ccSDaniel Jeong { 91b59320ccSDaniel Jeong return regmap_update_bits(pchip->regmap, reg, mask, val); 92b59320ccSDaniel Jeong } 93b59320ccSDaniel Jeong 94b59320ccSDaniel Jeong static int lp8755_buck_enable_time(struct regulator_dev *rdev) 95b59320ccSDaniel Jeong { 96b59320ccSDaniel Jeong int ret; 97b59320ccSDaniel Jeong unsigned int regval; 98b59320ccSDaniel Jeong enum lp8755_bucks id = rdev_get_id(rdev); 99b59320ccSDaniel Jeong struct lp8755_chip *pchip = rdev_get_drvdata(rdev); 100b59320ccSDaniel Jeong 101b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x12 + id, ®val); 102b59320ccSDaniel Jeong if (ret < 0) { 103b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 104b59320ccSDaniel Jeong return ret; 105b59320ccSDaniel Jeong } 106b59320ccSDaniel Jeong return (regval & 0xff) * 100; 107b59320ccSDaniel Jeong } 108b59320ccSDaniel Jeong 109b59320ccSDaniel Jeong static int lp8755_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) 110b59320ccSDaniel Jeong { 111b59320ccSDaniel Jeong int ret; 112b59320ccSDaniel Jeong unsigned int regbval = 0x0; 113b59320ccSDaniel Jeong enum lp8755_bucks id = rdev_get_id(rdev); 114b59320ccSDaniel Jeong struct lp8755_chip *pchip = rdev_get_drvdata(rdev); 115b59320ccSDaniel Jeong 116b59320ccSDaniel Jeong switch (mode) { 117b59320ccSDaniel Jeong case REGULATOR_MODE_FAST: 118b59320ccSDaniel Jeong /* forced pwm mode */ 119b59320ccSDaniel Jeong regbval = (0x01 << id); 120b59320ccSDaniel Jeong break; 121b59320ccSDaniel Jeong case REGULATOR_MODE_NORMAL: 122b59320ccSDaniel Jeong /* enable automatic pwm/pfm mode */ 123b59320ccSDaniel Jeong ret = lp8755_update_bits(pchip, 0x08 + id, 0x20, 0x00); 124b59320ccSDaniel Jeong if (ret < 0) 125b59320ccSDaniel Jeong goto err_i2c; 126b59320ccSDaniel Jeong break; 127b59320ccSDaniel Jeong case REGULATOR_MODE_IDLE: 128b59320ccSDaniel Jeong /* enable automatic pwm/pfm/lppfm mode */ 129b59320ccSDaniel Jeong ret = lp8755_update_bits(pchip, 0x08 + id, 0x20, 0x20); 130b59320ccSDaniel Jeong if (ret < 0) 131b59320ccSDaniel Jeong goto err_i2c; 132b59320ccSDaniel Jeong 133b59320ccSDaniel Jeong ret = lp8755_update_bits(pchip, 0x10, 0x01, 0x01); 134b59320ccSDaniel Jeong if (ret < 0) 135b59320ccSDaniel Jeong goto err_i2c; 136b59320ccSDaniel Jeong break; 137b59320ccSDaniel Jeong default: 138b59320ccSDaniel Jeong dev_err(pchip->dev, "Not supported buck mode %s\n", __func__); 139b59320ccSDaniel Jeong /* forced pwm mode */ 140b59320ccSDaniel Jeong regbval = (0x01 << id); 141b59320ccSDaniel Jeong } 142b59320ccSDaniel Jeong 143b59320ccSDaniel Jeong ret = lp8755_update_bits(pchip, 0x06, 0x01 << id, regbval); 144b59320ccSDaniel Jeong if (ret < 0) 145b59320ccSDaniel Jeong goto err_i2c; 146b59320ccSDaniel Jeong return ret; 147b59320ccSDaniel Jeong err_i2c: 148b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 149b59320ccSDaniel Jeong return ret; 150b59320ccSDaniel Jeong } 151b59320ccSDaniel Jeong 152b59320ccSDaniel Jeong static unsigned int lp8755_buck_get_mode(struct regulator_dev *rdev) 153b59320ccSDaniel Jeong { 154b59320ccSDaniel Jeong int ret; 155b59320ccSDaniel Jeong unsigned int regval; 156b59320ccSDaniel Jeong enum lp8755_bucks id = rdev_get_id(rdev); 157b59320ccSDaniel Jeong struct lp8755_chip *pchip = rdev_get_drvdata(rdev); 158b59320ccSDaniel Jeong 159b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x06, ®val); 160b59320ccSDaniel Jeong if (ret < 0) 161b59320ccSDaniel Jeong goto err_i2c; 162b59320ccSDaniel Jeong 163b59320ccSDaniel Jeong /* mode fast means forced pwm mode */ 164b59320ccSDaniel Jeong if (regval & (0x01 << id)) 165b59320ccSDaniel Jeong return REGULATOR_MODE_FAST; 166b59320ccSDaniel Jeong 167b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x08 + id, ®val); 168b59320ccSDaniel Jeong if (ret < 0) 169b59320ccSDaniel Jeong goto err_i2c; 170b59320ccSDaniel Jeong 171b59320ccSDaniel Jeong /* mode idle means automatic pwm/pfm/lppfm mode */ 172b59320ccSDaniel Jeong if (regval & 0x20) 173b59320ccSDaniel Jeong return REGULATOR_MODE_IDLE; 174b59320ccSDaniel Jeong 175b59320ccSDaniel Jeong /* mode normal means automatic pwm/pfm mode */ 176b59320ccSDaniel Jeong return REGULATOR_MODE_NORMAL; 177b59320ccSDaniel Jeong 178b59320ccSDaniel Jeong err_i2c: 179b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 180b59320ccSDaniel Jeong return 0; 181b59320ccSDaniel Jeong } 182b59320ccSDaniel Jeong 183b59320ccSDaniel Jeong static int lp8755_buck_set_ramp(struct regulator_dev *rdev, int ramp) 184b59320ccSDaniel Jeong { 185b59320ccSDaniel Jeong int ret; 186b59320ccSDaniel Jeong unsigned int regval = 0x00; 187b59320ccSDaniel Jeong enum lp8755_bucks id = rdev_get_id(rdev); 188b59320ccSDaniel Jeong struct lp8755_chip *pchip = rdev_get_drvdata(rdev); 189b59320ccSDaniel Jeong 190b59320ccSDaniel Jeong /* uV/us */ 191b59320ccSDaniel Jeong switch (ramp) { 192b59320ccSDaniel Jeong case 0 ... 230: 193b59320ccSDaniel Jeong regval = 0x07; 194b59320ccSDaniel Jeong break; 195b59320ccSDaniel Jeong case 231 ... 470: 196b59320ccSDaniel Jeong regval = 0x06; 197b59320ccSDaniel Jeong break; 198b59320ccSDaniel Jeong case 471 ... 940: 199b59320ccSDaniel Jeong regval = 0x05; 200b59320ccSDaniel Jeong break; 201b59320ccSDaniel Jeong case 941 ... 1900: 202b59320ccSDaniel Jeong regval = 0x04; 203b59320ccSDaniel Jeong break; 204b59320ccSDaniel Jeong case 1901 ... 3800: 205b59320ccSDaniel Jeong regval = 0x03; 206b59320ccSDaniel Jeong break; 207b59320ccSDaniel Jeong case 3801 ... 7500: 208b59320ccSDaniel Jeong regval = 0x02; 209b59320ccSDaniel Jeong break; 210b59320ccSDaniel Jeong case 7501 ... 15000: 211b59320ccSDaniel Jeong regval = 0x01; 212b59320ccSDaniel Jeong break; 213b59320ccSDaniel Jeong case 15001 ... 30000: 214b59320ccSDaniel Jeong regval = 0x00; 215b59320ccSDaniel Jeong break; 216b59320ccSDaniel Jeong default: 217b59320ccSDaniel Jeong dev_err(pchip->dev, 218b59320ccSDaniel Jeong "Not supported ramp value %d %s\n", ramp, __func__); 219b59320ccSDaniel Jeong return -EINVAL; 220b59320ccSDaniel Jeong } 221b59320ccSDaniel Jeong 222b59320ccSDaniel Jeong ret = lp8755_update_bits(pchip, 0x07 + id, 0x07, regval); 223b59320ccSDaniel Jeong if (ret < 0) 224b59320ccSDaniel Jeong goto err_i2c; 225b59320ccSDaniel Jeong return ret; 226b59320ccSDaniel Jeong err_i2c: 227b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 228b59320ccSDaniel Jeong return ret; 229b59320ccSDaniel Jeong } 230b59320ccSDaniel Jeong 231b59320ccSDaniel Jeong static struct regulator_ops lp8755_buck_ops = { 232b59320ccSDaniel Jeong .list_voltage = regulator_list_voltage_linear, 233b59320ccSDaniel Jeong .set_voltage_sel = regulator_set_voltage_sel_regmap, 234b59320ccSDaniel Jeong .get_voltage_sel = regulator_get_voltage_sel_regmap, 235b59320ccSDaniel Jeong .enable = regulator_enable_regmap, 236b59320ccSDaniel Jeong .disable = regulator_disable_regmap, 237b59320ccSDaniel Jeong .is_enabled = regulator_is_enabled_regmap, 238b59320ccSDaniel Jeong .enable_time = lp8755_buck_enable_time, 239b59320ccSDaniel Jeong .set_mode = lp8755_buck_set_mode, 240b59320ccSDaniel Jeong .get_mode = lp8755_buck_get_mode, 241b59320ccSDaniel Jeong .set_ramp_delay = lp8755_buck_set_ramp, 242b59320ccSDaniel Jeong }; 243b59320ccSDaniel Jeong 244b59320ccSDaniel Jeong #define lp8755_rail(_id) "lp8755_buck"#_id 245b59320ccSDaniel Jeong #define lp8755_buck_init(_id)\ 246b59320ccSDaniel Jeong {\ 247b59320ccSDaniel Jeong .constraints = {\ 248b59320ccSDaniel Jeong .name = lp8755_rail(_id),\ 249b59320ccSDaniel Jeong .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE,\ 250b59320ccSDaniel Jeong .min_uV = 500000,\ 251b59320ccSDaniel Jeong .max_uV = 1675000,\ 252b59320ccSDaniel Jeong },\ 253b59320ccSDaniel Jeong } 254b59320ccSDaniel Jeong 255b59320ccSDaniel Jeong static struct regulator_init_data lp8755_reg_default[LP8755_BUCK_MAX] = { 256510799eaSAxel Lin [LP8755_BUCK0] = lp8755_buck_init(0), 257510799eaSAxel Lin [LP8755_BUCK1] = lp8755_buck_init(1), 258510799eaSAxel Lin [LP8755_BUCK2] = lp8755_buck_init(2), 259510799eaSAxel Lin [LP8755_BUCK3] = lp8755_buck_init(3), 260510799eaSAxel Lin [LP8755_BUCK4] = lp8755_buck_init(4), 261510799eaSAxel Lin [LP8755_BUCK5] = lp8755_buck_init(5), 262b59320ccSDaniel Jeong }; 263b59320ccSDaniel Jeong 264b59320ccSDaniel Jeong static const struct lp8755_mphase mphase_buck[MPHASE_CONF_MAX] = { 265510799eaSAxel Lin { 3, { LP8755_BUCK0, LP8755_BUCK3, LP8755_BUCK5 } }, 266510799eaSAxel Lin { 6, { LP8755_BUCK0, LP8755_BUCK1, LP8755_BUCK2, LP8755_BUCK3, 267510799eaSAxel Lin LP8755_BUCK4, LP8755_BUCK5 } }, 268510799eaSAxel Lin { 5, { LP8755_BUCK0, LP8755_BUCK2, LP8755_BUCK3, LP8755_BUCK4, 269510799eaSAxel Lin LP8755_BUCK5} }, 270510799eaSAxel Lin { 4, { LP8755_BUCK0, LP8755_BUCK3, LP8755_BUCK4, LP8755_BUCK5} }, 271510799eaSAxel Lin { 3, { LP8755_BUCK0, LP8755_BUCK4, LP8755_BUCK5} }, 272510799eaSAxel Lin { 2, { LP8755_BUCK0, LP8755_BUCK5} }, 273510799eaSAxel Lin { 1, { LP8755_BUCK0} }, 274510799eaSAxel Lin { 2, { LP8755_BUCK0, LP8755_BUCK3} }, 275510799eaSAxel Lin { 4, { LP8755_BUCK0, LP8755_BUCK2, LP8755_BUCK3, LP8755_BUCK5} }, 276b59320ccSDaniel Jeong }; 277b59320ccSDaniel Jeong 278b59320ccSDaniel Jeong static int lp8755_init_data(struct lp8755_chip *pchip) 279b59320ccSDaniel Jeong { 280b59320ccSDaniel Jeong unsigned int regval; 281b59320ccSDaniel Jeong int ret, icnt, buck_num; 282b59320ccSDaniel Jeong struct lp8755_platform_data *pdata = pchip->pdata; 283b59320ccSDaniel Jeong 284b59320ccSDaniel Jeong /* read back muti-phase configuration */ 285b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x3D, ®val); 286b59320ccSDaniel Jeong if (ret < 0) 287b59320ccSDaniel Jeong goto out_i2c_error; 288cad877efSAxel Lin pchip->mphase = regval & 0x0F; 289b59320ccSDaniel Jeong 290b59320ccSDaniel Jeong /* set default data based on multi-phase config */ 291b59320ccSDaniel Jeong for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++) { 292b59320ccSDaniel Jeong buck_num = mphase_buck[pchip->mphase].buck_num[icnt]; 293b59320ccSDaniel Jeong pdata->buck_data[buck_num] = &lp8755_reg_default[buck_num]; 294b59320ccSDaniel Jeong } 295b59320ccSDaniel Jeong return ret; 296b59320ccSDaniel Jeong 297b59320ccSDaniel Jeong out_i2c_error: 298b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 299b59320ccSDaniel Jeong return ret; 300b59320ccSDaniel Jeong } 301b59320ccSDaniel Jeong 302b59320ccSDaniel Jeong #define lp8755_buck_desc(_id)\ 303b59320ccSDaniel Jeong {\ 304b59320ccSDaniel Jeong .name = lp8755_rail(_id),\ 305b59320ccSDaniel Jeong .id = LP8755_BUCK##_id,\ 306b59320ccSDaniel Jeong .ops = &lp8755_buck_ops,\ 307b59320ccSDaniel Jeong .n_voltages = LP8755_BUCK_LINEAR_OUT_MAX+1,\ 308b59320ccSDaniel Jeong .uV_step = 10000,\ 309b59320ccSDaniel Jeong .min_uV = 500000,\ 310b59320ccSDaniel Jeong .type = REGULATOR_VOLTAGE,\ 311b59320ccSDaniel Jeong .owner = THIS_MODULE,\ 312b59320ccSDaniel Jeong .enable_reg = LP8755_REG_BUCK##_id,\ 313b59320ccSDaniel Jeong .enable_mask = LP8755_BUCK_EN_M,\ 314b59320ccSDaniel Jeong .vsel_reg = LP8755_REG_BUCK##_id,\ 315b59320ccSDaniel Jeong .vsel_mask = LP8755_BUCK_VOUT_M,\ 316b59320ccSDaniel Jeong } 317b59320ccSDaniel Jeong 318b59320ccSDaniel Jeong static struct regulator_desc lp8755_regulators[] = { 319b59320ccSDaniel Jeong lp8755_buck_desc(0), 320b59320ccSDaniel Jeong lp8755_buck_desc(1), 321b59320ccSDaniel Jeong lp8755_buck_desc(2), 322b59320ccSDaniel Jeong lp8755_buck_desc(3), 323b59320ccSDaniel Jeong lp8755_buck_desc(4), 324b59320ccSDaniel Jeong lp8755_buck_desc(5), 325b59320ccSDaniel Jeong }; 326b59320ccSDaniel Jeong 327b59320ccSDaniel Jeong static int lp8755_regulator_init(struct lp8755_chip *pchip) 328b59320ccSDaniel Jeong { 329b59320ccSDaniel Jeong int ret, icnt, buck_num; 330b59320ccSDaniel Jeong struct lp8755_platform_data *pdata = pchip->pdata; 331b59320ccSDaniel Jeong struct regulator_config rconfig = { }; 332b59320ccSDaniel Jeong 333b59320ccSDaniel Jeong rconfig.regmap = pchip->regmap; 334b59320ccSDaniel Jeong rconfig.dev = pchip->dev; 335b59320ccSDaniel Jeong rconfig.driver_data = pchip; 336b59320ccSDaniel Jeong 337b59320ccSDaniel Jeong for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++) { 338b59320ccSDaniel Jeong buck_num = mphase_buck[pchip->mphase].buck_num[icnt]; 339b59320ccSDaniel Jeong rconfig.init_data = pdata->buck_data[buck_num]; 340b59320ccSDaniel Jeong rconfig.of_node = pchip->dev->of_node; 341b59320ccSDaniel Jeong pchip->rdev[buck_num] = 342b59320ccSDaniel Jeong regulator_register(&lp8755_regulators[buck_num], &rconfig); 343b59320ccSDaniel Jeong if (IS_ERR(pchip->rdev[buck_num])) { 344b59320ccSDaniel Jeong ret = PTR_ERR(pchip->rdev[buck_num]); 345a1a41ab4SAxel Lin pchip->rdev[buck_num] = NULL; 346a1a41ab4SAxel Lin dev_err(pchip->dev, "regulator init failed: buck %d\n", 347a1a41ab4SAxel Lin buck_num); 348b59320ccSDaniel Jeong goto err_buck; 349b59320ccSDaniel Jeong } 350b59320ccSDaniel Jeong } 351b59320ccSDaniel Jeong 352b59320ccSDaniel Jeong return 0; 353b59320ccSDaniel Jeong 354b59320ccSDaniel Jeong err_buck: 355b59320ccSDaniel Jeong for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 356b59320ccSDaniel Jeong regulator_unregister(pchip->rdev[icnt]); 357b59320ccSDaniel Jeong return ret; 358b59320ccSDaniel Jeong } 359b59320ccSDaniel Jeong 360b59320ccSDaniel Jeong static irqreturn_t lp8755_irq_handler(int irq, void *data) 361b59320ccSDaniel Jeong { 362b59320ccSDaniel Jeong int ret, icnt; 363b59320ccSDaniel Jeong unsigned int flag0, flag1; 364b59320ccSDaniel Jeong struct lp8755_chip *pchip = data; 365b59320ccSDaniel Jeong 366b59320ccSDaniel Jeong /* read flag0 register */ 367b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x0D, &flag0); 368b59320ccSDaniel Jeong if (ret < 0) 369b59320ccSDaniel Jeong goto err_i2c; 370b59320ccSDaniel Jeong /* clear flag register to pull up int. pin */ 371b59320ccSDaniel Jeong ret = lp8755_write(pchip, 0x0D, 0x00); 372b59320ccSDaniel Jeong if (ret < 0) 373b59320ccSDaniel Jeong goto err_i2c; 374b59320ccSDaniel Jeong 375b59320ccSDaniel Jeong /* sent power fault detection event to specific regulator */ 3761200c60bSAxel Lin for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 377b59320ccSDaniel Jeong if ((flag0 & (0x4 << icnt)) 378b59320ccSDaniel Jeong && (pchip->irqmask & (0x04 << icnt)) 379b59320ccSDaniel Jeong && (pchip->rdev[icnt] != NULL)) 380b59320ccSDaniel Jeong regulator_notifier_call_chain(pchip->rdev[icnt], 381b59320ccSDaniel Jeong LP8755_EVENT_PWR_FAULT, 382b59320ccSDaniel Jeong NULL); 383b59320ccSDaniel Jeong 384b59320ccSDaniel Jeong /* read flag1 register */ 385b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x0E, &flag1); 386b59320ccSDaniel Jeong if (ret < 0) 387b59320ccSDaniel Jeong goto err_i2c; 388b59320ccSDaniel Jeong /* clear flag register to pull up int. pin */ 389b59320ccSDaniel Jeong ret = lp8755_write(pchip, 0x0E, 0x00); 390b59320ccSDaniel Jeong if (ret < 0) 391b59320ccSDaniel Jeong goto err_i2c; 392b59320ccSDaniel Jeong 393b59320ccSDaniel Jeong /* send OCP event to all regualtor devices */ 394b59320ccSDaniel Jeong if ((flag1 & 0x01) && (pchip->irqmask & 0x01)) 395b59320ccSDaniel Jeong for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 396b59320ccSDaniel Jeong if (pchip->rdev[icnt] != NULL) 397b59320ccSDaniel Jeong regulator_notifier_call_chain(pchip->rdev[icnt], 398b59320ccSDaniel Jeong LP8755_EVENT_OCP, 399b59320ccSDaniel Jeong NULL); 400b59320ccSDaniel Jeong 401b59320ccSDaniel Jeong /* send OVP event to all regualtor devices */ 402b59320ccSDaniel Jeong if ((flag1 & 0x02) && (pchip->irqmask & 0x02)) 403b59320ccSDaniel Jeong for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 404b59320ccSDaniel Jeong if (pchip->rdev[icnt] != NULL) 405b59320ccSDaniel Jeong regulator_notifier_call_chain(pchip->rdev[icnt], 406b59320ccSDaniel Jeong LP8755_EVENT_OVP, 407b59320ccSDaniel Jeong NULL); 408b59320ccSDaniel Jeong return IRQ_HANDLED; 409b59320ccSDaniel Jeong 410b59320ccSDaniel Jeong err_i2c: 411b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 412b59320ccSDaniel Jeong return IRQ_NONE; 413b59320ccSDaniel Jeong } 414b59320ccSDaniel Jeong 415b59320ccSDaniel Jeong static int lp8755_int_config(struct lp8755_chip *pchip) 416b59320ccSDaniel Jeong { 417b59320ccSDaniel Jeong int ret; 418b59320ccSDaniel Jeong unsigned int regval; 419b59320ccSDaniel Jeong 420b59320ccSDaniel Jeong if (pchip->irq == 0) { 421b59320ccSDaniel Jeong dev_warn(pchip->dev, "not use interrupt : %s\n", __func__); 422b59320ccSDaniel Jeong return 0; 423b59320ccSDaniel Jeong } 424b59320ccSDaniel Jeong 425b59320ccSDaniel Jeong ret = lp8755_read(pchip, 0x0F, ®val); 426b59320ccSDaniel Jeong if (ret < 0) 427b59320ccSDaniel Jeong goto err_i2c; 428b59320ccSDaniel Jeong pchip->irqmask = regval; 429b59320ccSDaniel Jeong ret = request_threaded_irq(pchip->irq, NULL, lp8755_irq_handler, 430b59320ccSDaniel Jeong IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 431b59320ccSDaniel Jeong "lp8755-irq", pchip); 432b59320ccSDaniel Jeong if (ret) 433b59320ccSDaniel Jeong return ret; 434b59320ccSDaniel Jeong 435b59320ccSDaniel Jeong return ret; 436b59320ccSDaniel Jeong 437b59320ccSDaniel Jeong err_i2c: 438b59320ccSDaniel Jeong dev_err(pchip->dev, "i2c acceess error %s\n", __func__); 439b59320ccSDaniel Jeong return ret; 440b59320ccSDaniel Jeong } 441b59320ccSDaniel Jeong 442b59320ccSDaniel Jeong static const struct regmap_config lp8755_regmap = { 443b59320ccSDaniel Jeong .reg_bits = 8, 444b59320ccSDaniel Jeong .val_bits = 8, 445b59320ccSDaniel Jeong .max_register = LP8755_REG_MAX, 446b59320ccSDaniel Jeong }; 447b59320ccSDaniel Jeong 448b59320ccSDaniel Jeong static int lp8755_probe(struct i2c_client *client, 449b59320ccSDaniel Jeong const struct i2c_device_id *id) 450b59320ccSDaniel Jeong { 451b59320ccSDaniel Jeong int ret, icnt; 452b59320ccSDaniel Jeong struct lp8755_chip *pchip; 453b59320ccSDaniel Jeong struct lp8755_platform_data *pdata = client->dev.platform_data; 454b59320ccSDaniel Jeong 455b59320ccSDaniel Jeong if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { 456b59320ccSDaniel Jeong dev_err(&client->dev, "i2c functionality check fail.\n"); 457b59320ccSDaniel Jeong return -EOPNOTSUPP; 458b59320ccSDaniel Jeong } 459b59320ccSDaniel Jeong 460b59320ccSDaniel Jeong pchip = devm_kzalloc(&client->dev, 461b59320ccSDaniel Jeong sizeof(struct lp8755_chip), GFP_KERNEL); 462b59320ccSDaniel Jeong if (!pchip) 463b59320ccSDaniel Jeong return -ENOMEM; 464b59320ccSDaniel Jeong 465b59320ccSDaniel Jeong pchip->dev = &client->dev; 466b59320ccSDaniel Jeong pchip->regmap = devm_regmap_init_i2c(client, &lp8755_regmap); 467b59320ccSDaniel Jeong if (IS_ERR(pchip->regmap)) { 468b59320ccSDaniel Jeong ret = PTR_ERR(pchip->regmap); 469b59320ccSDaniel Jeong dev_err(&client->dev, "fail to allocate regmap %d\n", ret); 470b59320ccSDaniel Jeong return ret; 471b59320ccSDaniel Jeong } 472b59320ccSDaniel Jeong i2c_set_clientdata(client, pchip); 473b59320ccSDaniel Jeong 474b59320ccSDaniel Jeong if (pdata != NULL) { 475b59320ccSDaniel Jeong pchip->pdata = pdata; 476b59320ccSDaniel Jeong pchip->mphase = pdata->mphase; 477b59320ccSDaniel Jeong } else { 478b59320ccSDaniel Jeong pchip->pdata = devm_kzalloc(pchip->dev, 479b59320ccSDaniel Jeong sizeof(struct lp8755_platform_data), 480b59320ccSDaniel Jeong GFP_KERNEL); 481b59320ccSDaniel Jeong if (!pchip->pdata) 482b59320ccSDaniel Jeong return -ENOMEM; 483b59320ccSDaniel Jeong ret = lp8755_init_data(pchip); 484240a5291SAxel Lin if (ret < 0) { 485240a5291SAxel Lin dev_err(&client->dev, "fail to initialize chip\n"); 486240a5291SAxel Lin return ret; 487240a5291SAxel Lin } 488b59320ccSDaniel Jeong } 489b59320ccSDaniel Jeong 490b59320ccSDaniel Jeong ret = lp8755_regulator_init(pchip); 491240a5291SAxel Lin if (ret < 0) { 492240a5291SAxel Lin dev_err(&client->dev, "fail to initialize regulators\n"); 493b59320ccSDaniel Jeong goto err_regulator; 494240a5291SAxel Lin } 495b59320ccSDaniel Jeong 496b59320ccSDaniel Jeong pchip->irq = client->irq; 497b59320ccSDaniel Jeong ret = lp8755_int_config(pchip); 498240a5291SAxel Lin if (ret < 0) { 499240a5291SAxel Lin dev_err(&client->dev, "fail to irq config\n"); 500b59320ccSDaniel Jeong goto err_irq; 501240a5291SAxel Lin } 502b59320ccSDaniel Jeong 503b59320ccSDaniel Jeong return ret; 504b59320ccSDaniel Jeong 505b59320ccSDaniel Jeong err_irq: 506b59320ccSDaniel Jeong for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++) 507b59320ccSDaniel Jeong regulator_unregister(pchip->rdev[icnt]); 508b59320ccSDaniel Jeong 509b59320ccSDaniel Jeong err_regulator: 510b59320ccSDaniel Jeong /* output disable */ 5111200c60bSAxel Lin for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 512b59320ccSDaniel Jeong lp8755_write(pchip, icnt, 0x00); 513b59320ccSDaniel Jeong 514b59320ccSDaniel Jeong return ret; 515b59320ccSDaniel Jeong } 516b59320ccSDaniel Jeong 517b59320ccSDaniel Jeong static int lp8755_remove(struct i2c_client *client) 518b59320ccSDaniel Jeong { 519b59320ccSDaniel Jeong int icnt; 520b59320ccSDaniel Jeong struct lp8755_chip *pchip = i2c_get_clientdata(client); 521b59320ccSDaniel Jeong 522b59320ccSDaniel Jeong for (icnt = 0; icnt < mphase_buck[pchip->mphase].nreg; icnt++) 523b59320ccSDaniel Jeong regulator_unregister(pchip->rdev[icnt]); 524b59320ccSDaniel Jeong 5251200c60bSAxel Lin for (icnt = 0; icnt < LP8755_BUCK_MAX; icnt++) 526b59320ccSDaniel Jeong lp8755_write(pchip, icnt, 0x00); 527b59320ccSDaniel Jeong 528b59320ccSDaniel Jeong if (pchip->irq != 0) 529b59320ccSDaniel Jeong free_irq(pchip->irq, pchip); 530b59320ccSDaniel Jeong 531b59320ccSDaniel Jeong return 0; 532b59320ccSDaniel Jeong } 533b59320ccSDaniel Jeong 534b59320ccSDaniel Jeong static const struct i2c_device_id lp8755_id[] = { 535b59320ccSDaniel Jeong {LP8755_NAME, 0}, 536b59320ccSDaniel Jeong {} 537b59320ccSDaniel Jeong }; 538b59320ccSDaniel Jeong 539b59320ccSDaniel Jeong MODULE_DEVICE_TABLE(i2c, lp8755_id); 540b59320ccSDaniel Jeong 541b59320ccSDaniel Jeong static struct i2c_driver lp8755_i2c_driver = { 542b59320ccSDaniel Jeong .driver = { 543b59320ccSDaniel Jeong .name = LP8755_NAME, 544b59320ccSDaniel Jeong }, 545b59320ccSDaniel Jeong .probe = lp8755_probe, 546a1a41ab4SAxel Lin .remove = lp8755_remove, 547b59320ccSDaniel Jeong .id_table = lp8755_id, 548b59320ccSDaniel Jeong }; 549b59320ccSDaniel Jeong 550b59320ccSDaniel Jeong static int __init lp8755_init(void) 551b59320ccSDaniel Jeong { 552b59320ccSDaniel Jeong return i2c_add_driver(&lp8755_i2c_driver); 553b59320ccSDaniel Jeong } 554b59320ccSDaniel Jeong 555b59320ccSDaniel Jeong subsys_initcall(lp8755_init); 556b59320ccSDaniel Jeong 557b59320ccSDaniel Jeong static void __exit lp8755_exit(void) 558b59320ccSDaniel Jeong { 559b59320ccSDaniel Jeong i2c_del_driver(&lp8755_i2c_driver); 560b59320ccSDaniel Jeong } 561b59320ccSDaniel Jeong 562b59320ccSDaniel Jeong module_exit(lp8755_exit); 563b59320ccSDaniel Jeong 564b59320ccSDaniel Jeong MODULE_DESCRIPTION("Texas Instruments lp8755 driver"); 565b59320ccSDaniel Jeong MODULE_AUTHOR("Daniel Jeong <daniel.jeong@ti.com>"); 566b59320ccSDaniel Jeong MODULE_LICENSE("GPL v2"); 567