Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Voltage and current regulation for AD5398 and AD5821
0004  *
0005  * Copyright 2010 Analog Devices Inc.
0006  *
0007  * Enter bugs at http://blackfin.uclinux.org/
0008  */
0009 
0010 #include <linux/module.h>
0011 #include <linux/err.h>
0012 #include <linux/i2c.h>
0013 #include <linux/slab.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/regulator/driver.h>
0016 #include <linux/regulator/machine.h>
0017 
0018 #define AD5398_CURRENT_EN_MASK  0x8000
0019 
0020 struct ad5398_chip_info {
0021     struct i2c_client *client;
0022     int min_uA;
0023     int max_uA;
0024     unsigned int current_level;
0025     unsigned int current_mask;
0026     unsigned int current_offset;
0027     struct regulator_dev *rdev;
0028 };
0029 
0030 static int ad5398_calc_current(struct ad5398_chip_info *chip,
0031     unsigned selector)
0032 {
0033     unsigned range_uA = chip->max_uA - chip->min_uA;
0034 
0035     return chip->min_uA + (selector * range_uA / chip->current_level);
0036 }
0037 
0038 static int ad5398_read_reg(struct i2c_client *client, unsigned short *data)
0039 {
0040     unsigned short val;
0041     int ret;
0042 
0043     ret = i2c_master_recv(client, (char *)&val, 2);
0044     if (ret < 0) {
0045         dev_err(&client->dev, "I2C read error\n");
0046         return ret;
0047     }
0048     *data = be16_to_cpu(val);
0049 
0050     return ret;
0051 }
0052 
0053 static int ad5398_write_reg(struct i2c_client *client, const unsigned short data)
0054 {
0055     unsigned short val;
0056     int ret;
0057 
0058     val = cpu_to_be16(data);
0059     ret = i2c_master_send(client, (char *)&val, 2);
0060     if (ret != 2) {
0061         dev_err(&client->dev, "I2C write error\n");
0062         return ret < 0 ? ret : -EIO;
0063     }
0064 
0065     return 0;
0066 }
0067 
0068 static int ad5398_get_current_limit(struct regulator_dev *rdev)
0069 {
0070     struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
0071     struct i2c_client *client = chip->client;
0072     unsigned short data;
0073     int ret;
0074 
0075     ret = ad5398_read_reg(client, &data);
0076     if (ret < 0)
0077         return ret;
0078 
0079     ret = (data & chip->current_mask) >> chip->current_offset;
0080 
0081     return ad5398_calc_current(chip, ret);
0082 }
0083 
0084 static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
0085 {
0086     struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
0087     struct i2c_client *client = chip->client;
0088     unsigned range_uA = chip->max_uA - chip->min_uA;
0089     unsigned selector;
0090     unsigned short data;
0091     int ret;
0092 
0093     if (min_uA < chip->min_uA)
0094         min_uA = chip->min_uA;
0095     if (max_uA > chip->max_uA)
0096         max_uA = chip->max_uA;
0097 
0098     if (min_uA > chip->max_uA || max_uA < chip->min_uA)
0099         return -EINVAL;
0100 
0101     selector = DIV_ROUND_UP((min_uA - chip->min_uA) * chip->current_level,
0102                 range_uA);
0103     if (ad5398_calc_current(chip, selector) > max_uA)
0104         return -EINVAL;
0105 
0106     dev_dbg(&client->dev, "changing current %duA\n",
0107         ad5398_calc_current(chip, selector));
0108 
0109     /* read chip enable bit */
0110     ret = ad5398_read_reg(client, &data);
0111     if (ret < 0)
0112         return ret;
0113 
0114     /* prepare register data */
0115     selector = (selector << chip->current_offset) & chip->current_mask;
0116     data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK);
0117 
0118     /* write the new current value back as well as enable bit */
0119     ret = ad5398_write_reg(client, data);
0120 
0121     return ret;
0122 }
0123 
0124 static int ad5398_is_enabled(struct regulator_dev *rdev)
0125 {
0126     struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
0127     struct i2c_client *client = chip->client;
0128     unsigned short data;
0129     int ret;
0130 
0131     ret = ad5398_read_reg(client, &data);
0132     if (ret < 0)
0133         return ret;
0134 
0135     if (data & AD5398_CURRENT_EN_MASK)
0136         return 1;
0137     else
0138         return 0;
0139 }
0140 
0141 static int ad5398_enable(struct regulator_dev *rdev)
0142 {
0143     struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
0144     struct i2c_client *client = chip->client;
0145     unsigned short data;
0146     int ret;
0147 
0148     ret = ad5398_read_reg(client, &data);
0149     if (ret < 0)
0150         return ret;
0151 
0152     if (data & AD5398_CURRENT_EN_MASK)
0153         return 0;
0154 
0155     data |= AD5398_CURRENT_EN_MASK;
0156 
0157     ret = ad5398_write_reg(client, data);
0158 
0159     return ret;
0160 }
0161 
0162 static int ad5398_disable(struct regulator_dev *rdev)
0163 {
0164     struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
0165     struct i2c_client *client = chip->client;
0166     unsigned short data;
0167     int ret;
0168 
0169     ret = ad5398_read_reg(client, &data);
0170     if (ret < 0)
0171         return ret;
0172 
0173     if (!(data & AD5398_CURRENT_EN_MASK))
0174         return 0;
0175 
0176     data &= ~AD5398_CURRENT_EN_MASK;
0177 
0178     ret = ad5398_write_reg(client, data);
0179 
0180     return ret;
0181 }
0182 
0183 static const struct regulator_ops ad5398_ops = {
0184     .get_current_limit = ad5398_get_current_limit,
0185     .set_current_limit = ad5398_set_current_limit,
0186     .enable = ad5398_enable,
0187     .disable = ad5398_disable,
0188     .is_enabled = ad5398_is_enabled,
0189 };
0190 
0191 static const struct regulator_desc ad5398_reg = {
0192     .name = "isink",
0193     .id = 0,
0194     .ops = &ad5398_ops,
0195     .type = REGULATOR_CURRENT,
0196     .owner = THIS_MODULE,
0197 };
0198 
0199 struct ad5398_current_data_format {
0200     int current_bits;
0201     int current_offset;
0202     int min_uA;
0203     int max_uA;
0204 };
0205 
0206 static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
0207 
0208 static const struct i2c_device_id ad5398_id[] = {
0209     { "ad5398", (kernel_ulong_t)&df_10_4_120 },
0210     { "ad5821", (kernel_ulong_t)&df_10_4_120 },
0211     { }
0212 };
0213 MODULE_DEVICE_TABLE(i2c, ad5398_id);
0214 
0215 static int ad5398_probe(struct i2c_client *client,
0216                 const struct i2c_device_id *id)
0217 {
0218     struct regulator_init_data *init_data = dev_get_platdata(&client->dev);
0219     struct regulator_config config = { };
0220     struct ad5398_chip_info *chip;
0221     const struct ad5398_current_data_format *df =
0222             (struct ad5398_current_data_format *)id->driver_data;
0223 
0224     if (!init_data)
0225         return -EINVAL;
0226 
0227     chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
0228     if (!chip)
0229         return -ENOMEM;
0230 
0231     config.dev = &client->dev;
0232     config.init_data = init_data;
0233     config.driver_data = chip;
0234 
0235     chip->client = client;
0236 
0237     chip->min_uA = df->min_uA;
0238     chip->max_uA = df->max_uA;
0239     chip->current_level = 1 << df->current_bits;
0240     chip->current_offset = df->current_offset;
0241     chip->current_mask = (chip->current_level - 1) << chip->current_offset;
0242 
0243     chip->rdev = devm_regulator_register(&client->dev, &ad5398_reg,
0244                          &config);
0245     if (IS_ERR(chip->rdev)) {
0246         dev_err(&client->dev, "failed to register %s %s\n",
0247             id->name, ad5398_reg.name);
0248         return PTR_ERR(chip->rdev);
0249     }
0250 
0251     i2c_set_clientdata(client, chip);
0252     dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name);
0253     return 0;
0254 }
0255 
0256 static struct i2c_driver ad5398_driver = {
0257     .probe = ad5398_probe,
0258     .driver     = {
0259         .name   = "ad5398",
0260     },
0261     .id_table   = ad5398_id,
0262 };
0263 
0264 static int __init ad5398_init(void)
0265 {
0266     return i2c_add_driver(&ad5398_driver);
0267 }
0268 subsys_initcall(ad5398_init);
0269 
0270 static void __exit ad5398_exit(void)
0271 {
0272     i2c_del_driver(&ad5398_driver);
0273 }
0274 module_exit(ad5398_exit);
0275 
0276 MODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver");
0277 MODULE_AUTHOR("Sonic Zhang");
0278 MODULE_LICENSE("GPL");