Merge branch 'next' into for-linus
Prepare input updates for 5.6 merge window.
This commit is contained in:
@@ -333,7 +333,8 @@ static int ads7846_read12_ser(struct device *dev, unsigned command)
|
||||
req->xfer[1].len = 2;
|
||||
|
||||
/* for 1uF, settle for 800 usec; no cap, 100 usec. */
|
||||
req->xfer[1].delay_usecs = ts->vref_delay_usecs;
|
||||
req->xfer[1].delay.value = ts->vref_delay_usecs;
|
||||
req->xfer[1].delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
spi_message_add_tail(&req->xfer[1], &req->msg);
|
||||
|
||||
/* Enable reference voltage */
|
||||
@@ -1018,7 +1019,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
|
||||
* have had enough time to stabilize.
|
||||
*/
|
||||
if (pdata->settle_delay_usecs) {
|
||||
x->delay_usecs = pdata->settle_delay_usecs;
|
||||
x->delay.value = pdata->settle_delay_usecs;
|
||||
x->delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
|
||||
x++;
|
||||
x->tx_buf = &packet->read_y;
|
||||
@@ -1061,7 +1063,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
|
||||
|
||||
/* ... maybe discard first sample ... */
|
||||
if (pdata->settle_delay_usecs) {
|
||||
x->delay_usecs = pdata->settle_delay_usecs;
|
||||
x->delay.value = pdata->settle_delay_usecs;
|
||||
x->delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
|
||||
x++;
|
||||
x->tx_buf = &packet->read_x;
|
||||
@@ -1094,7 +1097,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
|
||||
|
||||
/* ... maybe discard first sample ... */
|
||||
if (pdata->settle_delay_usecs) {
|
||||
x->delay_usecs = pdata->settle_delay_usecs;
|
||||
x->delay.value = pdata->settle_delay_usecs;
|
||||
x->delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
|
||||
x++;
|
||||
x->tx_buf = &packet->read_z1;
|
||||
@@ -1125,7 +1129,8 @@ static void ads7846_setup_spi_msg(struct ads7846 *ts,
|
||||
|
||||
/* ... maybe discard first sample ... */
|
||||
if (pdata->settle_delay_usecs) {
|
||||
x->delay_usecs = pdata->settle_delay_usecs;
|
||||
x->delay.value = pdata->settle_delay_usecs;
|
||||
x->delay.unit = SPI_DELAY_UNIT_USECS;
|
||||
|
||||
x++;
|
||||
x->tx_buf = &packet->read_z2;
|
||||
|
@@ -13,22 +13,23 @@
|
||||
* http://www.glyn.com/Products/Displays
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#include <asm/unaligned.h>
|
||||
|
||||
#define WORK_REGISTER_THRESHOLD 0x00
|
||||
#define WORK_REGISTER_REPORT_RATE 0x08
|
||||
@@ -1050,6 +1051,7 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||
{
|
||||
const struct edt_i2c_chip_data *chip_data;
|
||||
struct edt_ft5x06_ts_data *tsdata;
|
||||
u8 buf[2] = { 0xfc, 0x00 };
|
||||
struct input_dev *input;
|
||||
unsigned long irq_flags;
|
||||
int error;
|
||||
@@ -1140,6 +1142,12 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy read access. EP0700MLP1 returns bogus data on the first
|
||||
* register read access and ignores writes.
|
||||
*/
|
||||
edt_ft5x06_ts_readwrite(tsdata->client, 2, buf, 2, buf);
|
||||
|
||||
edt_ft5x06_ts_set_regs(tsdata);
|
||||
edt_ft5x06_ts_get_defaults(&client->dev, tsdata);
|
||||
edt_ft5x06_ts_get_parameters(tsdata);
|
||||
@@ -1200,7 +1208,6 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
|
||||
return error;
|
||||
|
||||
edt_ft5x06_ts_prepare_debugfs(tsdata, dev_driver_string(&client->dev));
|
||||
device_init_wakeup(&client->dev, 1);
|
||||
|
||||
dev_dbg(&client->dev,
|
||||
"EDT FT5x06 initialized: IRQ %d, WAKE pin %d, Reset pin %d.\n",
|
||||
@@ -1220,29 +1227,6 @@ static int edt_ft5x06_ts_remove(struct i2c_client *client)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused edt_ft5x06_ts_suspend(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
enable_irq_wake(client->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __maybe_unused edt_ft5x06_ts_resume(struct device *dev)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
|
||||
if (device_may_wakeup(dev))
|
||||
disable_irq_wake(client->irq);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(edt_ft5x06_ts_pm_ops,
|
||||
edt_ft5x06_ts_suspend, edt_ft5x06_ts_resume);
|
||||
|
||||
static const struct edt_i2c_chip_data edt_ft5x06_data = {
|
||||
.max_support_points = 5,
|
||||
};
|
||||
@@ -1281,7 +1265,6 @@ static struct i2c_driver edt_ft5x06_ts_driver = {
|
||||
.driver = {
|
||||
.name = "edt_ft5x06",
|
||||
.of_match_table = edt_ft5x06_of_match,
|
||||
.pm = &edt_ft5x06_ts_pm_ops,
|
||||
},
|
||||
.id_table = edt_ft5x06_ts_id,
|
||||
.probe = edt_ft5x06_ts_probe,
|
||||
|
@@ -59,8 +59,10 @@
|
||||
#define CMD_HEADER_WRITE 0x54
|
||||
#define CMD_HEADER_READ 0x53
|
||||
#define CMD_HEADER_6B_READ 0x5B
|
||||
#define CMD_HEADER_ROM_READ 0x96
|
||||
#define CMD_HEADER_RESP 0x52
|
||||
#define CMD_HEADER_6B_RESP 0x9B
|
||||
#define CMD_HEADER_ROM_RESP 0x95
|
||||
#define CMD_HEADER_HELLO 0x55
|
||||
#define CMD_HEADER_REK 0x66
|
||||
|
||||
@@ -200,6 +202,10 @@ static int elants_i2c_execute_command(struct i2c_client *client,
|
||||
expected_response = CMD_HEADER_6B_RESP;
|
||||
break;
|
||||
|
||||
case CMD_HEADER_ROM_READ:
|
||||
expected_response = CMD_HEADER_ROM_RESP;
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(&client->dev, "%s: invalid command %*ph\n",
|
||||
__func__, (int)cmd_size, cmd);
|
||||
@@ -556,6 +562,8 @@ static int elants_i2c_initialize(struct elants_data *ts)
|
||||
|
||||
/* hw version is available even if device in recovery state */
|
||||
error2 = elants_i2c_query_hw_version(ts);
|
||||
if (!error2)
|
||||
error2 = elants_i2c_query_bc_version(ts);
|
||||
if (!error)
|
||||
error = error2;
|
||||
|
||||
@@ -563,8 +571,6 @@ static int elants_i2c_initialize(struct elants_data *ts)
|
||||
error = elants_i2c_query_fw_version(ts);
|
||||
if (!error)
|
||||
error = elants_i2c_query_test_version(ts);
|
||||
if (!error)
|
||||
error = elants_i2c_query_bc_version(ts);
|
||||
if (!error)
|
||||
error = elants_i2c_query_ts_info(ts);
|
||||
|
||||
@@ -613,39 +619,94 @@ static int elants_i2c_fw_write_page(struct i2c_client *client,
|
||||
return error;
|
||||
}
|
||||
|
||||
static int elants_i2c_validate_remark_id(struct elants_data *ts,
|
||||
const struct firmware *fw)
|
||||
{
|
||||
struct i2c_client *client = ts->client;
|
||||
int error;
|
||||
const u8 cmd[] = { CMD_HEADER_ROM_READ, 0x80, 0x1F, 0x00, 0x00, 0x21 };
|
||||
u8 resp[6] = { 0 };
|
||||
u16 ts_remark_id = 0;
|
||||
u16 fw_remark_id = 0;
|
||||
|
||||
/* Compare TS Remark ID and FW Remark ID */
|
||||
error = elants_i2c_execute_command(client, cmd, sizeof(cmd),
|
||||
resp, sizeof(resp));
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to query Remark ID: %d\n", error);
|
||||
return error;
|
||||
}
|
||||
|
||||
ts_remark_id = get_unaligned_be16(&resp[3]);
|
||||
|
||||
fw_remark_id = get_unaligned_le16(&fw->data[fw->size - 4]);
|
||||
|
||||
if (fw_remark_id != ts_remark_id) {
|
||||
dev_err(&client->dev,
|
||||
"Remark ID Mismatched: ts_remark_id=0x%04x, fw_remark_id=0x%04x.\n",
|
||||
ts_remark_id, fw_remark_id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int elants_i2c_do_update_firmware(struct i2c_client *client,
|
||||
const struct firmware *fw,
|
||||
bool force)
|
||||
{
|
||||
struct elants_data *ts = i2c_get_clientdata(client);
|
||||
const u8 enter_iap[] = { 0x45, 0x49, 0x41, 0x50 };
|
||||
const u8 enter_iap2[] = { 0x54, 0x00, 0x12, 0x34 };
|
||||
const u8 iap_ack[] = { 0x55, 0xaa, 0x33, 0xcc };
|
||||
const u8 close_idle[] = {0x54, 0x2c, 0x01, 0x01};
|
||||
const u8 close_idle[] = { 0x54, 0x2c, 0x01, 0x01 };
|
||||
u8 buf[HEADER_SIZE];
|
||||
u16 send_id;
|
||||
int page, n_fw_pages;
|
||||
int error;
|
||||
bool check_remark_id = ts->iap_version >= 0x60;
|
||||
|
||||
/* Recovery mode detection! */
|
||||
if (force) {
|
||||
dev_dbg(&client->dev, "Recovery mode procedure\n");
|
||||
|
||||
if (check_remark_id) {
|
||||
error = elants_i2c_validate_remark_id(ts, fw);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = elants_i2c_send(client, enter_iap2, sizeof(enter_iap2));
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to enter IAP mode: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
} else {
|
||||
/* Start IAP Procedure */
|
||||
dev_dbg(&client->dev, "Normal IAP procedure\n");
|
||||
|
||||
/* Close idle mode */
|
||||
error = elants_i2c_send(client, close_idle, sizeof(close_idle));
|
||||
if (error)
|
||||
dev_err(&client->dev, "Failed close idle: %d\n", error);
|
||||
msleep(60);
|
||||
|
||||
elants_i2c_sw_reset(client);
|
||||
msleep(20);
|
||||
error = elants_i2c_send(client, enter_iap, sizeof(enter_iap));
|
||||
}
|
||||
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to enter IAP mode: %d\n", error);
|
||||
return error;
|
||||
if (check_remark_id) {
|
||||
error = elants_i2c_validate_remark_id(ts, fw);
|
||||
if (error)
|
||||
return error;
|
||||
}
|
||||
|
||||
error = elants_i2c_send(client, enter_iap, sizeof(enter_iap));
|
||||
if (error) {
|
||||
dev_err(&client->dev, "failed to enter IAP mode: %d\n",
|
||||
error);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
||||
msleep(20);
|
||||
|
Reference in New Issue
Block a user