Re: [PATCHv2 4/5] Input: EXC3000: Add support to query model and fw_version

From: kbuild test robot
Date: Tue May 19 2020 - 22:11:32 EST


Hi Sebastian,

I love your patch! Yet something to improve:

[auto build test ERROR on input/next]
[also build test ERROR on v5.7-rc6 next-20200519]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Sebastian-Reichel/EXC3000-Updates/20200520-023207
base: https://git.kernel.org/pub/scm/linux/kernel/git/dtor/input.git next
config: x86_64-allyesconfig (attached as .config)
compiler: clang version 11.0.0 (https://github.com/llvm/llvm-project 135b877874fae96b4372c8a3fbfaa8ff44ff86e3)
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kbuild test robot <lkp@xxxxxxxxx>

All errors (new ones prefixed by >>, old ones prefixed by <<):

drivers/input/touchscreen/exc3000.c:51:13: error: use of undeclared identifier 'SZ_4K'
.max_xy = SZ_4K - 1,
^
drivers/input/touchscreen/exc3000.c:55:13: error: use of undeclared identifier 'SZ_16K'
.max_xy = SZ_16K - 1,
^
drivers/input/touchscreen/exc3000.c:59:13: error: use of undeclared identifier 'SZ_16K'
.max_xy = SZ_16K - 1,
^
drivers/input/touchscreen/exc3000.c:107:28: error: use of undeclared identifier 'SZ_16K'
if (data->info->max_xy == SZ_16K - 1)
^
>> drivers/input/touchscreen/exc3000.c:252:8: error: incompatible function pointer types initializing 'ssize_t (*)(struct device *, struct device_attribute *, char *)' (aka 'long (*)(struct device *, struct device_attribute *, char *)') with an expression of type 'int (struct device *, struct device_attribute *, char *)' [-Werror,-Wincompatible-function-pointer-types]
static DEVICE_ATTR_RO(fw_version);
^~~~~~~~~~~~~~~~~~~~~~~~~~
include/linux/device.h:133:45: note: expanded from macro 'DEVICE_ATTR_RO'
struct device_attribute dev_attr_##_name = __ATTR_RO(_name)
^~~~~~~~~~~~~~~~
include/linux/sysfs.h:117:10: note: expanded from macro '__ATTR_RO'
.show = _name##_show, ^~~~~~~~~~~~
<scratch space>:62:1: note: expanded from here
fw_version_show
^~~~~~~~~~~~~~~
5 errors generated.

vim +252 drivers/input/touchscreen/exc3000.c

47
48 static struct eeti_dev_info exc3000_info[] = {
49 [EETI_EXC3000] = {
50 .name = "EETI EXC3000 Touch Screen",
51 .max_xy = SZ_4K - 1,
52 },
53 [EETI_EXC80H60] = {
54 .name = "EETI EXC80H60 Touch Screen",
> 55 .max_xy = SZ_16K - 1,
56 },
57 [EETI_EXC80H84] = {
58 .name = "EETI EXC80H84 Touch Screen",
59 .max_xy = SZ_16K - 1,
60 },
61 };
62
63 struct exc3000_data {
64 struct i2c_client *client;
65 const struct eeti_dev_info *info;
66 struct input_dev *input;
67 struct touchscreen_properties prop;
68 struct timer_list timer;
69 u8 buf[2 * EXC3000_LEN_FRAME];
70 struct completion wait_event;
71 struct mutex query_lock;
72 int query_result;
73 char model[EXC3000_LEN_MODEL_NAME];
74 char fw_version[EXC3000_LEN_FW_VERSION];
75 };
76
77 static void exc3000_report_slots(struct input_dev *input,
78 struct touchscreen_properties *prop,
79 const u8 *buf, int num)
80 {
81 for (; num--; buf += EXC3000_LEN_POINT) {
82 if (buf[0] & BIT(0)) {
83 input_mt_slot(input, buf[1]);
84 input_mt_report_slot_state(input, MT_TOOL_FINGER, true);
85 touchscreen_report_pos(input, prop,
86 get_unaligned_le16(buf + 2),
87 get_unaligned_le16(buf + 4),
88 true);
89 }
90 }
91 }
92
93 static void exc3000_timer(struct timer_list *t)
94 {
95 struct exc3000_data *data = from_timer(data, t, timer);
96
97 input_mt_sync_frame(data->input);
98 input_sync(data->input);
99 }
100
101 static int exc3000_read_frame(struct exc3000_data *data, u8 *buf)
102 {
103 struct i2c_client *client = data->client;
104 u8 expected_event = EXC3000_MT1_EVENT;
105 int ret;
106
107 if (data->info->max_xy == SZ_16K - 1)
108 expected_event = EXC3000_MT2_EVENT;
109
110 ret = i2c_master_send(client, "'", 2);
111 if (ret < 0)
112 return ret;
113
114 if (ret != 2)
115 return -EIO;
116
117 ret = i2c_master_recv(client, buf, EXC3000_LEN_FRAME);
118 if (ret < 0)
119 return ret;
120
121 if (ret != EXC3000_LEN_FRAME)
122 return -EIO;
123
124 if (get_unaligned_le16(buf) != EXC3000_LEN_FRAME)
125 return -EINVAL;
126
127 if (buf[2] != expected_event)
128 return -EINVAL;
129
130 return 0;
131 }
132
133 static int exc3000_read_data(struct exc3000_data *data,
134 u8 *buf, int *n_slots)
135 {
136 int error;
137
138 error = exc3000_read_frame(data, buf);
139 if (error)
140 return error;
141
142 *n_slots = buf[3];
143 if (!*n_slots || *n_slots > EXC3000_NUM_SLOTS)
144 return -EINVAL;
145
146 if (*n_slots > EXC3000_SLOTS_PER_FRAME) {
147 /* Read 2nd frame to get the rest of the contacts. */
148 error = exc3000_read_frame(data, buf + EXC3000_LEN_FRAME);
149 if (error)
150 return error;
151
152 /* 2nd chunk must have number of contacts set to 0. */
153 if (buf[EXC3000_LEN_FRAME + 3] != 0)
154 return -EINVAL;
155 }
156
157 return 0;
158 }
159
160 static int exc3000_query_interrupt(struct exc3000_data *data)
161 {
162 u8 *buf = data->buf;
163 int err;
164
165 err = i2c_master_recv(data->client, buf, EXC3000_LEN_FRAME);
166 if (err < 0)
167 return err;
168
169 if (buf[0] != 0x42)
170 return -EPROTO;
171
172 if (buf[4] == 'E')
173 strlcpy(data->model, buf+5, sizeof(data->model));
174 else if (buf[4] == 'D')
175 strlcpy(data->fw_version, buf+5, sizeof(data->fw_version));
176 else
177 return -EPROTO;
178
179 return 0;
180 }
181
182 static irqreturn_t exc3000_interrupt(int irq, void *dev_id)
183 {
184 struct exc3000_data *data = dev_id;
185 struct input_dev *input = data->input;
186 u8 *buf = data->buf;
187 int slots, total_slots;
188 int error;
189
190 if (mutex_is_locked(&data->query_lock)) {
191 data->query_result = exc3000_query_interrupt(data);
192 complete(&data->wait_event);
193 goto out;
194 }
195
196 error = exc3000_read_data(data, buf, &total_slots);
197 if (error) {
198 /* Schedule a timer to release "stuck" contacts */
199 mod_timer(&data->timer,
200 jiffies + msecs_to_jiffies(EXC3000_TIMEOUT_MS));
201 goto out;
202 }
203
204 /*
205 * We read full state successfully, no contacts will be "stuck".
206 */
207 del_timer_sync(&data->timer);
208
209 while (total_slots > 0) {
210 slots = min(total_slots, EXC3000_SLOTS_PER_FRAME);
211 exc3000_report_slots(input, &data->prop, buf + 4, slots);
212 total_slots -= slots;
213 buf += EXC3000_LEN_FRAME;
214 }
215
216 input_mt_sync_frame(input);
217 input_sync(input);
218
219 out:
220 return IRQ_HANDLED;
221 }
222
223 static int fw_version_show(struct device *dev,
224 struct device_attribute *attr, char *buf)
225 {
226 struct exc3000_data *data = dev_get_drvdata(dev);
227 static const u8 request[68] = {
228 0x67, 0x00, 0x42, 0x00, 0x03, 0x01, 'D', 0x00
229 };
230 struct i2c_client *client = data->client;
231 int err;
232
233 mutex_lock(&data->query_lock);
234
235 data->query_result = -ETIMEDOUT;
236 reinit_completion(&data->wait_event);
237
238 err = i2c_master_send(client, request, sizeof(request));
239 if (err < 0) {
240 mutex_unlock(&data->query_lock);
241 return err;
242 }
243
244 wait_for_completion_interruptible_timeout(&data->wait_event, 1*HZ);
245 mutex_unlock(&data->query_lock);
246
247 if (data->query_result < 0)
248 return data->query_result;
249
250 return sprintf(buf, "%s\n", data->fw_version);
251 }
> 252 static DEVICE_ATTR_RO(fw_version);
253

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip