Patchwork [U-Boot,v7,02/26] pmic:i2c: Add I2C sensor byte order (big/little) to PMIC framework

login
register
mail settings
Submitter Łukasz Majewski
Date Nov. 13, 2012, 1:21 p.m.
Message ID <1352812937-15998-3-git-send-email-l.majewski@samsung.com>
Download mbox | patch
Permalink /patch/198645/
State Accepted
Delegated to: Anatolij Gustschin
Headers show

Comments

Łukasz Majewski - Nov. 13, 2012, 1:21 p.m.
Since the pmic_reg_read is the u32 value, the order in which bytes
are placed to form u32 value is important.

Support for big and little sensor endianess is added.

Moreover calls to [leXX|beXX]_to_cpu have been added to support
little and big endian SoCs.

Signed-off-by: Lukasz Majewski <l.majewski@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
Changes for v2:
- Move byte_order variable to struct pmic
Changes for v3:
- New names for sensor endianess (more readable)
- Support for SoCs with different endianess
Changes for v4:
- None
Changes for v5:
- None
Changes for v6:
- None
Changes for v7:
- None
---
 drivers/misc/pmic_i2c.c |   38 +++++++++++++++++++++++++++++---------
 include/pmic.h          |    2 ++
 2 files changed, 31 insertions(+), 9 deletions(-)

Patch

diff --git a/drivers/misc/pmic_i2c.c b/drivers/misc/pmic_i2c.c
index e74c372..1064bfe 100644
--- a/drivers/misc/pmic_i2c.c
+++ b/drivers/misc/pmic_i2c.c
@@ -30,6 +30,7 @@ 
 #include <linux/types.h>
 #include <pmic.h>
 #include <i2c.h>
+#include <compiler.h>
 
 int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
 {
@@ -40,16 +41,27 @@  int pmic_reg_write(struct pmic *p, u32 reg, u32 val)
 
 	switch (pmic_i2c_tx_num) {
 	case 3:
-		buf[0] = (val >> 16) & 0xff;
-		buf[1] = (val >> 8) & 0xff;
-		buf[2] = val & 0xff;
+		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
+			buf[2] = (cpu_to_le32(val) >> 16) & 0xff;
+			buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
+			buf[0] = cpu_to_le32(val) & 0xff;
+		} else {
+			buf[0] = (cpu_to_le32(val) >> 16) & 0xff;
+			buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
+			buf[2] = cpu_to_le32(val) & 0xff;
+		}
 		break;
 	case 2:
-		buf[0] = (val >> 8) & 0xff;
-		buf[1] = val & 0xff;
+		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG) {
+			buf[1] = (cpu_to_le32(val) >> 8) & 0xff;
+			buf[0] = cpu_to_le32(val) & 0xff;
+		} else {
+			buf[0] = (cpu_to_le32(val) >> 8) & 0xff;
+			buf[1] = cpu_to_le32(val) & 0xff;
+		}
 		break;
 	case 1:
-		buf[0] = val & 0xff;
+		buf[0] = cpu_to_le32(val) & 0xff;
 		break;
 	default:
 		printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
@@ -75,13 +87,21 @@  int pmic_reg_read(struct pmic *p, u32 reg, u32 *val)
 
 	switch (pmic_i2c_tx_num) {
 	case 3:
-		ret_val = buf[0] << 16 | buf[1] << 8 | buf[2];
+		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
+			ret_val = le32_to_cpu(buf[2] << 16
+					      | buf[1] << 8 | buf[0]);
+		else
+			ret_val = le32_to_cpu(buf[0] << 16 |
+					      buf[1] << 8 | buf[2]);
 		break;
 	case 2:
-		ret_val = buf[0] << 8 | buf[1];
+		if (p->sensor_byte_order == PMIC_SENSOR_BYTE_ORDER_BIG)
+			ret_val = le32_to_cpu(buf[1] << 8 | buf[0]);
+		else
+			ret_val = le32_to_cpu(buf[0] << 8 | buf[1]);
 		break;
 	case 1:
-		ret_val = buf[0];
+		ret_val = le32_to_cpu(buf[0]);
 		break;
 	default:
 		printf("%s: invalid tx_num: %d", __func__, pmic_i2c_tx_num);
diff --git a/include/pmic.h b/include/pmic.h
index 6a05b40..1a2db05 100644
--- a/include/pmic.h
+++ b/include/pmic.h
@@ -27,6 +27,7 @@ 
 enum { PMIC_I2C, PMIC_SPI, };
 enum { I2C_PMIC, I2C_NUM, };
 enum { PMIC_READ, PMIC_WRITE, };
+enum { PMIC_SENSOR_BYTE_ORDER_LITTLE, PMIC_SENSOR_BYTE_ORDER_BIG, };
 
 struct p_i2c {
 	unsigned char addr;
@@ -47,6 +48,7 @@  struct pmic {
 	const char *name;
 	unsigned char bus;
 	unsigned char interface;
+	unsigned char sensor_byte_order;
 	unsigned char number_of_regs;
 	union hw {
 		struct p_i2c i2c;