xref: /openbmc/linux/drivers/input/rmi4/rmi_f03.c (revision 8730046c)
1 /*
2  * Copyright (C) 2015-2016 Red Hat
3  * Copyright (C) 2015 Lyude Paul <thatslyude@gmail.com>
4  *
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.
8  */
9 
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"
15 
16 #define RMI_F03_RX_DATA_OFB		0x01
17 #define RMI_F03_OB_SIZE			2
18 
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)
23 
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
28 
29 struct f03_data {
30 	struct rmi_function *fn;
31 
32 	struct serio *serio;
33 
34 	u8 device_count;
35 	u8 rx_queue_length;
36 };
37 
38 static int rmi_f03_pt_write(struct serio *id, unsigned char val)
39 {
40 	struct f03_data *f03 = id->port_data;
41 	int error;
42 
43 	rmi_dbg(RMI_DEBUG_FN, &f03->fn->dev,
44 		"%s: Wrote %.2hhx to PS/2 passthrough address",
45 		__func__, val);
46 
47 	error = rmi_write(f03->fn->rmi_dev, f03->fn->fd.data_base_addr, val);
48 	if (error) {
49 		dev_err(&f03->fn->dev,
50 			"%s: Failed to write to F03 TX register (%d).\n",
51 			__func__, error);
52 		return error;
53 	}
54 
55 	return 0;
56 }
57 
58 static int rmi_f03_initialize(struct f03_data *f03)
59 {
60 	struct rmi_function *fn = f03->fn;
61 	struct device *dev = &fn->dev;
62 	int error;
63 	u8 bytes_per_device;
64 	u8 query1;
65 	u8 query2[RMI_F03_DEVICE_COUNT * RMI_F03_BYTES_PER_DEVICE];
66 	size_t query2_len;
67 
68 	error = rmi_read(fn->rmi_dev, fn->fd.query_base_addr, &query1);
69 	if (error) {
70 		dev_err(dev, "Failed to read query register (%d).\n", error);
71 		return error;
72 	}
73 
74 	f03->device_count = query1 & RMI_F03_DEVICE_COUNT;
75 	bytes_per_device = (query1 >> RMI_F03_BYTES_PER_DEVICE_SHIFT) &
76 				RMI_F03_BYTES_PER_DEVICE;
77 
78 	query2_len = f03->device_count * bytes_per_device;
79 
80 	/*
81 	 * The first generation of image sensors don't have a second part to
82 	 * their f03 query, as such we have to set some of these values manually
83 	 */
84 	if (query2_len < 1) {
85 		f03->device_count = 1;
86 		f03->rx_queue_length = 7;
87 	} else {
88 		error = rmi_read_block(fn->rmi_dev, fn->fd.query_base_addr + 1,
89 				       query2, query2_len);
90 		if (error) {
91 			dev_err(dev,
92 				"Failed to read second set of query registers (%d).\n",
93 				error);
94 			return error;
95 		}
96 
97 		f03->rx_queue_length = query2[0] & RMI_F03_QUEUE_LENGTH;
98 	}
99 
100 	return 0;
101 }
102 
103 static int rmi_f03_register_pt(struct f03_data *f03)
104 {
105 	struct serio *serio;
106 
107 	serio = kzalloc(sizeof(struct serio), GFP_KERNEL);
108 	if (!serio)
109 		return -ENOMEM;
110 
111 	serio->id.type = SERIO_8042;
112 	serio->write = rmi_f03_pt_write;
113 	serio->port_data = f03;
114 
115 	strlcpy(serio->name, "Synaptics RMI4 PS/2 pass-through",
116 		sizeof(serio->name));
117 	strlcpy(serio->phys, "synaptics-rmi4-pt/serio1",
118 		sizeof(serio->phys));
119 	serio->dev.parent = &f03->fn->dev;
120 
121 	f03->serio = serio;
122 
123 	serio_register_port(serio);
124 
125 	return 0;
126 }
127 
128 static int rmi_f03_probe(struct rmi_function *fn)
129 {
130 	struct device *dev = &fn->dev;
131 	struct f03_data *f03;
132 	int error;
133 
134 	f03 = devm_kzalloc(dev, sizeof(struct f03_data), GFP_KERNEL);
135 	if (!f03)
136 		return -ENOMEM;
137 
138 	f03->fn = fn;
139 
140 	error = rmi_f03_initialize(f03);
141 	if (error < 0)
142 		return error;
143 
144 	if (f03->device_count != 1)
145 		dev_warn(dev, "found %d devices on PS/2 passthrough",
146 			 f03->device_count);
147 
148 	dev_set_drvdata(dev, f03);
149 
150 	error = rmi_f03_register_pt(f03);
151 	if (error)
152 		return error;
153 
154 	return 0;
155 }
156 
157 static int rmi_f03_config(struct rmi_function *fn)
158 {
159 	fn->rmi_dev->driver->set_irq_bits(fn->rmi_dev, fn->irq_mask);
160 
161 	return 0;
162 }
163 
164 static int rmi_f03_attention(struct rmi_function *fn, unsigned long *irq_bits)
165 {
166 	struct rmi_device *rmi_dev = fn->rmi_dev;
167 	struct rmi_driver_data *drvdata = dev_get_drvdata(&rmi_dev->dev);
168 	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
169 	u16 data_addr = fn->fd.data_base_addr;
170 	const u8 ob_len = f03->rx_queue_length * RMI_F03_OB_SIZE;
171 	u8 obs[RMI_F03_QUEUE_LENGTH * RMI_F03_OB_SIZE];
172 	u8 ob_status;
173 	u8 ob_data;
174 	unsigned int serio_flags;
175 	int i;
176 	int error;
177 
178 	if (!rmi_dev)
179 		return -ENODEV;
180 
181 	if (drvdata->attn_data.data) {
182 		/* First grab the data passed by the transport device */
183 		if (drvdata->attn_data.size < ob_len) {
184 			dev_warn(&fn->dev, "F03 interrupted, but data is missing!\n");
185 			return 0;
186 		}
187 
188 		memcpy(obs, drvdata->attn_data.data, ob_len);
189 
190 		drvdata->attn_data.data += ob_len;
191 		drvdata->attn_data.size -= ob_len;
192 	} else {
193 		/* Grab all of the data registers, and check them for data */
194 		error = rmi_read_block(fn->rmi_dev, data_addr + RMI_F03_OB_OFFSET,
195 				       &obs, ob_len);
196 		if (error) {
197 			dev_err(&fn->dev,
198 				"%s: Failed to read F03 output buffers: %d\n",
199 				__func__, error);
200 			serio_interrupt(f03->serio, 0, SERIO_TIMEOUT);
201 			return error;
202 		}
203 	}
204 
205 	for (i = 0; i < ob_len; i += RMI_F03_OB_SIZE) {
206 		ob_status = obs[i];
207 		ob_data = obs[i + RMI_F03_OB_DATA_OFFSET];
208 		serio_flags = 0;
209 
210 		if (!(ob_status & RMI_F03_RX_DATA_OFB))
211 			continue;
212 
213 		if (ob_status & RMI_F03_OB_FLAG_TIMEOUT)
214 			serio_flags |= SERIO_TIMEOUT;
215 		if (ob_status & RMI_F03_OB_FLAG_PARITY)
216 			serio_flags |= SERIO_PARITY;
217 
218 		rmi_dbg(RMI_DEBUG_FN, &fn->dev,
219 			"%s: Received %.2hhx from PS2 guest T: %c P: %c\n",
220 			__func__, ob_data,
221 			serio_flags & SERIO_TIMEOUT ?  'Y' : 'N',
222 			serio_flags & SERIO_PARITY ? 'Y' : 'N');
223 
224 		serio_interrupt(f03->serio, ob_data, serio_flags);
225 	}
226 
227 	return 0;
228 }
229 
230 static void rmi_f03_remove(struct rmi_function *fn)
231 {
232 	struct f03_data *f03 = dev_get_drvdata(&fn->dev);
233 
234 	serio_unregister_port(f03->serio);
235 }
236 
237 struct rmi_function_handler rmi_f03_handler = {
238 	.driver = {
239 		.name = "rmi4_f03",
240 	},
241 	.func = 0x03,
242 	.probe = rmi_f03_probe,
243 	.config = rmi_f03_config,
244 	.attention = rmi_f03_attention,
245 	.remove = rmi_f03_remove,
246 };
247 
248 MODULE_AUTHOR("Lyude Paul <thatslyude@gmail.com>");
249 MODULE_DESCRIPTION("RMI F03 module");
250 MODULE_LICENSE("GPL");
251