Commit 9eff794b777ac9ca034129a1b637204000c8fb29
Committed by
Dmitry Torokhov
1 parent
c0409feb86
Exists in
master
and in
6 other branches
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>
Showing 4 changed files with 49 additions and 41 deletions Side-by-side Diff
drivers/input/misc/ad714x-i2c.c
1 | 1 | /* |
2 | 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 | 6 | * Licensed under the GPL-2 or later. |
7 | 7 | */ |
8 | 8 | |
... | ... | @@ -47,9 +47,10 @@ |
47 | 47 | } |
48 | 48 | |
49 | 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 | 52 | struct i2c_client *client = to_i2c_client(chip->dev); |
53 | + int i; | |
53 | 54 | int error; |
54 | 55 | |
55 | 56 | chip->xfer_buf[0] = cpu_to_be16(reg); |
56 | 57 | |
... | ... | @@ -58,14 +59,16 @@ |
58 | 59 | sizeof(*chip->xfer_buf)); |
59 | 60 | if (error >= 0) |
60 | 61 | error = i2c_master_recv(client, (u8 *)chip->xfer_buf, |
61 | - sizeof(*chip->xfer_buf)); | |
62 | + len * sizeof(*chip->xfer_buf)); | |
62 | 63 | |
63 | 64 | if (unlikely(error < 0)) { |
64 | 65 | dev_err(&client->dev, "I2C read error: %d\n", error); |
65 | 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 | 72 | return 0; |
70 | 73 | } |
71 | 74 |
drivers/input/misc/ad714x-spi.c
1 | 1 | /* |
2 | 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 | 6 | * Licensed under the GPL-2 or later. |
7 | 7 | */ |
8 | 8 | |
... | ... | @@ -31,11 +31,12 @@ |
31 | 31 | static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume); |
32 | 32 | |
33 | 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 | 36 | struct spi_device *spi = to_spi_device(chip->dev); |
37 | 37 | struct spi_message message; |
38 | 38 | struct spi_transfer xfer[2]; |
39 | + int i; | |
39 | 40 | int error; |
40 | 41 | |
41 | 42 | spi_message_init(&message); |
... | ... | @@ -48,7 +49,7 @@ |
48 | 49 | spi_message_add_tail(&xfer[0], &message); |
49 | 50 | |
50 | 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 | 53 | spi_message_add_tail(&xfer[1], &message); |
53 | 54 | |
54 | 55 | error = spi_sync(spi, &message); |
... | ... | @@ -57,7 +58,9 @@ |
57 | 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 | 64 | return 0; |
62 | 65 | } |
63 | 66 |
drivers/input/misc/ad714x.c
1 | 1 | /* |
2 | 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 | 6 | * Licensed under the GPL-2 or later. |
7 | 7 | */ |
... | ... | @@ -123,6 +123,7 @@ |
123 | 123 | * information to integrate all things which will be private data |
124 | 124 | * of spi/i2c device |
125 | 125 | */ |
126 | + | |
126 | 127 | static void ad714x_use_com_int(struct ad714x_chip *ad714x, |
127 | 128 | int start_stage, int end_stage) |
128 | 129 | { |
129 | 130 | |
... | ... | @@ -131,11 +132,11 @@ |
131 | 132 | |
132 | 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 | 136 | data |= 1 << end_stage; |
136 | 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 | 140 | data &= ~mask; |
140 | 141 | ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data); |
141 | 142 | } |
142 | 143 | |
... | ... | @@ -148,11 +149,11 @@ |
148 | 149 | |
149 | 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 | 153 | data &= ~(1 << end_stage); |
153 | 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 | 157 | data |= mask; |
157 | 158 | ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data); |
158 | 159 | } |
159 | 160 | |
160 | 161 | |
161 | 162 | |
... | ... | @@ -250,13 +251,16 @@ |
250 | 251 | struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx]; |
251 | 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 | 258 | for (i = hw->start_stage; i <= hw->end_stage; i++) { |
254 | - ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]); | |
255 | 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] - | |
259 | - ad714x->amb_reg[i]); | |
262 | + ad714x->sensor_val[i] = | |
263 | + abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]); | |
260 | 264 | } |
261 | 265 | } |
262 | 266 | |
263 | 267 | |
264 | 268 | |
265 | 269 | |
... | ... | @@ -419,13 +423,16 @@ |
419 | 423 | struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; |
420 | 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 | 430 | for (i = hw->start_stage; i <= hw->end_stage; i++) { |
423 | - ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]); | |
424 | 431 | ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, |
425 | - &ad714x->amb_reg[i]); | |
432 | + &ad714x->amb_reg[i], 1); | |
426 | 433 | if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) |
427 | - ad714x->sensor_val[i] = ad714x->adc_reg[i] - | |
428 | - ad714x->amb_reg[i]; | |
434 | + ad714x->sensor_val[i] = | |
435 | + ad714x->adc_reg[i] - ad714x->amb_reg[i]; | |
429 | 436 | else |
430 | 437 | ad714x->sensor_val[i] = 0; |
431 | 438 | } |
432 | 439 | |
433 | 440 | |
434 | 441 | |
... | ... | @@ -570,13 +577,16 @@ |
570 | 577 | struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx]; |
571 | 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 | 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 | 585 | ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM, |
576 | - &ad714x->amb_reg[i]); | |
586 | + &ad714x->amb_reg[i], 1); | |
577 | 587 | if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) |
578 | - ad714x->sensor_val[i] = ad714x->adc_reg[i] - | |
579 | - ad714x->amb_reg[i]; | |
588 | + ad714x->sensor_val[i] = | |
589 | + ad714x->adc_reg[i] - ad714x->amb_reg[i]; | |
580 | 590 | else |
581 | 591 | ad714x->sensor_val[i] = 0; |
582 | 592 | } |
... | ... | @@ -862,7 +872,7 @@ |
862 | 872 | { |
863 | 873 | unsigned short data; |
864 | 874 | |
865 | - ad714x->read(ad714x, AD714X_PARTID_REG, &data); | |
875 | + ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1); | |
866 | 876 | switch (data & 0xFFF0) { |
867 | 877 | case AD7142_PARTID: |
868 | 878 | ad714x->product = 0x7142; |
869 | 879 | |
... | ... | @@ -919,14 +929,12 @@ |
919 | 929 | ad714x->write(ad714x, AD714X_SYSCFG_REG + i, |
920 | 930 | ad714x->hw->sys_cfg_reg[i]); |
921 | 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 | 934 | ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF); |
925 | 935 | |
926 | 936 | /* clear all interrupts */ |
927 | - ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data); | |
928 | - ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data); | |
929 | - ad714x->read(ad714x, STG_COM_INT_STA_REG, &data); | |
937 | + ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3); | |
930 | 938 | } |
931 | 939 | |
932 | 940 | static irqreturn_t ad714x_interrupt_thread(int irq, void *data) |
... | ... | @@ -936,9 +944,7 @@ |
936 | 944 | |
937 | 945 | mutex_lock(&ad714x->mutex); |
938 | 946 | |
939 | - ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state); | |
940 | - ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &ad714x->h_state); | |
941 | - ad714x->read(ad714x, STG_COM_INT_STA_REG, &ad714x->c_state); | |
947 | + ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3); | |
942 | 948 | |
943 | 949 | for (i = 0; i < ad714x->hw->button_num; i++) |
944 | 950 | ad714x_button_state_machine(ad714x, i); |
... | ... | @@ -1225,8 +1231,6 @@ |
1225 | 1231 | |
1226 | 1232 | int ad714x_enable(struct ad714x_chip *ad714x) |
1227 | 1233 | { |
1228 | - unsigned short data; | |
1229 | - | |
1230 | 1234 | dev_dbg(ad714x->dev, "%s enter\n", __func__); |
1231 | 1235 | |
1232 | 1236 | mutex_lock(&ad714x->mutex); |
... | ... | @@ -1240,9 +1244,7 @@ |
1240 | 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); | |
1244 | - ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data); | |
1245 | - ad714x->read(ad714x, STG_COM_INT_STA_REG, &data); | |
1247 | + ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3); | |
1246 | 1248 | |
1247 | 1249 | mutex_unlock(&ad714x->mutex); |
1248 | 1250 |
drivers/input/misc/ad714x.h
1 | 1 | /* |
2 | 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 | 6 | * Licensed under the GPL-2 or later. |
7 | 7 | */ |
8 | 8 | |
9 | 9 | |
... | ... | @@ -18,12 +18,12 @@ |
18 | 18 | struct ad714x_driver_data; |
19 | 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 | 22 | typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short); |
23 | 23 | |
24 | 24 | struct ad714x_chip { |
25 | - unsigned short h_state; | |
26 | 25 | unsigned short l_state; |
26 | + unsigned short h_state; | |
27 | 27 | unsigned short c_state; |
28 | 28 | unsigned short adc_reg[STAGE_NUM]; |
29 | 29 | unsigned short amb_reg[STAGE_NUM]; |