summaryrefslogtreecommitdiff
path: root/drivers
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 14:11:39 -0700
commitf10a5407b58603fb3b084d7fbdbd50f47d010c82 (patch)
tree121a730685dab830c412f7c09027b0b04917d307 /drivers
parent477bc918c2323a51f577cd892ca49376f6feb5d5 (diff)
downloadlinux-3.10-f10a5407b58603fb3b084d7fbdbd50f47d010c82.tar.gz
linux-3.10-f10a5407b58603fb3b084d7fbdbd50f47d010c82.tar.bz2
linux-3.10-f10a5407b58603fb3b084d7fbdbd50f47d010c82.zip
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')
-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 a4929b72506..0780de0550d 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)
int position[3];
int i;
- position[0] = lis3->read_data(lis3, OUTX);
- position[1] = lis3->read_data(lis3, OUTY);
- position[2] = lis3->read_data(lis3, OUTZ);
+ if (lis3->blkread) {
+ if (lis3_dev.whoami == WAI_12B) {
+ u16 data[3];
+ lis3->blkread(lis3, OUTX_L, 6, (u8 *)data);
+ for (i = 0; i < 3; i++)
+ position[i] = (s16)le16_to_cpu(data[i]);
+ } else {
+ u8 data[5];
+ /* Data: x, dummy, y, dummy, z */
+ lis3->blkread(lis3, OUTX, 5, data);
+ for (i = 0; i < 3; i++)
+ position[i] = (s8)data[i * 2];
+ }
+ } else {
+ position[0] = lis3->read_data(lis3, OUTX);
+ position[1] = lis3->read_data(lis3, OUTY);
+ position[2] = lis3->read_data(lis3, OUTZ);
+ }
for (i = 0; i < 3; i++)
position[i] = (position[i] * lis3->scale) / LIS3_ACCURACY;
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 77ebb15ea0b..fdbe899a7f1 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -244,6 +244,7 @@ struct lis3lv02d {
int (*init) (struct lis3lv02d *lis3);
int (*write) (struct lis3lv02d *lis3, int reg, u8 val);
int (*read) (struct lis3lv02d *lis3, int reg, u8 *ret);
+ int (*blkread) (struct lis3lv02d *lis3, int reg, int len, u8 *ret);
int (*reg_ctrl) (struct lis3lv02d *lis3, bool state);
int *odrs; /* Supported output data rates */
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index c1e7420cf77..0074809917a 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)
return 0;
}
+static inline s32 lis3_i2c_blockread(struct lis3lv02d *lis3, int reg, int len,
+ u8 *v)
+{
+ struct i2c_client *c = lis3->bus_priv;
+ reg |= (1 << 7); /* 7th bit enables address auto incrementation */
+ return i2c_smbus_read_i2c_block_data(c, reg, len, v);
+}
+
static int lis3_i2c_init(struct lis3lv02d *lis3)
{
u8 reg;
@@ -102,6 +110,11 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL)
lis3_dev.reg_ctrl = lis3_reg_ctrl;
+ if ((pdata->driver_features & LIS3_USE_BLOCK_READ) &&
+ (i2c_check_functionality(client->adapter,
+ I2C_FUNC_SMBUS_I2C_BLOCK)))
+ lis3_dev.blkread = lis3_i2c_blockread;
+
if (pdata->axis_x)
lis3lv02d_axis_map.x = pdata->axis_x;