^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Azoteq IQS550/572/525 Trackpad/Touchscreen Controller
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Author: Jeff LaBundy <jeff@labundy.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * These devices require firmware exported from a PC-based configuration tool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * made available by the vendor. Firmware files may be pushed to the device's
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * nonvolatile memory by writing the filename to the 'fw_file' sysfs control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Link to PC-based configuration tool and data sheet: http://www.azoteq.com/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/err.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/firmware.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/input.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include <linux/input/touchscreen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/of_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define IQS5XX_FW_FILE_LEN 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define IQS5XX_NUM_RETRIES 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define IQS5XX_NUM_POINTS 256
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define IQS5XX_NUM_CONTACTS 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define IQS5XX_WR_BYTES_MAX 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #define IQS5XX_PROD_NUM_IQS550 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define IQS5XX_PROD_NUM_IQS572 58
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define IQS5XX_PROD_NUM_IQS525 52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define IQS5XX_PROJ_NUM_A000 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define IQS5XX_PROJ_NUM_B000 15
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define IQS5XX_MAJOR_VER_MIN 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define IQS5XX_RESUME 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define IQS5XX_SUSPEND 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define IQS5XX_SW_INPUT_EVENT 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define IQS5XX_SETUP_COMPLETE 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define IQS5XX_EVENT_MODE 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define IQS5XX_TP_EVENT 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define IQS5XX_FLIP_X 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define IQS5XX_FLIP_Y 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define IQS5XX_SWITCH_XY_AXIS 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define IQS5XX_PROD_NUM 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define IQS5XX_ABS_X 0x0016
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define IQS5XX_ABS_Y 0x0018
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IQS5XX_SYS_CTRL0 0x0431
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IQS5XX_SYS_CTRL1 0x0432
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IQS5XX_SYS_CFG0 0x058E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define IQS5XX_SYS_CFG1 0x058F
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define IQS5XX_TOTAL_RX 0x063D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define IQS5XX_TOTAL_TX 0x063E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define IQS5XX_XY_CFG0 0x0669
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define IQS5XX_X_RES 0x066E
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define IQS5XX_Y_RES 0x0670
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define IQS5XX_CHKSM 0x83C0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define IQS5XX_APP 0x8400
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define IQS5XX_CSTM 0xBE00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define IQS5XX_PMAP_END 0xBFFF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define IQS5XX_END_COMM 0xEEEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) #define IQS5XX_CHKSM_LEN (IQS5XX_APP - IQS5XX_CHKSM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define IQS5XX_APP_LEN (IQS5XX_CSTM - IQS5XX_APP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define IQS5XX_CSTM_LEN (IQS5XX_PMAP_END + 1 - IQS5XX_CSTM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define IQS5XX_PMAP_LEN (IQS5XX_PMAP_END + 1 - IQS5XX_CHKSM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define IQS5XX_REC_HDR_LEN 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define IQS5XX_REC_LEN_MAX 255
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define IQS5XX_REC_TYPE_DATA 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define IQS5XX_REC_TYPE_EOF 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define IQS5XX_BL_ADDR_MASK 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define IQS5XX_BL_CMD_VER 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define IQS5XX_BL_CMD_READ 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define IQS5XX_BL_CMD_EXEC 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define IQS5XX_BL_CMD_CRC 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define IQS5XX_BL_BLK_LEN_MAX 64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define IQS5XX_BL_ID 0x0200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define IQS5XX_BL_STATUS_RESET 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define IQS5XX_BL_STATUS_AVAIL 0xA5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define IQS5XX_BL_STATUS_NONE 0xEE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define IQS5XX_BL_CRC_PASS 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) #define IQS5XX_BL_CRC_FAIL 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) #define IQS5XX_BL_ATTEMPTS 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct iqs5xx_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct gpio_desc *reset_gpio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct mutex lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) u8 bl_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) struct iqs5xx_dev_id_info {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) __be16 prod_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) __be16 proj_num;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u8 major_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 minor_ver;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) u8 bl_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) struct iqs5xx_ihex_rec {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) char start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) char len[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) char addr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) char type[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) char data[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) struct iqs5xx_touch_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) __be16 abs_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) __be16 abs_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) __be16 strength;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) u8 area;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static int iqs5xx_read_burst(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) u16 reg, void *val, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) __be16 reg_buf = cpu_to_be16(reg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) struct i2c_msg msg[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) .flags = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) .len = sizeof(reg_buf),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) .buf = (u8 *)®_buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) .addr = client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) .len = len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) .buf = (u8 *)val,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * The first addressing attempt outside of a communication window fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * and must be retried, after which the device clock stretches until it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) for (i = 0; i < IQS5XX_NUM_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ret = i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) if (ret == ARRAY_SIZE(msg))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) usleep_range(200, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) dev_err(&client->dev, "Failed to read from address 0x%04X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static int iqs5xx_read_word(struct i2c_client *client, u16 reg, u16 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) __be16 val_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) error = iqs5xx_read_burst(client, reg, &val_buf, sizeof(val_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) *val = be16_to_cpu(val_buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static int iqs5xx_read_byte(struct i2c_client *client, u16 reg, u8 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return iqs5xx_read_burst(client, reg, val, sizeof(*val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) static int iqs5xx_write_burst(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) u16 reg, const void *val, u16 len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) u16 mlen = sizeof(reg) + len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) u8 mbuf[sizeof(reg) + IQS5XX_WR_BYTES_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (len > IQS5XX_WR_BYTES_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) put_unaligned_be16(reg, mbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) memcpy(mbuf + sizeof(reg), val, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) * The first addressing attempt outside of a communication window fails
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * and must be retried, after which the device clock stretches until it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * is available.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) for (i = 0; i < IQS5XX_NUM_RETRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ret = i2c_master_send(client, mbuf, mlen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) if (ret == mlen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) usleep_range(200, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) dev_err(&client->dev, "Failed to write to address 0x%04X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) reg, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) static int iqs5xx_write_word(struct i2c_client *client, u16 reg, u16 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) __be16 val_buf = cpu_to_be16(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return iqs5xx_write_burst(client, reg, &val_buf, sizeof(val_buf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static int iqs5xx_write_byte(struct i2c_client *client, u16 reg, u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return iqs5xx_write_burst(client, reg, &val, sizeof(val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static void iqs5xx_reset(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) gpiod_set_value_cansleep(iqs5xx->reset_gpio, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) usleep_range(200, 300);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) gpiod_set_value_cansleep(iqs5xx->reset_gpio, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) static int iqs5xx_bl_cmd(struct i2c_client *client, u8 bl_cmd, u16 bl_addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct i2c_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) u8 mbuf[sizeof(bl_cmd) + sizeof(bl_addr)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) msg.addr = client->addr ^ IQS5XX_BL_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) msg.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) msg.len = sizeof(bl_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) msg.buf = mbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) *mbuf = bl_cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) switch (bl_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) case IQS5XX_BL_CMD_VER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) case IQS5XX_BL_CMD_CRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) case IQS5XX_BL_CMD_EXEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) case IQS5XX_BL_CMD_READ:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) msg.len += sizeof(bl_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) put_unaligned_be16(bl_addr, mbuf + sizeof(bl_cmd));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) goto msg_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) switch (bl_cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) case IQS5XX_BL_CMD_VER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) msg.len = sizeof(u16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) case IQS5XX_BL_CMD_CRC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) msg.len = sizeof(u8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) * This delay saves the bus controller the trouble of having to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) * tolerate a relatively long clock-stretching period while the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) * CRC is calculated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) msleep(50);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) case IQS5XX_BL_CMD_EXEC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) usleep_range(10000, 10100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) msg.flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) ret = i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) goto msg_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if (bl_cmd == IQS5XX_BL_CMD_VER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) get_unaligned_be16(mbuf) != IQS5XX_BL_ID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) dev_err(&client->dev, "Unrecognized bootloader ID: 0x%04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) get_unaligned_be16(mbuf));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (bl_cmd == IQS5XX_BL_CMD_CRC && *mbuf != IQS5XX_BL_CRC_PASS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dev_err(&client->dev, "Bootloader CRC failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) msg_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (bl_cmd != IQS5XX_BL_CMD_VER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) "Unsuccessful bootloader command 0x%02X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) bl_cmd, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) static int iqs5xx_bl_open(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) int error, i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * The device opens a bootloader polling window for 2 ms following the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) * release of reset. If the host cannot establish communication during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * this time frame, it must cycle reset again.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) for (i = 0; i < IQS5XX_BL_ATTEMPTS; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) iqs5xx_reset(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) for (j = 0; j < IQS5XX_NUM_RETRIES; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_VER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) if (!error || error == -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) dev_err(&client->dev, "Failed to open bootloader: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) static int iqs5xx_bl_write(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) u16 bl_addr, u8 *pmap_data, u16 pmap_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) struct i2c_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) u8 mbuf[sizeof(bl_addr) + IQS5XX_BL_BLK_LEN_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) if (pmap_len % IQS5XX_BL_BLK_LEN_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) msg.addr = client->addr ^ IQS5XX_BL_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) msg.flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) msg.len = sizeof(mbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) msg.buf = mbuf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) for (i = 0; i < pmap_len; i += IQS5XX_BL_BLK_LEN_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) put_unaligned_be16(bl_addr + i, mbuf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) memcpy(mbuf + sizeof(bl_addr), pmap_data + i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) sizeof(mbuf) - sizeof(bl_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) goto msg_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) usleep_range(10000, 10100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) msg_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) dev_err(&client->dev, "Failed to write block at address 0x%04X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) bl_addr + i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) static int iqs5xx_bl_verify(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) u16 bl_addr, u8 *pmap_data, u16 pmap_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct i2c_msg msg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) int ret, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) u8 bl_data[IQS5XX_BL_BLK_LEN_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (pmap_len % IQS5XX_BL_BLK_LEN_MAX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) msg.addr = client->addr ^ IQS5XX_BL_ADDR_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) msg.flags = I2C_M_RD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) msg.len = sizeof(bl_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) msg.buf = bl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) for (i = 0; i < pmap_len; i += IQS5XX_BL_BLK_LEN_MAX) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) ret = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_READ, bl_addr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) ret = i2c_transfer(client->adapter, &msg, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) if (ret != 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) goto msg_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (memcmp(bl_data, pmap_data + i, sizeof(bl_data))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) "Failed to verify block at address 0x%04X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) bl_addr + i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) msg_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) dev_err(&client->dev, "Failed to read block at address 0x%04X: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) bl_addr + i, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) static int iqs5xx_set_state(struct i2c_client *client, u8 state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) int error1, error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) if (iqs5xx->bl_status == IQS5XX_BL_STATUS_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) mutex_lock(&iqs5xx->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Addressing the device outside of a communication window prompts it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) * to assert the RDY output, so disable the interrupt line to prevent
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * the handler from servicing a false interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) disable_irq(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) error1 = iqs5xx_write_byte(client, IQS5XX_SYS_CTRL1, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) error2 = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) usleep_range(50, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) enable_irq(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) mutex_unlock(&iqs5xx->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (error1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) return error1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return error2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) static int iqs5xx_open(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) struct iqs5xx_private *iqs5xx = input_get_drvdata(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) static void iqs5xx_close(struct input_dev *input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct iqs5xx_private *iqs5xx = input_get_drvdata(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) static int iqs5xx_axis_init(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct touchscreen_properties prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) u16 max_x, max_x_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) u16 max_y, max_y_hw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) if (!iqs5xx->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) input = devm_input_allocate_device(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) input->name = client->name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) input->id.bustype = BUS_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) input->open = iqs5xx_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) input->close = iqs5xx_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) input_set_capability(input, EV_ABS, ABS_MT_POSITION_X);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) input_set_capability(input, EV_ABS, ABS_MT_POSITION_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) input_set_capability(input, EV_ABS, ABS_MT_PRESSURE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) input_set_drvdata(input, iqs5xx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) iqs5xx->input = input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) touchscreen_parse_properties(iqs5xx->input, true, &prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) error = iqs5xx_read_byte(client, IQS5XX_TOTAL_RX, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) max_x_hw = (val - 1) * IQS5XX_NUM_POINTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) error = iqs5xx_read_byte(client, IQS5XX_TOTAL_TX, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) max_y_hw = (val - 1) * IQS5XX_NUM_POINTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) error = iqs5xx_read_byte(client, IQS5XX_XY_CFG0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) if (val & IQS5XX_SWITCH_XY_AXIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) swap(max_x_hw, max_y_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) if (prop.swap_x_y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) val ^= IQS5XX_SWITCH_XY_AXIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) if (prop.invert_x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) val ^= prop.swap_x_y ? IQS5XX_FLIP_Y : IQS5XX_FLIP_X;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) if (prop.invert_y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) val ^= prop.swap_x_y ? IQS5XX_FLIP_X : IQS5XX_FLIP_Y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) error = iqs5xx_write_byte(client, IQS5XX_XY_CFG0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (prop.max_x > max_x_hw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) dev_err(&client->dev, "Invalid maximum x-coordinate: %u > %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) prop.max_x, max_x_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) } else if (prop.max_x == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) error = iqs5xx_read_word(client, IQS5XX_X_RES, &max_x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) input_abs_set_max(iqs5xx->input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) prop.swap_x_y ? ABS_MT_POSITION_Y :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) ABS_MT_POSITION_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) max_x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) max_x = (u16)prop.max_x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) if (prop.max_y > max_y_hw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) dev_err(&client->dev, "Invalid maximum y-coordinate: %u > %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) prop.max_y, max_y_hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) } else if (prop.max_y == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) error = iqs5xx_read_word(client, IQS5XX_Y_RES, &max_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) input_abs_set_max(iqs5xx->input,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) prop.swap_x_y ? ABS_MT_POSITION_X :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) ABS_MT_POSITION_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) max_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) max_y = (u16)prop.max_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * Write horizontal and vertical resolution to the device in case its
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * original defaults were overridden or swapped as per the properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * specified in the device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) error = iqs5xx_write_word(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) prop.swap_x_y ? IQS5XX_Y_RES : IQS5XX_X_RES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) max_x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) error = iqs5xx_write_word(client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) prop.swap_x_y ? IQS5XX_X_RES : IQS5XX_Y_RES,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) max_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) error = input_mt_init_slots(iqs5xx->input, IQS5XX_NUM_CONTACTS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) INPUT_MT_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) dev_err(&client->dev, "Failed to initialize slots: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) static int iqs5xx_dev_init(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct iqs5xx_dev_id_info *dev_id_info;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) u8 buf[sizeof(*dev_id_info) + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) error = iqs5xx_read_burst(client, IQS5XX_PROD_NUM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) &buf[1], sizeof(*dev_id_info));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) return iqs5xx_bl_open(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * A000 and B000 devices use 8-bit and 16-bit addressing, respectively.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) * Querying an A000 device's version information with 16-bit addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * gives the appearance that the data is shifted by one byte; a nonzero
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * leading array element suggests this could be the case (in which case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * the missing zero is prepended).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) buf[0] = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) dev_id_info = (struct iqs5xx_dev_id_info *)&buf[(buf[1] > 0) ? 0 : 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) switch (be16_to_cpu(dev_id_info->prod_num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) case IQS5XX_PROD_NUM_IQS550:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) case IQS5XX_PROD_NUM_IQS572:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) case IQS5XX_PROD_NUM_IQS525:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) dev_err(&client->dev, "Unrecognized product number: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) be16_to_cpu(dev_id_info->prod_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) switch (be16_to_cpu(dev_id_info->proj_num)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) case IQS5XX_PROJ_NUM_A000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) dev_err(&client->dev, "Unsupported project number: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) be16_to_cpu(dev_id_info->proj_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return iqs5xx_bl_open(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) case IQS5XX_PROJ_NUM_B000:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) dev_err(&client->dev, "Unrecognized project number: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) be16_to_cpu(dev_id_info->proj_num));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (dev_id_info->major_ver < IQS5XX_MAJOR_VER_MIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) dev_err(&client->dev, "Unsupported major version: %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) dev_id_info->major_ver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) return iqs5xx_bl_open(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) switch (dev_id_info->bl_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) case IQS5XX_BL_STATUS_AVAIL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) case IQS5XX_BL_STATUS_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) "Unrecognized bootloader status: 0x%02X\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) dev_id_info->bl_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) error = iqs5xx_axis_init(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) error = iqs5xx_read_byte(client, IQS5XX_SYS_CFG0, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) val |= IQS5XX_SETUP_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) val &= ~IQS5XX_SW_INPUT_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) error = iqs5xx_write_byte(client, IQS5XX_SYS_CFG0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) val = IQS5XX_TP_EVENT | IQS5XX_EVENT_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) error = iqs5xx_write_byte(client, IQS5XX_SYS_CFG1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) error = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) iqs5xx->bl_status = dev_id_info->bl_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * Closure of the first communication window that appears following the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * release of reset appears to kick off an initialization period during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * which further communication is met with clock stretching. The return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * from this function is delayed so that further communication attempts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * avoid this period.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) msleep(100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static irqreturn_t iqs5xx_irq(int irq, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) struct iqs5xx_private *iqs5xx = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) struct iqs5xx_touch_data touch_data[IQS5XX_NUM_CONTACTS];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct i2c_client *client = iqs5xx->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) struct input_dev *input = iqs5xx->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int error, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * This check is purely a precaution, as the device does not assert the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) * RDY output during bootloader mode. If the device operates outside of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) * bootloader mode, the input device is guaranteed to be allocated.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) if (iqs5xx->bl_status == IQS5XX_BL_STATUS_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) error = iqs5xx_read_burst(client, IQS5XX_ABS_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) touch_data, sizeof(touch_data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) for (i = 0; i < ARRAY_SIZE(touch_data); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) u16 pressure = be16_to_cpu(touch_data[i].strength);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) input_mt_slot(input, i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) if (input_mt_report_slot_state(input, MT_TOOL_FINGER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) pressure != 0)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) input_report_abs(input, ABS_MT_POSITION_X,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) be16_to_cpu(touch_data[i].abs_x));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) input_report_abs(input, ABS_MT_POSITION_Y,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) be16_to_cpu(touch_data[i].abs_y));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) input_report_abs(input, ABS_MT_PRESSURE, pressure);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) input_mt_sync_frame(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) input_sync(input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) error = iqs5xx_write_byte(client, IQS5XX_END_COMM, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) return IRQ_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * Once the communication window is closed, a small delay is added to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * ensure the device's RDY output has been deasserted by the time the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * interrupt handler returns.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) usleep_range(50, 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static int iqs5xx_fw_file_parse(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) const char *fw_file, u8 *pmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) const struct firmware *fw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct iqs5xx_ihex_rec *rec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) size_t pos = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) int error, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) u16 rec_num = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) u16 rec_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) u8 rec_len, rec_type, rec_chksm, chksm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) u8 rec_hdr[IQS5XX_REC_HDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) u8 rec_data[IQS5XX_REC_LEN_MAX];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) * Firmware exported from the vendor's configuration tool deviates from
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) * standard ihex as follows: (1) the checksum for records corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) * to user-exported settings is not recalculated, and (2) an address of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) * 0xFFFF is used for the EOF record.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) * Because the ihex2fw tool tolerates neither (1) nor (2), the slightly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) * nonstandard ihex firmware is parsed directly by the driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) error = request_firmware(&fw, fw_file, &client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) dev_err(&client->dev, "Failed to request firmware %s: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) fw_file, error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) if (pos + sizeof(*rec) > fw->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) dev_err(&client->dev, "Insufficient firmware size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) rec = (struct iqs5xx_ihex_rec *)(fw->data + pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) pos += sizeof(*rec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) if (rec->start != ':') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) dev_err(&client->dev, "Invalid start at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) error = hex2bin(rec_hdr, rec->len, sizeof(rec_hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) dev_err(&client->dev, "Invalid header at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) rec_len = *rec_hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) rec_addr = get_unaligned_be16(rec_hdr + sizeof(rec_len));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) rec_type = *(rec_hdr + sizeof(rec_len) + sizeof(rec_addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) if (pos + rec_len * 2 > fw->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) dev_err(&client->dev, "Insufficient firmware size\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) pos += (rec_len * 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) error = hex2bin(rec_data, rec->data, rec_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) dev_err(&client->dev, "Invalid data at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) error = hex2bin(&rec_chksm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) rec->data + rec_len * 2, sizeof(rec_chksm));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) dev_err(&client->dev, "Invalid checksum at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) chksm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) for (i = 0; i < sizeof(rec_hdr); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) chksm += rec_hdr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) for (i = 0; i < rec_len; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) chksm += rec_data[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) chksm = ~chksm + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (chksm != rec_chksm && rec_addr < IQS5XX_CSTM) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) "Incorrect checksum at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) switch (rec_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) case IQS5XX_REC_TYPE_DATA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (rec_addr < IQS5XX_CHKSM ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) rec_addr > IQS5XX_PMAP_END) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) "Invalid address at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) memcpy(pmap + rec_addr - IQS5XX_CHKSM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) rec_data, rec_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) case IQS5XX_REC_TYPE_EOF:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) dev_err(&client->dev, "Invalid type at record %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) rec_num);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) rec_num++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) while (pos < fw->size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) if (*(fw->data + pos) == ':')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) pos++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) } while (rec_type != IQS5XX_REC_TYPE_EOF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) release_firmware(fw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static int iqs5xx_fw_file_write(struct i2c_client *client, const char *fw_file)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct iqs5xx_private *iqs5xx = i2c_get_clientdata(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) u8 *pmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) if (iqs5xx->bl_status == IQS5XX_BL_STATUS_NONE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) pmap = kzalloc(IQS5XX_PMAP_LEN, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) if (!pmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) error = iqs5xx_fw_file_parse(client, fw_file, pmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) goto err_kfree;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) mutex_lock(&iqs5xx->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) * Disable the interrupt line in case the first attempt(s) to enter the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) * bootloader don't happen quickly enough, in which case the device may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) * assert the RDY output until the next attempt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) disable_irq(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) iqs5xx->bl_status = IQS5XX_BL_STATUS_RESET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_VER, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) error = iqs5xx_bl_open(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) goto err_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) error = iqs5xx_bl_write(client, IQS5XX_CHKSM, pmap, IQS5XX_PMAP_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) goto err_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_CRC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) goto err_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) error = iqs5xx_bl_verify(client, IQS5XX_CSTM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) pmap + IQS5XX_CHKSM_LEN + IQS5XX_APP_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) IQS5XX_CSTM_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) goto err_reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) error = iqs5xx_bl_cmd(client, IQS5XX_BL_CMD_EXEC, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) err_reset:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) iqs5xx_reset(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) usleep_range(10000, 10100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) error = iqs5xx_dev_init(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) if (!error && iqs5xx->bl_status == IQS5XX_BL_STATUS_RESET)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) enable_irq(client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) mutex_unlock(&iqs5xx->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) err_kfree:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) kfree(pmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) static ssize_t fw_file_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) struct i2c_client *client = iqs5xx->client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) size_t len = count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) bool input_reg = !iqs5xx->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) char fw_file[IQS5XX_FW_FILE_LEN + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) if (!len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (buf[len - 1] == '\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) len--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) if (len > IQS5XX_FW_FILE_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return -ENAMETOOLONG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) memcpy(fw_file, buf, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) fw_file[len] = '\0';
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) error = iqs5xx_fw_file_write(client, fw_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) * If the input device was not allocated already, it is guaranteed to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * be allocated by this point and can finally be registered.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) if (input_reg) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) error = input_register_device(iqs5xx->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) "Failed to register device: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) static DEVICE_ATTR_WO(fw_file);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) static struct attribute *iqs5xx_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) &dev_attr_fw_file.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) static const struct attribute_group iqs5xx_attr_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) .attrs = iqs5xx_attrs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) static int __maybe_unused iqs5xx_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) struct input_dev *input = iqs5xx->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) mutex_lock(&input->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) if (input->users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) error = iqs5xx_set_state(iqs5xx->client, IQS5XX_SUSPEND);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) mutex_unlock(&input->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) static int __maybe_unused iqs5xx_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) struct iqs5xx_private *iqs5xx = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct input_dev *input = iqs5xx->input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) if (!input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) mutex_lock(&input->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (input->users)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) error = iqs5xx_set_state(iqs5xx->client, IQS5XX_RESUME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) mutex_unlock(&input->mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) static SIMPLE_DEV_PM_OPS(iqs5xx_pm, iqs5xx_suspend, iqs5xx_resume);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) static int iqs5xx_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct iqs5xx_private *iqs5xx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) iqs5xx = devm_kzalloc(&client->dev, sizeof(*iqs5xx), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) if (!iqs5xx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) i2c_set_clientdata(client, iqs5xx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) iqs5xx->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) iqs5xx->reset_gpio = devm_gpiod_get(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) "reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) if (IS_ERR(iqs5xx->reset_gpio)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) error = PTR_ERR(iqs5xx->reset_gpio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) dev_err(&client->dev, "Failed to request GPIO: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) mutex_init(&iqs5xx->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) iqs5xx_reset(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) usleep_range(10000, 10100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) error = iqs5xx_dev_init(client);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) error = devm_request_threaded_irq(&client->dev, client->irq,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) NULL, iqs5xx_irq, IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) client->name, iqs5xx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dev_err(&client->dev, "Failed to request IRQ: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) error = devm_device_add_group(&client->dev, &iqs5xx_attr_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) if (error) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) dev_err(&client->dev, "Failed to add attributes: %d\n", error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) if (iqs5xx->input) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) error = input_register_device(iqs5xx->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) if (error)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) dev_err(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) "Failed to register device: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) error);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) static const struct i2c_device_id iqs5xx_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) { "iqs550", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) { "iqs572", 1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) { "iqs525", 2 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) MODULE_DEVICE_TABLE(i2c, iqs5xx_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) static const struct of_device_id iqs5xx_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) { .compatible = "azoteq,iqs550" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) { .compatible = "azoteq,iqs572" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) { .compatible = "azoteq,iqs525" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) MODULE_DEVICE_TABLE(of, iqs5xx_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static struct i2c_driver iqs5xx_i2c_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) .name = "iqs5xx",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) .of_match_table = iqs5xx_of_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) .pm = &iqs5xx_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) .id_table = iqs5xx_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) .probe = iqs5xx_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) module_i2c_driver(iqs5xx_i2c_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) MODULE_AUTHOR("Jeff LaBundy <jeff@labundy.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) MODULE_DESCRIPTION("Azoteq IQS550/572/525 Trackpad/Touchscreen Controller");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) MODULE_LICENSE("GPL");