18b385d9b97a63ba621342858f9921324032a9167Sonic Zhang/* 28b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * Voltage and current regulation for AD5398 and AD5821 38b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * 48b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * Copyright 2010 Analog Devices Inc. 58b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * 68b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * Enter bugs at http://blackfin.uclinux.org/ 78b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * 88b385d9b97a63ba621342858f9921324032a9167Sonic Zhang * Licensed under the GPL-2 or later. 98b385d9b97a63ba621342858f9921324032a9167Sonic Zhang */ 108b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 118b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/module.h> 128b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/err.h> 138b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/i2c.h> 148b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/slab.h> 158b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/platform_device.h> 168b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/regulator/driver.h> 178b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#include <linux/regulator/machine.h> 188b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 198b385d9b97a63ba621342858f9921324032a9167Sonic Zhang#define AD5398_CURRENT_EN_MASK 0x8000 208b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 218b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstruct ad5398_chip_info { 228b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct i2c_client *client; 238b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int min_uA; 248b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int max_uA; 258b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned int current_level; 268b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned int current_mask; 278b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned int current_offset; 2858d463eec844f6381d63d04dc89d319ae3057ca9Axel Lin struct regulator_dev *rdev; 298b385d9b97a63ba621342858f9921324032a9167Sonic Zhang}; 308b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 318b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_calc_current(struct ad5398_chip_info *chip, 328b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned selector) 338b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 348b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned range_uA = chip->max_uA - chip->min_uA; 358b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 368b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return chip->min_uA + (selector * range_uA / chip->current_level); 378b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 388b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 398b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_read_reg(struct i2c_client *client, unsigned short *data) 408b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 418b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short val; 428b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 438b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 448b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = i2c_master_recv(client, (char *)&val, 2); 458b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) { 468b385d9b97a63ba621342858f9921324032a9167Sonic Zhang dev_err(&client->dev, "I2C read error\n"); 478b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 488b385d9b97a63ba621342858f9921324032a9167Sonic Zhang } 498b385d9b97a63ba621342858f9921324032a9167Sonic Zhang *data = be16_to_cpu(val); 508b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 518b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 528b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 538b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 548b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_write_reg(struct i2c_client *client, const unsigned short data) 558b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 568b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short val; 578b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 588b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 598b385d9b97a63ba621342858f9921324032a9167Sonic Zhang val = cpu_to_be16(data); 608b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = i2c_master_send(client, (char *)&val, 2); 618b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) 628b385d9b97a63ba621342858f9921324032a9167Sonic Zhang dev_err(&client->dev, "I2C write error\n"); 638b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 648b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 658b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 668b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 678b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_get_current_limit(struct regulator_dev *rdev) 688b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 698b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); 708b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct i2c_client *client = chip->client; 718b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short data; 728b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 738b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 748b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_read_reg(client, &data); 758b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) 768b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 778b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 788b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = (data & chip->current_mask) >> chip->current_offset; 798b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 808b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ad5398_calc_current(chip, ret); 818b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 828b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 838b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) 848b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 858b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); 868b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct i2c_client *client = chip->client; 878b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned range_uA = chip->max_uA - chip->min_uA; 888b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned selector; 898b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short data; 908b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 918b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 928b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (min_uA > chip->max_uA || min_uA < chip->min_uA) 938b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return -EINVAL; 948b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (max_uA > chip->max_uA || max_uA < chip->min_uA) 958b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return -EINVAL; 968b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 978148ed6e6618598729efa53d3a1f905379de801eAxel Lin selector = DIV_ROUND_UP((min_uA - chip->min_uA) * chip->current_level, 988148ed6e6618598729efa53d3a1f905379de801eAxel Lin range_uA); 998b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ad5398_calc_current(chip, selector) > max_uA) 1008b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return -EINVAL; 1018b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1028b385d9b97a63ba621342858f9921324032a9167Sonic Zhang dev_dbg(&client->dev, "changing current %dmA\n", 1038b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ad5398_calc_current(chip, selector) / 1000); 1048b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1058b385d9b97a63ba621342858f9921324032a9167Sonic Zhang /* read chip enable bit */ 1068b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_read_reg(client, &data); 1078b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) 1088b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1098b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1108b385d9b97a63ba621342858f9921324032a9167Sonic Zhang /* prepare register data */ 1118b385d9b97a63ba621342858f9921324032a9167Sonic Zhang selector = (selector << chip->current_offset) & chip->current_mask; 1128b385d9b97a63ba621342858f9921324032a9167Sonic Zhang data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK); 1138b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1148b385d9b97a63ba621342858f9921324032a9167Sonic Zhang /* write the new current value back as well as enable bit */ 1158b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_write_reg(client, data); 1168b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1178b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1188b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 1198b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1208b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_is_enabled(struct regulator_dev *rdev) 1218b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 1228b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); 1238b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct i2c_client *client = chip->client; 1248b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short data; 1258b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 1268b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1278b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_read_reg(client, &data); 1288b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) 1298b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1308b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1318b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (data & AD5398_CURRENT_EN_MASK) 1328b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return 1; 1338b385d9b97a63ba621342858f9921324032a9167Sonic Zhang else 1348b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return 0; 1358b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 1368b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1378b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_enable(struct regulator_dev *rdev) 1388b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 1398b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); 1408b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct i2c_client *client = chip->client; 1418b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short data; 1428b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 1438b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1448b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_read_reg(client, &data); 1458b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) 1468b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1478b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1488b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (data & AD5398_CURRENT_EN_MASK) 1498b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return 0; 1508b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1518b385d9b97a63ba621342858f9921324032a9167Sonic Zhang data |= AD5398_CURRENT_EN_MASK; 1528b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1538b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_write_reg(client, data); 1548b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1558b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1568b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 1578b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1588b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int ad5398_disable(struct regulator_dev *rdev) 1598b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 1608b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); 1618b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct i2c_client *client = chip->client; 1628b385d9b97a63ba621342858f9921324032a9167Sonic Zhang unsigned short data; 1638b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 1648b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1658b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_read_reg(client, &data); 1668b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (ret < 0) 1678b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1688b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1698b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (!(data & AD5398_CURRENT_EN_MASK)) 1708b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return 0; 1718b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1728b385d9b97a63ba621342858f9921324032a9167Sonic Zhang data &= ~AD5398_CURRENT_EN_MASK; 1738b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1748b385d9b97a63ba621342858f9921324032a9167Sonic Zhang ret = ad5398_write_reg(client, data); 1758b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1768b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 1778b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 1788b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1798b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic struct regulator_ops ad5398_ops = { 1808b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .get_current_limit = ad5398_get_current_limit, 1818b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .set_current_limit = ad5398_set_current_limit, 1828b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .enable = ad5398_enable, 1838b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .disable = ad5398_disable, 1848b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .is_enabled = ad5398_is_enabled, 1858b385d9b97a63ba621342858f9921324032a9167Sonic Zhang}; 1868b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1878b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic struct regulator_desc ad5398_reg = { 1888b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .name = "isink", 1898b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .id = 0, 1908b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .ops = &ad5398_ops, 1918b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .type = REGULATOR_CURRENT, 1928b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .owner = THIS_MODULE, 1938b385d9b97a63ba621342858f9921324032a9167Sonic Zhang}; 1948b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 1958b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstruct ad5398_current_data_format { 1968b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int current_bits; 1978b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int current_offset; 1988b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int min_uA; 1998b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int max_uA; 2008b385d9b97a63ba621342858f9921324032a9167Sonic Zhang}; 2018b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2028b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000}; 2038b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2048b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic const struct i2c_device_id ad5398_id[] = { 2058b385d9b97a63ba621342858f9921324032a9167Sonic Zhang { "ad5398", (kernel_ulong_t)&df_10_4_120 }, 2068b385d9b97a63ba621342858f9921324032a9167Sonic Zhang { "ad5821", (kernel_ulong_t)&df_10_4_120 }, 2078b385d9b97a63ba621342858f9921324032a9167Sonic Zhang { } 2088b385d9b97a63ba621342858f9921324032a9167Sonic Zhang}; 2098b385d9b97a63ba621342858f9921324032a9167Sonic ZhangMODULE_DEVICE_TABLE(i2c, ad5398_id); 2108b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2118b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int __devinit ad5398_probe(struct i2c_client *client, 2128b385d9b97a63ba621342858f9921324032a9167Sonic Zhang const struct i2c_device_id *id) 2138b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 2148b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct regulator_init_data *init_data = client->dev.platform_data; 2158b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip; 2168b385d9b97a63ba621342858f9921324032a9167Sonic Zhang const struct ad5398_current_data_format *df = 2178b385d9b97a63ba621342858f9921324032a9167Sonic Zhang (struct ad5398_current_data_format *)id->driver_data; 2188b385d9b97a63ba621342858f9921324032a9167Sonic Zhang int ret; 2198b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2208b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (!init_data) 2218b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return -EINVAL; 2228b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2238b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip = kzalloc(sizeof(*chip), GFP_KERNEL); 2248b385d9b97a63ba621342858f9921324032a9167Sonic Zhang if (!chip) 2258b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return -ENOMEM; 2268b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2278b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip->client = client; 2288b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2298b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip->min_uA = df->min_uA; 2308b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip->max_uA = df->max_uA; 2318b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip->current_level = 1 << df->current_bits; 2328b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip->current_offset = df->current_offset; 2338b385d9b97a63ba621342858f9921324032a9167Sonic Zhang chip->current_mask = (chip->current_level - 1) << chip->current_offset; 2348b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 23558d463eec844f6381d63d04dc89d319ae3057ca9Axel Lin chip->rdev = regulator_register(&ad5398_reg, &client->dev, 2362c043bcbf287dc69848054d5c02c55c20f7a7bc5Rajendra Nayak init_data, chip, NULL); 23758d463eec844f6381d63d04dc89d319ae3057ca9Axel Lin if (IS_ERR(chip->rdev)) { 23858d463eec844f6381d63d04dc89d319ae3057ca9Axel Lin ret = PTR_ERR(chip->rdev); 2398b385d9b97a63ba621342858f9921324032a9167Sonic Zhang dev_err(&client->dev, "failed to register %s %s\n", 2408b385d9b97a63ba621342858f9921324032a9167Sonic Zhang id->name, ad5398_reg.name); 2418b385d9b97a63ba621342858f9921324032a9167Sonic Zhang goto err; 2428b385d9b97a63ba621342858f9921324032a9167Sonic Zhang } 2438b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2448b385d9b97a63ba621342858f9921324032a9167Sonic Zhang i2c_set_clientdata(client, chip); 2458b385d9b97a63ba621342858f9921324032a9167Sonic Zhang dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name); 2468b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return 0; 2478b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2488b385d9b97a63ba621342858f9921324032a9167Sonic Zhangerr: 2498b385d9b97a63ba621342858f9921324032a9167Sonic Zhang kfree(chip); 2508b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return ret; 2518b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 2528b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2538b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int __devexit ad5398_remove(struct i2c_client *client) 2548b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 2558b385d9b97a63ba621342858f9921324032a9167Sonic Zhang struct ad5398_chip_info *chip = i2c_get_clientdata(client); 2568b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 25758d463eec844f6381d63d04dc89d319ae3057ca9Axel Lin regulator_unregister(chip->rdev); 2588b385d9b97a63ba621342858f9921324032a9167Sonic Zhang kfree(chip); 2598b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2608b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return 0; 2618b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 2628b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2638b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic struct i2c_driver ad5398_driver = { 2648b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .probe = ad5398_probe, 2658b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .remove = __devexit_p(ad5398_remove), 2668b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .driver = { 2678b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .name = "ad5398", 2688b385d9b97a63ba621342858f9921324032a9167Sonic Zhang }, 2698b385d9b97a63ba621342858f9921324032a9167Sonic Zhang .id_table = ad5398_id, 2708b385d9b97a63ba621342858f9921324032a9167Sonic Zhang}; 2718b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2728b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic int __init ad5398_init(void) 2738b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 2748b385d9b97a63ba621342858f9921324032a9167Sonic Zhang return i2c_add_driver(&ad5398_driver); 2758b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 276839b8362a78e02d123f6ac586349b357136a733fSonic Zhangsubsys_initcall(ad5398_init); 2778b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2788b385d9b97a63ba621342858f9921324032a9167Sonic Zhangstatic void __exit ad5398_exit(void) 2798b385d9b97a63ba621342858f9921324032a9167Sonic Zhang{ 2808b385d9b97a63ba621342858f9921324032a9167Sonic Zhang i2c_del_driver(&ad5398_driver); 2818b385d9b97a63ba621342858f9921324032a9167Sonic Zhang} 2828b385d9b97a63ba621342858f9921324032a9167Sonic Zhangmodule_exit(ad5398_exit); 2838b385d9b97a63ba621342858f9921324032a9167Sonic Zhang 2848b385d9b97a63ba621342858f9921324032a9167Sonic ZhangMODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver"); 2858b385d9b97a63ba621342858f9921324032a9167Sonic ZhangMODULE_AUTHOR("Sonic Zhang"); 2868b385d9b97a63ba621342858f9921324032a9167Sonic ZhangMODULE_LICENSE("GPL"); 2878b385d9b97a63ba621342858f9921324032a9167Sonic ZhangMODULE_ALIAS("i2c:ad5398-regulator"); 288