2 * Copyright (C) 2015-2016 Red Hat
3 * Copyright (C) 2015 Lyude Paul <thatslyude@gmail.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
10 #include <linux/kernel.h>
11 #include <linux/slab.h>
12 #include <linux/serio.h>
13 #include <linux/notifier.h>
14 #include "rmi_driver.h"
16 #define RMI_F03_RX_DATA_OFB 0x01
17 #define RMI_F03_OB_SIZE 2
19 #define RMI_F03_OB_OFFSET 2
20 #define RMI_F03_OB_DATA_OFFSET 1
21 #define RMI_F03_OB_FLAG_TIMEOUT BIT(6)
22 #define RMI_F03_OB_FLAG_PARITY BIT(7)
24 #define RMI_F03_DEVICE_COUNT 0x07
25 #define RMI_F03_BYTES_PER_DEVICE 0x07
26 #define RMI_F03_BYTES_PER_DEVICE_SHIFT 4
27 #define RMI_F03_QUEUE_LENGTH 0x0F
29 #define PSMOUSE_OOB_EXTRA_BTNS 0x01
32 struct rmi_function *fn;
36 unsigned int overwrite_buttons;
42 int rmi_f03_overwrite_button(struct rmi_function *fn, unsigned int button,
45 struct f03_data *f03 = dev_get_drvdata(&fn->dev);
48 if (button < BTN_LEFT || button > BTN_MIDDLE)
51 bit = BIT(button - BTN_LEFT);
54 f03->overwrite_buttons |= bit;
56 f03->overwrite_buttons &= ~bit;
61 void rmi_f03_commit_buttons(struct rmi_function *fn)
63 struct f03_data *f03 = dev_get_drvdata(&fn->dev);
64 struct serio *serio = f03->serio;
66 serio_pause_rx(serio);
68 serio->drv->interrupt(serio, PSMOUSE_OOB_EXTRA_BTNS,
70 serio->drv->interrupt(serio, f03->overwrite_buttons,
73 serio_continue_rx(serio);
76 static int rmi_f03_pt_write(struct serio *id, unsigned char val)
78 struct f03_data *f03 = id->port_data;
81 rmi_dbg(RMI_DEBUG_FN, &f03->fn->dev,
82 "%s: Wrote %.2hhx to PS/2 passthrough address",
85 error = rmi_write(f03->fn->rmi_dev, f03->fn->fd.data_base_addr, val);
87 dev_err(&f03->fn->dev,
88 "%s: Failed to write to F03 TX register (%d).\n",
96 static int rmi_f03_initialize(struct f03_data *f03)
98 struct rmi_function *fn = f03->fn;
99 struct device *dev = &fn->dev;
103 u8 query2[RMI_F03_DEVICE_COUNT * RMI_F03_BYTES_PER_DEVICE];
106 error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &query1);
108 dev_err(dev, "Failed to read query register (%d).\n", error);
112 f03->device_count = query1 & RMI_F03_DEVICE_COUNT;
113 bytes_per_device = (query1 >> RMI_F03_BYTES_PER_DEVICE_SHIFT) &
114 RMI_F03_BYTES_PER_DEVICE;
116 query2_len = f03->device_count * bytes_per_device;
119 * The first generation of image sensors don't have a second part to
120 * their f03 query, as such we have to set some of these values manually
122 if (query2_len < 1) {
123 f03->device_count = 1;
124 f03->rx_queue_length = 7;
126 error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr + 1,
130 "Failed to read second set of query registers (%d).\n",
135 f03->rx_queue_length = query2[0] & RMI_F03_QUEUE_LENGTH;
141 static int rmi_f03_register_pt(struct f03_data *f03)
145 serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
149 serio->id.type = SERIO_8042;
150 serio->write = rmi_f03_pt_write;
151 serio->port_data = f03;
153 strlcpy(serio->name, "Synaptics RMI4 PS/2 pass-through",
154 sizeof(serio->name));
155 strlcpy(serio->phys, "synaptics-rmi4-pt/serio1",
156 sizeof(serio->phys));
157 serio->dev.parent = &f03->fn->dev;
161 serio_register_port(serio);
166 static int rmi_f03_probe(struct rmi_function *fn)
168 struct device *dev = &fn->dev;
169 struct f03_data *f03;
172 f03 = devm_kzalloc(dev, sizeof(struct f03_data), GFP_KERNEL);
178 error = rmi_f03_initialize(f03);
182 if (f03->device_count != 1)
183 dev_warn(dev, "found %d devices on PS/2 passthrough",
186 dev_set_drvdata(dev, f03);
188 error = rmi_f03_register_pt(f03);
195 static int rmi_f03_config(struct rmi_function *fn)
197 fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
202 static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
204 struct rmi_device *rmi_dev = fn->rmi_dev;
205 struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
206 struct f03_data *f03 = dev_get_drvdata(&fn->dev);
207 u16 data_addr = fn->fd.data_base_addr;
208 const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
209 u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE];
212 unsigned int serio_flags;
216 if (drvdata->attn_data.data) {
217 /* First grab the data passed by the transport device */
218 if (drvdata->attn_data.size < ob_len) {
219 dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
223 memcpy(obs, drvdata->attn_data.data, ob_len);
225 drvdata->attn_data.data += ob_len;
226 drvdata->attn_data.size -= ob_len;
228 /* Grab all of the data registers, and check them for data */
229 error = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
233 "%s: Failed to read F03 output buffers: %d\n",
235 serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
240 for (i = 0; i < ob_len; i += RMI_F03_OB_SIZE) {
242 ob_data = obs[i + RMI_F03_OB_DATA_OFFSET];
245 if (!(ob_status & RMI_F03_RX_DATA_OFB))
248 if (ob_status & RMI_F03_OB_FLAG_TIMEOUT)
249 serio_flags |= SERIO_TIMEOUT;
250 if (ob_status & RMI_F03_OB_FLAG_PARITY)
251 serio_flags |= SERIO_PARITY;
253 rmi_dbg(RMI_DEBUG_FN, &fn->dev,
254 "%s: Received %.2hhx from PS2 guest T: %c P: %c\n",
256 serio_flags & SERIO_TIMEOUT ? 'Y' : 'N',
257 serio_flags & SERIO_PARITY ? 'Y' : 'N');
259 serio_interrupt(f03->serio, ob_data, serio_flags);
265 static void rmi_f03_remove(struct rmi_function *fn)
267 struct f03_data *f03 = dev_get_drvdata(&fn->dev);
269 serio_unregister_port(f03->serio);
272 struct rmi_function_handler rmi_f03_handler = {
277 .probe = rmi_f03_probe,
278 .config = rmi_f03_config,
279 .attention = rmi_f03_attention,
280 .remove = rmi_f03_remove,
283 MODULE_AUTHOR("Lyude Paul <thatslyude@gmail.com>");
284 MODULE_DESCRIPTION("RMI F03 module");
285 MODULE_LICENSE("GPL");