The ST1232 and ST1633 touch controllers have read/write registers for the X and Y resolution and it seems that these can also be pre-programmed so that the resolution is matched to that of the display paired with the touch panel. Instead of hard coding the resolution in the driver, read it from the controller when probing. This requires a delay after de-asserting reset in order to ensure that the I2C communication succeeds. I have tested this on ST1633 and the datasheet for ST1232 indicates that the format of these registers is the same there (and at the same address). Signed-off-by: John Keeping <john@xxxxxxxxxxxx> --- drivers/input/touchscreen/st1232.c | 55 +++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 9 deletions(-) diff --git a/drivers/input/touchscreen/st1232.c b/drivers/input/touchscreen/st1232.c index 63b29c7279e2..4e032d3a3737 100644 --- a/drivers/input/touchscreen/st1232.c +++ b/drivers/input/touchscreen/st1232.c @@ -28,10 +28,10 @@ #define ST_TS_MAX_FINGERS 10 +#define ST1232_RESOLUTION_REG 0x04 + struct st_chip_info { bool have_z; - u16 max_x; - u16 max_y; u16 max_area; u16 max_fingers; u8 start_reg; @@ -44,6 +44,8 @@ struct st1232_ts_data { struct dev_pm_qos_request low_latency_req; struct gpio_desc *reset_gpio; const struct st_chip_info *chip_info; + u16 max_x; + u16 max_y; int read_buf_len; u8 *read_buf; }; @@ -117,6 +119,36 @@ static int st1232_ts_parse_and_report(struct st1232_ts_data *ts) return n_contacts; } +static int st1232_ts_read_resolution(struct st1232_ts_data *ts) +{ + struct i2c_client *client = ts->client; + u8 start_reg = ST1232_RESOLUTION_REG; + u8 buf[3]; + struct i2c_msg msg[] = { + { + .addr = client->addr, + .len = sizeof(start_reg), + .buf = &start_reg, + }, + { + .addr = client->addr, + .flags = I2C_M_RD, + .len = sizeof(buf), + .buf = buf, + }, + }; + int ret; + + ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); + if (ret != ARRAY_SIZE(msg)) + return ret < 0 ? ret : -EIO; + + ts->max_x = (((buf[0] & 0xf0) << 4) | buf[1]) - 1; + ts->max_y = (((buf[0] & 0x0f) << 8) | buf[2]) - 1; + + return 0; +} + static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) { struct st1232_ts_data *ts = dev_id; @@ -146,8 +178,10 @@ static irqreturn_t st1232_ts_irq_handler(int irq, void *dev_id) static void st1232_ts_power(struct st1232_ts_data *ts, bool poweron) { - if (ts->reset_gpio) + if (ts->reset_gpio) { gpiod_set_value_cansleep(ts->reset_gpio, !poweron); + msleep(100); + } } static void st1232_ts_power_off(void *data) @@ -157,8 +191,6 @@ static void st1232_ts_power_off(void *data) static const struct st_chip_info st1232_chip_info = { .have_z = true, - .max_x = 0x31f, /* 800 - 1 */ - .max_y = 0x1df, /* 480 -1 */ .max_area = 0xff, .max_fingers = 2, .start_reg = 0x12, @@ -166,8 +198,6 @@ static const struct st_chip_info st1232_chip_info = { static const struct st_chip_info st1633_chip_info = { .have_z = false, - .max_x = 0x13f, /* 320 - 1 */ - .max_y = 0x1df, /* 480 -1 */ .max_area = 0x00, .max_fingers = 5, .start_reg = 0x12, @@ -236,6 +266,13 @@ static int st1232_ts_probe(struct i2c_client *client, return error; } + error = st1232_ts_read_resolution(ts); + if (error) { + dev_err(&client->dev, + "Failed to read touch panel resolution: %d\n", error); + return error; + } + input_dev->name = "st1232-touchscreen"; input_dev->id.bustype = BUS_I2C; @@ -244,9 +281,9 @@ static int st1232_ts_probe(struct i2c_client *client, ts->chip_info->max_area, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_X, - 0, ts->chip_info->max_x, 0, 0); + 0, ts->max_x, 0, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, - 0, ts->chip_info->max_y, 0, 0); + 0, ts->max_y, 0, 0); touchscreen_parse_properties(input_dev, true, &ts->prop); -- 2.27.0