1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * Copyright (c) 2015 - 2016 Red Hat, Inc |
4 | * Copyright (c) 2011, 2012 Synaptics Incorporated |
5 | * Copyright (c) 2011 Unixphere |
6 | */ |
7 | |
8 | #include <linux/kernel.h> |
9 | #include <linux/delay.h> |
10 | #include <linux/i2c.h> |
11 | #include <linux/interrupt.h> |
12 | #include <linux/kconfig.h> |
13 | #include <linux/lockdep.h> |
14 | #include <linux/module.h> |
15 | #include <linux/pm.h> |
16 | #include <linux/rmi.h> |
17 | #include <linux/slab.h> |
18 | #include "rmi_driver.h" |
19 | |
20 | #define SMB_PROTOCOL_VERSION_ADDRESS 0xfd |
21 | #define SMB_MAX_COUNT 32 |
22 | #define RMI_SMB2_MAP_SIZE 8 /* 8 entry of 4 bytes each */ |
23 | #define RMI_SMB2_MAP_FLAGS_WE 0x01 |
24 | |
25 | struct mapping_table_entry { |
26 | __le16 rmiaddr; |
27 | u8 readcount; |
28 | u8 flags; |
29 | }; |
30 | |
31 | struct rmi_smb_xport { |
32 | struct rmi_transport_dev xport; |
33 | struct i2c_client *client; |
34 | |
35 | struct mutex page_mutex; |
36 | int page; |
37 | u8 table_index; |
38 | struct mutex mappingtable_mutex; |
39 | struct mapping_table_entry mapping_table[RMI_SMB2_MAP_SIZE]; |
40 | }; |
41 | |
42 | static int rmi_smb_get_version(struct rmi_smb_xport *rmi_smb) |
43 | { |
44 | struct i2c_client *client = rmi_smb->client; |
45 | int retval; |
46 | |
47 | /* Check if for SMBus new version device by reading version byte. */ |
48 | retval = i2c_smbus_read_byte_data(client, SMB_PROTOCOL_VERSION_ADDRESS); |
49 | if (retval < 0) { |
50 | dev_err(&client->dev, "failed to get SMBus version number!\n" ); |
51 | return retval; |
52 | } |
53 | |
54 | return retval + 1; |
55 | } |
56 | |
57 | /* SMB block write - wrapper over ic2_smb_write_block */ |
58 | static int smb_block_write(struct rmi_transport_dev *xport, |
59 | u8 commandcode, const void *buf, size_t len) |
60 | { |
61 | struct rmi_smb_xport *rmi_smb = |
62 | container_of(xport, struct rmi_smb_xport, xport); |
63 | struct i2c_client *client = rmi_smb->client; |
64 | int retval; |
65 | |
66 | retval = i2c_smbus_write_block_data(client, command: commandcode, length: len, values: buf); |
67 | |
68 | rmi_dbg(RMI_DEBUG_XPORT, dev: &client->dev, |
69 | fmt: "wrote %zd bytes at %#04x: %d (%*ph)\n" , |
70 | len, commandcode, retval, (int)len, buf); |
71 | |
72 | return retval; |
73 | } |
74 | |
75 | /* |
76 | * The function to get command code for smbus operations and keeps |
77 | * records to the driver mapping table |
78 | */ |
79 | static int rmi_smb_get_command_code(struct rmi_transport_dev *xport, |
80 | u16 rmiaddr, int bytecount, bool isread, u8 *commandcode) |
81 | { |
82 | struct rmi_smb_xport *rmi_smb = |
83 | container_of(xport, struct rmi_smb_xport, xport); |
84 | struct mapping_table_entry new_map; |
85 | int i; |
86 | int retval = 0; |
87 | |
88 | mutex_lock(&rmi_smb->mappingtable_mutex); |
89 | |
90 | for (i = 0; i < RMI_SMB2_MAP_SIZE; i++) { |
91 | struct mapping_table_entry *entry = &rmi_smb->mapping_table[i]; |
92 | |
93 | if (le16_to_cpu(entry->rmiaddr) == rmiaddr) { |
94 | if (isread) { |
95 | if (entry->readcount == bytecount) |
96 | goto exit; |
97 | } else { |
98 | if (entry->flags & RMI_SMB2_MAP_FLAGS_WE) { |
99 | goto exit; |
100 | } |
101 | } |
102 | } |
103 | } |
104 | |
105 | i = rmi_smb->table_index; |
106 | rmi_smb->table_index = (i + 1) % RMI_SMB2_MAP_SIZE; |
107 | |
108 | /* constructs mapping table data entry. 4 bytes each entry */ |
109 | memset(&new_map, 0, sizeof(new_map)); |
110 | new_map.rmiaddr = cpu_to_le16(rmiaddr); |
111 | new_map.readcount = bytecount; |
112 | new_map.flags = !isread ? RMI_SMB2_MAP_FLAGS_WE : 0; |
113 | |
114 | retval = smb_block_write(xport, commandcode: i + 0x80, buf: &new_map, len: sizeof(new_map)); |
115 | if (retval < 0) { |
116 | /* |
117 | * if not written to device mapping table |
118 | * clear the driver mapping table records |
119 | */ |
120 | memset(&new_map, 0, sizeof(new_map)); |
121 | } |
122 | |
123 | /* save to the driver level mapping table */ |
124 | rmi_smb->mapping_table[i] = new_map; |
125 | |
126 | exit: |
127 | mutex_unlock(lock: &rmi_smb->mappingtable_mutex); |
128 | |
129 | if (retval < 0) |
130 | return retval; |
131 | |
132 | *commandcode = i; |
133 | return 0; |
134 | } |
135 | |
136 | static int rmi_smb_write_block(struct rmi_transport_dev *xport, u16 rmiaddr, |
137 | const void *databuff, size_t len) |
138 | { |
139 | int retval = 0; |
140 | u8 commandcode; |
141 | struct rmi_smb_xport *rmi_smb = |
142 | container_of(xport, struct rmi_smb_xport, xport); |
143 | int cur_len = (int)len; |
144 | |
145 | mutex_lock(&rmi_smb->page_mutex); |
146 | |
147 | while (cur_len > 0) { |
148 | /* |
149 | * break into 32 bytes chunks to write get command code |
150 | */ |
151 | int block_len = min_t(int, len, SMB_MAX_COUNT); |
152 | |
153 | retval = rmi_smb_get_command_code(xport, rmiaddr, bytecount: block_len, |
154 | isread: false, commandcode: &commandcode); |
155 | if (retval < 0) |
156 | goto exit; |
157 | |
158 | retval = smb_block_write(xport, commandcode, |
159 | buf: databuff, len: block_len); |
160 | if (retval < 0) |
161 | goto exit; |
162 | |
163 | /* prepare to write next block of bytes */ |
164 | cur_len -= SMB_MAX_COUNT; |
165 | databuff += SMB_MAX_COUNT; |
166 | rmiaddr += SMB_MAX_COUNT; |
167 | } |
168 | exit: |
169 | mutex_unlock(lock: &rmi_smb->page_mutex); |
170 | return retval; |
171 | } |
172 | |
173 | /* SMB block read - wrapper over ic2_smb_read_block */ |
174 | static int smb_block_read(struct rmi_transport_dev *xport, |
175 | u8 commandcode, void *buf, size_t len) |
176 | { |
177 | struct rmi_smb_xport *rmi_smb = |
178 | container_of(xport, struct rmi_smb_xport, xport); |
179 | struct i2c_client *client = rmi_smb->client; |
180 | int retval; |
181 | |
182 | retval = i2c_smbus_read_block_data(client, command: commandcode, values: buf); |
183 | if (retval < 0) |
184 | return retval; |
185 | |
186 | return retval; |
187 | } |
188 | |
189 | static int rmi_smb_read_block(struct rmi_transport_dev *xport, u16 rmiaddr, |
190 | void *databuff, size_t len) |
191 | { |
192 | struct rmi_smb_xport *rmi_smb = |
193 | container_of(xport, struct rmi_smb_xport, xport); |
194 | int retval; |
195 | u8 commandcode; |
196 | int cur_len = (int)len; |
197 | |
198 | mutex_lock(&rmi_smb->page_mutex); |
199 | memset(databuff, 0, len); |
200 | |
201 | while (cur_len > 0) { |
202 | /* break into 32 bytes chunks to write get command code */ |
203 | int block_len = min_t(int, cur_len, SMB_MAX_COUNT); |
204 | |
205 | retval = rmi_smb_get_command_code(xport, rmiaddr, bytecount: block_len, |
206 | isread: true, commandcode: &commandcode); |
207 | if (retval < 0) |
208 | goto exit; |
209 | |
210 | retval = smb_block_read(xport, commandcode, |
211 | buf: databuff, len: block_len); |
212 | if (retval < 0) |
213 | goto exit; |
214 | |
215 | /* prepare to read next block of bytes */ |
216 | cur_len -= SMB_MAX_COUNT; |
217 | databuff += SMB_MAX_COUNT; |
218 | rmiaddr += SMB_MAX_COUNT; |
219 | } |
220 | |
221 | retval = 0; |
222 | |
223 | exit: |
224 | mutex_unlock(lock: &rmi_smb->page_mutex); |
225 | return retval; |
226 | } |
227 | |
228 | static void rmi_smb_clear_state(struct rmi_smb_xport *rmi_smb) |
229 | { |
230 | /* the mapping table has been flushed, discard the current one */ |
231 | mutex_lock(&rmi_smb->mappingtable_mutex); |
232 | memset(rmi_smb->mapping_table, 0, sizeof(rmi_smb->mapping_table)); |
233 | mutex_unlock(lock: &rmi_smb->mappingtable_mutex); |
234 | } |
235 | |
236 | static int rmi_smb_enable_smbus_mode(struct rmi_smb_xport *rmi_smb) |
237 | { |
238 | struct i2c_client *client = rmi_smb->client; |
239 | int smbus_version; |
240 | |
241 | /* |
242 | * psmouse driver resets the controller, we only need to wait |
243 | * to give the firmware chance to fully reinitialize. |
244 | */ |
245 | if (rmi_smb->xport.pdata.reset_delay_ms) |
246 | msleep(msecs: rmi_smb->xport.pdata.reset_delay_ms); |
247 | |
248 | /* we need to get the smbus version to activate the touchpad */ |
249 | smbus_version = rmi_smb_get_version(rmi_smb); |
250 | if (smbus_version < 0) |
251 | return smbus_version; |
252 | |
253 | rmi_dbg(RMI_DEBUG_XPORT, dev: &client->dev, fmt: "Smbus version is %d" , |
254 | smbus_version); |
255 | |
256 | if (smbus_version != 2 && smbus_version != 3) { |
257 | dev_err(&client->dev, "Unrecognized SMB version %d\n" , |
258 | smbus_version); |
259 | return -ENODEV; |
260 | } |
261 | |
262 | return 0; |
263 | } |
264 | |
265 | static int rmi_smb_reset(struct rmi_transport_dev *xport, u16 reset_addr) |
266 | { |
267 | struct rmi_smb_xport *rmi_smb = |
268 | container_of(xport, struct rmi_smb_xport, xport); |
269 | |
270 | rmi_smb_clear_state(rmi_smb); |
271 | |
272 | /* |
273 | * We do not call the actual reset command, it has to be handled in |
274 | * PS/2 or there will be races between PS/2 and SMBus. PS/2 should |
275 | * ensure that a psmouse_reset is called before initializing the |
276 | * device and after it has been removed to be in a known state. |
277 | */ |
278 | return rmi_smb_enable_smbus_mode(rmi_smb); |
279 | } |
280 | |
281 | static const struct rmi_transport_ops rmi_smb_ops = { |
282 | .write_block = rmi_smb_write_block, |
283 | .read_block = rmi_smb_read_block, |
284 | .reset = rmi_smb_reset, |
285 | }; |
286 | |
287 | static int rmi_smb_probe(struct i2c_client *client) |
288 | { |
289 | struct rmi_device_platform_data *pdata = dev_get_platdata(dev: &client->dev); |
290 | struct rmi_smb_xport *rmi_smb; |
291 | int error; |
292 | |
293 | if (!pdata) { |
294 | dev_err(&client->dev, "no platform data, aborting\n" ); |
295 | return -ENOMEM; |
296 | } |
297 | |
298 | if (!i2c_check_functionality(adap: client->adapter, |
299 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | |
300 | I2C_FUNC_SMBUS_HOST_NOTIFY)) { |
301 | dev_err(&client->dev, |
302 | "adapter does not support required functionality\n" ); |
303 | return -ENODEV; |
304 | } |
305 | |
306 | if (client->irq <= 0) { |
307 | dev_err(&client->dev, "no IRQ provided, giving up\n" ); |
308 | return client->irq ? client->irq : -ENODEV; |
309 | } |
310 | |
311 | rmi_smb = devm_kzalloc(dev: &client->dev, size: sizeof(struct rmi_smb_xport), |
312 | GFP_KERNEL); |
313 | if (!rmi_smb) |
314 | return -ENOMEM; |
315 | |
316 | rmi_dbg(RMI_DEBUG_XPORT, dev: &client->dev, fmt: "Probing %s\n" , |
317 | dev_name(dev: &client->dev)); |
318 | |
319 | rmi_smb->client = client; |
320 | mutex_init(&rmi_smb->page_mutex); |
321 | mutex_init(&rmi_smb->mappingtable_mutex); |
322 | |
323 | rmi_smb->xport.dev = &client->dev; |
324 | rmi_smb->xport.pdata = *pdata; |
325 | rmi_smb->xport.pdata.irq = client->irq; |
326 | rmi_smb->xport.proto_name = "smb" ; |
327 | rmi_smb->xport.ops = &rmi_smb_ops; |
328 | |
329 | error = rmi_smb_enable_smbus_mode(rmi_smb); |
330 | if (error) |
331 | return error; |
332 | |
333 | i2c_set_clientdata(client, data: rmi_smb); |
334 | |
335 | dev_info(&client->dev, "registering SMbus-connected sensor\n" ); |
336 | |
337 | error = rmi_register_transport_device(xport: &rmi_smb->xport); |
338 | if (error) { |
339 | dev_err(&client->dev, "failed to register sensor: %d\n" , error); |
340 | return error; |
341 | } |
342 | |
343 | return 0; |
344 | } |
345 | |
346 | static void rmi_smb_remove(struct i2c_client *client) |
347 | { |
348 | struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client); |
349 | |
350 | rmi_unregister_transport_device(xport: &rmi_smb->xport); |
351 | } |
352 | |
353 | static int rmi_smb_suspend(struct device *dev) |
354 | { |
355 | struct i2c_client *client = to_i2c_client(dev); |
356 | struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client); |
357 | int ret; |
358 | |
359 | ret = rmi_driver_suspend(rmi_dev: rmi_smb->xport.rmi_dev, enable_wake: true); |
360 | if (ret) |
361 | dev_warn(dev, "Failed to suspend device: %d\n" , ret); |
362 | |
363 | return ret; |
364 | } |
365 | |
366 | static int rmi_smb_runtime_suspend(struct device *dev) |
367 | { |
368 | struct i2c_client *client = to_i2c_client(dev); |
369 | struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client); |
370 | int ret; |
371 | |
372 | ret = rmi_driver_suspend(rmi_dev: rmi_smb->xport.rmi_dev, enable_wake: false); |
373 | if (ret) |
374 | dev_warn(dev, "Failed to suspend device: %d\n" , ret); |
375 | |
376 | return ret; |
377 | } |
378 | |
379 | static int rmi_smb_resume(struct device *dev) |
380 | { |
381 | struct i2c_client *client = container_of(dev, struct i2c_client, dev); |
382 | struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client); |
383 | struct rmi_device *rmi_dev = rmi_smb->xport.rmi_dev; |
384 | int ret; |
385 | |
386 | rmi_smb_reset(xport: &rmi_smb->xport, reset_addr: 0); |
387 | |
388 | rmi_reset(d: rmi_dev); |
389 | |
390 | ret = rmi_driver_resume(rmi_dev: rmi_smb->xport.rmi_dev, clear_wake: true); |
391 | if (ret) |
392 | dev_warn(dev, "Failed to resume device: %d\n" , ret); |
393 | |
394 | return 0; |
395 | } |
396 | |
397 | static int rmi_smb_runtime_resume(struct device *dev) |
398 | { |
399 | struct i2c_client *client = to_i2c_client(dev); |
400 | struct rmi_smb_xport *rmi_smb = i2c_get_clientdata(client); |
401 | int ret; |
402 | |
403 | ret = rmi_driver_resume(rmi_dev: rmi_smb->xport.rmi_dev, clear_wake: false); |
404 | if (ret) |
405 | dev_warn(dev, "Failed to resume device: %d\n" , ret); |
406 | |
407 | return 0; |
408 | } |
409 | |
410 | static const struct dev_pm_ops rmi_smb_pm = { |
411 | SYSTEM_SLEEP_PM_OPS(rmi_smb_suspend, rmi_smb_resume) |
412 | RUNTIME_PM_OPS(rmi_smb_runtime_suspend, rmi_smb_runtime_resume, NULL) |
413 | }; |
414 | |
415 | static const struct i2c_device_id rmi_id[] = { |
416 | { "rmi4_smbus" , 0 }, |
417 | { } |
418 | }; |
419 | MODULE_DEVICE_TABLE(i2c, rmi_id); |
420 | |
421 | static struct i2c_driver rmi_smb_driver = { |
422 | .driver = { |
423 | .name = "rmi4_smbus" , |
424 | .pm = pm_ptr(&rmi_smb_pm), |
425 | }, |
426 | .id_table = rmi_id, |
427 | .probe = rmi_smb_probe, |
428 | .remove = rmi_smb_remove, |
429 | }; |
430 | |
431 | module_i2c_driver(rmi_smb_driver); |
432 | |
433 | MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com>" ); |
434 | MODULE_AUTHOR("Benjamin Tissoires <benjamin.tissoires@redhat.com>" ); |
435 | MODULE_DESCRIPTION("RMI4 SMBus driver" ); |
436 | MODULE_LICENSE("GPL" ); |
437 | |