diff options
author | Michael Hennerich <michael.hennerich@analog.com> | 2011-08-22 12:45:42 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-08-22 12:59:26 -0400 |
commit | 9eff794b777ac9ca034129a1b637204000c8fb29 (patch) | |
tree | 5f833d94eb3b3a084e5083b89bdc8728447f1665 /drivers | |
parent | c0409feb86893f5ccf73964c7b2b47ca64bdb014 (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.c | 11 | ||||
-rw-r--r-- | drivers/input/misc/ad714x-spi.c | 11 | ||||
-rw-r--r-- | drivers/input/misc/ad714x.c | 62 | ||||
-rw-r--r-- | drivers/input/misc/ad714x.h | 6 |
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 | ||
49 | static int ad714x_i2c_read(struct ad714x_chip *chip, | 49 | static 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) | |||
31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); | 31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); |
32 | 32 | ||
33 | static int ad714x_spi_read(struct ad714x_chip *chip, | 33 | static 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 | |||
126 | static void ad714x_use_com_int(struct ad714x_chip *ad714x, | 127 | static 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 | ||
932 | static irqreturn_t ad714x_interrupt_thread(int irq, void *data) | 940 | static 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 | ||
1226 | int ad714x_enable(struct ad714x_chip *ad714x) | 1232 | int 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; | |||
18 | struct ad714x_driver_data; | 18 | struct ad714x_driver_data; |
19 | struct ad714x_chip; | 19 | struct ad714x_chip; |
20 | 20 | ||
21 | typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *); | 21 | typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *, size_t); |
22 | typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short); | 22 | typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short); |
23 | 23 | ||
24 | struct ad714x_chip { | 24 | struct 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]; |