aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-22 12:45:39 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2011-08-22 12:59:20 -0400
commitc0409feb86893f5ccf73964c7b2b47ca64bdb014 (patch)
treecb889f2e239a6261e8b657979b932b32bae579da
parent6337de2204be3b7b40825a1d30de30e514e8947b (diff)
Input: ad714x - use DMA-safe buffers for spi_write()
spi_write() requires use of DMA-safe (cacheline aligned) buffers. Also use the same buffers when reading data since to avoid extra locking and potential memory allocation in spi_write_then_read(). Acked-by: Michael Hennerich <michael.hennerich@analog.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r--drivers/input/misc/ad714x-i2c.c60
-rw-r--r--drivers/input/misc/ad714x-spi.c51
-rw-r--r--drivers/input/misc/ad714x.c90
-rw-r--r--drivers/input/misc/ad714x.h33
4 files changed, 131 insertions, 103 deletions
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index 00a6a223212a..6c6121865f0e 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -27,40 +27,46 @@ static int ad714x_i2c_resume(struct device *dev)
27 27
28static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume); 28static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
29 29
30static int ad714x_i2c_write(struct device *dev, unsigned short reg, 30static int ad714x_i2c_write(struct ad714x_chip *chip,
31 unsigned short data) 31 unsigned short reg, unsigned short data)
32{ 32{
33 struct i2c_client *client = to_i2c_client(dev); 33 struct i2c_client *client = to_i2c_client(chip->dev);
34 int ret = 0; 34 int error;
35 unsigned short tx[2] = { 35
36 cpu_to_be16(reg), 36 chip->xfer_buf[0] = cpu_to_be16(reg);
37 cpu_to_be16(data) 37 chip->xfer_buf[1] = cpu_to_be16(data);
38 }; 38
39 39 error = i2c_master_send(client, (u8 *)chip->xfer_buf,
40 ret = i2c_master_send(client, (u8 *)tx, 4); 40 2 * sizeof(*chip->xfer_buf));
41 if (ret < 0) 41 if (unlikely(error < 0)) {
42 dev_err(&client->dev, "I2C write error\n"); 42 dev_err(&client->dev, "I2C write error: %d\n", error);
43 43 return error;
44 return ret; 44 }
45
46 return 0;
45} 47}
46 48
47static int ad714x_i2c_read(struct device *dev, unsigned short reg, 49static int ad714x_i2c_read(struct ad714x_chip *chip,
48 unsigned short *data) 50 unsigned short reg, unsigned short *data)
49{ 51{
50 struct i2c_client *client = to_i2c_client(dev); 52 struct i2c_client *client = to_i2c_client(chip->dev);
51 int ret = 0; 53 int error;
52 unsigned short tx = cpu_to_be16(reg); 54
55 chip->xfer_buf[0] = cpu_to_be16(reg);
53 56
54 ret = i2c_master_send(client, (u8 *)&tx, 2); 57 error = i2c_master_send(client, (u8 *)chip->xfer_buf,
55 if (ret >= 0) 58 sizeof(*chip->xfer_buf));
56 ret = i2c_master_recv(client, (u8 *)data, 2); 59 if (error >= 0)
60 error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
61 sizeof(*chip->xfer_buf));
57 62
58 if (unlikely(ret < 0)) 63 if (unlikely(error < 0)) {
59 dev_err(&client->dev, "I2C read error\n"); 64 dev_err(&client->dev, "I2C read error: %d\n", error);
60 else 65 return error;
61 *data = be16_to_cpu(*data); 66 }
62 67
63 return ret; 68 *data = be16_to_cpup(chip->xfer_buf);
69 return 0;
64} 70}
65 71
66static int __devinit ad714x_i2c_probe(struct i2c_client *client, 72static int __devinit ad714x_i2c_probe(struct i2c_client *client,
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c
index 0c7f9488f5cb..306577dc0b98 100644
--- a/drivers/input/misc/ad714x-spi.c
+++ b/drivers/input/misc/ad714x-spi.c
@@ -30,31 +30,54 @@ static int ad714x_spi_resume(struct device *dev)
30 30
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 device *dev, 33static int ad714x_spi_read(struct ad714x_chip *chip,
34 unsigned short reg, unsigned short *data) 34 unsigned short reg, unsigned short *data)
35{ 35{
36 struct spi_device *spi = to_spi_device(dev); 36 struct spi_device *spi = to_spi_device(chip->dev);
37 unsigned short tx = cpu_to_be16(AD714x_SPI_CMD_PREFIX | 37 struct spi_message message;
38 struct spi_transfer xfer[2];
39 int error;
40
41 spi_message_init(&message);
42 memset(xfer, 0, sizeof(xfer));
43
44 chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
38 AD714x_SPI_READ | reg); 45 AD714x_SPI_READ | reg);
39 int ret; 46 xfer[0].tx_buf = &chip->xfer_buf[0];
47 xfer[0].len = sizeof(chip->xfer_buf[0]);
48 spi_message_add_tail(&xfer[0], &message);
40 49
41 ret = spi_write_then_read(spi, &tx, 2, data, 2); 50 xfer[1].rx_buf = &chip->xfer_buf[1];
51 xfer[1].len = sizeof(chip->xfer_buf[1]);
52 spi_message_add_tail(&xfer[1], &message);
42 53
43 *data = be16_to_cpup(data); 54 error = spi_sync(spi, &message);
55 if (unlikely(error)) {
56 dev_err(chip->dev, "SPI read error: %d\n", error);
57 return error;
58 }
44 59
45 return ret; 60 *data = be16_to_cpu(chip->xfer_buf[1]);
61 return 0;
46} 62}
47 63
48static int ad714x_spi_write(struct device *dev, 64static int ad714x_spi_write(struct ad714x_chip *chip,
49 unsigned short reg, unsigned short data) 65 unsigned short reg, unsigned short data)
50{ 66{
51 struct spi_device *spi = to_spi_device(dev); 67 struct spi_device *spi = to_spi_device(chip->dev);
52 unsigned short tx[2] = { 68 int error;
53 cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg),
54 cpu_to_be16(data)
55 };
56 69
57 return spi_write(spi, (u8 *)tx, 4); 70 chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
71 chip->xfer_buf[1] = cpu_to_be16(data);
72
73 error = spi_write(spi, (u8 *)chip->xfer_buf,
74 2 * sizeof(*chip->xfer_buf));
75 if (unlikely(error)) {
76 dev_err(chip->dev, "SPI write error: %d\n", error);
77 return error;
78 }
79
80 return 0;
58} 81}
59 82
60static int __devinit ad714x_spi_probe(struct spi_device *spi) 83static int __devinit ad714x_spi_probe(struct spi_device *spi)
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c
index c3a62c42cd28..2be0366c8123 100644
--- a/drivers/input/misc/ad714x.c
+++ b/drivers/input/misc/ad714x.c
@@ -59,7 +59,6 @@
59#define STAGE11_AMBIENT 0x27D 59#define STAGE11_AMBIENT 0x27D
60 60
61#define PER_STAGE_REG_NUM 36 61#define PER_STAGE_REG_NUM 36
62#define STAGE_NUM 12
63#define STAGE_CFGREG_NUM 8 62#define STAGE_CFGREG_NUM 8
64#define SYS_CFGREG_NUM 8 63#define SYS_CFGREG_NUM 8
65 64
@@ -124,28 +123,6 @@ struct ad714x_driver_data {
124 * information to integrate all things which will be private data 123 * information to integrate all things which will be private data
125 * of spi/i2c device 124 * of spi/i2c device
126 */ 125 */
127struct ad714x_chip {
128 unsigned short h_state;
129 unsigned short l_state;
130 unsigned short c_state;
131 unsigned short adc_reg[STAGE_NUM];
132 unsigned short amb_reg[STAGE_NUM];
133 unsigned short sensor_val[STAGE_NUM];
134
135 struct ad714x_platform_data *hw;
136 struct ad714x_driver_data *sw;
137
138 int irq;
139 struct device *dev;
140 ad714x_read_t read;
141 ad714x_write_t write;
142
143 struct mutex mutex;
144
145 unsigned product;
146 unsigned version;
147};
148
149static void ad714x_use_com_int(struct ad714x_chip *ad714x, 126static void ad714x_use_com_int(struct ad714x_chip *ad714x,
150 int start_stage, int end_stage) 127 int start_stage, int end_stage)
151{ 128{
@@ -154,13 +131,13 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
154 131
155 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); 132 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
156 133
157 ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); 134 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data);
158 data |= 1 << end_stage; 135 data |= 1 << end_stage;
159 ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); 136 ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
160 137
161 ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); 138 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data);
162 data &= ~mask; 139 data &= ~mask;
163 ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data); 140 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
164} 141}
165 142
166static void ad714x_use_thr_int(struct ad714x_chip *ad714x, 143static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
@@ -171,13 +148,13 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
171 148
172 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); 149 mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
173 150
174 ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); 151 ad714x->read(ad714x, STG_COM_INT_EN_REG, &data);
175 data &= ~(1 << end_stage); 152 data &= ~(1 << end_stage);
176 ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); 153 ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
177 154
178 ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); 155 ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data);
179 data |= mask; 156 data |= mask;
180 ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data); 157 ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
181} 158}
182 159
183static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x, 160static int ad714x_cal_highest_stage(struct ad714x_chip *ad714x,
@@ -274,10 +251,8 @@ static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
274 int i; 251 int i;
275 252
276 for (i = hw->start_stage; i <= hw->end_stage; i++) { 253 for (i = hw->start_stage; i <= hw->end_stage; i++) {
277 ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, 254 ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
278 &ad714x->adc_reg[i]); 255 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
279 ad714x->read(ad714x->dev,
280 STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
281 &ad714x->amb_reg[i]); 256 &ad714x->amb_reg[i]);
282 257
283 ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] - 258 ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] -
@@ -445,10 +420,8 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
445 int i; 420 int i;
446 421
447 for (i = hw->start_stage; i <= hw->end_stage; i++) { 422 for (i = hw->start_stage; i <= hw->end_stage; i++) {
448 ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, 423 ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
449 &ad714x->adc_reg[i]); 424 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
450 ad714x->read(ad714x->dev,
451 STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
452 &ad714x->amb_reg[i]); 425 &ad714x->amb_reg[i]);
453 if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) 426 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
454 ad714x->sensor_val[i] = ad714x->adc_reg[i] - 427 ad714x->sensor_val[i] = ad714x->adc_reg[i] -
@@ -598,10 +571,8 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
598 int i; 571 int i;
599 572
600 for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) { 573 for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
601 ad714x->read(ad714x->dev, CDC_RESULT_S0 + i, 574 ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
602 &ad714x->adc_reg[i]); 575 ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
603 ad714x->read(ad714x->dev,
604 STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
605 &ad714x->amb_reg[i]); 576 &ad714x->amb_reg[i]);
606 if (ad714x->adc_reg[i] > ad714x->amb_reg[i]) 577 if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
607 ad714x->sensor_val[i] = ad714x->adc_reg[i] - 578 ad714x->sensor_val[i] = ad714x->adc_reg[i] -
@@ -891,7 +862,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
891{ 862{
892 unsigned short data; 863 unsigned short data;
893 864
894 ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data); 865 ad714x->read(ad714x, AD714X_PARTID_REG, &data);
895 switch (data & 0xFFF0) { 866 switch (data & 0xFFF0) {
896 case AD7142_PARTID: 867 case AD7142_PARTID:
897 ad714x->product = 0x7142; 868 ad714x->product = 0x7142;
@@ -940,23 +911,22 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
940 for (i = 0; i < STAGE_NUM; i++) { 911 for (i = 0; i < STAGE_NUM; i++) {
941 reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM; 912 reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
942 for (j = 0; j < STAGE_CFGREG_NUM; j++) 913 for (j = 0; j < STAGE_CFGREG_NUM; j++)
943 ad714x->write(ad714x->dev, reg_base + j, 914 ad714x->write(ad714x, reg_base + j,
944 ad714x->hw->stage_cfg_reg[i][j]); 915 ad714x->hw->stage_cfg_reg[i][j]);
945 } 916 }
946 917
947 for (i = 0; i < SYS_CFGREG_NUM; i++) 918 for (i = 0; i < SYS_CFGREG_NUM; i++)
948 ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i, 919 ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
949 ad714x->hw->sys_cfg_reg[i]); 920 ad714x->hw->sys_cfg_reg[i]);
950 for (i = 0; i < SYS_CFGREG_NUM; i++) 921 for (i = 0; i < SYS_CFGREG_NUM; i++)
951 ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i, 922 ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data);
952 &data);
953 923
954 ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF); 924 ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
955 925
956 /* clear all interrupts */ 926 /* clear all interrupts */
957 ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data); 927 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data);
958 ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data); 928 ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
959 ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data); 929 ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
960} 930}
961 931
962static irqreturn_t ad714x_interrupt_thread(int irq, void *data) 932static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
@@ -966,9 +936,9 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
966 936
967 mutex_lock(&ad714x->mutex); 937 mutex_lock(&ad714x->mutex);
968 938
969 ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state); 939 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state);
970 ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state); 940 ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &ad714x->h_state);
971 ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state); 941 ad714x->read(ad714x, STG_COM_INT_STA_REG, &ad714x->c_state);
972 942
973 for (i = 0; i < ad714x->hw->button_num; i++) 943 for (i = 0; i < ad714x->hw->button_num; i++)
974 ad714x_button_state_machine(ad714x, i); 944 ad714x_button_state_machine(ad714x, i);
@@ -1245,7 +1215,7 @@ int ad714x_disable(struct ad714x_chip *ad714x)
1245 mutex_lock(&ad714x->mutex); 1215 mutex_lock(&ad714x->mutex);
1246 1216
1247 data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3; 1217 data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
1248 ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data); 1218 ad714x->write(ad714x, AD714X_PWR_CTRL, data);
1249 1219
1250 mutex_unlock(&ad714x->mutex); 1220 mutex_unlock(&ad714x->mutex);
1251 1221
@@ -1263,16 +1233,16 @@ int ad714x_enable(struct ad714x_chip *ad714x)
1263 1233
1264 /* resume to non-shutdown mode */ 1234 /* resume to non-shutdown mode */
1265 1235
1266 ad714x->write(ad714x->dev, AD714X_PWR_CTRL, 1236 ad714x->write(ad714x, AD714X_PWR_CTRL,
1267 ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]); 1237 ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
1268 1238
1269 /* make sure the interrupt output line is not low level after resume, 1239 /* make sure the interrupt output line is not low level after resume,
1270 * otherwise we will get no chance to enter falling-edge irq again 1240 * otherwise we will get no chance to enter falling-edge irq again
1271 */ 1241 */
1272 1242
1273 ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data); 1243 ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data);
1274 ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data); 1244 ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
1275 ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data); 1245 ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
1276 1246
1277 mutex_unlock(&ad714x->mutex); 1247 mutex_unlock(&ad714x->mutex);
1278 1248
diff --git a/drivers/input/misc/ad714x.h b/drivers/input/misc/ad714x.h
index 45c54fb13f07..d12d14911fc3 100644
--- a/drivers/input/misc/ad714x.h
+++ b/drivers/input/misc/ad714x.h
@@ -11,11 +11,40 @@
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13 13
14#define STAGE_NUM 12
15
14struct device; 16struct device;
17struct ad714x_platform_data;
18struct ad714x_driver_data;
15struct ad714x_chip; 19struct ad714x_chip;
16 20
17typedef int (*ad714x_read_t)(struct device *, unsigned short, unsigned short *); 21typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *);
18typedef int (*ad714x_write_t)(struct device *, unsigned short, unsigned short); 22typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short);
23
24struct ad714x_chip {
25 unsigned short h_state;
26 unsigned short l_state;
27 unsigned short c_state;
28 unsigned short adc_reg[STAGE_NUM];
29 unsigned short amb_reg[STAGE_NUM];
30 unsigned short sensor_val[STAGE_NUM];
31
32 struct ad714x_platform_data *hw;
33 struct ad714x_driver_data *sw;
34
35 int irq;
36 struct device *dev;
37 ad714x_read_t read;
38 ad714x_write_t write;
39
40 struct mutex mutex;
41
42 unsigned product;
43 unsigned version;
44
45 __be16 xfer_buf[16] ____cacheline_aligned;
46
47};
19 48
20int ad714x_disable(struct ad714x_chip *ad714x); 49int ad714x_disable(struct ad714x_chip *ad714x);
21int ad714x_enable(struct ad714x_chip *ad714x); 50int ad714x_enable(struct ad714x_chip *ad714x);