* [PATCH 1/4] Input: ad714xx-spi - force SPI bus into the default 8-bit mode
@ 2011-08-21 20:09 Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 2/4] Input: ad714x - fix endianness issues Dmitry Torokhov
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-21 20:09 UTC (permalink / raw)
To: Michael Hennerich; +Cc: linux-input, drivers, device-drivers-devel
From: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
drivers/input/misc/ad714x-spi.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c
index 4120dd5..da83ac9 100644
--- a/drivers/input/misc/ad714x-spi.c
+++ b/drivers/input/misc/ad714x-spi.c
@@ -54,6 +54,12 @@ static int ad714x_spi_write(struct device *dev, unsigned short reg,
static int __devinit ad714x_spi_probe(struct spi_device *spi)
{
struct ad714x_chip *chip;
+ int err;
+
+ spi->bits_per_word = 8;
+ err = spi_setup(spi);
+ if (err < 0)
+ return err;
chip = ad714x_probe(&spi->dev, BUS_SPI, spi->irq,
ad714x_spi_read, ad714x_spi_write);
--
1.7.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/4] Input: ad714x - fix endianness issues
2011-08-21 20:09 [PATCH 1/4] Input: ad714xx-spi - force SPI bus into the default 8-bit mode Dmitry Torokhov
@ 2011-08-21 20:09 ` Dmitry Torokhov
2011-08-23 16:22 ` Mark Brown
2011-08-21 20:09 ` [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write() Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 4/4] Input: ad714x - read the interrupt status registers in a row Dmitry Torokhov
2 siblings, 1 reply; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-21 20:09 UTC (permalink / raw)
To: Michael Hennerich; +Cc: linux-input, drivers, device-drivers-devel
From: Michael Hennerich <michael.hennerich@analog.com>
Allow driver to be used on Big Endian boxes.
Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
drivers/input/misc/ad714x-i2c.c | 34 ++++++++++------------------------
drivers/input/misc/ad714x-spi.c | 24 +++++++++++++++---------
2 files changed, 25 insertions(+), 33 deletions(-)
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index e21deb1..00a6a22 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -32,17 +32,12 @@ static int ad714x_i2c_write(struct device *dev, unsigned short reg,
{
struct i2c_client *client = to_i2c_client(dev);
int ret = 0;
- u8 *_reg = (u8 *)®
- u8 *_data = (u8 *)&data;
-
- u8 tx[4] = {
- _reg[1],
- _reg[0],
- _data[1],
- _data[0]
+ unsigned short tx[2] = {
+ cpu_to_be16(reg),
+ cpu_to_be16(data)
};
- ret = i2c_master_send(client, tx, 4);
+ ret = i2c_master_send(client, (u8 *)tx, 4);
if (ret < 0)
dev_err(&client->dev, "I2C write error\n");
@@ -54,25 +49,16 @@ static int ad714x_i2c_read(struct device *dev, unsigned short reg,
{
struct i2c_client *client = to_i2c_client(dev);
int ret = 0;
- u8 *_reg = (u8 *)®
- u8 *_data = (u8 *)data;
+ unsigned short tx = cpu_to_be16(reg);
- u8 tx[2] = {
- _reg[1],
- _reg[0]
- };
- u8 rx[2];
-
- ret = i2c_master_send(client, tx, 2);
+ ret = i2c_master_send(client, (u8 *)&tx, 2);
if (ret >= 0)
- ret = i2c_master_recv(client, rx, 2);
+ ret = i2c_master_recv(client, (u8 *)data, 2);
- if (unlikely(ret < 0)) {
+ if (unlikely(ret < 0))
dev_err(&client->dev, "I2C read error\n");
- } else {
- _data[0] = rx[1];
- _data[1] = rx[0];
- }
+ else
+ *data = be16_to_cpu(*data);
return ret;
}
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c
index da83ac9..0c7f948 100644
--- a/drivers/input/misc/ad714x-spi.c
+++ b/drivers/input/misc/ad714x-spi.c
@@ -6,7 +6,7 @@
* Licensed under the GPL-2 or later.
*/
-#include <linux/input.h> /* BUS_I2C */
+#include <linux/input.h> /* BUS_SPI */
#include <linux/module.h>
#include <linux/spi/spi.h>
#include <linux/pm.h>
@@ -30,22 +30,28 @@ static int ad714x_spi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
-static int ad714x_spi_read(struct device *dev, unsigned short reg,
- unsigned short *data)
+static int ad714x_spi_read(struct device *dev,
+ unsigned short reg, unsigned short *data)
{
struct spi_device *spi = to_spi_device(dev);
- unsigned short tx = AD714x_SPI_CMD_PREFIX | AD714x_SPI_READ | reg;
+ unsigned short tx = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
+ AD714x_SPI_READ | reg);
+ int ret;
- return spi_write_then_read(spi, (u8 *)&tx, 2, (u8 *)data, 2);
+ ret = spi_write_then_read(spi, &tx, 2, data, 2);
+
+ *data = be16_to_cpup(data);
+
+ return ret;
}
-static int ad714x_spi_write(struct device *dev, unsigned short reg,
- unsigned short data)
+static int ad714x_spi_write(struct device *dev,
+ unsigned short reg, unsigned short data)
{
struct spi_device *spi = to_spi_device(dev);
unsigned short tx[2] = {
- AD714x_SPI_CMD_PREFIX | reg,
- data
+ cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg),
+ cpu_to_be16(data)
};
return spi_write(spi, (u8 *)tx, 4);
--
1.7.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-21 20:09 [PATCH 1/4] Input: ad714xx-spi - force SPI bus into the default 8-bit mode Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 2/4] Input: ad714x - fix endianness issues Dmitry Torokhov
@ 2011-08-21 20:09 ` Dmitry Torokhov
2011-08-22 0:17 ` [Device-drivers-devel] " Mike Frysinger
2011-08-22 11:43 ` Michael Hennerich
2011-08-21 20:09 ` [PATCH 4/4] Input: ad714x - read the interrupt status registers in a row Dmitry Torokhov
2 siblings, 2 replies; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-21 20:09 UTC (permalink / raw)
To: Michael Hennerich; +Cc: linux-input, drivers, device-drivers-devel
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().
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
---
drivers/input/misc/ad714x-i2c.c | 60 ++++++++++++++------------
drivers/input/misc/ad714x-spi.c | 51 ++++++++++++++++------
drivers/input/misc/ad714x.c | 90 +++++++++++++--------------------------
drivers/input/misc/ad714x.h | 33 +++++++++++++-
4 files changed, 131 insertions(+), 103 deletions(-)
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index 00a6a22..6c61218 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)
static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
-static int ad714x_i2c_write(struct device *dev, unsigned short reg,
- unsigned short data)
+static int ad714x_i2c_write(struct ad714x_chip *chip,
+ unsigned short reg, unsigned short data)
{
- struct i2c_client *client = to_i2c_client(dev);
- int ret = 0;
- unsigned short tx[2] = {
- cpu_to_be16(reg),
- cpu_to_be16(data)
- };
-
- ret = i2c_master_send(client, (u8 *)tx, 4);
- if (ret < 0)
- dev_err(&client->dev, "I2C write error\n");
-
- return ret;
+ struct i2c_client *client = to_i2c_client(chip->dev);
+ int error;
+
+ chip->xfer_buf[0] = cpu_to_be16(reg);
+ chip->xfer_buf[1] = cpu_to_be16(data);
+
+ error = i2c_master_send(client, (u8 *)chip->xfer_buf,
+ 2 * sizeof(*chip->xfer_buf));
+ if (unlikely(error < 0)) {
+ dev_err(&client->dev, "I2C write error: %d\n", error);
+ return error;
+ }
+
+ return 0;
}
-static int ad714x_i2c_read(struct device *dev, unsigned short reg,
- unsigned short *data)
+static int ad714x_i2c_read(struct ad714x_chip *chip,
+ unsigned short reg, unsigned short *data)
{
- struct i2c_client *client = to_i2c_client(dev);
- int ret = 0;
- unsigned short tx = cpu_to_be16(reg);
+ struct i2c_client *client = to_i2c_client(chip->dev);
+ int error;
+
+ chip->xfer_buf[0] = cpu_to_be16(reg);
- ret = i2c_master_send(client, (u8 *)&tx, 2);
- if (ret >= 0)
- ret = i2c_master_recv(client, (u8 *)data, 2);
+ error = i2c_master_send(client, (u8 *)chip->xfer_buf,
+ sizeof(*chip->xfer_buf));
+ if (error >= 0)
+ error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
+ sizeof(*chip->xfer_buf));
- if (unlikely(ret < 0))
- dev_err(&client->dev, "I2C read error\n");
- else
- *data = be16_to_cpu(*data);
+ if (unlikely(error < 0)) {
+ dev_err(&client->dev, "I2C read error: %d\n", error);
+ return error;
+ }
- return ret;
+ *data = be16_to_cpup(chip->xfer_buf);
+ return 0;
}
static 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 0c7f948..306577d 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)
static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
-static int ad714x_spi_read(struct device *dev,
+static int ad714x_spi_read(struct ad714x_chip *chip,
unsigned short reg, unsigned short *data)
{
- struct spi_device *spi = to_spi_device(dev);
- unsigned short tx = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
+ struct spi_device *spi = to_spi_device(chip->dev);
+ struct spi_message message;
+ struct spi_transfer xfer[2];
+ int error;
+
+ spi_message_init(&message);
+ memset(xfer, 0, sizeof(xfer));
+
+ chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
AD714x_SPI_READ | reg);
- int ret;
+ xfer[0].tx_buf = &chip->xfer_buf[0];
+ xfer[0].len = sizeof(chip->xfer_buf[0]);
+ spi_message_add_tail(&xfer[0], &message);
- ret = spi_write_then_read(spi, &tx, 2, data, 2);
+ xfer[1].rx_buf = &chip->xfer_buf[1];
+ xfer[1].len = sizeof(chip->xfer_buf[1]);
+ spi_message_add_tail(&xfer[1], &message);
- *data = be16_to_cpup(data);
+ error = spi_sync(spi, &message);
+ if (unlikely(error)) {
+ dev_err(chip->dev, "SPI read error: %d\n", error);
+ return error;
+ }
- return ret;
+ *data = be16_to_cpu(chip->xfer_buf[1]);
+ return 0;
}
-static int ad714x_spi_write(struct device *dev,
+static int ad714x_spi_write(struct ad714x_chip *chip,
unsigned short reg, unsigned short data)
{
- struct spi_device *spi = to_spi_device(dev);
- unsigned short tx[2] = {
- cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg),
- cpu_to_be16(data)
- };
+ struct spi_device *spi = to_spi_device(chip->dev);
+ int error;
- return spi_write(spi, (u8 *)tx, 4);
+ chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
+ chip->xfer_buf[1] = cpu_to_be16(data);
+
+ error = spi_write(spi, (u8 *)chip->xfer_buf,
+ 2 * sizeof(*chip->xfer_buf));
+ if (unlikely(error)) {
+ dev_err(chip->dev, "SPI write error: %d\n", error);
+ return error;
+ }
+
+ return 0;
}
static int __devinit ad714x_spi_probe(struct spi_device *spi)
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c
index c3a62c4..2be0366 100644
--- a/drivers/input/misc/ad714x.c
+++ b/drivers/input/misc/ad714x.c
@@ -59,7 +59,6 @@
#define STAGE11_AMBIENT 0x27D
#define PER_STAGE_REG_NUM 36
-#define STAGE_NUM 12
#define STAGE_CFGREG_NUM 8
#define SYS_CFGREG_NUM 8
@@ -124,28 +123,6 @@ struct ad714x_driver_data {
* information to integrate all things which will be private data
* of spi/i2c device
*/
-struct ad714x_chip {
- unsigned short h_state;
- unsigned short l_state;
- unsigned short c_state;
- unsigned short adc_reg[STAGE_NUM];
- unsigned short amb_reg[STAGE_NUM];
- unsigned short sensor_val[STAGE_NUM];
-
- struct ad714x_platform_data *hw;
- struct ad714x_driver_data *sw;
-
- int irq;
- struct device *dev;
- ad714x_read_t read;
- ad714x_write_t write;
-
- struct mutex mutex;
-
- unsigned product;
- unsigned version;
-};
-
static void ad714x_use_com_int(struct ad714x_chip *ad714x,
int start_stage, int end_stage)
{
@@ -154,13 +131,13 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
- ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_COM_INT_EN_REG, &data);
data |= 1 << end_stage;
- ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
+ ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
- ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data);
data &= ~mask;
- ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
+ ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
}
static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
@@ -171,13 +148,13 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
- ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_COM_INT_EN_REG, &data);
data &= ~(1 << end_stage);
- ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
+ ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
- ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data);
data |= mask;
- ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
+ ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
}
static 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)
int i;
for (i = hw->start_stage; i <= hw->end_stage; i++) {
- ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
- &ad714x->adc_reg[i]);
- ad714x->read(ad714x->dev,
- STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
+ ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
+ ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i]);
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)
int i;
for (i = hw->start_stage; i <= hw->end_stage; i++) {
- ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
- &ad714x->adc_reg[i]);
- ad714x->read(ad714x->dev,
- STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
+ ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
+ ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i]);
if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
ad714x->sensor_val[i] = ad714x->adc_reg[i] -
@@ -598,10 +571,8 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
int i;
for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
- ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
- &ad714x->adc_reg[i]);
- ad714x->read(ad714x->dev,
- STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
+ ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
+ ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
&ad714x->amb_reg[i]);
if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
ad714x->sensor_val[i] = ad714x->adc_reg[i] -
@@ -891,7 +862,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
{
unsigned short data;
- ad714x->read(ad714x->dev, AD714X_PARTID_REG, &data);
+ ad714x->read(ad714x, AD714X_PARTID_REG, &data);
switch (data & 0xFFF0) {
case AD7142_PARTID:
ad714x->product = 0x7142;
@@ -940,23 +911,22 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
for (i = 0; i < STAGE_NUM; i++) {
reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
for (j = 0; j < STAGE_CFGREG_NUM; j++)
- ad714x->write(ad714x->dev, reg_base + j,
+ ad714x->write(ad714x, reg_base + j,
ad714x->hw->stage_cfg_reg[i][j]);
}
for (i = 0; i < SYS_CFGREG_NUM; i++)
- ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i,
+ ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
ad714x->hw->sys_cfg_reg[i]);
for (i = 0; i < SYS_CFGREG_NUM; i++)
- ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i,
- &data);
+ ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data);
- ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF);
+ ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
/* clear all interrupts */
- ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
- ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
- ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
}
static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
@@ -966,9 +936,9 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
mutex_lock(&ad714x->mutex);
- ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &ad714x->l_state);
- ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &ad714x->h_state);
- ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &ad714x->c_state);
+ ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state);
+ ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &ad714x->h_state);
+ ad714x->read(ad714x, STG_COM_INT_STA_REG, &ad714x->c_state);
for (i = 0; i < ad714x->hw->button_num; i++)
ad714x_button_state_machine(ad714x, i);
@@ -1245,7 +1215,7 @@ int ad714x_disable(struct ad714x_chip *ad714x)
mutex_lock(&ad714x->mutex);
data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
- ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data);
+ ad714x->write(ad714x, AD714X_PWR_CTRL, data);
mutex_unlock(&ad714x->mutex);
@@ -1263,16 +1233,16 @@ int ad714x_enable(struct ad714x_chip *ad714x)
/* resume to non-shutdown mode */
- ad714x->write(ad714x->dev, AD714X_PWR_CTRL,
+ ad714x->write(ad714x, AD714X_PWR_CTRL,
ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
/* make sure the interrupt output line is not low level after resume,
* otherwise we will get no chance to enter falling-edge irq again
*/
- ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG, &data);
- ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG, &data);
- ad714x->read(ad714x->dev, STG_COM_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
mutex_unlock(&ad714x->mutex);
diff --git a/drivers/input/misc/ad714x.h b/drivers/input/misc/ad714x.h
index 45c54fb..d12d149 100644
--- a/drivers/input/misc/ad714x.h
+++ b/drivers/input/misc/ad714x.h
@@ -11,11 +11,40 @@
#include <linux/types.h>
+#define STAGE_NUM 12
+
struct device;
+struct ad714x_platform_data;
+struct ad714x_driver_data;
struct ad714x_chip;
-typedef int (*ad714x_read_t)(struct device *, unsigned short, unsigned short *);
-typedef int (*ad714x_write_t)(struct device *, unsigned short, unsigned short);
+typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *);
+typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short);
+
+struct ad714x_chip {
+ unsigned short h_state;
+ unsigned short l_state;
+ unsigned short c_state;
+ unsigned short adc_reg[STAGE_NUM];
+ unsigned short amb_reg[STAGE_NUM];
+ unsigned short sensor_val[STAGE_NUM];
+
+ struct ad714x_platform_data *hw;
+ struct ad714x_driver_data *sw;
+
+ int irq;
+ struct device *dev;
+ ad714x_read_t read;
+ ad714x_write_t write;
+
+ struct mutex mutex;
+
+ unsigned product;
+ unsigned version;
+
+ __be16 xfer_buf[16] ____cacheline_aligned;
+
+};
int ad714x_disable(struct ad714x_chip *ad714x);
int ad714x_enable(struct ad714x_chip *ad714x);
--
1.7.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 4/4] Input: ad714x - read the interrupt status registers in a row
2011-08-21 20:09 [PATCH 1/4] Input: ad714xx-spi - force SPI bus into the default 8-bit mode Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 2/4] Input: ad714x - fix endianness issues Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write() Dmitry Torokhov
@ 2011-08-21 20:09 ` Dmitry Torokhov
2 siblings, 0 replies; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-21 20:09 UTC (permalink / raw)
To: Michael Hennerich; +Cc: linux-input, drivers, device-drivers-devel
From: Michael Hennerich <michael.hennerich@analog.com>
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>
---
drivers/input/misc/ad714x-i2c.c | 11 ++++--
drivers/input/misc/ad714x-spi.c | 11 ++++--
drivers/input/misc/ad714x.c | 62 ++++++++++++++++++++-------------------
drivers/input/misc/ad714x.h | 4 +-
4 files changed, 48 insertions(+), 40 deletions(-)
diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
index 6c61218..025417d 100644
--- a/drivers/input/misc/ad714x-i2c.c
+++ b/drivers/input/misc/ad714x-i2c.c
@@ -1,7 +1,7 @@
/*
* AD714X CapTouch Programmable Controller driver (I2C bus)
*
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -47,9 +47,10 @@ static int ad714x_i2c_write(struct ad714x_chip *chip,
}
static int ad714x_i2c_read(struct ad714x_chip *chip,
- unsigned short reg, unsigned short *data)
+ unsigned short reg, unsigned short *data, size_t len)
{
struct i2c_client *client = to_i2c_client(chip->dev);
+ int i;
int error;
chip->xfer_buf[0] = cpu_to_be16(reg);
@@ -58,14 +59,16 @@ static int ad714x_i2c_read(struct ad714x_chip *chip,
sizeof(*chip->xfer_buf));
if (error >= 0)
error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
- sizeof(*chip->xfer_buf));
+ len * sizeof(*chip->xfer_buf));
if (unlikely(error < 0)) {
dev_err(&client->dev, "I2C read error: %d\n", error);
return error;
}
- *data = be16_to_cpup(chip->xfer_buf);
+ for (i = 0; i < len; i++)
+ data[i] = be16_to_cpu(chip->xfer_buf[i]);
+
return 0;
}
diff --git a/drivers/input/misc/ad714x-spi.c b/drivers/input/misc/ad714x-spi.c
index 306577d..875b508 100644
--- a/drivers/input/misc/ad714x-spi.c
+++ b/drivers/input/misc/ad714x-spi.c
@@ -1,7 +1,7 @@
/*
* AD714X CapTouch Programmable Controller driver (SPI bus)
*
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -31,11 +31,12 @@ static int ad714x_spi_resume(struct device *dev)
static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
static int ad714x_spi_read(struct ad714x_chip *chip,
- unsigned short reg, unsigned short *data)
+ unsigned short reg, unsigned short *data, size_t len)
{
struct spi_device *spi = to_spi_device(chip->dev);
struct spi_message message;
struct spi_transfer xfer[2];
+ int i;
int error;
spi_message_init(&message);
@@ -48,7 +49,7 @@ static int ad714x_spi_read(struct ad714x_chip *chip,
spi_message_add_tail(&xfer[0], &message);
xfer[1].rx_buf = &chip->xfer_buf[1];
- xfer[1].len = sizeof(chip->xfer_buf[1]);
+ xfer[1].len = sizeof(chip->xfer_buf[1]) * len;
spi_message_add_tail(&xfer[1], &message);
error = spi_sync(spi, &message);
@@ -57,7 +58,9 @@ static int ad714x_spi_read(struct ad714x_chip *chip,
return error;
}
- *data = be16_to_cpu(chip->xfer_buf[1]);
+ for (i = 0; i < len; i++)
+ data[i] = be16_to_cpu(chip->xfer_buf[i + 1]);
+
return 0;
}
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c
index 2be0366..ca42c7d 100644
--- a/drivers/input/misc/ad714x.c
+++ b/drivers/input/misc/ad714x.c
@@ -1,7 +1,7 @@
/*
* AD714X CapTouch Programmable Controller driver supporting AD7142/3/7/8/7A
*
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -123,6 +123,7 @@ struct ad714x_driver_data {
* information to integrate all things which will be private data
* of spi/i2c device
*/
+
static void ad714x_use_com_int(struct ad714x_chip *ad714x,
int start_stage, int end_stage)
{
@@ -131,11 +132,11 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
- ad714x->read(ad714x, STG_COM_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
data |= 1 << end_stage;
ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
- ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
data &= ~mask;
ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
}
@@ -148,11 +149,11 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1);
- ad714x->read(ad714x, STG_COM_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_COM_INT_EN_REG, &data, 1);
data &= ~(1 << end_stage);
ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
- ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data);
+ ad714x->read(ad714x, STG_HIGH_INT_EN_REG, &data, 1);
data |= mask;
ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
}
@@ -250,13 +251,16 @@ static void ad714x_slider_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
struct ad714x_slider_plat *hw = &ad714x->hw->slider[idx];
int i;
+ ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
+ &ad714x->adc_reg[hw->start_stage],
+ hw->end_stage - hw->start_stage + 1);
+
for (i = hw->start_stage; i <= hw->end_stage; i++) {
- ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
- &ad714x->amb_reg[i]);
+ &ad714x->amb_reg[i], 1);
- ad714x->sensor_val[i] = abs(ad714x->adc_reg[i] -
- ad714x->amb_reg[i]);
+ ad714x->sensor_val[i] =
+ abs(ad714x->adc_reg[i] - ad714x->amb_reg[i]);
}
}
@@ -419,13 +423,16 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx];
int i;
+ ad714x->read(ad714x, CDC_RESULT_S0 + hw->start_stage,
+ &ad714x->adc_reg[hw->start_stage],
+ hw->end_stage - hw->start_stage + 1);
+
for (i = hw->start_stage; i <= hw->end_stage; i++) {
- ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
- &ad714x->amb_reg[i]);
+ &ad714x->amb_reg[i], 1);
if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
- ad714x->sensor_val[i] = ad714x->adc_reg[i] -
- ad714x->amb_reg[i];
+ ad714x->sensor_val[i] =
+ ad714x->adc_reg[i] - ad714x->amb_reg[i];
else
ad714x->sensor_val[i] = 0;
}
@@ -570,13 +577,16 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
struct ad714x_touchpad_plat *hw = &ad714x->hw->touchpad[idx];
int i;
+ ad714x->read(ad714x, CDC_RESULT_S0 + hw->x_start_stage,
+ &ad714x->adc_reg[hw->x_start_stage],
+ hw->x_end_stage - hw->x_start_stage + 1);
+
for (i = hw->x_start_stage; i <= hw->x_end_stage; i++) {
- ad714x->read(ad714x, CDC_RESULT_S0 + i, &ad714x->adc_reg[i]);
ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
- &ad714x->amb_reg[i]);
+ &ad714x->amb_reg[i], 1);
if (ad714x->adc_reg[i] > ad714x->amb_reg[i])
- ad714x->sensor_val[i] = ad714x->adc_reg[i] -
- ad714x->amb_reg[i];
+ ad714x->sensor_val[i] =
+ ad714x->adc_reg[i] - ad714x->amb_reg[i];
else
ad714x->sensor_val[i] = 0;
}
@@ -862,7 +872,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
{
unsigned short data;
- ad714x->read(ad714x, AD714X_PARTID_REG, &data);
+ ad714x->read(ad714x, AD714X_PARTID_REG, &data, 1);
switch (data & 0xFFF0) {
case AD7142_PARTID:
ad714x->product = 0x7142;
@@ -919,14 +929,12 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
ad714x->hw->sys_cfg_reg[i]);
for (i = 0; i < SYS_CFGREG_NUM; i++)
- ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data);
+ ad714x->read(ad714x, AD714X_SYSCFG_REG + i, &data, 1);
ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
/* clear all interrupts */
- ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data);
- ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
- ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
}
static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
@@ -936,9 +944,7 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
mutex_lock(&ad714x->mutex);
- ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state);
- ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &ad714x->h_state);
- ad714x->read(ad714x, STG_COM_INT_STA_REG, &ad714x->c_state);
+ ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
for (i = 0; i < ad714x->hw->button_num; i++)
ad714x_button_state_machine(ad714x, i);
@@ -1225,8 +1231,6 @@ EXPORT_SYMBOL(ad714x_disable);
int ad714x_enable(struct ad714x_chip *ad714x)
{
- unsigned short data;
-
dev_dbg(ad714x->dev, "%s enter\n", __func__);
mutex_lock(&ad714x->mutex);
@@ -1240,9 +1244,7 @@ int ad714x_enable(struct ad714x_chip *ad714x)
* otherwise we will get no chance to enter falling-edge irq again
*/
- ad714x->read(ad714x, STG_LOW_INT_STA_REG, &data);
- ad714x->read(ad714x, STG_HIGH_INT_STA_REG, &data);
- ad714x->read(ad714x, STG_COM_INT_STA_REG, &data);
+ ad714x->read(ad714x, STG_LOW_INT_STA_REG, &ad714x->l_state, 3);
mutex_unlock(&ad714x->mutex);
diff --git a/drivers/input/misc/ad714x.h b/drivers/input/misc/ad714x.h
index d12d149..6edc080 100644
--- a/drivers/input/misc/ad714x.h
+++ b/drivers/input/misc/ad714x.h
@@ -1,7 +1,7 @@
/*
* AD714X CapTouch Programmable Controller driver (bus interfaces)
*
- * Copyright 2009 Analog Devices Inc.
+ * Copyright 2009-2011 Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/
@@ -18,7 +18,7 @@ struct ad714x_platform_data;
struct ad714x_driver_data;
struct ad714x_chip;
-typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *);
+typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *, size_t);
typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short);
struct ad714x_chip {
--
1.7.6
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [Device-drivers-devel] [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-21 20:09 ` [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write() Dmitry Torokhov
@ 2011-08-22 0:17 ` Mike Frysinger
2011-08-22 0:46 ` Dmitry Torokhov
2011-08-22 0:46 ` Dmitry Torokhov
2011-08-22 11:43 ` Michael Hennerich
1 sibling, 2 replies; 12+ messages in thread
From: Mike Frysinger @ 2011-08-22 0:17 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Michael Hennerich, drivers, device-drivers-devel, linux-input
On Sun, Aug 21, 2011 at 16:09, Dmitry Torokhov wrote:
> 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().
seems like there's a whole lot of style changes unrelated to spi and
dma ... more so than the actual dma/spi change.
-mike
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Device-drivers-devel] [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-22 0:17 ` [Device-drivers-devel] " Mike Frysinger
@ 2011-08-22 0:46 ` Dmitry Torokhov
2011-08-22 0:46 ` Dmitry Torokhov
1 sibling, 0 replies; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-22 0:46 UTC (permalink / raw)
To: Mike Frysinger
Cc: Michael Hennerich, drivers, device-drivers-devel, linux-input
ike Frysinger <vapier.adi@gmail.com> wrote:
>On Sun, Aug 21, 2011 at 16:09, Dmitry Torokhov wrote:
>> 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().
>
>seems like there's a whole lot of style changes unrelated to spi and
>dma ... more so than the actual dma/spi change.
Hmm, I tried to control myself so (aside of return -> error) renames there shouldn't be many style changes... The diff looks big because we are passing ad714x instead of ad714x->dev to the read/write methods.
--
Dmitry
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [Device-drivers-devel] [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-22 0:17 ` [Device-drivers-devel] " Mike Frysinger
2011-08-22 0:46 ` Dmitry Torokhov
@ 2011-08-22 0:46 ` Dmitry Torokhov
1 sibling, 0 replies; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-22 0:46 UTC (permalink / raw)
To: Mike Frysinger
Cc: Michael Hennerich, drivers, device-drivers-devel, linux-input
ike Frysinger <vapier.adi@gmail.com> wrote:
>On Sun, Aug 21, 2011 at 16:09, Dmitry Torokhov wrote:
>> 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().
>
>seems like there's a whole lot of style changes unrelated to spi and
>dma ... more so than the actual dma/spi change.
Hmm, I tried to control myself so (aside of return -> error) renames there shouldn't be many style changes... The diff looks big because we are passing ad714x instead of ad714x->dev to the read/write methods.
--
Dmitry
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-21 20:09 ` [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write() Dmitry Torokhov
2011-08-22 0:17 ` [Device-drivers-devel] " Mike Frysinger
@ 2011-08-22 11:43 ` Michael Hennerich
2011-08-22 16:39 ` Dmitry Torokhov
1 sibling, 1 reply; 12+ messages in thread
From: Michael Hennerich @ 2011-08-22 11:43 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, Drivers, device-drivers-devel
On 08/21/2011 10:09 PM, Dmitry Torokhov wrote:
> 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().
>
> Signed-off-by: Dmitry Torokhov<dtor@mail.ru>
Looks good - one piece of the original patch set got lost.
See below - patch follows.
Thanks!
Acked-by: Michael Hennerich <michael.hennerich@analog.com>
> ---
> drivers/input/misc/ad714x-i2c.c | 60 ++++++++++++++------------
> drivers/input/misc/ad714x-spi.c | 51 ++++++++++++++++------
> drivers/input/misc/ad714x.c | 90 +++++++++++++--------------------------
> drivers/input/misc/ad714x.h | 33 +++++++++++++-
> 4 files changed, 131 insertions(+), 103 deletions(-)
>
> diff --git a/drivers/input/misc/ad714x-i2c.c b/drivers/input/misc/ad714x-i2c.c
> index 00a6a22..6c61218 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)
>
> static SIMPLE_DEV_PM_OPS(ad714x_i2c_pm, ad714x_i2c_suspend, ad714x_i2c_resume);
>
> -static int ad714x_i2c_write(struct device *dev, unsigned short reg,
> - unsigned short data)
> +static int ad714x_i2c_write(struct ad714x_chip *chip,
> + unsigned short reg, unsigned short data)
> {
> - struct i2c_client *client = to_i2c_client(dev);
> - int ret = 0;
> - unsigned short tx[2] = {
> - cpu_to_be16(reg),
> - cpu_to_be16(data)
> - };
> -
> - ret = i2c_master_send(client, (u8 *)tx, 4);
> - if (ret< 0)
> - dev_err(&client->dev, "I2C write error\n");
> -
> - return ret;
> + struct i2c_client *client = to_i2c_client(chip->dev);
> + int error;
> +
> + chip->xfer_buf[0] = cpu_to_be16(reg);
> + chip->xfer_buf[1] = cpu_to_be16(data);
> +
> + error = i2c_master_send(client, (u8 *)chip->xfer_buf,
> + 2 * sizeof(*chip->xfer_buf));
> + if (unlikely(error< 0)) {
> + dev_err(&client->dev, "I2C write error: %d\n", error);
> + return error;
> + }
> +
> + return 0;
> }
>
> -static int ad714x_i2c_read(struct device *dev, unsigned short reg,
> - unsigned short *data)
> +static int ad714x_i2c_read(struct ad714x_chip *chip,
> + unsigned short reg, unsigned short *data)
> {
> - struct i2c_client *client = to_i2c_client(dev);
> - int ret = 0;
> - unsigned short tx = cpu_to_be16(reg);
> + struct i2c_client *client = to_i2c_client(chip->dev);
> + int error;
> +
> + chip->xfer_buf[0] = cpu_to_be16(reg);
>
> - ret = i2c_master_send(client, (u8 *)&tx, 2);
> - if (ret>= 0)
> - ret = i2c_master_recv(client, (u8 *)data, 2);
> + error = i2c_master_send(client, (u8 *)chip->xfer_buf,
> + sizeof(*chip->xfer_buf));
> + if (error>= 0)
> + error = i2c_master_recv(client, (u8 *)chip->xfer_buf,
> + sizeof(*chip->xfer_buf));
>
> - if (unlikely(ret< 0))
> - dev_err(&client->dev, "I2C read error\n");
> - else
> - *data = be16_to_cpu(*data);
> + if (unlikely(error< 0)) {
> + dev_err(&client->dev, "I2C read error: %d\n", error);
> + return error;
> + }
>
> - return ret;
> + *data = be16_to_cpup(chip->xfer_buf);
> + return 0;
> }
>
> static 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 0c7f948..306577d 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)
>
> static SIMPLE_DEV_PM_OPS(ad714x_spi_pm, ad714x_spi_suspend, ad714x_spi_resume);
>
> -static int ad714x_spi_read(struct device *dev,
> +static int ad714x_spi_read(struct ad714x_chip *chip,
> unsigned short reg, unsigned short *data)
> {
> - struct spi_device *spi = to_spi_device(dev);
> - unsigned short tx = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
> + struct spi_device *spi = to_spi_device(chip->dev);
> + struct spi_message message;
> + struct spi_transfer xfer[2];
> + int error;
> +
> + spi_message_init(&message);
> + memset(xfer, 0, sizeof(xfer));
> +
> + chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX |
> AD714x_SPI_READ | reg);
> - int ret;
> + xfer[0].tx_buf =&chip->xfer_buf[0];
> + xfer[0].len = sizeof(chip->xfer_buf[0]);
> + spi_message_add_tail(&xfer[0],&message);
>
> - ret = spi_write_then_read(spi,&tx, 2, data, 2);
> + xfer[1].rx_buf =&chip->xfer_buf[1];
> + xfer[1].len = sizeof(chip->xfer_buf[1]);
> + spi_message_add_tail(&xfer[1],&message);
>
> - *data = be16_to_cpup(data);
> + error = spi_sync(spi,&message);
> + if (unlikely(error)) {
> + dev_err(chip->dev, "SPI read error: %d\n", error);
> + return error;
> + }
>
> - return ret;
> + *data = be16_to_cpu(chip->xfer_buf[1]);
> + return 0;
> }
>
> -static int ad714x_spi_write(struct device *dev,
> +static int ad714x_spi_write(struct ad714x_chip *chip,
> unsigned short reg, unsigned short data)
> {
> - struct spi_device *spi = to_spi_device(dev);
> - unsigned short tx[2] = {
> - cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg),
> - cpu_to_be16(data)
> - };
> + struct spi_device *spi = to_spi_device(chip->dev);
> + int error;
>
> - return spi_write(spi, (u8 *)tx, 4);
> + chip->xfer_buf[0] = cpu_to_be16(AD714x_SPI_CMD_PREFIX | reg);
> + chip->xfer_buf[1] = cpu_to_be16(data);
> +
> + error = spi_write(spi, (u8 *)chip->xfer_buf,
> + 2 * sizeof(*chip->xfer_buf));
> + if (unlikely(error)) {
> + dev_err(chip->dev, "SPI write error: %d\n", error);
> + return error;
> + }
> +
> + return 0;
> }
>
> static int __devinit ad714x_spi_probe(struct spi_device *spi)
> diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c
> index c3a62c4..2be0366 100644
> --- a/drivers/input/misc/ad714x.c
> +++ b/drivers/input/misc/ad714x.c
> @@ -59,7 +59,6 @@
> #define STAGE11_AMBIENT 0x27D
>
> #define PER_STAGE_REG_NUM 36
> -#define STAGE_NUM 12
> #define STAGE_CFGREG_NUM 8
> #define SYS_CFGREG_NUM 8
>
> @@ -124,28 +123,6 @@ struct ad714x_driver_data {
> * information to integrate all things which will be private data
> * of spi/i2c device
> */
> -struct ad714x_chip {
> - unsigned short h_state;
> - unsigned short l_state;
> - unsigned short c_state;
> - unsigned short adc_reg[STAGE_NUM];
> - unsigned short amb_reg[STAGE_NUM];
> - unsigned short sensor_val[STAGE_NUM];
> -
> - struct ad714x_platform_data *hw;
> - struct ad714x_driver_data *sw;
> -
> - int irq;
> - struct device *dev;
> - ad714x_read_t read;
> - ad714x_write_t write;
> -
> - struct mutex mutex;
> -
> - unsigned product;
> - unsigned version;
> -};
> -
> static void ad714x_use_com_int(struct ad714x_chip *ad714x,
> int start_stage, int end_stage)
> {
> @@ -154,13 +131,13 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x,
>
> mask = ((1<< (end_stage + 1)) - 1) - ((1<< start_stage) - 1);
>
> - ad714x->read(ad714x->dev, STG_COM_INT_EN_REG,&data);
> + ad714x->read(ad714x, STG_COM_INT_EN_REG,&data);
> data |= 1<< end_stage;
> - ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
> + ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
>
> - ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG,&data);
> + ad714x->read(ad714x, STG_HIGH_INT_EN_REG,&data);
> data&= ~mask;
> - ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
> + ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
> }
>
> static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
> @@ -171,13 +148,13 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x,
>
> mask = ((1<< (end_stage + 1)) - 1) - ((1<< start_stage) - 1);
>
> - ad714x->read(ad714x->dev, STG_COM_INT_EN_REG,&data);
> + ad714x->read(ad714x, STG_COM_INT_EN_REG,&data);
> data&= ~(1<< end_stage);
> - ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data);
> + ad714x->write(ad714x, STG_COM_INT_EN_REG, data);
>
> - ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG,&data);
> + ad714x->read(ad714x, STG_HIGH_INT_EN_REG,&data);
> data |= mask;
> - ad714x->write(ad714x->dev, STG_HIGH_INT_EN_REG, data);
> + ad714x->write(ad714x, STG_HIGH_INT_EN_REG, data);
> }
>
> static 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)
> int i;
>
> for (i = hw->start_stage; i<= hw->end_stage; i++) {
> - ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
> -&ad714x->adc_reg[i]);
> - ad714x->read(ad714x->dev,
> - STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
> + ad714x->read(ad714x, CDC_RESULT_S0 + i,&ad714x->adc_reg[i]);
> + ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
> &ad714x->amb_reg[i]);
>
> 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)
> int i;
>
> for (i = hw->start_stage; i<= hw->end_stage; i++) {
> - ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
> -&ad714x->adc_reg[i]);
> - ad714x->read(ad714x->dev,
> - STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
> + ad714x->read(ad714x, CDC_RESULT_S0 + i,&ad714x->adc_reg[i]);
> + ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
> &ad714x->amb_reg[i]);
> if (ad714x->adc_reg[i]> ad714x->amb_reg[i])
> ad714x->sensor_val[i] = ad714x->adc_reg[i] -
> @@ -598,10 +571,8 @@ static void touchpad_cal_sensor_val(struct ad714x_chip *ad714x, int idx)
> int i;
>
> for (i = hw->x_start_stage; i<= hw->x_end_stage; i++) {
> - ad714x->read(ad714x->dev, CDC_RESULT_S0 + i,
> -&ad714x->adc_reg[i]);
> - ad714x->read(ad714x->dev,
> - STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
> + ad714x->read(ad714x, CDC_RESULT_S0 + i,&ad714x->adc_reg[i]);
> + ad714x->read(ad714x, STAGE0_AMBIENT + i * PER_STAGE_REG_NUM,
> &ad714x->amb_reg[i]);
> if (ad714x->adc_reg[i]> ad714x->amb_reg[i])
> ad714x->sensor_val[i] = ad714x->adc_reg[i] -
> @@ -891,7 +862,7 @@ static int ad714x_hw_detect(struct ad714x_chip *ad714x)
> {
> unsigned short data;
>
> - ad714x->read(ad714x->dev, AD714X_PARTID_REG,&data);
> + ad714x->read(ad714x, AD714X_PARTID_REG,&data);
> switch (data& 0xFFF0) {
> case AD7142_PARTID:
> ad714x->product = 0x7142;
> @@ -940,23 +911,22 @@ static void ad714x_hw_init(struct ad714x_chip *ad714x)
> for (i = 0; i< STAGE_NUM; i++) {
> reg_base = AD714X_STAGECFG_REG + i * STAGE_CFGREG_NUM;
> for (j = 0; j< STAGE_CFGREG_NUM; j++)
> - ad714x->write(ad714x->dev, reg_base + j,
> + ad714x->write(ad714x, reg_base + j,
> ad714x->hw->stage_cfg_reg[i][j]);
> }
>
> for (i = 0; i< SYS_CFGREG_NUM; i++)
> - ad714x->write(ad714x->dev, AD714X_SYSCFG_REG + i,
> + ad714x->write(ad714x, AD714X_SYSCFG_REG + i,
> ad714x->hw->sys_cfg_reg[i]);
> for (i = 0; i< SYS_CFGREG_NUM; i++)
> - ad714x->read(ad714x->dev, AD714X_SYSCFG_REG + i,
> -&data);
> + ad714x->read(ad714x, AD714X_SYSCFG_REG + i,&data);
>
> - ad714x->write(ad714x->dev, AD714X_STG_CAL_EN_REG, 0xFFF);
> + ad714x->write(ad714x, AD714X_STG_CAL_EN_REG, 0xFFF);
>
> /* clear all interrupts */
> - ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG,&data);
> - ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG,&data);
> - ad714x->read(ad714x->dev, STG_COM_INT_STA_REG,&data);
> + ad714x->read(ad714x, STG_LOW_INT_STA_REG,&data);
> + ad714x->read(ad714x, STG_HIGH_INT_STA_REG,&data);
> + ad714x->read(ad714x, STG_COM_INT_STA_REG,&data);
> }
>
> static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
> @@ -966,9 +936,9 @@ static irqreturn_t ad714x_interrupt_thread(int irq, void *data)
>
> mutex_lock(&ad714x->mutex);
>
> - ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG,&ad714x->l_state);
> - ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG,&ad714x->h_state);
> - ad714x->read(ad714x->dev, STG_COM_INT_STA_REG,&ad714x->c_state);
> + ad714x->read(ad714x, STG_LOW_INT_STA_REG,&ad714x->l_state);
> + ad714x->read(ad714x, STG_HIGH_INT_STA_REG,&ad714x->h_state);
> + ad714x->read(ad714x, STG_COM_INT_STA_REG,&ad714x->c_state);
>
> for (i = 0; i< ad714x->hw->button_num; i++)
> ad714x_button_state_machine(ad714x, i);
> @@ -1245,7 +1215,7 @@ int ad714x_disable(struct ad714x_chip *ad714x)
> mutex_lock(&ad714x->mutex);
>
> data = ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL] | 0x3;
> - ad714x->write(ad714x->dev, AD714X_PWR_CTRL, data);
> + ad714x->write(ad714x, AD714X_PWR_CTRL, data);
>
> mutex_unlock(&ad714x->mutex);
>
> @@ -1263,16 +1233,16 @@ int ad714x_enable(struct ad714x_chip *ad714x)
>
> /* resume to non-shutdown mode */
>
> - ad714x->write(ad714x->dev, AD714X_PWR_CTRL,
> + ad714x->write(ad714x, AD714X_PWR_CTRL,
> ad714x->hw->sys_cfg_reg[AD714X_PWR_CTRL]);
>
> /* make sure the interrupt output line is not low level after resume,
> * otherwise we will get no chance to enter falling-edge irq again
> */
>
> - ad714x->read(ad714x->dev, STG_LOW_INT_STA_REG,&data);
> - ad714x->read(ad714x->dev, STG_HIGH_INT_STA_REG,&data);
> - ad714x->read(ad714x->dev, STG_COM_INT_STA_REG,&data);
> + ad714x->read(ad714x, STG_LOW_INT_STA_REG,&data);
> + ad714x->read(ad714x, STG_HIGH_INT_STA_REG,&data);
> + ad714x->read(ad714x, STG_COM_INT_STA_REG,&data);
>
> mutex_unlock(&ad714x->mutex);
>
> diff --git a/drivers/input/misc/ad714x.h b/drivers/input/misc/ad714x.h
> index 45c54fb..d12d149 100644
> --- a/drivers/input/misc/ad714x.h
> +++ b/drivers/input/misc/ad714x.h
> @@ -11,11 +11,40 @@
>
> #include<linux/types.h>
>
> +#define STAGE_NUM 12
> +
> struct device;
> +struct ad714x_platform_data;
> +struct ad714x_driver_data;
> struct ad714x_chip;
>
> -typedef int (*ad714x_read_t)(struct device *, unsigned short, unsigned short *);
> -typedef int (*ad714x_write_t)(struct device *, unsigned short, unsigned short);
> +typedef int (*ad714x_read_t)(struct ad714x_chip *, unsigned short, unsigned short *);
> +typedef int (*ad714x_write_t)(struct ad714x_chip *, unsigned short, unsigned short);
> +
> +struct ad714x_chip {
> + unsigned short h_state;
> + unsigned short l_state;
Since we read status interrupt registers in row, we also need to place the
storage members sequentially. This part got dropped from the original
patch set.
Patch follows.
> + unsigned short c_state;
> + unsigned short adc_reg[STAGE_NUM];
> + unsigned short amb_reg[STAGE_NUM];
> + unsigned short sensor_val[STAGE_NUM];
> +
> + struct ad714x_platform_data *hw;
> + struct ad714x_driver_data *sw;
> +
> + int irq;
> + struct device *dev;
> + ad714x_read_t read;
> + ad714x_write_t write;
> +
> + struct mutex mutex;
> +
> + unsigned product;
> + unsigned version;
> +
> + __be16 xfer_buf[16] ____cacheline_aligned;
> +
> +};
>
> int ad714x_disable(struct ad714x_chip *ad714x);
> int ad714x_enable(struct ad714x_chip *ad714x);
> --
> 1.7.6
>
>
--
Greetings,
Michael
--
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin,
Margaret Seif
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-22 11:43 ` Michael Hennerich
@ 2011-08-22 16:39 ` Dmitry Torokhov
2011-08-23 7:02 ` Hennerich, Michael
0 siblings, 1 reply; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-22 16:39 UTC (permalink / raw)
To: michael.hennerich; +Cc: linux-input, Drivers, device-drivers-devel
On Monday, August 22, 2011 04:43:52 AM Michael Hennerich wrote:
> On 08/21/2011 10:09 PM, Dmitry Torokhov wrote:
> > 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().
> >
> > Signed-off-by: Dmitry Torokhov<dtor@mail.ru>
>
> Looks good - one piece of the original patch set got lost.
Aww, sorry about that.
> See below - patch follows.
Thank you very much, I'll fold it in your original patch - no reason
for having a known broken change in the tree if it can be corrected.
--
Dmitry
^ permalink raw reply [flat|nested] 12+ messages in thread
* RE: [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write()
2011-08-22 16:39 ` Dmitry Torokhov
@ 2011-08-23 7:02 ` Hennerich, Michael
0 siblings, 0 replies; 12+ messages in thread
From: Hennerich, Michael @ 2011-08-23 7:02 UTC (permalink / raw)
To: Dmitry Torokhov; +Cc: linux-input, Drivers, device-drivers-devel
Dmitry Torokhov wrote on 2011-08-22:
> On Monday, August 22, 2011 04:43:52 AM Michael Hennerich wrote:
>> On 08/21/2011 10:09 PM, Dmitry Torokhov wrote:
>>> 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().
>>>
>>> Signed-off-by: Dmitry Torokhov<dtor@mail.ru>
>>
>> Looks good - one piece of the original patch set got lost.
>
> Aww, sorry about that.
>
>> See below - patch follows.
>
> Thank you very much, I'll fold it in your original patch - no reason
> for having a known broken change in the tree if it can be corrected.
>
Thanks!
Greetings,
Michael
--
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Sitz der Gesellschaft: Muenchen; Registergericht: Muenchen HRB 40368;
Geschaeftsfuehrer:Dr.Carsten Suckrow, Thomas Wessel, William A. Martin, Margaret Seif
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/4] Input: ad714x - fix endianness issues
2011-08-21 20:09 ` [PATCH 2/4] Input: ad714x - fix endianness issues Dmitry Torokhov
@ 2011-08-23 16:22 ` Mark Brown
2011-08-23 16:50 ` Dmitry Torokhov
0 siblings, 1 reply; 12+ messages in thread
From: Mark Brown @ 2011-08-23 16:22 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Michael Hennerich, linux-input, drivers, device-drivers-devel
On Sun, Aug 21, 2011 at 01:09:03PM -0700, Dmitry Torokhov wrote:
> From: Michael Hennerich <michael.hennerich@analog.com>
>
> Allow driver to be used on Big Endian boxes.
>
> Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Might the regmap API be helpful here?
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/4] Input: ad714x - fix endianness issues
2011-08-23 16:22 ` Mark Brown
@ 2011-08-23 16:50 ` Dmitry Torokhov
0 siblings, 0 replies; 12+ messages in thread
From: Dmitry Torokhov @ 2011-08-23 16:50 UTC (permalink / raw)
To: Mark Brown; +Cc: Michael Hennerich, linux-input, drivers, device-drivers-devel
On Tue, Aug 23, 2011 at 05:22:57PM +0100, Mark Brown wrote:
> On Sun, Aug 21, 2011 at 01:09:03PM -0700, Dmitry Torokhov wrote:
> > From: Michael Hennerich <michael.hennerich@analog.com>
> >
> > Allow driver to be used on Big Endian boxes.
> >
> > Signed-off-by: Michael Hennerich <michael.hennerich@analog.com>
> > Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
>
> Might the regmap API be helpful here?
Looks like it might ;)... But as a follow-up for 3.2.
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-08-23 16:50 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-08-21 20:09 [PATCH 1/4] Input: ad714xx-spi - force SPI bus into the default 8-bit mode Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 2/4] Input: ad714x - fix endianness issues Dmitry Torokhov
2011-08-23 16:22 ` Mark Brown
2011-08-23 16:50 ` Dmitry Torokhov
2011-08-21 20:09 ` [PATCH 3/4] Input: ad714x - use DMA-safe buffers for spi_write() Dmitry Torokhov
2011-08-22 0:17 ` [Device-drivers-devel] " Mike Frysinger
2011-08-22 0:46 ` Dmitry Torokhov
2011-08-22 0:46 ` Dmitry Torokhov
2011-08-22 11:43 ` Michael Hennerich
2011-08-22 16:39 ` Dmitry Torokhov
2011-08-23 7:02 ` Hennerich, Michael
2011-08-21 20:09 ` [PATCH 4/4] Input: ad714x - read the interrupt status registers in a row Dmitry Torokhov
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.