1 /*
2  * cros_ec_lpc - LPC access to the Chrome OS Embedded Controller
3  *
4  * Copyright (C) 2012-2015 Google, Inc
5  *
6  * This software is licensed under the terms of the GNU General Public
7  * License version 2, as published by the Free Software Foundation, and
8  * may be copied, distributed, and modified under those terms.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * This driver uses the Chrome OS EC byte-level message-based protocol for
16  * communicating the keyboard state (which keys are pressed) from a keyboard EC
17  * to the AP over some bus (such as i2c, lpc, spi).  The EC does debouncing,
18  * but everything else (including deghosting) is done here.  The main
19  * motivation for this is to keep the EC firmware as simple as possible, since
20  * it cannot be easily upgraded and EC flash/IRAM space is relatively
21  * expensive.
22  */
23 
24 #include <linux/dmi.h>
25 #include <linux/delay.h>
26 #include <linux/io.h>
27 #include <linux/mfd/cros_ec.h>
28 #include <linux/mfd/cros_ec_commands.h>
29 #include <linux/module.h>
30 #include <linux/platform_device.h>
31 #include <linux/printk.h>
32 
33 #define DRV_NAME "cros_ec_lpc"
34 
35 static int ec_response_timed_out(void)
36 {
37 	unsigned long one_second = jiffies + HZ;
38 
39 	usleep_range(200, 300);
40 	do {
41 		if (!(inb(EC_LPC_ADDR_HOST_CMD) & EC_LPC_STATUS_BUSY_MASK))
42 			return 0;
43 		usleep_range(100, 200);
44 	} while (time_before(jiffies, one_second));
45 
46 	return 1;
47 }
48 
49 static int cros_ec_cmd_xfer_lpc(struct cros_ec_device *ec,
50 				struct cros_ec_command *msg)
51 {
52 	struct ec_lpc_host_args args;
53 	int csum;
54 	int i;
55 	int ret = 0;
56 
57 	if (msg->outsize > EC_PROTO2_MAX_PARAM_SIZE ||
58 	    msg->insize > EC_PROTO2_MAX_PARAM_SIZE) {
59 		dev_err(ec->dev,
60 			"invalid buffer sizes (out %d, in %d)\n",
61 			msg->outsize, msg->insize);
62 		return -EINVAL;
63 	}
64 
65 	/* Now actually send the command to the EC and get the result */
66 	args.flags = EC_HOST_ARGS_FLAG_FROM_HOST;
67 	args.command_version = msg->version;
68 	args.data_size = msg->outsize;
69 
70 	/* Initialize checksum */
71 	csum = msg->command + args.flags +
72 		args.command_version + args.data_size;
73 
74 	/* Copy data and update checksum */
75 	for (i = 0; i < msg->outsize; i++) {
76 		outb(msg->outdata[i], EC_LPC_ADDR_HOST_PARAM + i);
77 		csum += msg->outdata[i];
78 	}
79 
80 	/* Finalize checksum and write args */
81 	args.checksum = csum & 0xFF;
82 	outb(args.flags, EC_LPC_ADDR_HOST_ARGS);
83 	outb(args.command_version, EC_LPC_ADDR_HOST_ARGS + 1);
84 	outb(args.data_size, EC_LPC_ADDR_HOST_ARGS + 2);
85 	outb(args.checksum, EC_LPC_ADDR_HOST_ARGS + 3);
86 
87 	/* Here we go */
88 	outb(msg->command, EC_LPC_ADDR_HOST_CMD);
89 
90 	if (ec_response_timed_out()) {
91 		dev_warn(ec->dev, "EC responsed timed out\n");
92 		ret = -EIO;
93 		goto done;
94 	}
95 
96 	/* Check result */
97 	msg->result = inb(EC_LPC_ADDR_HOST_DATA);
98 
99 	switch (msg->result) {
100 	case EC_RES_SUCCESS:
101 		break;
102 	case EC_RES_IN_PROGRESS:
103 		ret = -EAGAIN;
104 		dev_dbg(ec->dev, "command 0x%02x in progress\n",
105 			msg->command);
106 		goto done;
107 	default:
108 		dev_dbg(ec->dev, "command 0x%02x returned %d\n",
109 			msg->command, msg->result);
110 	}
111 
112 	/* Read back args */
113 	args.flags = inb(EC_LPC_ADDR_HOST_ARGS);
114 	args.command_version = inb(EC_LPC_ADDR_HOST_ARGS + 1);
115 	args.data_size = inb(EC_LPC_ADDR_HOST_ARGS + 2);
116 	args.checksum = inb(EC_LPC_ADDR_HOST_ARGS + 3);
117 
118 	if (args.data_size > msg->insize) {
119 		dev_err(ec->dev,
120 			"packet too long (%d bytes, expected %d)",
121 			args.data_size, msg->insize);
122 		ret = -ENOSPC;
123 		goto done;
124 	}
125 
126 	/* Start calculating response checksum */
127 	csum = msg->command + args.flags +
128 		args.command_version + args.data_size;
129 
130 	/* Read response and update checksum */
131 	for (i = 0; i < args.data_size; i++) {
132 		msg->indata[i] = inb(EC_LPC_ADDR_HOST_PARAM + i);
133 		csum += msg->indata[i];
134 	}
135 
136 	/* Verify checksum */
137 	if (args.checksum != (csum & 0xFF)) {
138 		dev_err(ec->dev,
139 			"bad packet checksum, expected %02x, got %02x\n",
140 			args.checksum, csum & 0xFF);
141 		ret = -EBADMSG;
142 		goto done;
143 	}
144 
145 	/* Return actual amount of data received */
146 	ret = args.data_size;
147 done:
148 	return ret;
149 }
150 
151 /* Returns num bytes read, or negative on error. Doesn't need locking. */
152 static int cros_ec_lpc_readmem(struct cros_ec_device *ec, unsigned int offset,
153 			       unsigned int bytes, void *dest)
154 {
155 	int i = offset;
156 	char *s = dest;
157 	int cnt = 0;
158 
159 	if (offset >= EC_MEMMAP_SIZE - bytes)
160 		return -EINVAL;
161 
162 	/* fixed length */
163 	if (bytes) {
164 		for (; cnt < bytes; i++, s++, cnt++)
165 			*s = inb(EC_LPC_ADDR_MEMMAP + i);
166 		return cnt;
167 	}
168 
169 	/* string */
170 	for (; i < EC_MEMMAP_SIZE; i++, s++) {
171 		*s = inb(EC_LPC_ADDR_MEMMAP + i);
172 		cnt++;
173 		if (!*s)
174 			break;
175 	}
176 
177 	return cnt;
178 }
179 
180 static int cros_ec_lpc_probe(struct platform_device *pdev)
181 {
182 	struct device *dev = &pdev->dev;
183 	struct cros_ec_device *ec_dev;
184 	int ret;
185 
186 	if (!devm_request_region(dev, EC_LPC_ADDR_MEMMAP, EC_MEMMAP_SIZE,
187 				 dev_name(dev))) {
188 		dev_err(dev, "couldn't reserve memmap region\n");
189 		return -EBUSY;
190 	}
191 
192 	if ((inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) != 'E') ||
193 	    (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1) != 'C')) {
194 		dev_err(dev, "EC ID not detected\n");
195 		return -ENODEV;
196 	}
197 
198 	if (!devm_request_region(dev, EC_HOST_CMD_REGION0,
199 				 EC_HOST_CMD_REGION_SIZE, dev_name(dev))) {
200 		dev_err(dev, "couldn't reserve region0\n");
201 		return -EBUSY;
202 	}
203 	if (!devm_request_region(dev, EC_HOST_CMD_REGION1,
204 				 EC_HOST_CMD_REGION_SIZE, dev_name(dev))) {
205 		dev_err(dev, "couldn't reserve region1\n");
206 		return -EBUSY;
207 	}
208 
209 	ec_dev = devm_kzalloc(dev, sizeof(*ec_dev), GFP_KERNEL);
210 	if (!ec_dev)
211 		return -ENOMEM;
212 
213 	platform_set_drvdata(pdev, ec_dev);
214 	ec_dev->dev = dev;
215 	ec_dev->ec_name = pdev->name;
216 	ec_dev->phys_name = dev_name(dev);
217 	ec_dev->parent = dev;
218 	ec_dev->cmd_xfer = cros_ec_cmd_xfer_lpc;
219 	ec_dev->cmd_readmem = cros_ec_lpc_readmem;
220 
221 	ret = cros_ec_register(ec_dev);
222 	if (ret) {
223 		dev_err(dev, "couldn't register ec_dev (%d)\n", ret);
224 		return ret;
225 	}
226 
227 	return 0;
228 }
229 
230 static int cros_ec_lpc_remove(struct platform_device *pdev)
231 {
232 	struct cros_ec_device *ec_dev;
233 
234 	ec_dev = platform_get_drvdata(pdev);
235 	cros_ec_remove(ec_dev);
236 
237 	return 0;
238 }
239 
240 static struct dmi_system_id cros_ec_lpc_dmi_table[] __initdata = {
241 	{
242 		/*
243 		 * Today all Chromebooks/boxes ship with Google_* as version and
244 		 * coreboot as bios vendor. No other systems with this
245 		 * combination are known to date.
246 		 */
247 		.matches = {
248 			DMI_MATCH(DMI_BIOS_VENDOR, "coreboot"),
249 			DMI_MATCH(DMI_BIOS_VERSION, "Google_"),
250 		},
251 	},
252 	{
253 		/* x86-link, the Chromebook Pixel. */
254 		.matches = {
255 			DMI_MATCH(DMI_SYS_VENDOR, "GOOGLE"),
256 			DMI_MATCH(DMI_PRODUCT_NAME, "Link"),
257 		},
258 	},
259 	{
260 		/* x86-peppy, the Acer C720 Chromebook. */
261 		.matches = {
262 			DMI_MATCH(DMI_SYS_VENDOR, "Acer"),
263 			DMI_MATCH(DMI_PRODUCT_NAME, "Peppy"),
264 		},
265 	},
266 	{ /* sentinel */ }
267 };
268 MODULE_DEVICE_TABLE(dmi, cros_ec_lpc_dmi_table);
269 
270 static struct platform_driver cros_ec_lpc_driver = {
271 	.driver = {
272 		.name = DRV_NAME,
273 	},
274 	.probe = cros_ec_lpc_probe,
275 	.remove = cros_ec_lpc_remove,
276 };
277 
278 static struct platform_device cros_ec_lpc_device = {
279 	.name = DRV_NAME
280 };
281 
282 static int __init cros_ec_lpc_init(void)
283 {
284 	int ret;
285 
286 	if (!dmi_check_system(cros_ec_lpc_dmi_table)) {
287 		pr_err(DRV_NAME ": unsupported system.\n");
288 		return -ENODEV;
289 	}
290 
291 	/* Register the driver */
292 	ret = platform_driver_register(&cros_ec_lpc_driver);
293 	if (ret) {
294 		pr_err(DRV_NAME ": can't register driver: %d\n", ret);
295 		return ret;
296 	}
297 
298 	/* Register the device, and it'll get hooked up automatically */
299 	ret = platform_device_register(&cros_ec_lpc_device);
300 	if (ret) {
301 		pr_err(DRV_NAME ": can't register device: %d\n", ret);
302 		platform_driver_unregister(&cros_ec_lpc_driver);
303 		return ret;
304 	}
305 
306 	return 0;
307 }
308 
309 static void __exit cros_ec_lpc_exit(void)
310 {
311 	platform_device_unregister(&cros_ec_lpc_device);
312 	platform_driver_unregister(&cros_ec_lpc_driver);
313 }
314 
315 module_init(cros_ec_lpc_init);
316 module_exit(cros_ec_lpc_exit);
317 
318 MODULE_LICENSE("GPL");
319 MODULE_DESCRIPTION("ChromeOS EC LPC driver");
320