1 /*
2  * Support for OLPC XO-1 System Control Interrupts (SCI)
3  *
4  * Copyright (C) 2010 One Laptop per Child
5  * Copyright (C) 2006 Red Hat, Inc.
6  * Copyright (C) 2006 Advanced Micro Devices, Inc.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13 
14 #include <linux/cs5535.h>
15 #include <linux/device.h>
16 #include <linux/gpio.h>
17 #include <linux/input.h>
18 #include <linux/interrupt.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm.h>
21 #include <linux/mfd/core.h>
22 #include <linux/suspend.h>
23 #include <linux/workqueue.h>
24 
25 #include <asm/io.h>
26 #include <asm/msr.h>
27 #include <asm/olpc.h>
28 
29 #define DRV_NAME	"olpc-xo1-sci"
30 #define PFX		DRV_NAME ": "
31 
32 static unsigned long acpi_base;
33 static struct input_dev *power_button_idev;
34 static struct input_dev *ebook_switch_idev;
35 static struct input_dev *lid_switch_idev;
36 
37 static int sci_irq;
38 
39 static bool lid_open;
40 static bool lid_inverted;
41 static int lid_wake_mode;
42 
43 enum lid_wake_modes {
44 	LID_WAKE_ALWAYS,
45 	LID_WAKE_OPEN,
46 	LID_WAKE_CLOSE,
47 };
48 
49 static const char * const lid_wake_mode_names[] = {
50 	[LID_WAKE_ALWAYS] = "always",
51 	[LID_WAKE_OPEN] = "open",
52 	[LID_WAKE_CLOSE] = "close",
53 };
54 
55 /* Report current ebook switch state through input layer */
56 static void send_ebook_state(void)
57 {
58 	unsigned char state;
59 
60 	if (olpc_ec_cmd(EC_READ_EB_MODE, NULL, 0, &state, 1)) {
61 		pr_err(PFX "failed to get ebook state\n");
62 		return;
63 	}
64 
65 	input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state);
66 	input_sync(ebook_switch_idev);
67 }
68 
69 static void flip_lid_inverter(void)
70 {
71 	/* gpio is high; invert so we'll get l->h event interrupt */
72 	if (lid_inverted)
73 		cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_INPUT_INVERT);
74 	else
75 		cs5535_gpio_set(OLPC_GPIO_LID, GPIO_INPUT_INVERT);
76 	lid_inverted = !lid_inverted;
77 }
78 
79 static void detect_lid_state(void)
80 {
81 	/*
82 	 * the edge detector hookup on the gpio inputs on the geode is
83 	 * odd, to say the least.  See http://dev.laptop.org/ticket/5703
84 	 * for details, but in a nutshell:  we don't use the edge
85 	 * detectors.  instead, we make use of an anomoly:  with the both
86 	 * edge detectors turned off, we still get an edge event on a
87 	 * positive edge transition.  to take advantage of this, we use the
88 	 * front-end inverter to ensure that that's the edge we're always
89 	 * going to see next.
90 	 */
91 
92 	int state;
93 
94 	state = cs5535_gpio_isset(OLPC_GPIO_LID, GPIO_READ_BACK);
95 	lid_open = !state ^ !lid_inverted; /* x ^^ y */
96 	if (!state)
97 		return;
98 
99 	flip_lid_inverter();
100 }
101 
102 /* Report current lid switch state through input layer */
103 static void send_lid_state(void)
104 {
105 	input_report_switch(lid_switch_idev, SW_LID, !lid_open);
106 	input_sync(lid_switch_idev);
107 }
108 
109 static ssize_t lid_wake_mode_show(struct device *dev,
110 				  struct device_attribute *attr, char *buf)
111 {
112 	const char *mode = lid_wake_mode_names[lid_wake_mode];
113 	return sprintf(buf, "%s\n", mode);
114 }
115 static ssize_t lid_wake_mode_set(struct device *dev,
116 				 struct device_attribute *attr,
117 				 const char *buf, size_t count)
118 {
119 	int i;
120 	for (i = 0; i < ARRAY_SIZE(lid_wake_mode_names); i++) {
121 		const char *mode = lid_wake_mode_names[i];
122 		if (strlen(mode) != count || strncasecmp(mode, buf, count))
123 			continue;
124 
125 		lid_wake_mode = i;
126 		return count;
127 	}
128 	return -EINVAL;
129 }
130 static DEVICE_ATTR(lid_wake_mode, S_IWUSR | S_IRUGO, lid_wake_mode_show,
131 		   lid_wake_mode_set);
132 
133 /*
134  * Process all items in the EC's SCI queue.
135  *
136  * This is handled in a workqueue because olpc_ec_cmd can be slow (and
137  * can even timeout).
138  *
139  * If propagate_events is false, the queue is drained without events being
140  * generated for the interrupts.
141  */
142 static void process_sci_queue(bool propagate_events)
143 {
144 	int r;
145 	u16 data;
146 
147 	do {
148 		r = olpc_ec_sci_query(&data);
149 		if (r || !data)
150 			break;
151 
152 		pr_debug(PFX "SCI 0x%x received\n", data);
153 
154 		if (data == EC_SCI_SRC_EBOOK && propagate_events)
155 			send_ebook_state();
156 	} while (data);
157 
158 	if (r)
159 		pr_err(PFX "Failed to clear SCI queue");
160 }
161 
162 static void process_sci_queue_work(struct work_struct *work)
163 {
164 	process_sci_queue(true);
165 }
166 
167 static DECLARE_WORK(sci_work, process_sci_queue_work);
168 
169 static irqreturn_t xo1_sci_intr(int irq, void *dev_id)
170 {
171 	struct platform_device *pdev = dev_id;
172 	u32 sts;
173 	u32 gpe;
174 
175 	sts = inl(acpi_base + CS5536_PM1_STS);
176 	outl(sts | 0xffff, acpi_base + CS5536_PM1_STS);
177 
178 	gpe = inl(acpi_base + CS5536_PM_GPE0_STS);
179 	outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);
180 
181 	dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe);
182 
183 	if (sts & CS5536_PWRBTN_FLAG && !(sts & CS5536_WAK_FLAG)) {
184 		input_report_key(power_button_idev, KEY_POWER, 1);
185 		input_sync(power_button_idev);
186 		input_report_key(power_button_idev, KEY_POWER, 0);
187 		input_sync(power_button_idev);
188 	}
189 
190 	if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */
191 		cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
192 		schedule_work(&sci_work);
193 	}
194 
195 	cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
196 	cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
197 	detect_lid_state();
198 	send_lid_state();
199 
200 	return IRQ_HANDLED;
201 }
202 
203 static int xo1_sci_suspend(struct platform_device *pdev, pm_message_t state)
204 {
205 	if (device_may_wakeup(&power_button_idev->dev))
206 		olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN);
207 	else
208 		olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN);
209 
210 	if (device_may_wakeup(&ebook_switch_idev->dev))
211 		olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK);
212 	else
213 		olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK);
214 
215 	if (!device_may_wakeup(&lid_switch_idev->dev)) {
216 		cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
217 	} else if ((lid_open && lid_wake_mode == LID_WAKE_OPEN) ||
218 		   (!lid_open && lid_wake_mode == LID_WAKE_CLOSE)) {
219 		flip_lid_inverter();
220 
221 		/* we may have just caused an event */
222 		cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
223 		cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
224 
225 		cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
226 	}
227 
228 	return 0;
229 }
230 
231 static int xo1_sci_resume(struct platform_device *pdev)
232 {
233 	/*
234 	 * We don't know what may have happened while we were asleep.
235 	 * Reestablish our lid setup so we're sure to catch all transitions.
236 	 */
237 	detect_lid_state();
238 	send_lid_state();
239 	cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
240 
241 	/* Enable all EC events */
242 	olpc_ec_mask_write(EC_SCI_SRC_ALL);
243 	return 0;
244 }
245 
246 static int __devinit setup_sci_interrupt(struct platform_device *pdev)
247 {
248 	u32 lo, hi;
249 	u32 sts;
250 	int r;
251 
252 	rdmsr(0x51400020, lo, hi);
253 	sci_irq = (lo >> 20) & 15;
254 
255 	if (sci_irq) {
256 		dev_info(&pdev->dev, "SCI is mapped to IRQ %d\n", sci_irq);
257 	} else {
258 		/* Zero means masked */
259 		dev_info(&pdev->dev, "SCI unmapped. Mapping to IRQ 3\n");
260 		sci_irq = 3;
261 		lo |= 0x00300000;
262 		wrmsrl(0x51400020, lo);
263 	}
264 
265 	/* Select level triggered in PIC */
266 	if (sci_irq < 8) {
267 		lo = inb(CS5536_PIC_INT_SEL1);
268 		lo |= 1 << sci_irq;
269 		outb(lo, CS5536_PIC_INT_SEL1);
270 	} else {
271 		lo = inb(CS5536_PIC_INT_SEL2);
272 		lo |= 1 << (sci_irq - 8);
273 		outb(lo, CS5536_PIC_INT_SEL2);
274 	}
275 
276 	/* Enable SCI from power button, and clear pending interrupts */
277 	sts = inl(acpi_base + CS5536_PM1_STS);
278 	outl((CS5536_PM_PWRBTN << 16) | 0xffff, acpi_base + CS5536_PM1_STS);
279 
280 	r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev);
281 	if (r)
282 		dev_err(&pdev->dev, "can't request interrupt\n");
283 
284 	return r;
285 }
286 
287 static int __devinit setup_ec_sci(void)
288 {
289 	int r;
290 
291 	r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI");
292 	if (r)
293 		return r;
294 
295 	gpio_direction_input(OLPC_GPIO_ECSCI);
296 
297 	/* Clear pending EC SCI events */
298 	cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
299 	cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS);
300 
301 	/*
302 	 * Enable EC SCI events, and map them to both a PME and the SCI
303 	 * interrupt.
304 	 *
305 	 * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can
306 	 * be mapped to regular interrupts *or* Geode-specific Power
307 	 * Management Events (PMEs) - events that bring the system out of
308 	 * suspend. In this case, we want both of those things - the system
309 	 * wakeup, *and* the ability to get an interrupt when an event occurs.
310 	 *
311 	 * To achieve this, we map the GPIO to a PME, and then we use one
312 	 * of the many generic knobs on the CS5535 PIC to additionally map the
313 	 * PME to the regular SCI interrupt line.
314 	 */
315 	cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE);
316 
317 	/* Set the SCI to cause a PME event on group 7 */
318 	cs5535_gpio_setup_event(OLPC_GPIO_ECSCI, 7, 1);
319 
320 	/* And have group 7 also fire the SCI interrupt */
321 	cs5535_pic_unreqz_select_high(7, sci_irq);
322 
323 	return 0;
324 }
325 
326 static void free_ec_sci(void)
327 {
328 	gpio_free(OLPC_GPIO_ECSCI);
329 }
330 
331 static int __devinit setup_lid_events(void)
332 {
333 	int r;
334 
335 	r = gpio_request(OLPC_GPIO_LID, "OLPC-LID");
336 	if (r)
337 		return r;
338 
339 	gpio_direction_input(OLPC_GPIO_LID);
340 
341 	cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_INPUT_INVERT);
342 	lid_inverted = 0;
343 
344 	/* Clear edge detection and event enable for now */
345 	cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
346 	cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
347 	cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
348 	cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
349 	cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
350 
351 	/* Set the LID to cause an PME event on group 6 */
352 	cs5535_gpio_setup_event(OLPC_GPIO_LID, 6, 1);
353 
354 	/* Set PME group 6 to fire the SCI interrupt */
355 	cs5535_gpio_set_irq(6, sci_irq);
356 
357 	/* Enable the event */
358 	cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
359 
360 	return 0;
361 }
362 
363 static void free_lid_events(void)
364 {
365 	gpio_free(OLPC_GPIO_LID);
366 }
367 
368 static int __devinit setup_power_button(struct platform_device *pdev)
369 {
370 	int r;
371 
372 	power_button_idev = input_allocate_device();
373 	if (!power_button_idev)
374 		return -ENOMEM;
375 
376 	power_button_idev->name = "Power Button";
377 	power_button_idev->phys = DRV_NAME "/input0";
378 	set_bit(EV_KEY, power_button_idev->evbit);
379 	set_bit(KEY_POWER, power_button_idev->keybit);
380 
381 	power_button_idev->dev.parent = &pdev->dev;
382 	device_init_wakeup(&power_button_idev->dev, 1);
383 
384 	r = input_register_device(power_button_idev);
385 	if (r) {
386 		dev_err(&pdev->dev, "failed to register power button: %d\n", r);
387 		input_free_device(power_button_idev);
388 	}
389 
390 	return r;
391 }
392 
393 static void free_power_button(void)
394 {
395 	input_unregister_device(power_button_idev);
396 	input_free_device(power_button_idev);
397 }
398 
399 static int __devinit setup_ebook_switch(struct platform_device *pdev)
400 {
401 	int r;
402 
403 	ebook_switch_idev = input_allocate_device();
404 	if (!ebook_switch_idev)
405 		return -ENOMEM;
406 
407 	ebook_switch_idev->name = "EBook Switch";
408 	ebook_switch_idev->phys = DRV_NAME "/input1";
409 	set_bit(EV_SW, ebook_switch_idev->evbit);
410 	set_bit(SW_TABLET_MODE, ebook_switch_idev->swbit);
411 
412 	ebook_switch_idev->dev.parent = &pdev->dev;
413 	device_set_wakeup_capable(&ebook_switch_idev->dev, true);
414 
415 	r = input_register_device(ebook_switch_idev);
416 	if (r) {
417 		dev_err(&pdev->dev, "failed to register ebook switch: %d\n", r);
418 		input_free_device(ebook_switch_idev);
419 	}
420 
421 	return r;
422 }
423 
424 static void free_ebook_switch(void)
425 {
426 	input_unregister_device(ebook_switch_idev);
427 	input_free_device(ebook_switch_idev);
428 }
429 
430 static int __devinit setup_lid_switch(struct platform_device *pdev)
431 {
432 	int r;
433 
434 	lid_switch_idev = input_allocate_device();
435 	if (!lid_switch_idev)
436 		return -ENOMEM;
437 
438 	lid_switch_idev->name = "Lid Switch";
439 	lid_switch_idev->phys = DRV_NAME "/input2";
440 	set_bit(EV_SW, lid_switch_idev->evbit);
441 	set_bit(SW_LID, lid_switch_idev->swbit);
442 
443 	lid_switch_idev->dev.parent = &pdev->dev;
444 	device_set_wakeup_capable(&lid_switch_idev->dev, true);
445 
446 	r = input_register_device(lid_switch_idev);
447 	if (r) {
448 		dev_err(&pdev->dev, "failed to register lid switch: %d\n", r);
449 		goto err_register;
450 	}
451 
452 	r = device_create_file(&lid_switch_idev->dev, &dev_attr_lid_wake_mode);
453 	if (r) {
454 		dev_err(&pdev->dev, "failed to create wake mode attr: %d\n", r);
455 		goto err_create_attr;
456 	}
457 
458 	return 0;
459 
460 err_create_attr:
461 	input_unregister_device(lid_switch_idev);
462 err_register:
463 	input_free_device(lid_switch_idev);
464 	return r;
465 }
466 
467 static void free_lid_switch(void)
468 {
469 	device_remove_file(&lid_switch_idev->dev, &dev_attr_lid_wake_mode);
470 	input_unregister_device(lid_switch_idev);
471 	input_free_device(lid_switch_idev);
472 }
473 
474 static int __devinit xo1_sci_probe(struct platform_device *pdev)
475 {
476 	struct resource *res;
477 	int r;
478 
479 	/* don't run on non-XOs */
480 	if (!machine_is_olpc())
481 		return -ENODEV;
482 
483 	r = mfd_cell_enable(pdev);
484 	if (r)
485 		return r;
486 
487 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
488 	if (!res) {
489 		dev_err(&pdev->dev, "can't fetch device resource info\n");
490 		return -EIO;
491 	}
492 	acpi_base = res->start;
493 
494 	r = setup_power_button(pdev);
495 	if (r)
496 		return r;
497 
498 	r = setup_ebook_switch(pdev);
499 	if (r)
500 		goto err_ebook;
501 
502 	r = setup_lid_switch(pdev);
503 	if (r)
504 		goto err_lid;
505 
506 	r = setup_lid_events();
507 	if (r)
508 		goto err_lidevt;
509 
510 	r = setup_ec_sci();
511 	if (r)
512 		goto err_ecsci;
513 
514 	/* Enable PME generation for EC-generated events */
515 	outl(CS5536_GPIOM6_PME_EN | CS5536_GPIOM7_PME_EN,
516 		acpi_base + CS5536_PM_GPE0_EN);
517 
518 	/* Clear pending events */
519 	outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);
520 	process_sci_queue(false);
521 
522 	/* Initial sync */
523 	send_ebook_state();
524 	detect_lid_state();
525 	send_lid_state();
526 
527 	r = setup_sci_interrupt(pdev);
528 	if (r)
529 		goto err_sci;
530 
531 	/* Enable all EC events */
532 	olpc_ec_mask_write(EC_SCI_SRC_ALL);
533 
534 	return r;
535 
536 err_sci:
537 	free_ec_sci();
538 err_ecsci:
539 	free_lid_events();
540 err_lidevt:
541 	free_lid_switch();
542 err_lid:
543 	free_ebook_switch();
544 err_ebook:
545 	free_power_button();
546 	return r;
547 }
548 
549 static int __devexit xo1_sci_remove(struct platform_device *pdev)
550 {
551 	mfd_cell_disable(pdev);
552 	free_irq(sci_irq, pdev);
553 	cancel_work_sync(&sci_work);
554 	free_ec_sci();
555 	free_lid_events();
556 	free_lid_switch();
557 	free_ebook_switch();
558 	free_power_button();
559 	acpi_base = 0;
560 	return 0;
561 }
562 
563 static struct platform_driver xo1_sci_driver = {
564 	.driver = {
565 		.name = "olpc-xo1-sci-acpi",
566 	},
567 	.probe = xo1_sci_probe,
568 	.remove = __devexit_p(xo1_sci_remove),
569 	.suspend = xo1_sci_suspend,
570 	.resume = xo1_sci_resume,
571 };
572 
573 static int __init xo1_sci_init(void)
574 {
575 	return platform_driver_register(&xo1_sci_driver);
576 }
577 arch_initcall(xo1_sci_init);
578