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_PS_PSTHRU
;
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");