aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Hennerich <michael.hennerich@analog.com>2011-08-22 12:45:42 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-22 12:59:26 -0400
commit9eff794b777ac9ca034129a1b637204000c8fb29 (patch)
tree5f833d94eb3b3a084e5083b89bdc8728447f1665 /drivers
parentc0409feb86893f5ccf73964c7b2b47ca64bdb014 (diff)
Input: ad714x - read the interrupt status registers in a row
The interrupt status registers should be read in row to avoid invalid data. Alter "read" method for both bus options to allow reading several registers in a row and make sure we read interrupt status registers properly. Read sequence saves 50% of bus transactions compared to single register reads. So use it also for the result registers, which are also located in a row. Also update copyright notice. Signed-off-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/input/misc/ad714x-i2c.c11
-rw-r--r--drivers/input/misc/ad714x-spi.c11
-rw-r--r--drivers/input/misc/ad714x.c62
-rw-r--r--drivers/input/misc/ad714x.h6
4 files changed, 49 insertions, 41 deletions
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index 6c6121865f0e..025417d74ca2 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * AD714X CapTouch Programmable Controller driver (I2C bus) 2 * AD714X CapTouch Programmable Controller driver (I2C bus)
3 * 3 *
4 * Copyright 2009 Analog Devices Inc. 4 * Copyright 2009-2011 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
@@ -47,9 +47,10 @@ static int ad714x_i2c_write(struct ad714x_chip *chip,
47} 47}
48 48
49static int ad714x_i2c_read(struct ad714x_chip *chip, 49static int ad714x_i2c_read(struct ad714x_chip *chip,
50 unsigned short reg, unsigned short *data) 50 unsigned short reg, unsigned short *data, size_t len)
51{ 51{
52 struct i2c_client *client = to_i2c_client(chip->dev); 52 struct i2c_client *client = to_i2c_client(chip->dev);
53 int i;
53 int error; 54 int error;
54 55
55 chip->xfer_buf[0] = cpu_to_be16(reg); 56 chip->xfer_buf[0] = cpu_to_be16(reg);
@@ -58,14 +59,16 @@ static int ad714x_i2c_read(struct ad714x_chip *chip,
58 sizeof(*chip->xfer_buf)); 59 sizeof(*chip->xfer_buf));
59 if (error >= 0) 60 if (error >= 0)
60 error = i2c_master_recv(client, (u8 *)chip->xfer_buf, 61 error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
61 sizeof(*chip->xfer_buf)); 62 len * sizeof(*chip->xfer_buf));
62 63
63 if (unlikely(error < 0)) { 64 if (unlikely(error < 0)) {
64 dev_err(&client->dev, "I2C read error: %d\n", error); 65 dev_err(&client->dev, "I2C read error: %d\n", error);
65 return error; 66 return error;
66 } 67 }
67 68
68 *data = be16_to_cpup(chip->xfer_buf); 69 for (i = 0; i < len; i++)
70 data[i] = be16_to_cpu(chip->xfer_buf[i]);
71
69 return 0; 72 return 0;
70} 73}
71 74
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c
index 306577dc0b98..875b50811361 100644
--- a/drivers/input/misc/ad714x-spi.c
+++ b/drivers/input/misc/ad714x-spi.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * AD714X CapTouch Programmable Controller driver (SPI bus) 2 * AD714X CapTouch Programmable Controller driver (SPI bus)
3 * 3 *
4 * Copyright 2009 Analog Devices Inc. 4 * Copyright 2009-2011 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
@@ -31,11 +31,12 @@ static int ad714x_spi_resume(struct device *dev)
31static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); 31static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
32 32
33static int ad714x_spi_read(struct ad714x_chip *chip, 33static int ad714x_spi_read(struct ad714x_chip *chip,
34 unsigned short reg, unsigned short *data) 34 unsigned short reg, unsigned short *data, size_t len)
35{ 35{
36 struct spi_device *spi = to_spi_device(chip->dev); 36 struct spi_device *spi = to_spi_device(chip->dev);
37 struct spi_message message; 37 struct spi_message message;
38 struct spi_transfer xfer[2]; 38 struct spi_transfer xfer[2];
39 int i;
39 int error; 40 int error;
40 41
41 spi_message_init(&message); 42 spi_message_init(&message);
@@ -48,7 +49,7 @@ static int ad714x_spi_read(struct ad714x_chip *chip,
48 spi_message_add_tail(&xfer[0], &message); 49 spi_message_add_tail(&xfer[0], &message);
49 50
50 xfer[1].rx_buf = &chip->xfer_buf[1]; 51 xfer[1].rx_buf = &chip->xfer_buf[1];
51 xfer[1].len = sizeof(chip->xfer_buf[1]); 52 xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
52 spi_message_add_tail(&xfer[1], &message); 53 spi_message_add_tail(&xfer[1], &message);
53 54
54 error = spi_sync(spi, &message); 55 error = spi_sync(spi, &message);
@@ -57,7 +58,9 @@ static int ad714x_spi_read(struct ad714x_chip *chip,
57 return error; 58 return error;
58 } 59 }
59 60
60 *data = be16_to_cpu(chip->xfer_buf[1]); 61 for (i = 0; i < len; i++)
62 data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
63
61 return 0; 64 return 0;
62} 65}
63 66
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c
index 2be0366c8123..ca42c7d2a3c7 100644
--- a/drivers/input/misc/ad714x.c
+++ b/drivers/input/misc/ad714x.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A 2 * AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
3 * 3 *
4 * Copyright 2009 Analog Devices Inc. 4 * Copyright 2009-2011 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
@@ -123,6 +123,7 @@ struct ad714x_driver_data {
123 * information to integrate all things which will be private data 123 * information to integrate all things which will be private data
124 * of spi/i2c device 124 * of spi/i2c device
125 */ 125 */
126
126static void ad714x_use_com_int(struct ad714x_chip *ad714x, 127static void ad714x_use_com_int(struct ad714x_chip *ad714x,
127 int start_stage, int end_stage) 128 int start_stage, int end_stage)
128{ 129{
@@ -131,11 +132,11 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
131 132
132 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); 133 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
133 134
134 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data); 135 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
135 data |= 1 << end_stage; 136 data |= 1 << end_stage;
136 ad714x->write(ad714x, STG_COM_INT_EN_REG, data); 137 ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
137 138
138 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data); 139 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
139 data &= ~mask; 140 data &= ~mask;
140 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data); 141 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
141} 142}
@@ -148,11 +149,11 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
148 149
149 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); 150 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
150 151
151 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data); 152 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
152 data &= ~(1 << end_stage); 153 data &= ~(1 << end_stage);
153 ad714x->write(ad714x, STG_COM_INT_EN_REG, data); 154 ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
154 155
155 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data); 156 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
156 data |= mask; 157 data |= mask;
157 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data); 158 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
158} 159}
@@ -250,13 +251,16 @@ static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
250 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; 251 struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
251 int i; 252 int i;
252 253
254 ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
255 &ad714x->adc_reg[hw->start_stage],
256 hw->end_stage - hw->start_stage + 1);
257
253 for (i = hw->start_stage; i <= hw->end_stage; i++) { 258 for (i = hw->start_stage; i <= hw->end_stage; i++) {
254 ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
255 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, 259 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
256 &ad714x->amb_reg[i]); 260 &ad714x->amb_reg[i], 1);
257 261
258 ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] - 262 ad714x->sensor_val[i] =
259 ad714x->amb_reg[i]); 263 abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
260 } 264 }
261} 265}
262 266
@@ -419,13 +423,16 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
419 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; 423 struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
420 int i; 424 int i;
421 425
426 ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
427 &ad714x->adc_reg[hw->start_stage],
428 hw->end_stage - hw->start_stage + 1);
429
422 for (i = hw->start_stage; i <= hw->end_stage; i++) { 430 for (i = hw->start_stage; i <= hw->end_stage; i++) {
423 ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
424 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, 431 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
425 &ad714x->amb_reg[i]); 432 &ad714x->amb_reg[i], 1);
426 if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) 433 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
427 ad714x->sensor_val[i] = ad714x->adc_reg[i] - 434 ad714x->sensor_val[i] =
428 ad714x->amb_reg[i]; 435 ad714x->adc_reg[i] - ad714x->amb_reg[i];
429 else 436 else
430 ad714x->sensor_val[i] = 0; 437 ad714x->sensor_val[i] = 0;
431 } 438 }
@@ -570,13 +577,16 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
570 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; 577 struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
571 int i; 578 int i;
572 579
580 ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
581 &ad714x->adc_reg[hw->x_start_stage],
582 hw->x_end_stage - hw->x_start_stage + 1);
583
573 for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) { 584 for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
574 ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
575 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, 585 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
576 &ad714x->amb_reg[i]); 586 &ad714x->amb_reg[i], 1);
577 if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) 587 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
578 ad714x->sensor_val[i] = ad714x->adc_reg[i] - 588 ad714x->sensor_val[i] =
579 ad714x->amb_reg[i]; 589 ad714x->adc_reg[i] - ad714x->amb_reg[i];
580 else 590 else
581 ad714x->sensor_val[i] = 0; 591 ad714x->sensor_val[i] = 0;
582 } 592 }
@@ -862,7 +872,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
862{ 872{
863 unsigned short data; 873 unsigned short data;
864 874
865 ad714x->read(ad714x, AD714X_PARTID_REG, &data); 875 ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
866 switch (data & 0xFFF0) { 876 switch (data & 0xFFF0) {
867 case AD7142_PARTID: 877 case AD7142_PARTID:
868 ad714x->product = 0x7142; 878 ad714x->product = 0x7142;
@@ -919,14 +929,12 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
919 ad714x->write(ad714x, AD714X_SYSCFG_REG + i, 929 ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
920 ad714x->hw->sys_cfg_reg[i]); 930 ad714x->hw->sys_cfg_reg[i]);
921 for (i = 0; i < SYS_CFGREG_NUM; i++) 931 for (i = 0; i < SYS_CFGREG_NUM; i++)
922 ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data); 932 ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
923 933
924 ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF); 934 ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
925 935
926 /* clear all interrupts */ 936 /* clear all interrupts */
927 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data); 937 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
928 ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
929 ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
930} 938}
931 939
932static irqreturn_t ad714x_interrupt_thread(int irq, void *data) 940static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
@@ -936,9 +944,7 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
936 944
937 mutex_lock(&ad714x->mutex); 945 mutex_lock(&ad714x->mutex);
938 946
939 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state); 947 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
940 ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &ad714x->h_state);
941 ad714x->read(ad714x, STG_COM_INT_STA_REG, &ad714x->c_state);
942 948
943 for (i = 0; i < ad714x->hw->button_num; i++) 949 for (i = 0; i < ad714x->hw->button_num; i++)
944 ad714x_button_state_machine(ad714x, i); 950 ad714x_button_state_machine(ad714x, i);
@@ -1225,8 +1231,6 @@ EXPORT_SYMBOL(ad714x_disable);
1225 1231
1226int ad714x_enable(struct ad714x_chip *ad714x) 1232int ad714x_enable(struct ad714x_chip *ad714x)
1227{ 1233{
1228 unsigned short data;
1229
1230 dev_dbg(ad714x->dev, "%s enter\n", __func__); 1234 dev_dbg(ad714x->dev, "%s enter\n", __func__);
1231 1235
1232 mutex_lock(&ad714x->mutex); 1236 mutex_lock(&ad714x->mutex);
@@ -1240,9 +1244,7 @@ int ad714x_enable(struct ad714x_chip *ad714x)
1240 * otherwise we will get no chance to enter falling-edge irq again 1244 * otherwise we will get no chance to enter falling-edge irq again
1241 */ 1245 */
1242 1246
1243 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data); 1247 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
1244 ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
1245 ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
1246 1248
1247 mutex_unlock(&ad714x->mutex); 1249 mutex_unlock(&ad714x->mutex);
1248 1250
diff --git a/drivers/input/misc/ad714x.h b/drivers/input/misc/ad714x.h
index d12d14911fc3..3c85455aa66d 100644
--- a/drivers/input/misc/ad714x.h
+++ b/drivers/input/misc/ad714x.h
@@ -1,7 +1,7 @@
1/* 1/*
2 * AD714X CapTouch Programmable Controller driver (bus interfaces) 2 * AD714X CapTouch Programmable Controller driver (bus interfaces)
3 * 3 *
4 * Copyright 2009 Analog Devices Inc. 4 * Copyright 2009-2011 Analog Devices Inc.
5 * 5 *
6 * Licensed under the GPL-2 or later. 6 * Licensed under the GPL-2 or later.
7 */ 7 */
@@ -18,12 +18,12 @@ struct ad714x_platform_data;
18struct ad714x_driver_data; 18struct ad714x_driver_data;
19struct ad714x_chip; 19struct ad714x_chip;
20 20
21typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *); 21typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *, size_t);
22typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short); 22typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short);
23 23
24struct ad714x_chip { 24struct ad714x_chip {
25 unsigned short h_state;
26 unsigned short l_state; 25 unsigned short l_state;
26 unsigned short h_state;
27 unsigned short c_state; 27 unsigned short c_state;
28 unsigned short adc_reg[STAGE_NUM]; 28 unsigned short adc_reg[STAGE_NUM];
29 unsigned short amb_reg[STAGE_NUM]; 29 unsigned short amb_reg[STAGE_NUM];