/drivers/regulator/max8649.c
C | 409 lines | 324 code | 61 blank | 24 comment | 24 complexity | 54cd97ce369008ed3170912a063a685a MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
1/* 2 * Regulators driver for Maxim max8649 3 * 4 * Copyright (C) 2009-2010 Marvell International Ltd. 5 * Haojian Zhuang <haojian.zhuang@marvell.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 version 2 as 9 * published by the Free Software Foundation. 10 */ 11#include <linux/kernel.h> 12#include <linux/module.h> 13#include <linux/err.h> 14#include <linux/i2c.h> 15#include <linux/platform_device.h> 16#include <linux/regulator/driver.h> 17#include <linux/slab.h> 18#include <linux/regulator/max8649.h> 19 20#define MAX8649_DCDC_VMIN 750000 /* uV */ 21#define MAX8649_DCDC_VMAX 1380000 /* uV */ 22#define MAX8649_DCDC_STEP 10000 /* uV */ 23#define MAX8649_VOL_MASK 0x3f 24 25/* Registers */ 26#define MAX8649_MODE0 0x00 27#define MAX8649_MODE1 0x01 28#define MAX8649_MODE2 0x02 29#define MAX8649_MODE3 0x03 30#define MAX8649_CONTROL 0x04 31#define MAX8649_SYNC 0x05 32#define MAX8649_RAMP 0x06 33#define MAX8649_CHIP_ID1 0x08 34#define MAX8649_CHIP_ID2 0x09 35 36/* Bits */ 37#define MAX8649_EN_PD (1 << 7) 38#define MAX8649_VID0_PD (1 << 6) 39#define MAX8649_VID1_PD (1 << 5) 40#define MAX8649_VID_MASK (3 << 5) 41 42#define MAX8649_FORCE_PWM (1 << 7) 43#define MAX8649_SYNC_EXTCLK (1 << 6) 44 45#define MAX8649_EXT_MASK (3 << 6) 46 47#define MAX8649_RAMP_MASK (7 << 5) 48#define MAX8649_RAMP_DOWN (1 << 1) 49 50struct max8649_regulator_info { 51 struct regulator_dev *regulator; 52 struct i2c_client *i2c; 53 struct device *dev; 54 struct mutex io_lock; 55 56 int vol_reg; 57 unsigned mode:2; /* bit[1:0] = VID1, VID0 */ 58 unsigned extclk_freq:2; 59 unsigned extclk:1; 60 unsigned ramp_timing:3; 61 unsigned ramp_down:1; 62}; 63 64/* I2C operations */ 65 66static inline int max8649_read_device(struct i2c_client *i2c, 67 int reg, int bytes, void *dest) 68{ 69 unsigned char data; 70 int ret; 71 72 data = (unsigned char)reg; 73 ret = i2c_master_send(i2c, &data, 1); 74 if (ret < 0) 75 return ret; 76 ret = i2c_master_recv(i2c, dest, bytes); 77 if (ret < 0) 78 return ret; 79 return 0; 80} 81 82static inline int max8649_write_device(struct i2c_client *i2c, 83 int reg, int bytes, void *src) 84{ 85 unsigned char buf[bytes + 1]; 86 int ret; 87 88 buf[0] = (unsigned char)reg; 89 memcpy(&buf[1], src, bytes); 90 91 ret = i2c_master_send(i2c, buf, bytes + 1); 92 if (ret < 0) 93 return ret; 94 return 0; 95} 96 97static int max8649_reg_read(struct i2c_client *i2c, int reg) 98{ 99 struct max8649_regulator_info *info = i2c_get_clientdata(i2c); 100 unsigned char data; 101 int ret; 102 103 mutex_lock(&info->io_lock); 104 ret = max8649_read_device(i2c, reg, 1, &data); 105 mutex_unlock(&info->io_lock); 106 107 if (ret < 0) 108 return ret; 109 return (int)data; 110} 111 112static int max8649_set_bits(struct i2c_client *i2c, int reg, 113 unsigned char mask, unsigned char data) 114{ 115 struct max8649_regulator_info *info = i2c_get_clientdata(i2c); 116 unsigned char value; 117 int ret; 118 119 mutex_lock(&info->io_lock); 120 ret = max8649_read_device(i2c, reg, 1, &value); 121 if (ret < 0) 122 goto out; 123 value &= ~mask; 124 value |= data; 125 ret = max8649_write_device(i2c, reg, 1, &value); 126out: 127 mutex_unlock(&info->io_lock); 128 return ret; 129} 130 131static inline int check_range(int min_uV, int max_uV) 132{ 133 if ((min_uV < MAX8649_DCDC_VMIN) || (max_uV > MAX8649_DCDC_VMAX) 134 || (min_uV > max_uV)) 135 return -EINVAL; 136 return 0; 137} 138 139static int max8649_list_voltage(struct regulator_dev *rdev, unsigned index) 140{ 141 return (MAX8649_DCDC_VMIN + index * MAX8649_DCDC_STEP); 142} 143 144static int max8649_get_voltage(struct regulator_dev *rdev) 145{ 146 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 147 unsigned char data; 148 int ret; 149 150 ret = max8649_reg_read(info->i2c, info->vol_reg); 151 if (ret < 0) 152 return ret; 153 data = (unsigned char)ret & MAX8649_VOL_MASK; 154 return max8649_list_voltage(rdev, data); 155} 156 157static int max8649_set_voltage(struct regulator_dev *rdev, 158 int min_uV, int max_uV, unsigned *selector) 159{ 160 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 161 unsigned char data, mask; 162 163 if (check_range(min_uV, max_uV)) { 164 dev_err(info->dev, "invalid voltage range (%d, %d) uV\n", 165 min_uV, max_uV); 166 return -EINVAL; 167 } 168 data = (min_uV - MAX8649_DCDC_VMIN + MAX8649_DCDC_STEP - 1) 169 / MAX8649_DCDC_STEP; 170 mask = MAX8649_VOL_MASK; 171 *selector = data & mask; 172 173 return max8649_set_bits(info->i2c, info->vol_reg, mask, data); 174} 175 176/* EN_PD means pulldown on EN input */ 177static int max8649_enable(struct regulator_dev *rdev) 178{ 179 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 180 return max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_EN_PD, 0); 181} 182 183/* 184 * Applied internal pulldown resistor on EN input pin. 185 * If pulldown EN pin outside, it would be better. 186 */ 187static int max8649_disable(struct regulator_dev *rdev) 188{ 189 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 190 return max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_EN_PD, 191 MAX8649_EN_PD); 192} 193 194static int max8649_is_enabled(struct regulator_dev *rdev) 195{ 196 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 197 int ret; 198 199 ret = max8649_reg_read(info->i2c, MAX8649_CONTROL); 200 if (ret < 0) 201 return ret; 202 return !((unsigned char)ret & MAX8649_EN_PD); 203} 204 205static int max8649_enable_time(struct regulator_dev *rdev) 206{ 207 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 208 int voltage, rate, ret; 209 210 /* get voltage */ 211 ret = max8649_reg_read(info->i2c, info->vol_reg); 212 if (ret < 0) 213 return ret; 214 ret &= MAX8649_VOL_MASK; 215 voltage = max8649_list_voltage(rdev, (unsigned char)ret); /* uV */ 216 217 /* get rate */ 218 ret = max8649_reg_read(info->i2c, MAX8649_RAMP); 219 if (ret < 0) 220 return ret; 221 ret = (ret & MAX8649_RAMP_MASK) >> 5; 222 rate = (32 * 1000) >> ret; /* uV/uS */ 223 224 return (voltage / rate); 225} 226 227static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode) 228{ 229 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 230 231 switch (mode) { 232 case REGULATOR_MODE_FAST: 233 max8649_set_bits(info->i2c, info->vol_reg, MAX8649_FORCE_PWM, 234 MAX8649_FORCE_PWM); 235 break; 236 case REGULATOR_MODE_NORMAL: 237 max8649_set_bits(info->i2c, info->vol_reg, 238 MAX8649_FORCE_PWM, 0); 239 break; 240 default: 241 return -EINVAL; 242 } 243 return 0; 244} 245 246static unsigned int max8649_get_mode(struct regulator_dev *rdev) 247{ 248 struct max8649_regulator_info *info = rdev_get_drvdata(rdev); 249 int ret; 250 251 ret = max8649_reg_read(info->i2c, info->vol_reg); 252 if (ret & MAX8649_FORCE_PWM) 253 return REGULATOR_MODE_FAST; 254 return REGULATOR_MODE_NORMAL; 255} 256 257static struct regulator_ops max8649_dcdc_ops = { 258 .set_voltage = max8649_set_voltage, 259 .get_voltage = max8649_get_voltage, 260 .list_voltage = max8649_list_voltage, 261 .enable = max8649_enable, 262 .disable = max8649_disable, 263 .is_enabled = max8649_is_enabled, 264 .enable_time = max8649_enable_time, 265 .set_mode = max8649_set_mode, 266 .get_mode = max8649_get_mode, 267 268}; 269 270static struct regulator_desc dcdc_desc = { 271 .name = "max8649", 272 .ops = &max8649_dcdc_ops, 273 .type = REGULATOR_VOLTAGE, 274 .n_voltages = 1 << 6, 275 .owner = THIS_MODULE, 276}; 277 278static int __devinit max8649_regulator_probe(struct i2c_client *client, 279 const struct i2c_device_id *id) 280{ 281 struct max8649_platform_data *pdata = client->dev.platform_data; 282 struct max8649_regulator_info *info = NULL; 283 unsigned char data; 284 int ret; 285 286 info = kzalloc(sizeof(struct max8649_regulator_info), GFP_KERNEL); 287 if (!info) { 288 dev_err(&client->dev, "No enough memory\n"); 289 return -ENOMEM; 290 } 291 292 info->i2c = client; 293 info->dev = &client->dev; 294 mutex_init(&info->io_lock); 295 i2c_set_clientdata(client, info); 296 297 info->mode = pdata->mode; 298 switch (info->mode) { 299 case 0: 300 info->vol_reg = MAX8649_MODE0; 301 break; 302 case 1: 303 info->vol_reg = MAX8649_MODE1; 304 break; 305 case 2: 306 info->vol_reg = MAX8649_MODE2; 307 break; 308 case 3: 309 info->vol_reg = MAX8649_MODE3; 310 break; 311 default: 312 break; 313 } 314 315 ret = max8649_reg_read(info->i2c, MAX8649_CHIP_ID1); 316 if (ret < 0) { 317 dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n", 318 ret); 319 goto out; 320 } 321 dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", ret); 322 323 /* enable VID0 & VID1 */ 324 max8649_set_bits(info->i2c, MAX8649_CONTROL, MAX8649_VID_MASK, 0); 325 326 /* enable/disable external clock synchronization */ 327 info->extclk = pdata->extclk; 328 data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0; 329 max8649_set_bits(info->i2c, info->vol_reg, MAX8649_SYNC_EXTCLK, data); 330 if (info->extclk) { 331 /* set external clock frequency */ 332 info->extclk_freq = pdata->extclk_freq; 333 max8649_set_bits(info->i2c, MAX8649_SYNC, MAX8649_EXT_MASK, 334 info->extclk_freq << 6); 335 } 336 337 if (pdata->ramp_timing) { 338 info->ramp_timing = pdata->ramp_timing; 339 max8649_set_bits(info->i2c, MAX8649_RAMP, MAX8649_RAMP_MASK, 340 info->ramp_timing << 5); 341 } 342 343 info->ramp_down = pdata->ramp_down; 344 if (info->ramp_down) { 345 max8649_set_bits(info->i2c, MAX8649_RAMP, MAX8649_RAMP_DOWN, 346 MAX8649_RAMP_DOWN); 347 } 348 349 info->regulator = regulator_register(&dcdc_desc, &client->dev, 350 pdata->regulator, info); 351 if (IS_ERR(info->regulator)) { 352 dev_err(info->dev, "failed to register regulator %s\n", 353 dcdc_desc.name); 354 ret = PTR_ERR(info->regulator); 355 goto out; 356 } 357 358 dev_info(info->dev, "Max8649 regulator device is detected.\n"); 359 return 0; 360out: 361 kfree(info); 362 return ret; 363} 364 365static int __devexit max8649_regulator_remove(struct i2c_client *client) 366{ 367 struct max8649_regulator_info *info = i2c_get_clientdata(client); 368 369 if (info) { 370 if (info->regulator) 371 regulator_unregister(info->regulator); 372 kfree(info); 373 } 374 375 return 0; 376} 377 378static const struct i2c_device_id max8649_id[] = { 379 { "max8649", 0 }, 380 { } 381}; 382MODULE_DEVICE_TABLE(i2c, max8649_id); 383 384static struct i2c_driver max8649_driver = { 385 .probe = max8649_regulator_probe, 386 .remove = __devexit_p(max8649_regulator_remove), 387 .driver = { 388 .name = "max8649", 389 }, 390 .id_table = max8649_id, 391}; 392 393static int __init max8649_init(void) 394{ 395 return i2c_add_driver(&max8649_driver); 396} 397subsys_initcall(max8649_init); 398 399static void __exit max8649_exit(void) 400{ 401 i2c_del_driver(&max8649_driver); 402} 403module_exit(max8649_exit); 404 405/* Module information */ 406MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver"); 407MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>"); 408MODULE_LICENSE("GPL"); 409