summaryrefslogtreecommitdiff
path: root/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c')
-rwxr-xr-xdrivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c152
1 files changed, 152 insertions, 0 deletions
diff --git a/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c b/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c
new file mode 100755
index 00000000..6249df50
--- /dev/null
+++ b/drivers/power/wmt_battery/gauge/ug31xx/ug31xx_i2c.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2012, ASUSTek, Inc. All Rights Reserved.
+ */
+#include <linux/module.h>
+#include <linux/param.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/slab.h>
+#include <asm/unaligned.h>
+#include <linux/interrupt.h>
+#include <linux/idr.h>
+#include <linux/proc_fs.h>
+#include <linux/uaccess.h>
+#include "ug31xx_i2c.h"
+
+static struct i2c_client *ug31xx_client = NULL;
+
+void ug31xx_i2c_client_set(struct i2c_client *client)
+{
+ ug31xx_client = client;
+ dev_info(&ug31xx_client->dev, "%s: Ug31xx i2c client saved.\n", __func__);
+}
+
+int ug31xx_read_i2c(struct i2c_client *client,
+ u8 reg, int *rt_value, int b_single)
+{
+ struct i2c_msg msg[2];
+ unsigned char data[4];
+ int err;
+
+ if (!client || !client->adapter)
+ return -ENODEV;
+
+ if (!rt_value) return -EINVAL;
+
+ data[0] = reg;
+ //err = i2c_transfer(client->adapter, msg, 1);
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0 | I2C_M_NOSTART;
+ msg[0].len = 1;
+ if (reg >= 0x80) {
+ data[1] = SECURITY_KEY;
+ msg[0].len++;
+ }
+ msg[0].buf = (unsigned char *)data;
+
+ msg[1].addr = client->addr;
+ msg[1].flags = (I2C_M_RD);
+ msg[1].len = b_single ? 1 : 2;
+ msg[1].buf = (unsigned char *)data;
+
+ err = i2c_transfer(client->adapter, msg, sizeof(msg)/sizeof(struct i2c_msg));
+
+ if (err < 0) return err;
+
+ if (b_single)
+ *rt_value = data[0];
+ else
+ *rt_value = get_unaligned_le16(data);
+
+ return 0;
+}
+
+int ug31xx_write_i2c(struct i2c_client *client,
+ u8 reg, int rt_value, int b_single)
+{
+ struct i2c_msg msg[1];
+ unsigned char data[4];
+ int err;
+ int idx;
+ int tmp_buf=0;
+
+ if (!client || !client->adapter)
+ return -ENODEV;
+
+ idx = 0;
+ data[idx++] = reg;
+ if (reg >= 0x80) {
+ data[idx++] = SECURITY_KEY;
+ }
+ data[idx++] = rt_value & 0x0FF;
+ data[idx++] = (rt_value & 0x0FF00)>>8;
+
+ msg[0].addr = client->addr;
+ msg[0].flags = 0 | I2C_M_NOSTART;
+ msg[0].len = b_single ? idx-1 : idx;
+ msg[0].buf = (unsigned char *)data;
+
+ err = i2c_transfer(client->adapter, msg, sizeof(msg)/sizeof(struct i2c_msg));
+
+ if (err >= 0)
+ err = ug31xx_read_i2c(client, reg, &tmp_buf, b_single);
+ //dev_info(&client->dev, "%s:: 0x%02X, 0x%04X, 0x%04X. %s\n",
+ // __func__, reg, rt_value, tmp_buf, err < 0 ? "FAIL" : "SUCCESS");
+
+ return err < 0 ? err : 0;
+}
+
+bool _API_I2C_Write(u16 writeAddress, u8 writeLength, u8 *PWriteData)
+{
+ int i, ret;
+ int byte_flag=0;
+
+ if (!PWriteData) {
+ dev_err(&ug31xx_client->dev, "%s: Write buffer pointer error.\n", __func__);
+ return false;
+ }
+
+ byte_flag = ONE_BYTE;
+
+ for (i=0; i<writeLength; i++) {
+ int tmp_buf = PWriteData[i];
+
+ ret = ug31xx_write_i2c(ug31xx_client, writeAddress+i, tmp_buf, byte_flag);
+ if (ret) {
+ dev_err(&ug31xx_client->dev, "%s: Write data(0x%02X) fail. %d\n",
+ __func__, i, ret);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool _API_I2C_Read(u16 readAddress, u8 readLength, u8 *pReadDataBuffer)
+{
+ int i, ret;
+ int byte_flag=0;
+
+ if (!pReadDataBuffer) {
+ dev_err(&ug31xx_client->dev, "%s: Read buffer pointer error.\n", __func__);
+ return false;
+ }
+
+ byte_flag = ONE_BYTE;
+
+ for (i=0; i<readLength; i++) {
+ int tmp_buf=0;
+
+ ret = ug31xx_read_i2c(ug31xx_client, readAddress+i, &tmp_buf, byte_flag);
+ if (ret) {
+ dev_err(&ug31xx_client->dev, "%s: read data(0x%02X) fail. %d\n",
+ __func__, i, ret);
+ return false;
+ }
+ pReadDataBuffer[i] = tmp_buf;
+ }
+
+ return true;
+}
+