^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) // Samsung S6SY761 Touchscreen device driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) // Copyright (c) 2017 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) // Copyright (c) 2017 Andi Shyti <andi@etezian.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <asm/unaligned.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/i2c.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/input/mt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/input/touchscreen.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/regulator/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* commands */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #define S6SY761_SENSE_ON 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #define S6SY761_SENSE_OFF 0x11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #define S6SY761_TOUCH_FUNCTION 0x30 /* R/W for get/set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define S6SY761_FIRMWARE_INTEGRITY 0x21
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #define S6SY761_PANEL_INFO 0x23
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define S6SY761_DEVICE_ID 0x52
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define S6SY761_BOOT_STATUS 0x55
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #define S6SY761_READ_ONE_EVENT 0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #define S6SY761_READ_ALL_EVENT 0x61
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define S6SY761_CLEAR_EVENT_STACK 0x62
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define S6SY761_APPLICATION_MODE 0xe4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) /* events */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define S6SY761_EVENT_INFO 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define S6SY761_EVENT_VENDOR_INFO 0x07
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define S6SY761_INFO_BOOT_COMPLETE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* firmware status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define S6SY761_FW_OK 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * the functionalities are put as a reference
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * as in the device I am using none of them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * works therefore not used in this driver yet.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* touchscreen functionalities */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #define S6SY761_MASK_TOUCH BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define S6SY761_MASK_HOVER BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #define S6SY761_MASK_COVER BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #define S6SY761_MASK_GLOVE BIT(3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define S6SY761_MASK_STYLUS BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define S6SY761_MASK_PALM BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define S6SY761_MASK_WET BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define S6SY761_MASK_PROXIMITY BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) /* boot status (BS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define S6SY761_BS_BOOT_LOADER 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define S6SY761_BS_APPLICATION 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /* event id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define S6SY761_EVENT_ID_COORDINATE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define S6SY761_EVENT_ID_STATUS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) /* event register masks */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) #define S6SY761_MASK_TOUCH_STATE 0xc0 /* byte 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define S6SY761_MASK_TID 0x3c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) #define S6SY761_MASK_EID 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define S6SY761_MASK_X 0xf0 /* byte 3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define S6SY761_MASK_Y 0x0f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define S6SY761_MASK_Z 0x3f /* byte 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define S6SY761_MASK_LEFT_EVENTS 0x3f /* byte 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define S6SY761_MASK_TOUCH_TYPE 0xc0 /* MSB in byte 6, LSB in byte 7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* event touch state values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define S6SY761_TS_NONE 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define S6SY761_TS_PRESS 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define S6SY761_TS_MOVE 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define S6SY761_TS_RELEASE 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /* application modes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define S6SY761_APP_NORMAL 0x0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define S6SY761_APP_LOW_POWER 0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define S6SY761_APP_TEST 0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define S6SY761_APP_FLASH 0x3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define S6SY761_APP_SLEEP 0x4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define S6SY761_EVENT_SIZE 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) #define S6SY761_EVENT_COUNT 32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define S6SY761_DEVID_SIZE 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define S6SY761_PANEL_ID_SIZE 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define S6SY761_TS_STATUS_SIZE 5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define S6SY761_MAX_FINGERS 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) #define S6SY761_DEV_NAME "s6sy761"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) enum s6sy761_regulators {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) S6SY761_REGULATOR_VDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) S6SY761_REGULATOR_AVDD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) struct s6sy761_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) struct i2c_client *client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) struct regulator_bulk_data regulators[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) struct input_dev *input;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) struct touchscreen_properties prop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) u8 data[S6SY761_EVENT_SIZE * S6SY761_EVENT_COUNT];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) u16 devid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) u8 tx_channel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * We can't simply use i2c_smbus_read_i2c_block_data because we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) * need to read more than 255 bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static int s6sy761_read_events(struct s6sy761_data *sdata, u16 n_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) u8 cmd = S6SY761_READ_ALL_EVENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) struct i2c_msg msgs[2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) .addr = sdata->client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) .len = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) .buf = &cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) .addr = sdata->client->addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) .flags = I2C_M_RD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) .len = (n_events * S6SY761_EVENT_SIZE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) .buf = sdata->data + S6SY761_EVENT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) ret = i2c_transfer(sdata->client->adapter, msgs, ARRAY_SIZE(msgs));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return ret == ARRAY_SIZE(msgs) ? 0 : -EIO;
^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) static void s6sy761_report_coordinates(struct s6sy761_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) u8 *event, u8 tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) u8 major = event[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) u8 minor = event[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) u8 z = event[6] & S6SY761_MASK_Z;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u16 x = (event[1] << 4) | ((event[3] & S6SY761_MASK_X) >> 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u16 y = (event[2] << 4) | (event[3] & S6SY761_MASK_Y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) input_mt_slot(sdata->input, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) input_report_abs(sdata->input, ABS_MT_POSITION_X, x);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) input_report_abs(sdata->input, ABS_MT_POSITION_Y, y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) input_report_abs(sdata->input, ABS_MT_TOUCH_MAJOR, major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) input_report_abs(sdata->input, ABS_MT_TOUCH_MINOR, minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) input_report_abs(sdata->input, ABS_MT_PRESSURE, z);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) input_sync(sdata->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) static void s6sy761_report_release(struct s6sy761_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) u8 *event, u8 tid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) input_mt_slot(sdata->input, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) input_mt_report_slot_state(sdata->input, MT_TOOL_FINGER, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) input_sync(sdata->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) static void s6sy761_handle_coordinates(struct s6sy761_data *sdata, u8 *event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) u8 tid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 touch_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) if (unlikely(!(event[0] & S6SY761_MASK_TID)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) tid = ((event[0] & S6SY761_MASK_TID) >> 2) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) touch_state = (event[0] & S6SY761_MASK_TOUCH_STATE) >> 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) switch (touch_state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) case S6SY761_TS_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) case S6SY761_TS_RELEASE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) s6sy761_report_release(sdata, event, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case S6SY761_TS_PRESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case S6SY761_TS_MOVE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) s6sy761_report_coordinates(sdata, event, tid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static void s6sy761_handle_events(struct s6sy761_data *sdata, u8 n_events)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) for (i = 0; i < n_events; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) u8 *event = &sdata->data[i * S6SY761_EVENT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) u8 event_id = event[0] & S6SY761_MASK_EID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) if (!event[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) switch (event_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case S6SY761_EVENT_ID_COORDINATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) s6sy761_handle_coordinates(sdata, event);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) case S6SY761_EVENT_ID_STATUS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) static irqreturn_t s6sy761_irq_handler(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) struct s6sy761_data *sdata = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) u8 n_events;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) ret = i2c_smbus_read_i2c_block_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) S6SY761_READ_ONE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) S6SY761_EVENT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) sdata->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev_err(&sdata->client->dev, "failed to read events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) if (!sdata->data[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) n_events = sdata->data[7] & S6SY761_MASK_LEFT_EVENTS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) if (unlikely(n_events > S6SY761_EVENT_COUNT - 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) if (n_events) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) ret = s6sy761_read_events(sdata, n_events);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (ret < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) dev_err(&sdata->client->dev, "failed to read events\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) s6sy761_handle_events(sdata, n_events + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) static int s6sy761_input_open(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) struct s6sy761_data *sdata = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return i2c_smbus_write_byte(sdata->client, S6SY761_SENSE_ON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void s6sy761_input_close(struct input_dev *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct s6sy761_data *sdata = input_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) ret = i2c_smbus_write_byte(sdata->client, S6SY761_SENSE_OFF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) dev_err(&sdata->client->dev, "failed to turn off sensing\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static ssize_t s6sy761_sysfs_devid(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) struct s6sy761_data *sdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return sprintf(buf, "%#x\n", sdata->devid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) static DEVICE_ATTR(devid, 0444, s6sy761_sysfs_devid, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) static struct attribute *s6sy761_sysfs_attrs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) &dev_attr_devid.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) NULL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) static struct attribute_group s6sy761_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) .attrs = s6sy761_sysfs_attrs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) static int s6sy761_power_on(struct s6sy761_data *sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) u8 buffer[S6SY761_EVENT_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) u8 event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) ret = regulator_bulk_enable(ARRAY_SIZE(sdata->regulators),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) sdata->regulators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) msleep(140);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) /* double check whether the touch is functional */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) ret = i2c_smbus_read_i2c_block_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) S6SY761_READ_ONE_EVENT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) S6SY761_EVENT_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) event = (buffer[0] >> 2) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if ((event != S6SY761_EVENT_INFO &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) event != S6SY761_EVENT_VENDOR_INFO) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) buffer[1] != S6SY761_INFO_BOOT_COMPLETE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) ret = i2c_smbus_read_byte_data(sdata->client, S6SY761_BOOT_STATUS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) /* for some reasons the device might be stuck in the bootloader */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) if (ret != S6SY761_BS_APPLICATION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* enable touch functionality */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) ret = i2c_smbus_write_word_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) S6SY761_TOUCH_FUNCTION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) S6SY761_MASK_TOUCH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static int s6sy761_hw_init(struct s6sy761_data *sdata,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) unsigned int *max_x, unsigned int *max_y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) u8 buffer[S6SY761_PANEL_ID_SIZE]; /* larger read size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) ret = s6sy761_power_on(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) ret = i2c_smbus_read_i2c_block_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) S6SY761_DEVICE_ID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) S6SY761_DEVID_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) sdata->devid = get_unaligned_be16(buffer + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) ret = i2c_smbus_read_i2c_block_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) S6SY761_PANEL_INFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) S6SY761_PANEL_ID_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) *max_x = get_unaligned_be16(buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *max_y = get_unaligned_be16(buffer + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) /* if no tx channels defined, at least keep one */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) sdata->tx_channel = max_t(u8, buffer[8], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) ret = i2c_smbus_read_byte_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) S6SY761_FIRMWARE_INTEGRITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) else if (ret != S6SY761_FW_OK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) return -ENODEV;
^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)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) static void s6sy761_power_off(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct s6sy761_data *sdata = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) disable_irq(sdata->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) regulator_bulk_disable(ARRAY_SIZE(sdata->regulators),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) sdata->regulators);
^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 s6sy761_probe(struct i2c_client *client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) const struct i2c_device_id *id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) struct s6sy761_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) unsigned int max_x, max_y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) I2C_FUNC_SMBUS_BYTE_DATA |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) I2C_FUNC_SMBUS_I2C_BLOCK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) sdata = devm_kzalloc(&client->dev, sizeof(*sdata), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) if (!sdata)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) i2c_set_clientdata(client, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) sdata->client = client;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) sdata->regulators[S6SY761_REGULATOR_VDD].supply = "vdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) sdata->regulators[S6SY761_REGULATOR_AVDD].supply = "avdd";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) err = devm_regulator_bulk_get(&client->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) ARRAY_SIZE(sdata->regulators),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) sdata->regulators);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) err = devm_add_action_or_reset(&client->dev, s6sy761_power_off, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) err = s6sy761_hw_init(sdata, &max_x, &max_y);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) sdata->input = devm_input_allocate_device(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) if (!sdata->input)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) sdata->input->name = S6SY761_DEV_NAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) sdata->input->id.bustype = BUS_I2C;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) sdata->input->open = s6sy761_input_open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) sdata->input->close = s6sy761_input_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) input_set_abs_params(sdata->input, ABS_MT_POSITION_X, 0, max_x, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) input_set_abs_params(sdata->input, ABS_MT_POSITION_Y, 0, max_y, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) input_set_abs_params(sdata->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) input_set_abs_params(sdata->input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) input_set_abs_params(sdata->input, ABS_MT_PRESSURE, 0, 255, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) touchscreen_parse_properties(sdata->input, true, &sdata->prop);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if (!input_abs_get_max(sdata->input, ABS_X) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) !input_abs_get_max(sdata->input, ABS_Y)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) dev_warn(&client->dev, "the axis have not been set\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) err = input_mt_init_slots(sdata->input, sdata->tx_channel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) INPUT_MT_DIRECT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) input_set_drvdata(sdata->input, sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) err = input_register_device(sdata->input);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) err = devm_request_threaded_irq(&client->dev, client->irq, NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) s6sy761_irq_handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) IRQF_TRIGGER_LOW | IRQF_ONESHOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) "s6sy761_irq", sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) err = devm_device_add_group(&client->dev, &s6sy761_attribute_group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) pm_runtime_enable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) static int s6sy761_remove(struct i2c_client *client)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) pm_runtime_disable(&client->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static int __maybe_unused s6sy761_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) struct s6sy761_data *sdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) return i2c_smbus_write_byte_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) S6SY761_APPLICATION_MODE, S6SY761_APP_SLEEP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) static int __maybe_unused s6sy761_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) struct s6sy761_data *sdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return i2c_smbus_write_byte_data(sdata->client,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) S6SY761_APPLICATION_MODE, S6SY761_APP_NORMAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) static int __maybe_unused s6sy761_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) struct s6sy761_data *sdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) s6sy761_power_off(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) static int __maybe_unused s6sy761_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) struct s6sy761_data *sdata = dev_get_drvdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) enable_irq(sdata->client->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) return s6sy761_power_on(sdata);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) static const struct dev_pm_ops s6sy761_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) SET_SYSTEM_SLEEP_PM_OPS(s6sy761_suspend, s6sy761_resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) SET_RUNTIME_PM_OPS(s6sy761_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) s6sy761_runtime_resume, NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static const struct of_device_id s6sy761_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) { .compatible = "samsung,s6sy761", },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) MODULE_DEVICE_TABLE(of, s6sy761_of_match);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) static const struct i2c_device_id s6sy761_id[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) { "s6sy761", 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) { },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) MODULE_DEVICE_TABLE(i2c, s6sy761_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static struct i2c_driver s6sy761_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) .name = S6SY761_DEV_NAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) .of_match_table = of_match_ptr(s6sy761_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) .pm = &s6sy761_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .probe = s6sy761_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .remove = s6sy761_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) .id_table = s6sy761_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) module_i2c_driver(s6sy761_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) MODULE_AUTHOR("Andi Shyti <andi.shyti@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) MODULE_DESCRIPTION("Samsung S6SY761 Touch Screen");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) MODULE_LICENSE("GPL v2");