From 84c99db879314d58e0064f02b481f668f45d0070 Mon Sep 17 00:00:00 2001 From: Ashish Jangam Date: Mon, 12 Dec 2011 20:06:56 +0530 Subject: MFD: DA9052/53 MFD core module The DA9052/53 is a highly integrated PMIC subsystem with supply domain flexibility to support wide range of high performance application. It provides voltage regulators, GPIO controller, Touch Screen, RTC, Battery control and other functionality. This patch is functionally tested on Samsung SMDKV6410. Signed-off-by: David Dajun Chen Signed-off-by: Ashish Jangam Acked-by: Samuel Ortiz Signed-off-by: Mark Brown --- drivers/mfd/da9052-i2c.c | 140 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 drivers/mfd/da9052-i2c.c (limited to 'drivers/mfd/da9052-i2c.c') diff --git a/drivers/mfd/da9052-i2c.c b/drivers/mfd/da9052-i2c.c new file mode 100644 index 000000000000..44b97c70a61f --- /dev/null +++ b/drivers/mfd/da9052-i2c.c @@ -0,0 +1,140 @@ +/* + * I2C access for DA9052 PMICs. + * + * Copyright(c) 2011 Dialog Semiconductor Ltd. + * + * Author: David Dajun Chen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) +{ + int reg_val, ret; + + ret = regmap_read(da9052->regmap, DA9052_CONTROL_B_REG, ®_val); + if (ret < 0) + return ret; + + if (reg_val & DA9052_CONTROL_B_WRITEMODE) { + reg_val &= ~DA9052_CONTROL_B_WRITEMODE; + ret = regmap_write(da9052->regmap, DA9052_CONTROL_B_REG, + reg_val); + if (ret < 0) + return ret; + } + + return 0; +} + +static int __devinit da9052_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct da9052 *da9052; + int ret; + + da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); + if (!da9052) + return -ENOMEM; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_info(&client->dev, "Error in %s:i2c_check_functionality\n", + __func__); + ret = -ENODEV; + goto err; + } + + da9052->dev = &client->dev; + da9052->chip_irq = client->irq; + + i2c_set_clientdata(client, da9052); + + da9052->regmap = regmap_init_i2c(client, &da9052_regmap_config); + if (IS_ERR(da9052->regmap)) { + ret = PTR_ERR(da9052->regmap); + dev_err(&client->dev, "Failed to allocate register map: %d\n", + ret); + goto err; + } + + ret = da9052_i2c_enable_multiwrite(da9052); + if (ret < 0) + goto err; + + ret = da9052_device_init(da9052, id->driver_data); + if (ret != 0) + goto err; + + return 0; + +err: + kfree(da9052); + return ret; +} + +static int da9052_i2c_remove(struct i2c_client *client) +{ + struct da9052 *da9052 = i2c_get_clientdata(client); + + da9052_device_exit(da9052); + kfree(da9052); + + return 0; +} + +static struct i2c_device_id da9052_i2c_id[] = { + {"da9052", DA9052}, + {"da9053-aa", DA9053_AA}, + {"da9053-ba", DA9053_BA}, + {"da9053-bb", DA9053_BB}, + {} +}; + +static struct i2c_driver da9052_i2c_driver = { + .probe = da9052_i2c_probe, + .remove = da9052_i2c_remove, + .id_table = da9052_i2c_id, + .driver = { + .name = "da9052", + .owner = THIS_MODULE, + }, +}; + +static int __init da9052_i2c_init(void) +{ + int ret; + + ret = i2c_add_driver(&da9052_i2c_driver); + if (ret != 0) { + pr_err("DA9052 I2C registration failed %d\n", ret); + return ret; + } + + return 0; +} +subsys_initcall(da9052_i2c_init); + +static void __exit da9052_i2c_exit(void) +{ + i2c_del_driver(&da9052_i2c_driver); +} +module_exit(da9052_i2c_exit); + +MODULE_AUTHOR("David Dajun Chen "); +MODULE_DESCRIPTION("I2C driver for Dialog DA9052 PMIC"); +MODULE_LICENSE("GPL"); -- cgit v1.2.1