[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-i2c.c b/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-i2c.c
new file mode 100644
index 0000000..a4c5c2f
--- /dev/null
+++ b/ap/os/linux/linux-3.4.x/drivers/mfd/zx234290-i2c.c
@@ -0,0 +1,304 @@
+/*
+ * zx234290-i2c.c  --  I2C access for ZTE ZX234290 PMIC
+ *
+ * Copyright 2016 ZTE Inc.
+ *
+ * Author: yuxiang<yu.xiang5@zte.com.cn>
+ *
+ *  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 <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/zx234290.h>
+#include <linux/wakelock.h>
+
+static struct i2c_client *zx234290_i2c =0;
+static DEFINE_MUTEX(zx234290_i2c_lock);
+
+int zx29_i2c_xfer_PSM(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
+#if 1
+int zx234290_i2c_read_simple(u8 reg, void *dest)
+{
+	mutex_lock(&zx234290_i2c_lock);
+//	struct i2c_client *i2c = zx234290->control_data;
+	struct i2c_client *i2c = zx234290_i2c;
+	struct i2c_msg xfer[2];
+	int ret;
+
+	/* Write register */
+	xfer[0].addr = i2c->addr;
+	xfer[0].flags = 0;
+	xfer[0].len = 1;
+	xfer[0].buf = &reg;
+
+	/* Read data */
+	xfer[1].addr = i2c->addr;
+	xfer[1].flags = I2C_M_RD;
+	xfer[1].len = 1;
+	xfer[1].buf = dest;
+
+	ret = i2c_transfer(i2c->adapter, xfer, 2);
+	if (ret == 2)
+		ret = 0;
+	else if (ret >= 0)
+	{
+		ret = -EIO;
+
+		printk(KERN_INFO "[zx234290 i2c]read-1 error. reg:%x\n", reg);
+	}
+	mutex_unlock(&zx234290_i2c_lock);
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zx234290_i2c_read_simple);
+
+int zx234290_i2c_read_simple_PSM(u8 reg, void *dest)
+{
+//	struct i2c_client *i2c = zx234290->control_data;
+	struct i2c_client *i2c = zx234290_i2c;
+	struct i2c_msg xfer[2];
+	int ret;
+
+	/* Write register */
+	xfer[0].addr = i2c->addr;
+	xfer[0].flags = 0;
+	xfer[0].len = 1;
+	xfer[0].buf = &reg;
+
+	/* Read data */
+	xfer[1].addr = i2c->addr;
+	xfer[1].flags = I2C_M_RD;
+	xfer[1].len = 1;
+	xfer[1].buf = dest;
+
+	ret = zx29_i2c_xfer_PSM(i2c->adapter, xfer, 2);
+	if (ret == 2)
+		ret = 0;
+	else
+	{
+		ret = -EIO;
+
+		printk(KERN_INFO "[zx234290 i2c]read-psm error. reg:%x\n", reg);
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(zx234290_i2c_read_simple_PSM);
+
+int zx234290_i2c_write_simple(u8 reg, void *src)
+{
+	mutex_lock(&zx234290_i2c_lock);
+//	struct i2c_client *i2c = zx234290->control_data;
+	struct i2c_client *i2c = zx234290_i2c;
+	/* we add 1 byte for device register */
+	u8 msg[4];
+	int ret;
+
+	//if (reg > ZX234290_MAX_REGISTER)
+	//	return -EINVAL;
+
+	msg[0] = reg;
+	memcpy(&msg[1], src, 1);
+
+	ret = i2c_master_send(i2c, msg, 1 + 1);
+	if (ret < 0){
+		mutex_unlock(&zx234290_i2c_lock);
+
+		printk(KERN_INFO "[zx234290 i2c]write-3 error. reg:%x\n", reg);
+
+		return ret;
+	}
+	if (ret != 1 + 1){
+		mutex_unlock(&zx234290_i2c_lock);
+		printk(KERN_INFO "[zx234290 i2c]write-4 error. reg:%x\n", reg);
+		return -EIO;
+	}
+
+	mutex_unlock(&zx234290_i2c_lock);
+	return 0;
+}
+EXPORT_SYMBOL_GPL(zx234290_i2c_write_simple);
+
+int zx234290_i2c_write_simple_PSM(u8 reg, void *src)
+{
+//	struct i2c_client *i2c = zx234290->control_data;
+	struct i2c_client *i2c = zx234290_i2c;
+	/* we add 1 byte for device register */
+	u8 buf[4];
+	int ret;
+	struct i2c_msg msg;
+
+	if (reg > ZX234290_MAX_REGISTER)
+		return -EINVAL;
+
+	buf[0] = reg;
+	memcpy(buf+1, src, 1);
+
+	msg.addr = i2c->addr;
+	msg.flags = 0;
+	msg.len = 2;
+	msg.buf = (char *)buf;
+
+	ret = zx29_i2c_xfer_PSM(i2c->adapter, &msg, 1);
+	if (ret != 1) {
+		printk(KERN_INFO "[zx234290 i2c]write-psm error. reg:%x\n", reg);
+
+		return ret;
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(zx234290_i2c_write_simple_PSM);
+#endif
+
+
+
+//static i2c_client *zx234290_i2c=0;
+#if 1
+static int zx234290_i2c_read(struct zx234290 *zx234290, u8 reg,
+				  int bytes, void *dest)
+{
+	struct i2c_client *i2c = zx234290->control_data;
+//	struct i2c_client *i2c = zx234290_i2c;
+	struct i2c_msg xfer[2];
+	int ret;
+
+	/* Write register */
+	xfer[0].addr = i2c->addr;
+	xfer[0].flags = 0;
+	xfer[0].len = 1;
+	xfer[0].buf = &reg;
+
+	/* Read data */
+	xfer[1].addr = i2c->addr;
+	xfer[1].flags = I2C_M_RD;
+	xfer[1].len = bytes;
+	xfer[1].buf = dest;
+
+	ret = i2c_transfer(i2c->adapter, xfer, 2);
+	if (ret == 2)
+		ret = 0;
+	else if (ret >= 0)
+	{
+		ret = -EIO;
+
+		printk(KERN_INFO "[zx234290 i2c]read error. reg:%x\n", reg);
+	}
+
+	return ret;
+}
+
+static int zx234290_i2c_write(struct zx234290 *zx234290, u8 reg,
+				   int bytes, void *src)
+{
+	struct i2c_client *i2c = zx234290->control_data;
+//	struct i2c_client *i2c = zx234290_i2c;
+	/* we add 1 byte for device register */
+	u8 msg[ZX234290_MAX_REGISTER + 1];
+	int ret;
+
+	if (bytes > ZX234290_MAX_REGISTER)
+		return -EINVAL;
+
+	msg[0] = reg;
+	memcpy(&msg[1], src, bytes);
+
+	ret = i2c_master_send(i2c, msg, bytes + 1);
+	if (ret < 0)
+	{
+		printk(KERN_INFO "[zx234290 i2c]write-1 error. reg:%x\n", reg);
+
+		return ret;
+	}
+	if (ret != bytes + 1)
+	{
+		printk(KERN_INFO "[zx234290 i2c]write-2 error. reg:%x\n", reg);
+
+		return -EIO;
+	}
+
+	return 0;
+}
+#endif
+
+static int zx234290_i2c_probe(struct i2c_client *i2c,
+			    const struct i2c_device_id *id)
+{
+	struct zx234290 *zx234290;
+
+	zx234290_i2c = i2c;
+
+	zx234290 = kzalloc(sizeof(struct zx234290), GFP_KERNEL);
+	if (zx234290 == NULL)
+		return -ENOMEM;
+
+	i2c_set_clientdata(i2c, zx234290);
+	zx234290->dev = &i2c->dev;
+	zx234290->control_data = i2c;
+	zx234290->read = zx234290_i2c_read;
+	zx234290->write = zx234290_i2c_write;
+
+	return zx234290_device_init(zx234290);
+}
+
+static int zx234290_i2c_remove(struct i2c_client *i2c)
+{
+	struct zx234290 *zx234290 = i2c_get_clientdata(i2c);
+
+	if(!zx234290)
+		return -EINVAL;
+	zx234290_device_exit(zx234290);
+
+	return 0;
+}
+
+static const struct i2c_device_id zx234290_i2c_id[] = {
+	{"zx234290", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, zx234290_i2c_id);
+
+#if 1
+static struct i2c_driver zx234290_i2c_driver = {
+	.driver = {
+		   .name = "zx234290",
+		   .owner = THIS_MODULE,
+	},
+	.probe = zx234290_i2c_probe,
+	.remove = zx234290_i2c_remove,
+	.id_table = zx234290_i2c_id,
+};
+#endif
+struct wake_lock adc_wake_lock;
+static int __init zx234290_i2c_init(void)
+{
+	int ret;
+	wake_lock_init(&adc_wake_lock, WAKE_LOCK_SUSPEND, "adc_lock");
+	ret = i2c_add_driver(&zx234290_i2c_driver);
+	if (ret != 0)
+		pr_err("Failed to register ZX234290 I2C driver: %d\n", ret);
+
+	return ret;
+}
+/* init early so consumer devices can complete system boot */
+subsys_initcall(zx234290_i2c_init);
+
+static void __exit zx234290_i2c_exit(void)
+{
+	i2c_del_driver(&zx234290_i2c_driver);
+}
+module_exit(zx234290_i2c_exit);
+
+MODULE_AUTHOR("Dongjian");
+MODULE_DESCRIPTION("ZX234290 chip family multi-function driver");
+MODULE_LICENSE("GPL");