linux/drivers/regulator/max8649.c
<<
>>
Prefs
   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
 410