aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/misc/ad714x.c
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/input/misc/ad714x.c
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/input/misc/ad714x.c')
-rw-r--r--drivers/input/misc/ad714x.c62
1 files changed, 32 insertions, 30 deletions
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