2 * Support for OLPC XO-1 System Control Interrupts (SCI)
4 * Copyright (C) 2010 One Laptop per Child
5 * Copyright (C) 2006 Red Hat, Inc.
6 * Copyright (C) 2006 Advanced Micro Devices, Inc.
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.
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>
21 #include <linux/mfd/core.h>
22 #include <linux/power_supply.h>
23 #include <linux/suspend.h>
24 #include <linux/workqueue.h>
30 #define DRV_NAME "olpc-xo1-sci"
31 #define PFX DRV_NAME ": "
33 static unsigned long acpi_base
;
34 static struct input_dev
*power_button_idev
;
35 static struct input_dev
*ebook_switch_idev
;
36 static struct input_dev
*lid_switch_idev
;
41 static bool lid_inverted
;
42 static int lid_wake_mode
;
50 static const char * const lid_wake_mode_names
[] = {
51 [LID_WAKE_ALWAYS
] = "always",
52 [LID_WAKE_OPEN
] = "open",
53 [LID_WAKE_CLOSE
] = "close",
56 static void battery_status_changed(void)
58 struct power_supply
*psy
= power_supply_get_by_name("olpc-battery");
61 power_supply_changed(psy
);
66 static void ac_status_changed(void)
68 struct power_supply
*psy
= power_supply_get_by_name("olpc-ac");
71 power_supply_changed(psy
);
76 /* Report current ebook switch state through input layer */
77 static void send_ebook_state(void)
81 if (olpc_ec_cmd(EC_READ_EB_MODE
, NULL
, 0, &state
, 1)) {
82 pr_err(PFX
"failed to get ebook state\n");
86 input_report_switch(ebook_switch_idev
, SW_TABLET_MODE
, state
);
87 input_sync(ebook_switch_idev
);
90 static void flip_lid_inverter(void)
92 /* gpio is high; invert so we'll get l->h event interrupt */
94 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_INPUT_INVERT
);
96 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_INPUT_INVERT
);
97 lid_inverted
= !lid_inverted
;
100 static void detect_lid_state(void)
103 * the edge detector hookup on the gpio inputs on the geode is
104 * odd, to say the least. See http://dev.laptop.org/ticket/5703
105 * for details, but in a nutshell: we don't use the edge
106 * detectors. instead, we make use of an anomoly: with the both
107 * edge detectors turned off, we still get an edge event on a
108 * positive edge transition. to take advantage of this, we use the
109 * front-end inverter to ensure that that's the edge we're always
115 state
= cs5535_gpio_isset(OLPC_GPIO_LID
, GPIO_READ_BACK
);
116 lid_open
= !state
^ !lid_inverted
; /* x ^^ y */
123 /* Report current lid switch state through input layer */
124 static void send_lid_state(void)
126 input_report_switch(lid_switch_idev
, SW_LID
, !lid_open
);
127 input_sync(lid_switch_idev
);
130 static ssize_t
lid_wake_mode_show(struct device
*dev
,
131 struct device_attribute
*attr
, char *buf
)
133 const char *mode
= lid_wake_mode_names
[lid_wake_mode
];
134 return sprintf(buf
, "%s\n", mode
);
136 static ssize_t
lid_wake_mode_set(struct device
*dev
,
137 struct device_attribute
*attr
,
138 const char *buf
, size_t count
)
141 for (i
= 0; i
< ARRAY_SIZE(lid_wake_mode_names
); i
++) {
142 const char *mode
= lid_wake_mode_names
[i
];
143 if (strlen(mode
) != count
|| strncasecmp(mode
, buf
, count
))
151 static DEVICE_ATTR(lid_wake_mode
, S_IWUSR
| S_IRUGO
, lid_wake_mode_show
,
155 * Process all items in the EC's SCI queue.
157 * This is handled in a workqueue because olpc_ec_cmd can be slow (and
160 * If propagate_events is false, the queue is drained without events being
161 * generated for the interrupts.
163 static void process_sci_queue(bool propagate_events
)
169 r
= olpc_ec_sci_query(&data
);
173 pr_debug(PFX
"SCI 0x%x received\n", data
);
176 case EC_SCI_SRC_BATERR
:
177 case EC_SCI_SRC_BATSOC
:
178 case EC_SCI_SRC_BATTERY
:
179 case EC_SCI_SRC_BATCRIT
:
180 battery_status_changed();
182 case EC_SCI_SRC_ACPWR
:
187 if (data
== EC_SCI_SRC_EBOOK
&& propagate_events
)
192 pr_err(PFX
"Failed to clear SCI queue");
195 static void process_sci_queue_work(struct work_struct
*work
)
197 process_sci_queue(true);
200 static DECLARE_WORK(sci_work
, process_sci_queue_work
);
202 static irqreturn_t
xo1_sci_intr(int irq
, void *dev_id
)
204 struct platform_device
*pdev
= dev_id
;
208 sts
= inl(acpi_base
+ CS5536_PM1_STS
);
209 outl(sts
| 0xffff, acpi_base
+ CS5536_PM1_STS
);
211 gpe
= inl(acpi_base
+ CS5536_PM_GPE0_STS
);
212 outl(0xffffffff, acpi_base
+ CS5536_PM_GPE0_STS
);
214 dev_dbg(&pdev
->dev
, "sts %x gpe %x\n", sts
, gpe
);
216 if (sts
& CS5536_PWRBTN_FLAG
&& !(sts
& CS5536_WAK_FLAG
)) {
217 input_report_key(power_button_idev
, KEY_POWER
, 1);
218 input_sync(power_button_idev
);
219 input_report_key(power_button_idev
, KEY_POWER
, 0);
220 input_sync(power_button_idev
);
223 if (gpe
& CS5536_GPIOM7_PME_FLAG
) { /* EC GPIO */
224 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_NEGATIVE_EDGE_STS
);
225 schedule_work(&sci_work
);
228 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
229 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
236 static int xo1_sci_suspend(struct platform_device
*pdev
, pm_message_t state
)
238 if (device_may_wakeup(&power_button_idev
->dev
))
239 olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN
);
241 olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN
);
243 if (device_may_wakeup(&ebook_switch_idev
->dev
))
244 olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK
);
246 olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK
);
248 if (!device_may_wakeup(&lid_switch_idev
->dev
)) {
249 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
250 } else if ((lid_open
&& lid_wake_mode
== LID_WAKE_OPEN
) ||
251 (!lid_open
&& lid_wake_mode
== LID_WAKE_CLOSE
)) {
254 /* we may have just caused an event */
255 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
256 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
258 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
264 static int xo1_sci_resume(struct platform_device
*pdev
)
267 * We don't know what may have happened while we were asleep.
268 * Reestablish our lid setup so we're sure to catch all transitions.
272 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
274 /* Enable all EC events */
275 olpc_ec_mask_write(EC_SCI_SRC_ALL
);
277 /* Power/battery status might have changed too */
278 battery_status_changed();
283 static int __devinit
setup_sci_interrupt(struct platform_device
*pdev
)
289 rdmsr(0x51400020, lo
, hi
);
290 sci_irq
= (lo
>> 20) & 15;
293 dev_info(&pdev
->dev
, "SCI is mapped to IRQ %d\n", sci_irq
);
295 /* Zero means masked */
296 dev_info(&pdev
->dev
, "SCI unmapped. Mapping to IRQ 3\n");
299 wrmsrl(0x51400020, lo
);
302 /* Select level triggered in PIC */
304 lo
= inb(CS5536_PIC_INT_SEL1
);
306 outb(lo
, CS5536_PIC_INT_SEL1
);
308 lo
= inb(CS5536_PIC_INT_SEL2
);
309 lo
|= 1 << (sci_irq
- 8);
310 outb(lo
, CS5536_PIC_INT_SEL2
);
313 /* Enable SCI from power button, and clear pending interrupts */
314 sts
= inl(acpi_base
+ CS5536_PM1_STS
);
315 outl((CS5536_PM_PWRBTN
<< 16) | 0xffff, acpi_base
+ CS5536_PM1_STS
);
317 r
= request_irq(sci_irq
, xo1_sci_intr
, 0, DRV_NAME
, pdev
);
319 dev_err(&pdev
->dev
, "can't request interrupt\n");
324 static int __devinit
setup_ec_sci(void)
328 r
= gpio_request(OLPC_GPIO_ECSCI
, "OLPC-ECSCI");
332 gpio_direction_input(OLPC_GPIO_ECSCI
);
334 /* Clear pending EC SCI events */
335 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_NEGATIVE_EDGE_STS
);
336 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_POSITIVE_EDGE_STS
);
339 * Enable EC SCI events, and map them to both a PME and the SCI
342 * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can
343 * be mapped to regular interrupts *or* Geode-specific Power
344 * Management Events (PMEs) - events that bring the system out of
345 * suspend. In this case, we want both of those things - the system
346 * wakeup, *and* the ability to get an interrupt when an event occurs.
348 * To achieve this, we map the GPIO to a PME, and then we use one
349 * of the many generic knobs on the CS5535 PIC to additionally map the
350 * PME to the regular SCI interrupt line.
352 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_EVENTS_ENABLE
);
354 /* Set the SCI to cause a PME event on group 7 */
355 cs5535_gpio_setup_event(OLPC_GPIO_ECSCI
, 7, 1);
357 /* And have group 7 also fire the SCI interrupt */
358 cs5535_pic_unreqz_select_high(7, sci_irq
);
363 static void free_ec_sci(void)
365 gpio_free(OLPC_GPIO_ECSCI
);
368 static int __devinit
setup_lid_events(void)
372 r
= gpio_request(OLPC_GPIO_LID
, "OLPC-LID");
376 gpio_direction_input(OLPC_GPIO_LID
);
378 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_INPUT_INVERT
);
381 /* Clear edge detection and event enable for now */
382 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
383 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_EN
);
384 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_EN
);
385 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
386 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
388 /* Set the LID to cause an PME event on group 6 */
389 cs5535_gpio_setup_event(OLPC_GPIO_LID
, 6, 1);
391 /* Set PME group 6 to fire the SCI interrupt */
392 cs5535_gpio_set_irq(6, sci_irq
);
394 /* Enable the event */
395 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
400 static void free_lid_events(void)
402 gpio_free(OLPC_GPIO_LID
);
405 static int __devinit
setup_power_button(struct platform_device
*pdev
)
409 power_button_idev
= input_allocate_device();
410 if (!power_button_idev
)
413 power_button_idev
->name
= "Power Button";
414 power_button_idev
->phys
= DRV_NAME
"/input0";
415 set_bit(EV_KEY
, power_button_idev
->evbit
);
416 set_bit(KEY_POWER
, power_button_idev
->keybit
);
418 power_button_idev
->dev
.parent
= &pdev
->dev
;
419 device_init_wakeup(&power_button_idev
->dev
, 1);
421 r
= input_register_device(power_button_idev
);
423 dev_err(&pdev
->dev
, "failed to register power button: %d\n", r
);
424 input_free_device(power_button_idev
);
430 static void free_power_button(void)
432 input_unregister_device(power_button_idev
);
433 input_free_device(power_button_idev
);
436 static int __devinit
setup_ebook_switch(struct platform_device
*pdev
)
440 ebook_switch_idev
= input_allocate_device();
441 if (!ebook_switch_idev
)
444 ebook_switch_idev
->name
= "EBook Switch";
445 ebook_switch_idev
->phys
= DRV_NAME
"/input1";
446 set_bit(EV_SW
, ebook_switch_idev
->evbit
);
447 set_bit(SW_TABLET_MODE
, ebook_switch_idev
->swbit
);
449 ebook_switch_idev
->dev
.parent
= &pdev
->dev
;
450 device_set_wakeup_capable(&ebook_switch_idev
->dev
, true);
452 r
= input_register_device(ebook_switch_idev
);
454 dev_err(&pdev
->dev
, "failed to register ebook switch: %d\n", r
);
455 input_free_device(ebook_switch_idev
);
461 static void free_ebook_switch(void)
463 input_unregister_device(ebook_switch_idev
);
464 input_free_device(ebook_switch_idev
);
467 static int __devinit
setup_lid_switch(struct platform_device
*pdev
)
471 lid_switch_idev
= input_allocate_device();
472 if (!lid_switch_idev
)
475 lid_switch_idev
->name
= "Lid Switch";
476 lid_switch_idev
->phys
= DRV_NAME
"/input2";
477 set_bit(EV_SW
, lid_switch_idev
->evbit
);
478 set_bit(SW_LID
, lid_switch_idev
->swbit
);
480 lid_switch_idev
->dev
.parent
= &pdev
->dev
;
481 device_set_wakeup_capable(&lid_switch_idev
->dev
, true);
483 r
= input_register_device(lid_switch_idev
);
485 dev_err(&pdev
->dev
, "failed to register lid switch: %d\n", r
);
489 r
= device_create_file(&lid_switch_idev
->dev
, &dev_attr_lid_wake_mode
);
491 dev_err(&pdev
->dev
, "failed to create wake mode attr: %d\n", r
);
492 goto err_create_attr
;
498 input_unregister_device(lid_switch_idev
);
500 input_free_device(lid_switch_idev
);
504 static void free_lid_switch(void)
506 device_remove_file(&lid_switch_idev
->dev
, &dev_attr_lid_wake_mode
);
507 input_unregister_device(lid_switch_idev
);
508 input_free_device(lid_switch_idev
);
511 static int __devinit
xo1_sci_probe(struct platform_device
*pdev
)
513 struct resource
*res
;
516 /* don't run on non-XOs */
517 if (!machine_is_olpc())
520 r
= mfd_cell_enable(pdev
);
524 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
526 dev_err(&pdev
->dev
, "can't fetch device resource info\n");
529 acpi_base
= res
->start
;
531 r
= setup_power_button(pdev
);
535 r
= setup_ebook_switch(pdev
);
539 r
= setup_lid_switch(pdev
);
543 r
= setup_lid_events();
551 /* Enable PME generation for EC-generated events */
552 outl(CS5536_GPIOM6_PME_EN
| CS5536_GPIOM7_PME_EN
,
553 acpi_base
+ CS5536_PM_GPE0_EN
);
555 /* Clear pending events */
556 outl(0xffffffff, acpi_base
+ CS5536_PM_GPE0_STS
);
557 process_sci_queue(false);
564 r
= setup_sci_interrupt(pdev
);
568 /* Enable all EC events */
569 olpc_ec_mask_write(EC_SCI_SRC_ALL
);
586 static int __devexit
xo1_sci_remove(struct platform_device
*pdev
)
588 mfd_cell_disable(pdev
);
589 free_irq(sci_irq
, pdev
);
590 cancel_work_sync(&sci_work
);
600 static struct platform_driver xo1_sci_driver
= {
602 .name
= "olpc-xo1-sci-acpi",
604 .probe
= xo1_sci_probe
,
605 .remove
= __devexit_p(xo1_sci_remove
),
606 .suspend
= xo1_sci_suspend
,
607 .resume
= xo1_sci_resume
,
610 static int __init
xo1_sci_init(void)
612 return platform_driver_register(&xo1_sci_driver
);
614 arch_initcall(xo1_sci_init
);