Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
On Wed, Jul 15, 2015 at 02:13:26PM +0200, Sebastian Reichel wrote: > -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) > -{ > - u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value; > - struct spi_transfer xfer = { > - .tx_buf = , > - .len= 4, > - .bits_per_word = 24, > - }; I wonder why the original code used 24 bit-sized-words for transfers... -- Dmitry -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
On Wed, Jul 15, 2015 at 02:13:26PM +0200, Sebastian Reichel wrote: -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) -{ - u32 tx = ((reg | TSC2005_REG_PND0) 16) | value; - struct spi_transfer xfer = { - .tx_buf = tx, - .len= 4, - .bits_per_word = 24, - }; I wonder why the original code used 24 bit-sized-words for transfers... -- Dmitry -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
Hi Dmitry, On Wed, Jul 15, 2015 at 02:29:55PM -0700, Dmitry Torokhov wrote: > I also got: > > CC [M] drivers/input/touchscreen/tsc2005.o > Building modules, stage 2. > Kernel: arch/x86/boot/bzImage is ready (#1383) > MODPOST 1403 modules > ERROR: "devm_regmap_init_spi" [drivers/input/touchscreen/tsc2005.ko] > undefined! > make[1]: *** [__modpost] Error 1 > make: *** [modules] Error 2 > > I guess we need "select REGMAP_SPI". Right. I will add this in PATCHv2. -- Sebastian signature.asc Description: Digital signature
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
On Wed, Jul 15, 2015 at 02:29:55PM -0700, Dmitry Torokhov wrote: > Hi Sebastian, > > On Wed, Jul 15, 2015 at 02:13:26PM +0200, Sebastian Reichel wrote: > > > /* read the coordinates */ > > - error = spi_sync(ts->spi, >spi_read_msg); > > + error = regmap_bulk_read(ts->regmap, TSC2005_REG_X, , > > +TSC2005_DATA_REGS); > > if (unlikely(error)) > > goto out; > > > > - x = ts->spi_x.spi_rx; > > - y = ts->spi_y.spi_rx; > > - z1 = ts->spi_z1.spi_rx; > > - z2 = ts->spi_z2.spi_rx; > > - > > /* validate position */ > > - if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) > > + if (unlikely(tsdata.x > MAX_12BIT || tsdata.y > MAX_12BIT)) > > goto out; > > > > /* Skip reading if the pressure components are out of range */ > > - if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) > > + if (unlikely(tsdata.z1 == 0 || tsdata.z2 > MAX_12BIT)) > > + goto out; > > + if (unlikely(tsdata.z1 >= tsdata.z2)) > > goto out; > > I guess that means that tsc2005 is (and was) endian-broken. We can't use > the data off the wire directly... So I'll drop bucnh of the changes in > this function so we can convert to CPU endianness before using. Ah, no, SPI transfers do convert to/from CPU endianness... > > I also got: > > CC [M] drivers/input/touchscreen/tsc2005.o > Building modules, stage 2. > Kernel: arch/x86/boot/bzImage is ready (#1383) > MODPOST 1403 modules > ERROR: "devm_regmap_init_spi" [drivers/input/touchscreen/tsc2005.ko] > undefined! > make[1]: *** [__modpost] Error 1 > make: *** [modules] Error 2 > > I guess we need "select REGMAP_SPI". > > Thanks. > > -- > Dmitry > > > Input: tsc2005 - convert to regmap > > From: Sebastian Reichel > > Convert driver, so that it uses regmap instead of directly using > spi_transfer for all register accesses. > > Signed-off-by: Sebastian Reichel > Signed-off-by: Dmitry Torokhov > --- > drivers/input/touchscreen/Kconfig |9 +- > drivers/input/touchscreen/tsc2005.c | 149 > --- > 2 files changed, 55 insertions(+), 103 deletions(-) > > diff --git a/drivers/input/touchscreen/Kconfig > b/drivers/input/touchscreen/Kconfig > index 9b3da52..c1acbbc 100644 > --- a/drivers/input/touchscreen/Kconfig > +++ b/drivers/input/touchscreen/Kconfig > @@ -915,10 +915,11 @@ config TOUCHSCREEN_TSC_SERIO > module will be called tsc40. > > config TOUCHSCREEN_TSC2005 > -tristate "TSC2005 based touchscreens" > -depends on SPI_MASTER > -help > - Say Y here if you have a TSC2005 based touchscreen. > + tristate "TSC2005 based touchscreens" > + depends on SPI_MASTER > + select REGMAP_SPI > + help > + Say Y here if you have a TSC2005 based touchscreen. > > If unsure, say N. > > diff --git a/drivers/input/touchscreen/tsc2005.c > b/drivers/input/touchscreen/tsc2005.c > index 2a27a1f..a04248e 100644 > --- a/drivers/input/touchscreen/tsc2005.c > +++ b/drivers/input/touchscreen/tsc2005.c > @@ -34,6 +34,7 @@ > #include > #include > #include > +#include > > /* > * The touchscreen interface operates as follows: > @@ -120,20 +121,36 @@ > #define TSC2005_SPI_MAX_SPEED_HZ 1000 > #define TSC2005_PENUP_TIME_MS40 > > -struct tsc2005_spi_rd { > - struct spi_transfer spi_xfer; > - u32 spi_tx; > - u32 spi_rx; > +static const struct regmap_range tsc2005_writable_ranges[] = { > + regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2), > }; > > +static const struct regmap_access_table tsc2005_writable_table = { > + .yes_ranges = tsc2005_writable_ranges, > + .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges), > +}; > + > +static struct regmap_config tsc2005_regmap_config = { > + .reg_bits = 8, > + .val_bits = 16, > + .reg_stride = 0x08, > + .max_register = 0x78, > + .read_flag_mask = TSC2005_REG_READ, > + .wr_table = _writable_table, > + .use_single_rw = true, > +}; > + > +struct tsc2005_data { > + u16 x; > + u16 y; > + u16 z1; > + u16 z2; > +} __packed; > +#define TSC2005_DATA_REGS 4 > + > struct tsc2005 { > struct spi_device *spi; > - > - struct spi_message spi_read_msg; > - struct tsc2005_spi_rd spi_x; > - struct tsc2005_spi_rd spi_y; > - struct tsc2005_spi_rd spi_z1; > - struct tsc2005_spi_rd spi_z2; > + struct regmap *regmap; > > struct input_dev*idev; > charphys[32]; > @@ -190,62 +207,6 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) > return 0; > } > > -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) > -{ > - u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value; > - struct spi_transfer xfer = { > - .tx_buf = , > - .len= 4, > -
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
Hi Sebastian, On Wed, Jul 15, 2015 at 02:13:26PM +0200, Sebastian Reichel wrote: > /* read the coordinates */ > - error = spi_sync(ts->spi, >spi_read_msg); > + error = regmap_bulk_read(ts->regmap, TSC2005_REG_X, , > + TSC2005_DATA_REGS); > if (unlikely(error)) > goto out; > > - x = ts->spi_x.spi_rx; > - y = ts->spi_y.spi_rx; > - z1 = ts->spi_z1.spi_rx; > - z2 = ts->spi_z2.spi_rx; > - > /* validate position */ > - if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) > + if (unlikely(tsdata.x > MAX_12BIT || tsdata.y > MAX_12BIT)) > goto out; > > /* Skip reading if the pressure components are out of range */ > - if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) > + if (unlikely(tsdata.z1 == 0 || tsdata.z2 > MAX_12BIT)) > + goto out; > + if (unlikely(tsdata.z1 >= tsdata.z2)) > goto out; I guess that means that tsc2005 is (and was) endian-broken. We can't use the data off the wire directly... So I'll drop bucnh of the changes in this function so we can convert to CPU endianness before using. I also got: CC [M] drivers/input/touchscreen/tsc2005.o Building modules, stage 2. Kernel: arch/x86/boot/bzImage is ready (#1383) MODPOST 1403 modules ERROR: "devm_regmap_init_spi" [drivers/input/touchscreen/tsc2005.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 I guess we need "select REGMAP_SPI". Thanks. -- Dmitry Input: tsc2005 - convert to regmap From: Sebastian Reichel Convert driver, so that it uses regmap instead of directly using spi_transfer for all register accesses. Signed-off-by: Sebastian Reichel Signed-off-by: Dmitry Torokhov --- drivers/input/touchscreen/Kconfig |9 +- drivers/input/touchscreen/tsc2005.c | 149 --- 2 files changed, 55 insertions(+), 103 deletions(-) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 9b3da52..c1acbbc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -915,10 +915,11 @@ config TOUCHSCREEN_TSC_SERIO module will be called tsc40. config TOUCHSCREEN_TSC2005 -tristate "TSC2005 based touchscreens" -depends on SPI_MASTER -help - Say Y here if you have a TSC2005 based touchscreen. + tristate "TSC2005 based touchscreens" + depends on SPI_MASTER + select REGMAP_SPI + help + Say Y here if you have a TSC2005 based touchscreen. If unsure, say N. diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 2a27a1f..a04248e 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -34,6 +34,7 @@ #include #include #include +#include /* * The touchscreen interface operates as follows: @@ -120,20 +121,36 @@ #define TSC2005_SPI_MAX_SPEED_HZ 1000 #define TSC2005_PENUP_TIME_MS 40 -struct tsc2005_spi_rd { - struct spi_transfer spi_xfer; - u32 spi_tx; - u32 spi_rx; +static const struct regmap_range tsc2005_writable_ranges[] = { + regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2), }; +static const struct regmap_access_table tsc2005_writable_table = { + .yes_ranges = tsc2005_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges), +}; + +static struct regmap_config tsc2005_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_stride = 0x08, + .max_register = 0x78, + .read_flag_mask = TSC2005_REG_READ, + .wr_table = _writable_table, + .use_single_rw = true, +}; + +struct tsc2005_data { + u16 x; + u16 y; + u16 z1; + u16 z2; +} __packed; +#define TSC2005_DATA_REGS 4 + struct tsc2005 { struct spi_device *spi; - - struct spi_message spi_read_msg; - struct tsc2005_spi_rd spi_x; - struct tsc2005_spi_rd spi_y; - struct tsc2005_spi_rd spi_z1; - struct tsc2005_spi_rd spi_z2; + struct regmap *regmap; struct input_dev*idev; charphys[32]; @@ -190,62 +207,6 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) return 0; } -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) -{ - u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value; - struct spi_transfer xfer = { - .tx_buf = , - .len= 4, - .bits_per_word = 24, - }; - struct spi_message msg; - int error; - - spi_message_init(); - spi_message_add_tail(, ); - - error = spi_sync(ts->spi, ); - if (error) { - dev_err(>spi->dev, - "%s: failed, register: %x, value: %x, error: %d\n", -
[PATCH 2/4] Input: tsc2005 - convert to regmap
Convert driver, so that it uses regmap instead of directly using spi_transfer for all register accesses. Signed-off-by: Sebastian Reichel --- drivers/input/touchscreen/tsc2005.c | 170 1 file changed, 58 insertions(+), 112 deletions(-) diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 87038b2..0aec45a 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -34,6 +34,7 @@ #include #include #include +#include /* * The touchscreen interface operates as follows: @@ -120,20 +121,36 @@ #define TSC2005_SPI_MAX_SPEED_HZ 1000 #define TSC2005_PENUP_TIME_MS 40 -struct tsc2005_spi_rd { - struct spi_transfer spi_xfer; - u32 spi_tx; - u32 spi_rx; +static const struct regmap_range tsc2005_writable_ranges[] = { + regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2), }; +static const struct regmap_access_table tsc2005_writable_table = { + .yes_ranges = tsc2005_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges), +}; + +static struct regmap_config tsc2005_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_stride = 0x08, + .max_register = 0x78, + .read_flag_mask = TSC2005_REG_READ, + .wr_table = _writable_table, + .use_single_rw = true, +}; + +struct tsc2005_data { + u16 x; + u16 y; + u16 z1; + u16 z2; +} __packed; +#define TSC2005_DATA_REGS 4 + struct tsc2005 { struct spi_device *spi; - - struct spi_message spi_read_msg; - struct tsc2005_spi_rd spi_x; - struct tsc2005_spi_rd spi_y; - struct tsc2005_spi_rd spi_z1; - struct tsc2005_spi_rd spi_z2; + struct regmap *regmap; struct input_dev*idev; charphys[32]; @@ -190,62 +207,6 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) return 0; } -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) -{ - u32 tx = ((reg | TSC2005_REG_PND0) << 16) | value; - struct spi_transfer xfer = { - .tx_buf = , - .len= 4, - .bits_per_word = 24, - }; - struct spi_message msg; - int error; - - spi_message_init(); - spi_message_add_tail(, ); - - error = spi_sync(ts->spi, ); - if (error) { - dev_err(>spi->dev, - "%s: failed, register: %x, value: %x, error: %d\n", - __func__, reg, value, error); - return error; - } - - return 0; -} - -static void tsc2005_setup_read(struct tsc2005_spi_rd *rd, u8 reg, bool last) -{ - memset(rd, 0, sizeof(*rd)); - - rd->spi_tx = (reg | TSC2005_REG_READ) << 16; - rd->spi_xfer.tx_buf= >spi_tx; - rd->spi_xfer.rx_buf= >spi_rx; - rd->spi_xfer.len = 4; - rd->spi_xfer.bits_per_word = 24; - rd->spi_xfer.cs_change = !last; -} - -static int tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value) -{ - struct tsc2005_spi_rd spi_rd; - struct spi_message msg; - int error; - - tsc2005_setup_read(_rd, reg, true); - - spi_message_init(); - spi_message_add_tail(_rd.spi_xfer, ); - - error = spi_sync(ts->spi, ); - if (error) - return error; - - *value = spi_rd.spi_rx; - return 0; -} - static void tsc2005_update_pen_state(struct tsc2005 *ts, int x, int y, int pressure) { @@ -274,26 +235,23 @@ static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) struct tsc2005 *ts = _ts; unsigned long flags; unsigned int pressure; - u32 x, y; - u32 z1, z2; + struct tsc2005_data tsdata; int error; /* read the coordinates */ - error = spi_sync(ts->spi, >spi_read_msg); + error = regmap_bulk_read(ts->regmap, TSC2005_REG_X, , +TSC2005_DATA_REGS); if (unlikely(error)) goto out; - x = ts->spi_x.spi_rx; - y = ts->spi_y.spi_rx; - z1 = ts->spi_z1.spi_rx; - z2 = ts->spi_z2.spi_rx; - /* validate position */ - if (unlikely(x > MAX_12BIT || y > MAX_12BIT)) + if (unlikely(tsdata.x > MAX_12BIT || tsdata.y > MAX_12BIT)) goto out; /* Skip reading if the pressure components are out of range */ - if (unlikely(z1 == 0 || z2 > MAX_12BIT || z1 >= z2)) + if (unlikely(tsdata.z1 == 0 || tsdata.z2 > MAX_12BIT)) + goto out; + if (unlikely(tsdata.z1 >= tsdata.z2)) goto out; /* @@ -301,8 +259,8 @@ static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) * the value before pen-up - that implies SPI fed us
[PATCH 2/4] Input: tsc2005 - convert to regmap
Convert driver, so that it uses regmap instead of directly using spi_transfer for all register accesses. Signed-off-by: Sebastian Reichel s...@kernel.org --- drivers/input/touchscreen/tsc2005.c | 170 1 file changed, 58 insertions(+), 112 deletions(-) diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 87038b2..0aec45a 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -34,6 +34,7 @@ #include linux/spi/spi.h #include linux/spi/tsc2005.h #include linux/regulator/consumer.h +#include linux/regmap.h /* * The touchscreen interface operates as follows: @@ -120,20 +121,36 @@ #define TSC2005_SPI_MAX_SPEED_HZ 1000 #define TSC2005_PENUP_TIME_MS 40 -struct tsc2005_spi_rd { - struct spi_transfer spi_xfer; - u32 spi_tx; - u32 spi_rx; +static const struct regmap_range tsc2005_writable_ranges[] = { + regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2), }; +static const struct regmap_access_table tsc2005_writable_table = { + .yes_ranges = tsc2005_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges), +}; + +static struct regmap_config tsc2005_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_stride = 0x08, + .max_register = 0x78, + .read_flag_mask = TSC2005_REG_READ, + .wr_table = tsc2005_writable_table, + .use_single_rw = true, +}; + +struct tsc2005_data { + u16 x; + u16 y; + u16 z1; + u16 z2; +} __packed; +#define TSC2005_DATA_REGS 4 + struct tsc2005 { struct spi_device *spi; - - struct spi_message spi_read_msg; - struct tsc2005_spi_rd spi_x; - struct tsc2005_spi_rd spi_y; - struct tsc2005_spi_rd spi_z1; - struct tsc2005_spi_rd spi_z2; + struct regmap *regmap; struct input_dev*idev; charphys[32]; @@ -190,62 +207,6 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) return 0; } -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) -{ - u32 tx = ((reg | TSC2005_REG_PND0) 16) | value; - struct spi_transfer xfer = { - .tx_buf = tx, - .len= 4, - .bits_per_word = 24, - }; - struct spi_message msg; - int error; - - spi_message_init(msg); - spi_message_add_tail(xfer, msg); - - error = spi_sync(ts-spi, msg); - if (error) { - dev_err(ts-spi-dev, - %s: failed, register: %x, value: %x, error: %d\n, - __func__, reg, value, error); - return error; - } - - return 0; -} - -static void tsc2005_setup_read(struct tsc2005_spi_rd *rd, u8 reg, bool last) -{ - memset(rd, 0, sizeof(*rd)); - - rd-spi_tx = (reg | TSC2005_REG_READ) 16; - rd-spi_xfer.tx_buf= rd-spi_tx; - rd-spi_xfer.rx_buf= rd-spi_rx; - rd-spi_xfer.len = 4; - rd-spi_xfer.bits_per_word = 24; - rd-spi_xfer.cs_change = !last; -} - -static int tsc2005_read(struct tsc2005 *ts, u8 reg, u16 *value) -{ - struct tsc2005_spi_rd spi_rd; - struct spi_message msg; - int error; - - tsc2005_setup_read(spi_rd, reg, true); - - spi_message_init(msg); - spi_message_add_tail(spi_rd.spi_xfer, msg); - - error = spi_sync(ts-spi, msg); - if (error) - return error; - - *value = spi_rd.spi_rx; - return 0; -} - static void tsc2005_update_pen_state(struct tsc2005 *ts, int x, int y, int pressure) { @@ -274,26 +235,23 @@ static irqreturn_t tsc2005_irq_thread(int irq, void *_ts) struct tsc2005 *ts = _ts; unsigned long flags; unsigned int pressure; - u32 x, y; - u32 z1, z2; + struct tsc2005_data tsdata; int error; /* read the coordinates */ - error = spi_sync(ts-spi, ts-spi_read_msg); + error = regmap_bulk_read(ts-regmap, TSC2005_REG_X, tsdata, +TSC2005_DATA_REGS); if (unlikely(error)) goto out; - x = ts-spi_x.spi_rx; - y = ts-spi_y.spi_rx; - z1 = ts-spi_z1.spi_rx; - z2 = ts-spi_z2.spi_rx; - /* validate position */ - if (unlikely(x MAX_12BIT || y MAX_12BIT)) + if (unlikely(tsdata.x MAX_12BIT || tsdata.y MAX_12BIT)) goto out; /* Skip reading if the pressure components are out of range */ - if (unlikely(z1 == 0 || z2 MAX_12BIT || z1 = z2)) + if (unlikely(tsdata.z1 == 0 || tsdata.z2 MAX_12BIT)) + goto out; + if (unlikely(tsdata.z1 = tsdata.z2)) goto out; /* @@ -301,8 +259,8 @@ static
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
On Wed, Jul 15, 2015 at 02:29:55PM -0700, Dmitry Torokhov wrote: Hi Sebastian, On Wed, Jul 15, 2015 at 02:13:26PM +0200, Sebastian Reichel wrote: /* read the coordinates */ - error = spi_sync(ts-spi, ts-spi_read_msg); + error = regmap_bulk_read(ts-regmap, TSC2005_REG_X, tsdata, +TSC2005_DATA_REGS); if (unlikely(error)) goto out; - x = ts-spi_x.spi_rx; - y = ts-spi_y.spi_rx; - z1 = ts-spi_z1.spi_rx; - z2 = ts-spi_z2.spi_rx; - /* validate position */ - if (unlikely(x MAX_12BIT || y MAX_12BIT)) + if (unlikely(tsdata.x MAX_12BIT || tsdata.y MAX_12BIT)) goto out; /* Skip reading if the pressure components are out of range */ - if (unlikely(z1 == 0 || z2 MAX_12BIT || z1 = z2)) + if (unlikely(tsdata.z1 == 0 || tsdata.z2 MAX_12BIT)) + goto out; + if (unlikely(tsdata.z1 = tsdata.z2)) goto out; I guess that means that tsc2005 is (and was) endian-broken. We can't use the data off the wire directly... So I'll drop bucnh of the changes in this function so we can convert to CPU endianness before using. Ah, no, SPI transfers do convert to/from CPU endianness... I also got: CC [M] drivers/input/touchscreen/tsc2005.o Building modules, stage 2. Kernel: arch/x86/boot/bzImage is ready (#1383) MODPOST 1403 modules ERROR: devm_regmap_init_spi [drivers/input/touchscreen/tsc2005.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 I guess we need select REGMAP_SPI. Thanks. -- Dmitry Input: tsc2005 - convert to regmap From: Sebastian Reichel s...@kernel.org Convert driver, so that it uses regmap instead of directly using spi_transfer for all register accesses. Signed-off-by: Sebastian Reichel s...@kernel.org Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com --- drivers/input/touchscreen/Kconfig |9 +- drivers/input/touchscreen/tsc2005.c | 149 --- 2 files changed, 55 insertions(+), 103 deletions(-) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 9b3da52..c1acbbc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -915,10 +915,11 @@ config TOUCHSCREEN_TSC_SERIO module will be called tsc40. config TOUCHSCREEN_TSC2005 -tristate TSC2005 based touchscreens -depends on SPI_MASTER -help - Say Y here if you have a TSC2005 based touchscreen. + tristate TSC2005 based touchscreens + depends on SPI_MASTER + select REGMAP_SPI + help + Say Y here if you have a TSC2005 based touchscreen. If unsure, say N. diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 2a27a1f..a04248e 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -34,6 +34,7 @@ #include linux/spi/spi.h #include linux/spi/tsc2005.h #include linux/regulator/consumer.h +#include linux/regmap.h /* * The touchscreen interface operates as follows: @@ -120,20 +121,36 @@ #define TSC2005_SPI_MAX_SPEED_HZ 1000 #define TSC2005_PENUP_TIME_MS40 -struct tsc2005_spi_rd { - struct spi_transfer spi_xfer; - u32 spi_tx; - u32 spi_rx; +static const struct regmap_range tsc2005_writable_ranges[] = { + regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2), }; +static const struct regmap_access_table tsc2005_writable_table = { + .yes_ranges = tsc2005_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges), +}; + +static struct regmap_config tsc2005_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_stride = 0x08, + .max_register = 0x78, + .read_flag_mask = TSC2005_REG_READ, + .wr_table = tsc2005_writable_table, + .use_single_rw = true, +}; + +struct tsc2005_data { + u16 x; + u16 y; + u16 z1; + u16 z2; +} __packed; +#define TSC2005_DATA_REGS 4 + struct tsc2005 { struct spi_device *spi; - - struct spi_message spi_read_msg; - struct tsc2005_spi_rd spi_x; - struct tsc2005_spi_rd spi_y; - struct tsc2005_spi_rd spi_z1; - struct tsc2005_spi_rd spi_z2; + struct regmap *regmap; struct input_dev*idev; charphys[32]; @@ -190,62 +207,6 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) return 0; } -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) -{ - u32 tx = ((reg | TSC2005_REG_PND0) 16) | value; - struct spi_transfer xfer = { - .tx_buf = tx, - .len= 4, - .bits_per_word = 24, - }; - struct spi_message msg; -
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
Hi Dmitry, On Wed, Jul 15, 2015 at 02:29:55PM -0700, Dmitry Torokhov wrote: I also got: CC [M] drivers/input/touchscreen/tsc2005.o Building modules, stage 2. Kernel: arch/x86/boot/bzImage is ready (#1383) MODPOST 1403 modules ERROR: devm_regmap_init_spi [drivers/input/touchscreen/tsc2005.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 I guess we need select REGMAP_SPI. Right. I will add this in PATCHv2. -- Sebastian signature.asc Description: Digital signature
Re: [PATCH 2/4] Input: tsc2005 - convert to regmap
Hi Sebastian, On Wed, Jul 15, 2015 at 02:13:26PM +0200, Sebastian Reichel wrote: /* read the coordinates */ - error = spi_sync(ts-spi, ts-spi_read_msg); + error = regmap_bulk_read(ts-regmap, TSC2005_REG_X, tsdata, + TSC2005_DATA_REGS); if (unlikely(error)) goto out; - x = ts-spi_x.spi_rx; - y = ts-spi_y.spi_rx; - z1 = ts-spi_z1.spi_rx; - z2 = ts-spi_z2.spi_rx; - /* validate position */ - if (unlikely(x MAX_12BIT || y MAX_12BIT)) + if (unlikely(tsdata.x MAX_12BIT || tsdata.y MAX_12BIT)) goto out; /* Skip reading if the pressure components are out of range */ - if (unlikely(z1 == 0 || z2 MAX_12BIT || z1 = z2)) + if (unlikely(tsdata.z1 == 0 || tsdata.z2 MAX_12BIT)) + goto out; + if (unlikely(tsdata.z1 = tsdata.z2)) goto out; I guess that means that tsc2005 is (and was) endian-broken. We can't use the data off the wire directly... So I'll drop bucnh of the changes in this function so we can convert to CPU endianness before using. I also got: CC [M] drivers/input/touchscreen/tsc2005.o Building modules, stage 2. Kernel: arch/x86/boot/bzImage is ready (#1383) MODPOST 1403 modules ERROR: devm_regmap_init_spi [drivers/input/touchscreen/tsc2005.ko] undefined! make[1]: *** [__modpost] Error 1 make: *** [modules] Error 2 I guess we need select REGMAP_SPI. Thanks. -- Dmitry Input: tsc2005 - convert to regmap From: Sebastian Reichel s...@kernel.org Convert driver, so that it uses regmap instead of directly using spi_transfer for all register accesses. Signed-off-by: Sebastian Reichel s...@kernel.org Signed-off-by: Dmitry Torokhov dmitry.torok...@gmail.com --- drivers/input/touchscreen/Kconfig |9 +- drivers/input/touchscreen/tsc2005.c | 149 --- 2 files changed, 55 insertions(+), 103 deletions(-) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 9b3da52..c1acbbc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -915,10 +915,11 @@ config TOUCHSCREEN_TSC_SERIO module will be called tsc40. config TOUCHSCREEN_TSC2005 -tristate TSC2005 based touchscreens -depends on SPI_MASTER -help - Say Y here if you have a TSC2005 based touchscreen. + tristate TSC2005 based touchscreens + depends on SPI_MASTER + select REGMAP_SPI + help + Say Y here if you have a TSC2005 based touchscreen. If unsure, say N. diff --git a/drivers/input/touchscreen/tsc2005.c b/drivers/input/touchscreen/tsc2005.c index 2a27a1f..a04248e 100644 --- a/drivers/input/touchscreen/tsc2005.c +++ b/drivers/input/touchscreen/tsc2005.c @@ -34,6 +34,7 @@ #include linux/spi/spi.h #include linux/spi/tsc2005.h #include linux/regulator/consumer.h +#include linux/regmap.h /* * The touchscreen interface operates as follows: @@ -120,20 +121,36 @@ #define TSC2005_SPI_MAX_SPEED_HZ 1000 #define TSC2005_PENUP_TIME_MS 40 -struct tsc2005_spi_rd { - struct spi_transfer spi_xfer; - u32 spi_tx; - u32 spi_rx; +static const struct regmap_range tsc2005_writable_ranges[] = { + regmap_reg_range(TSC2005_REG_AUX_HIGH, TSC2005_REG_CFR2), }; +static const struct regmap_access_table tsc2005_writable_table = { + .yes_ranges = tsc2005_writable_ranges, + .n_yes_ranges = ARRAY_SIZE(tsc2005_writable_ranges), +}; + +static struct regmap_config tsc2005_regmap_config = { + .reg_bits = 8, + .val_bits = 16, + .reg_stride = 0x08, + .max_register = 0x78, + .read_flag_mask = TSC2005_REG_READ, + .wr_table = tsc2005_writable_table, + .use_single_rw = true, +}; + +struct tsc2005_data { + u16 x; + u16 y; + u16 z1; + u16 z2; +} __packed; +#define TSC2005_DATA_REGS 4 + struct tsc2005 { struct spi_device *spi; - - struct spi_message spi_read_msg; - struct tsc2005_spi_rd spi_x; - struct tsc2005_spi_rd spi_y; - struct tsc2005_spi_rd spi_z1; - struct tsc2005_spi_rd spi_z2; + struct regmap *regmap; struct input_dev*idev; charphys[32]; @@ -190,62 +207,6 @@ static int tsc2005_cmd(struct tsc2005 *ts, u8 cmd) return 0; } -static int tsc2005_write(struct tsc2005 *ts, u8 reg, u16 value) -{ - u32 tx = ((reg | TSC2005_REG_PND0) 16) | value; - struct spi_transfer xfer = { - .tx_buf = tx, - .len= 4, - .bits_per_word = 24, - }; - struct spi_message msg; - int error; - - spi_message_init(msg); - spi_message_add_tail(xfer, msg); - - error = spi_sync(ts-spi, msg); - if (error) { -