Initial Contribution
msm-2.6.38: tag AU_LINUX_ANDROID_GINGERBREAD.02.03.04.00.142
Signed-off-by: Bryan Huntsman <bryanh@codeaurora.org>
diff --git a/drivers/mfd/tps65023.c b/drivers/mfd/tps65023.c
new file mode 100644
index 0000000..e67997c
--- /dev/null
+++ b/drivers/mfd/tps65023.c
@@ -0,0 +1,122 @@
+/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/i2c.h>
+#include <linux/mfd/tps65023.h>
+
+/* TPS65023_registers */
+#define TPS65023_VERSION 0
+#define TPS65023_PGOODZ 1
+#define TPS65023_MASK 2
+#define TPS65023_REG_CTRL 3
+#define TPS65023_CON_CTRL 4
+#define TPS65023_CON_CTRL2 5
+#define TPS65023_DEFCORE 6
+#define TPS65023_DEFSLEW 7
+#define TPS65023_LDO_CTRL 8
+#define TPS65023_MAX 9
+
+static struct i2c_client *tpsclient;
+
+int tps65023_set_dcdc1_level(int mvolts)
+{
+ int val;
+ int ret;
+
+ if (!tpsclient)
+ return -ENODEV;
+
+ if (mvolts < 800 || mvolts > 1600)
+ return -EINVAL;
+
+ if (mvolts == 1600)
+ val = 0x1F;
+ else
+ val = ((mvolts - 800)/25) & 0x1F;
+
+ ret = i2c_smbus_write_byte_data(tpsclient, TPS65023_DEFCORE, val);
+
+ if (!ret)
+ ret = i2c_smbus_write_byte_data(tpsclient,
+ TPS65023_CON_CTRL2, 0x80);
+
+ return ret;
+}
+EXPORT_SYMBOL(tps65023_set_dcdc1_level);
+
+int tps65023_get_dcdc1_level(int *mvolts)
+{
+ int val;
+
+ if (!tpsclient)
+ return -ENODEV;
+
+ val = i2c_smbus_read_byte_data(tpsclient, TPS65023_DEFCORE) & 0x1F;
+
+ if (val == 0x1F)
+ *mvolts = 1600;
+ else
+ *mvolts = (val * 25) + 800;
+ return 0;
+}
+EXPORT_SYMBOL(tps65023_get_dcdc1_level);
+
+static int tps65023_probe(struct i2c_client *client,
+ const struct i2c_device_id *dev_id)
+{
+ if (!i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_BYTE_DATA)) {
+ printk(KERN_ERR "TPS65023 does not support SMBUS_BYTE_DATA.\n");
+ return -EINVAL;
+ }
+
+ tpsclient = client;
+ printk(KERN_INFO "TPS65023: PMIC probed.\n");
+ return 0;
+}
+
+static int __devexit tps65023_remove(struct i2c_client *client)
+{
+ tpsclient = NULL;
+ return 0;
+}
+
+static const struct i2c_device_id tps65023_id[] = {
+ { "tps65023", 0 },
+ { }
+};
+MODULE_DEVICE_TABLE(i2c, tps65023_id);
+
+static struct i2c_driver tps65023_driver = {
+ .driver = {
+ .name = "tps65023",
+ .owner = THIS_MODULE,
+ },
+ .probe = tps65023_probe,
+ .remove = __devexit_p(tps65023_remove),
+ .id_table = tps65023_id,
+};
+
+static int __init tps65023_init(void)
+{
+ return i2c_add_driver(&tps65023_driver);
+}
+
+
+static void __exit tps65023_exit(void)
+{
+ i2c_del_driver(&tps65023_driver);
+}
+
+module_init(tps65023_init);
+module_exit(tps65023_exit);