Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^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");