aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2009-09-18 16:45:44 -0400
committerJean Delvare <khali@linux-fr.org>2009-09-18 16:45:44 -0400
commitac7809414fb1e3e49b88ad6016e57598594aa4e2 (patch)
treeb00de5f5130f8b21bc1be49e5b90c0190aed555d
parent27693ce5f372c0af3b0730f5152b35432afa0fd7 (diff)
i2c/tsl2550: Use combined SMBus transactions
Make the I/O faster, mainly by using combined SMBus transactions when possible. While the TSL2550 datasheet doesn't say the device supports them, they seem to work just fine in practice, and a combined transaction is faster than two simple transactions in many cases and always more reliable. A side effect is to suppress the delays between SMBus writes and reads. The datasheet doesn't say they are needed and things work just fine for me without them. I also couldn't see any reason for the delay between reading the two channels. Nor for the loop to get a reading in the first place. The 400 ms delay between samples only matters at chip power-up, after that the chip always hold the previously sampled value so we never get to wait. All these changes make reading the lux value much faster and cheaper. Signed-off-by: Jean Delvare <khali@linux-fr.org> Tested-by: Michele De Candia <michele.decandia@valueteam.com> Cc: Rodolfo Giometti <giometti@linux.it>
-rw-r--r--drivers/i2c/chips/tsl2550.c42
1 files changed, 10 insertions, 32 deletions
diff --git a/drivers/i2c/chips/tsl2550.c b/drivers/i2c/chips/tsl2550.c
index b96f3025e588..aa96bd2d27ea 100644
--- a/drivers/i2c/chips/tsl2550.c
+++ b/drivers/i2c/chips/tsl2550.c
@@ -24,10 +24,9 @@
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/i2c.h> 25#include <linux/i2c.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/delay.h>
28 27
29#define TSL2550_DRV_NAME "tsl2550" 28#define TSL2550_DRV_NAME "tsl2550"
30#define DRIVER_VERSION "1.1.2" 29#define DRIVER_VERSION "1.2"
31 30
32/* 31/*
33 * Defines 32 * Defines
@@ -96,32 +95,13 @@ static int tsl2550_set_power_state(struct i2c_client *client, int state)
96 95
97static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd) 96static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
98{ 97{
99 unsigned long end; 98 int ret;
100 int loop = 0, ret = 0;
101 99
102 /* 100 ret = i2c_smbus_read_byte_data(client, cmd);
103 * Read ADC channel waiting at most 400ms (see data sheet for further 101 if (ret < 0)
104 * info). 102 return ret;
105 * To avoid long busy wait we spin for few milliseconds then
106 * start sleeping.
107 */
108 end = jiffies + msecs_to_jiffies(400);
109 while (time_before(jiffies, end)) {
110 i2c_smbus_write_byte(client, cmd);
111
112 if (loop++ < 5)
113 mdelay(1);
114 else
115 msleep(1);
116
117 ret = i2c_smbus_read_byte(client);
118 if (ret < 0)
119 return ret;
120 else if (ret & 0x0080)
121 break;
122 }
123 if (!(ret & 0x80)) 103 if (!(ret & 0x80))
124 return -EIO; 104 return -EAGAIN;
125 return ret & 0x7f; /* remove the "valid" bit */ 105 return ret & 0x7f; /* remove the "valid" bit */
126} 106}
127 107
@@ -285,8 +265,6 @@ static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
285 return ret; 265 return ret;
286 ch0 = ret; 266 ch0 = ret;
287 267
288 mdelay(1);
289
290 ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1); 268 ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
291 if (ret < 0) 269 if (ret < 0)
292 return ret; 270 return ret;
@@ -345,11 +323,10 @@ static int tsl2550_init_client(struct i2c_client *client)
345 * Probe the chip. To do so we try to power up the device and then to 323 * Probe the chip. To do so we try to power up the device and then to
346 * read back the 0x03 code 324 * read back the 0x03 code
347 */ 325 */
348 err = i2c_smbus_write_byte(client, TSL2550_POWER_UP); 326 err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
349 if (err < 0) 327 if (err < 0)
350 return err; 328 return err;
351 mdelay(1); 329 if (err != TSL2550_POWER_UP)
352 if (i2c_smbus_read_byte(client) != TSL2550_POWER_UP)
353 return -ENODEV; 330 return -ENODEV;
354 data->power_state = 1; 331 data->power_state = 1;
355 332
@@ -374,7 +351,8 @@ static int __devinit tsl2550_probe(struct i2c_client *client,
374 struct tsl2550_data *data; 351 struct tsl2550_data *data;
375 int *opmode, err = 0; 352 int *opmode, err = 0;
376 353
377 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE)) { 354 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
355 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
378 err = -EIO; 356 err = -EIO;
379 goto exit; 357 goto exit;
380 } 358 }