aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorSamu Onkalo <samu.p.onkalo@nokia.com>2010-10-22 07:57:31 -0400
committerGuenter Roeck <guenter.roeck@ericsson.com>2010-10-25 17:11:39 -0400
commitf10a5407b58603fb3b084d7fbdbd50f47d010c82 (patch)
tree121a730685dab830c412f7c09027b0b04917d307 /drivers/hwmon
parent477bc918c2323a51f577cd892ca49376f6feb5d5 (diff)
hwmon: lis3: use block read to access data registers
Add optional blockread function to interface driver. If available the chip driver uses it for data register access. For 12 bit device it reads 6 bytes to get 3*16bit data. For 8 bit device it reads out 5 bytes since every second byte is dummy. This optimizes bus usage and reduces number of operations and interrupts needed for one data update. Signed-off-by: Samu Onkalo <samu.p.onkalo@nokia.com> Acked-by: Jonathan Cameron <jic23@cam.ac.uk> Acked-by: Eric Piel <eric.piel@tremplin-utc.net> Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/lis3lv02d.c21
-rw-r--r--drivers/hwmon/lis3lv02d.h1
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c13
3 files changed, 32 insertions, 3 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index a4929b72506e..0780de0550df 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -154,9 +154,24 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
154 int position[3]; 154 int position[3];
155 int i; 155 int i;
156 156
157 position[0] = lis3->read_data(lis3, OUTX); 157 if (lis3->blkread) {
158 position[1] = lis3->read_data(lis3, OUTY); 158 if (lis3_dev.whoami == WAI_12B) {
159 position[2] = lis3->read_data(lis3, OUTZ); 159 u16 data[3];
160 lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
161 for (i = 0; i < 3; i++)
162 position[i] = (s16)le16_to_cpu(data[i]);
163 } else {
164 u8 data[5];
165 /* Data: x, dummy, y, dummy, z */
166 lis3->blkread(lis3, OUTX, 5, data);
167 for (i = 0; i < 3; i++)
168 position[i] = (s8)data[i * 2];
169 }
170 } else {
171 position[0] = lis3->read_data(lis3, OUTX);
172 position[1] = lis3->read_data(lis3, OUTY);
173 position[2] = lis3->read_data(lis3, OUTZ);
174 }
160 175
161 for (i = 0; i < 3; i++) 176 for (i = 0; i < 3; i++)
162 position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY; 177 position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 77ebb15ea0b3..fdbe899a7f14 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -244,6 +244,7 @@ struct lis3lv02d {
244 int (*init) (struct lis3lv02d *lis3); 244 int (*init) (struct lis3lv02d *lis3);
245 int (*write) (struct lis3lv02d *lis3, int reg, u8 val); 245 int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
246 int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret); 246 int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
247 int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
247 int (*reg_ctrl) (struct lis3lv02d *lis3, bool state); 248 int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
248 249
249 int *odrs; /* Supported output data rates */ 250 int *odrs; /* Supported output data rates */
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index c1e7420cf77d..0074809917a2 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -66,6 +66,14 @@ static inline s32 lis3_i2c_read(struct lis3lv02d *lis3, int reg, u8 *v)
66 return 0; 66 return 0;
67} 67}
68 68
69static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
70 u8 *v)
71{
72 struct i2c_client *c = lis3->bus_priv;
73 reg |= (1 << 7); /* 7th bit enables address auto incrementation */
74 return i2c_smbus_read_i2c_block_data(c, reg, len, v);
75}
76
69static int lis3_i2c_init(struct lis3lv02d *lis3) 77static int lis3_i2c_init(struct lis3lv02d *lis3)
70{ 78{
71 u8 reg; 79 u8 reg;
@@ -102,6 +110,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
102 if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL) 110 if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
103 lis3_dev.reg_ctrl = lis3_reg_ctrl; 111 lis3_dev.reg_ctrl = lis3_reg_ctrl;
104 112
113 if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
114 (i2c_check_functionality(client->adapter,
115 I2C_FUNC_SMBUS_I2C_BLOCK)))
116 lis3_dev.blkread = lis3_i2c_blockread;
117
105 if (pdata->axis_x) 118 if (pdata->axis_x)
106 lis3lv02d_axis_map.x = pdata->axis_x; 119 lis3lv02d_axis_map.x = pdata->axis_x;
107 120