root/drivers/regulator/max8649.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. max8649_enable_time
  2. max8649_set_mode
  3. max8649_get_mode
  4. max8649_regulator_probe
  5. max8649_init
  6. max8649_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Regulators driver for Maxim max8649
   4  *
   5  * Copyright (C) 2009-2010 Marvell International Ltd.
   6  *      Haojian Zhuang <haojian.zhuang@marvell.com>
   7  */
   8 #include <linux/kernel.h>
   9 #include <linux/module.h>
  10 #include <linux/err.h>
  11 #include <linux/i2c.h>
  12 #include <linux/platform_device.h>
  13 #include <linux/regulator/driver.h>
  14 #include <linux/slab.h>
  15 #include <linux/regulator/max8649.h>
  16 #include <linux/regmap.h>
  17 
  18 #define MAX8649_DCDC_VMIN       750000          /* uV */
  19 #define MAX8649_DCDC_VMAX       1380000         /* uV */
  20 #define MAX8649_DCDC_STEP       10000           /* uV */
  21 #define MAX8649_VOL_MASK        0x3f
  22 
  23 /* Registers */
  24 #define MAX8649_MODE0           0x00
  25 #define MAX8649_MODE1           0x01
  26 #define MAX8649_MODE2           0x02
  27 #define MAX8649_MODE3           0x03
  28 #define MAX8649_CONTROL         0x04
  29 #define MAX8649_SYNC            0x05
  30 #define MAX8649_RAMP            0x06
  31 #define MAX8649_CHIP_ID1        0x08
  32 #define MAX8649_CHIP_ID2        0x09
  33 
  34 /* Bits */
  35 #define MAX8649_EN_PD           (1 << 7)
  36 #define MAX8649_VID0_PD         (1 << 6)
  37 #define MAX8649_VID1_PD         (1 << 5)
  38 #define MAX8649_VID_MASK        (3 << 5)
  39 
  40 #define MAX8649_FORCE_PWM       (1 << 7)
  41 #define MAX8649_SYNC_EXTCLK     (1 << 6)
  42 
  43 #define MAX8649_EXT_MASK        (3 << 6)
  44 
  45 #define MAX8649_RAMP_MASK       (7 << 5)
  46 #define MAX8649_RAMP_DOWN       (1 << 1)
  47 
  48 struct max8649_regulator_info {
  49         struct device           *dev;
  50         struct regmap           *regmap;
  51 
  52         unsigned        mode:2; /* bit[1:0] = VID1, VID0 */
  53         unsigned        extclk_freq:2;
  54         unsigned        extclk:1;
  55         unsigned        ramp_timing:3;
  56         unsigned        ramp_down:1;
  57 };
  58 
  59 static int max8649_enable_time(struct regulator_dev *rdev)
  60 {
  61         struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
  62         int voltage, rate, ret;
  63         unsigned int val;
  64 
  65         /* get voltage */
  66         ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val);
  67         if (ret != 0)
  68                 return ret;
  69         val &= MAX8649_VOL_MASK;
  70         voltage = regulator_list_voltage_linear(rdev, (unsigned char)val);
  71 
  72         /* get rate */
  73         ret = regmap_read(info->regmap, MAX8649_RAMP, &val);
  74         if (ret != 0)
  75                 return ret;
  76         ret = (val & MAX8649_RAMP_MASK) >> 5;
  77         rate = (32 * 1000) >> ret;      /* uV/uS */
  78 
  79         return DIV_ROUND_UP(voltage, rate);
  80 }
  81 
  82 static int max8649_set_mode(struct regulator_dev *rdev, unsigned int mode)
  83 {
  84         struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
  85 
  86         switch (mode) {
  87         case REGULATOR_MODE_FAST:
  88                 regmap_update_bits(info->regmap, rdev->desc->vsel_reg,
  89                                    MAX8649_FORCE_PWM, MAX8649_FORCE_PWM);
  90                 break;
  91         case REGULATOR_MODE_NORMAL:
  92                 regmap_update_bits(info->regmap, rdev->desc->vsel_reg,
  93                                    MAX8649_FORCE_PWM, 0);
  94                 break;
  95         default:
  96                 return -EINVAL;
  97         }
  98         return 0;
  99 }
 100 
 101 static unsigned int max8649_get_mode(struct regulator_dev *rdev)
 102 {
 103         struct max8649_regulator_info *info = rdev_get_drvdata(rdev);
 104         unsigned int val;
 105         int ret;
 106 
 107         ret = regmap_read(info->regmap, rdev->desc->vsel_reg, &val);
 108         if (ret != 0)
 109                 return ret;
 110         if (val & MAX8649_FORCE_PWM)
 111                 return REGULATOR_MODE_FAST;
 112         return REGULATOR_MODE_NORMAL;
 113 }
 114 
 115 static const struct regulator_ops max8649_dcdc_ops = {
 116         .set_voltage_sel = regulator_set_voltage_sel_regmap,
 117         .get_voltage_sel = regulator_get_voltage_sel_regmap,
 118         .list_voltage   = regulator_list_voltage_linear,
 119         .map_voltage    = regulator_map_voltage_linear,
 120         .enable         = regulator_enable_regmap,
 121         .disable        = regulator_disable_regmap,
 122         .is_enabled     = regulator_is_enabled_regmap,
 123         .enable_time    = max8649_enable_time,
 124         .set_mode       = max8649_set_mode,
 125         .get_mode       = max8649_get_mode,
 126 
 127 };
 128 
 129 static struct regulator_desc dcdc_desc = {
 130         .name           = "max8649",
 131         .ops            = &max8649_dcdc_ops,
 132         .type           = REGULATOR_VOLTAGE,
 133         .n_voltages     = 1 << 6,
 134         .owner          = THIS_MODULE,
 135         .vsel_mask      = MAX8649_VOL_MASK,
 136         .min_uV         = MAX8649_DCDC_VMIN,
 137         .uV_step        = MAX8649_DCDC_STEP,
 138         .enable_reg     = MAX8649_CONTROL,
 139         .enable_mask    = MAX8649_EN_PD,
 140         .enable_is_inverted = true,
 141 };
 142 
 143 static const struct regmap_config max8649_regmap_config = {
 144         .reg_bits = 8,
 145         .val_bits = 8,
 146 };
 147 
 148 static int max8649_regulator_probe(struct i2c_client *client,
 149                                              const struct i2c_device_id *id)
 150 {
 151         struct max8649_platform_data *pdata = dev_get_platdata(&client->dev);
 152         struct max8649_regulator_info *info = NULL;
 153         struct regulator_dev *regulator;
 154         struct regulator_config config = { };
 155         unsigned int val;
 156         unsigned char data;
 157         int ret;
 158 
 159         info = devm_kzalloc(&client->dev, sizeof(struct max8649_regulator_info),
 160                             GFP_KERNEL);
 161         if (!info)
 162                 return -ENOMEM;
 163 
 164         info->regmap = devm_regmap_init_i2c(client, &max8649_regmap_config);
 165         if (IS_ERR(info->regmap)) {
 166                 ret = PTR_ERR(info->regmap);
 167                 dev_err(&client->dev, "Failed to allocate register map: %d\n", ret);
 168                 return ret;
 169         }
 170 
 171         info->dev = &client->dev;
 172         i2c_set_clientdata(client, info);
 173 
 174         info->mode = pdata->mode;
 175         switch (info->mode) {
 176         case 0:
 177                 dcdc_desc.vsel_reg = MAX8649_MODE0;
 178                 break;
 179         case 1:
 180                 dcdc_desc.vsel_reg = MAX8649_MODE1;
 181                 break;
 182         case 2:
 183                 dcdc_desc.vsel_reg = MAX8649_MODE2;
 184                 break;
 185         case 3:
 186                 dcdc_desc.vsel_reg = MAX8649_MODE3;
 187                 break;
 188         default:
 189                 break;
 190         }
 191 
 192         ret = regmap_read(info->regmap, MAX8649_CHIP_ID1, &val);
 193         if (ret != 0) {
 194                 dev_err(info->dev, "Failed to detect ID of MAX8649:%d\n",
 195                         ret);
 196                 return ret;
 197         }
 198         dev_info(info->dev, "Detected MAX8649 (ID:%x)\n", val);
 199 
 200         /* enable VID0 & VID1 */
 201         regmap_update_bits(info->regmap, MAX8649_CONTROL, MAX8649_VID_MASK, 0);
 202 
 203         /* enable/disable external clock synchronization */
 204         info->extclk = pdata->extclk;
 205         data = (info->extclk) ? MAX8649_SYNC_EXTCLK : 0;
 206         regmap_update_bits(info->regmap, dcdc_desc.vsel_reg,
 207                            MAX8649_SYNC_EXTCLK, data);
 208         if (info->extclk) {
 209                 /* set external clock frequency */
 210                 info->extclk_freq = pdata->extclk_freq;
 211                 regmap_update_bits(info->regmap, MAX8649_SYNC, MAX8649_EXT_MASK,
 212                                    info->extclk_freq << 6);
 213         }
 214 
 215         if (pdata->ramp_timing) {
 216                 info->ramp_timing = pdata->ramp_timing;
 217                 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_MASK,
 218                                    info->ramp_timing << 5);
 219         }
 220 
 221         info->ramp_down = pdata->ramp_down;
 222         if (info->ramp_down) {
 223                 regmap_update_bits(info->regmap, MAX8649_RAMP, MAX8649_RAMP_DOWN,
 224                                    MAX8649_RAMP_DOWN);
 225         }
 226 
 227         config.dev = &client->dev;
 228         config.init_data = pdata->regulator;
 229         config.driver_data = info;
 230         config.regmap = info->regmap;
 231 
 232         regulator = devm_regulator_register(&client->dev, &dcdc_desc,
 233                                                   &config);
 234         if (IS_ERR(regulator)) {
 235                 dev_err(info->dev, "failed to register regulator %s\n",
 236                         dcdc_desc.name);
 237                 return PTR_ERR(regulator);
 238         }
 239 
 240         return 0;
 241 }
 242 
 243 static const struct i2c_device_id max8649_id[] = {
 244         { "max8649", 0 },
 245         { }
 246 };
 247 MODULE_DEVICE_TABLE(i2c, max8649_id);
 248 
 249 static struct i2c_driver max8649_driver = {
 250         .probe          = max8649_regulator_probe,
 251         .driver         = {
 252                 .name   = "max8649",
 253         },
 254         .id_table       = max8649_id,
 255 };
 256 
 257 static int __init max8649_init(void)
 258 {
 259         return i2c_add_driver(&max8649_driver);
 260 }
 261 subsys_initcall(max8649_init);
 262 
 263 static void __exit max8649_exit(void)
 264 {
 265         i2c_del_driver(&max8649_driver);
 266 }
 267 module_exit(max8649_exit);
 268 
 269 /* Module information */
 270 MODULE_DESCRIPTION("MAXIM 8649 voltage regulator driver");
 271 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
 272 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */