1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Support for OLPC XO-1 System Control Interrupts (SCI)
5 * Copyright (C) 2010 One Laptop per Child
6 * Copyright (C) 2006 Red Hat, Inc.
7 * Copyright (C) 2006 Advanced Micro Devices, Inc.
10 #include <linux/cs5535.h>
11 #include <linux/device.h>
12 #include <linux/gpio.h>
13 #include <linux/input.h>
14 #include <linux/interrupt.h>
15 #include <linux/platform_device.h>
17 #include <linux/pm_wakeup.h>
18 #include <linux/power_supply.h>
19 #include <linux/suspend.h>
20 #include <linux/workqueue.h>
21 #include <linux/olpc-ec.h>
27 #define DRV_NAME "olpc-xo1-sci"
28 #define PFX DRV_NAME ": "
30 static unsigned long acpi_base
;
31 static struct input_dev
*power_button_idev
;
32 static struct input_dev
*ebook_switch_idev
;
33 static struct input_dev
*lid_switch_idev
;
38 static bool lid_inverted
;
39 static int lid_wake_mode
;
47 static const char * const lid_wake_mode_names
[] = {
48 [LID_WAKE_ALWAYS
] = "always",
49 [LID_WAKE_OPEN
] = "open",
50 [LID_WAKE_CLOSE
] = "close",
53 static void battery_status_changed(void)
55 struct power_supply
*psy
= power_supply_get_by_name("olpc-battery");
58 power_supply_changed(psy
);
59 power_supply_put(psy
);
63 static void ac_status_changed(void)
65 struct power_supply
*psy
= power_supply_get_by_name("olpc-ac");
68 power_supply_changed(psy
);
69 power_supply_put(psy
);
73 /* Report current ebook switch state through input layer */
74 static void send_ebook_state(void)
78 if (olpc_ec_cmd(EC_READ_EB_MODE
, NULL
, 0, &state
, 1)) {
79 pr_err(PFX
"failed to get ebook state\n");
83 if (!!test_bit(SW_TABLET_MODE
, ebook_switch_idev
->sw
) == state
)
84 return; /* Nothing new to report. */
86 input_report_switch(ebook_switch_idev
, SW_TABLET_MODE
, state
);
87 input_sync(ebook_switch_idev
);
88 pm_wakeup_event(&ebook_switch_idev
->dev
, 0);
91 static void flip_lid_inverter(void)
93 /* gpio is high; invert so we'll get l->h event interrupt */
95 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_INPUT_INVERT
);
97 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_INPUT_INVERT
);
98 lid_inverted
= !lid_inverted
;
101 static void detect_lid_state(void)
104 * the edge detector hookup on the gpio inputs on the geode is
105 * odd, to say the least. See http://dev.laptop.org/ticket/5703
106 * for details, but in a nutshell: we don't use the edge
107 * detectors. instead, we make use of an anomaly: with the both
108 * edge detectors turned off, we still get an edge event on a
109 * positive edge transition. to take advantage of this, we use the
110 * front-end inverter to ensure that that's the edge we're always
116 state
= cs5535_gpio_isset(OLPC_GPIO_LID
, GPIO_READ_BACK
);
117 lid_open
= !state
^ !lid_inverted
; /* x ^^ y */
124 /* Report current lid switch state through input layer */
125 static void send_lid_state(void)
127 if (!!test_bit(SW_LID
, lid_switch_idev
->sw
) == !lid_open
)
128 return; /* Nothing new to report. */
130 input_report_switch(lid_switch_idev
, SW_LID
, !lid_open
);
131 input_sync(lid_switch_idev
);
132 pm_wakeup_event(&lid_switch_idev
->dev
, 0);
135 static ssize_t
lid_wake_mode_show(struct device
*dev
,
136 struct device_attribute
*attr
, char *buf
)
138 const char *mode
= lid_wake_mode_names
[lid_wake_mode
];
139 return sprintf(buf
, "%s\n", mode
);
141 static ssize_t
lid_wake_mode_set(struct device
*dev
,
142 struct device_attribute
*attr
,
143 const char *buf
, size_t count
)
146 for (i
= 0; i
< ARRAY_SIZE(lid_wake_mode_names
); i
++) {
147 const char *mode
= lid_wake_mode_names
[i
];
148 if (strlen(mode
) != count
|| strncasecmp(mode
, buf
, count
))
156 static DEVICE_ATTR(lid_wake_mode
, S_IWUSR
| S_IRUGO
, lid_wake_mode_show
,
159 static struct attribute
*lid_attrs
[] = {
160 &dev_attr_lid_wake_mode
.attr
,
163 ATTRIBUTE_GROUPS(lid
);
166 * Process all items in the EC's SCI queue.
168 * This is handled in a workqueue because olpc_ec_cmd can be slow (and
171 * If propagate_events is false, the queue is drained without events being
172 * generated for the interrupts.
174 static void process_sci_queue(bool propagate_events
)
180 r
= olpc_ec_sci_query(&data
);
184 pr_debug(PFX
"SCI 0x%x received\n", data
);
187 case EC_SCI_SRC_BATERR
:
188 case EC_SCI_SRC_BATSOC
:
189 case EC_SCI_SRC_BATTERY
:
190 case EC_SCI_SRC_BATCRIT
:
191 battery_status_changed();
193 case EC_SCI_SRC_ACPWR
:
198 if (data
== EC_SCI_SRC_EBOOK
&& propagate_events
)
203 pr_err(PFX
"Failed to clear SCI queue");
206 static void process_sci_queue_work(struct work_struct
*work
)
208 process_sci_queue(true);
211 static DECLARE_WORK(sci_work
, process_sci_queue_work
);
213 static irqreturn_t
xo1_sci_intr(int irq
, void *dev_id
)
215 struct platform_device
*pdev
= dev_id
;
219 sts
= inl(acpi_base
+ CS5536_PM1_STS
);
220 outl(sts
| 0xffff, acpi_base
+ CS5536_PM1_STS
);
222 gpe
= inl(acpi_base
+ CS5536_PM_GPE0_STS
);
223 outl(0xffffffff, acpi_base
+ CS5536_PM_GPE0_STS
);
225 dev_dbg(&pdev
->dev
, "sts %x gpe %x\n", sts
, gpe
);
227 if (sts
& CS5536_PWRBTN_FLAG
) {
228 if (!(sts
& CS5536_WAK_FLAG
)) {
229 /* Only report power button input when it was pressed
230 * during regular operation (as opposed to when it
231 * was used to wake the system). */
232 input_report_key(power_button_idev
, KEY_POWER
, 1);
233 input_sync(power_button_idev
);
234 input_report_key(power_button_idev
, KEY_POWER
, 0);
235 input_sync(power_button_idev
);
237 /* Report the wakeup event in all cases. */
238 pm_wakeup_event(&power_button_idev
->dev
, 0);
241 if ((sts
& (CS5536_RTC_FLAG
| CS5536_WAK_FLAG
)) ==
242 (CS5536_RTC_FLAG
| CS5536_WAK_FLAG
)) {
243 /* When the system is woken by the RTC alarm, report the
244 * event on the rtc device. */
245 struct device
*rtc
= bus_find_device_by_name(
246 &platform_bus_type
, NULL
, "rtc_cmos");
248 pm_wakeup_event(rtc
, 0);
253 if (gpe
& CS5536_GPIOM7_PME_FLAG
) { /* EC GPIO */
254 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_NEGATIVE_EDGE_STS
);
255 schedule_work(&sci_work
);
258 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
259 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
266 static int xo1_sci_suspend(struct platform_device
*pdev
, pm_message_t state
)
268 if (device_may_wakeup(&power_button_idev
->dev
))
269 olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN
);
271 olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN
);
273 if (device_may_wakeup(&ebook_switch_idev
->dev
))
274 olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK
);
276 olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK
);
278 if (!device_may_wakeup(&lid_switch_idev
->dev
)) {
279 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
280 } else if ((lid_open
&& lid_wake_mode
== LID_WAKE_OPEN
) ||
281 (!lid_open
&& lid_wake_mode
== LID_WAKE_CLOSE
)) {
284 /* we may have just caused an event */
285 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
286 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
288 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
294 static int xo1_sci_resume(struct platform_device
*pdev
)
297 * We don't know what may have happened while we were asleep.
298 * Reestablish our lid setup so we're sure to catch all transitions.
302 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
304 /* Enable all EC events */
305 olpc_ec_mask_write(EC_SCI_SRC_ALL
);
307 /* Power/battery status might have changed too */
308 battery_status_changed();
313 static int setup_sci_interrupt(struct platform_device
*pdev
)
319 rdmsr(0x51400020, lo
, hi
);
320 sci_irq
= (lo
>> 20) & 15;
323 dev_info(&pdev
->dev
, "SCI is mapped to IRQ %d\n", sci_irq
);
325 /* Zero means masked */
326 dev_info(&pdev
->dev
, "SCI unmapped. Mapping to IRQ 3\n");
329 wrmsrl(0x51400020, lo
);
332 /* Select level triggered in PIC */
334 lo
= inb(CS5536_PIC_INT_SEL1
);
336 outb(lo
, CS5536_PIC_INT_SEL1
);
338 lo
= inb(CS5536_PIC_INT_SEL2
);
339 lo
|= 1 << (sci_irq
- 8);
340 outb(lo
, CS5536_PIC_INT_SEL2
);
343 /* Enable interesting SCI events, and clear pending interrupts */
344 sts
= inl(acpi_base
+ CS5536_PM1_STS
);
345 outl(((CS5536_PM_PWRBTN
| CS5536_PM_RTC
) << 16) | 0xffff,
346 acpi_base
+ CS5536_PM1_STS
);
348 r
= request_irq(sci_irq
, xo1_sci_intr
, 0, DRV_NAME
, pdev
);
350 dev_err(&pdev
->dev
, "can't request interrupt\n");
355 static int setup_ec_sci(void)
359 r
= gpio_request(OLPC_GPIO_ECSCI
, "OLPC-ECSCI");
363 gpio_direction_input(OLPC_GPIO_ECSCI
);
365 /* Clear pending EC SCI events */
366 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_NEGATIVE_EDGE_STS
);
367 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_POSITIVE_EDGE_STS
);
370 * Enable EC SCI events, and map them to both a PME and the SCI
373 * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can
374 * be mapped to regular interrupts *or* Geode-specific Power
375 * Management Events (PMEs) - events that bring the system out of
376 * suspend. In this case, we want both of those things - the system
377 * wakeup, *and* the ability to get an interrupt when an event occurs.
379 * To achieve this, we map the GPIO to a PME, and then we use one
380 * of the many generic knobs on the CS5535 PIC to additionally map the
381 * PME to the regular SCI interrupt line.
383 cs5535_gpio_set(OLPC_GPIO_ECSCI
, GPIO_EVENTS_ENABLE
);
385 /* Set the SCI to cause a PME event on group 7 */
386 cs5535_gpio_setup_event(OLPC_GPIO_ECSCI
, 7, 1);
388 /* And have group 7 also fire the SCI interrupt */
389 cs5535_pic_unreqz_select_high(7, sci_irq
);
394 static void free_ec_sci(void)
396 gpio_free(OLPC_GPIO_ECSCI
);
399 static int setup_lid_events(void)
403 r
= gpio_request(OLPC_GPIO_LID
, "OLPC-LID");
407 gpio_direction_input(OLPC_GPIO_LID
);
409 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_INPUT_INVERT
);
412 /* Clear edge detection and event enable for now */
413 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
414 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_EN
);
415 cs5535_gpio_clear(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_EN
);
416 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_NEGATIVE_EDGE_STS
);
417 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_POSITIVE_EDGE_STS
);
419 /* Set the LID to cause an PME event on group 6 */
420 cs5535_gpio_setup_event(OLPC_GPIO_LID
, 6, 1);
422 /* Set PME group 6 to fire the SCI interrupt */
423 cs5535_gpio_set_irq(6, sci_irq
);
425 /* Enable the event */
426 cs5535_gpio_set(OLPC_GPIO_LID
, GPIO_EVENTS_ENABLE
);
431 static void free_lid_events(void)
433 gpio_free(OLPC_GPIO_LID
);
436 static int setup_power_button(struct platform_device
*pdev
)
440 power_button_idev
= input_allocate_device();
441 if (!power_button_idev
)
444 power_button_idev
->name
= "Power Button";
445 power_button_idev
->phys
= DRV_NAME
"/input0";
446 set_bit(EV_KEY
, power_button_idev
->evbit
);
447 set_bit(KEY_POWER
, power_button_idev
->keybit
);
449 power_button_idev
->dev
.parent
= &pdev
->dev
;
450 device_init_wakeup(&power_button_idev
->dev
, 1);
452 r
= input_register_device(power_button_idev
);
454 dev_err(&pdev
->dev
, "failed to register power button: %d\n", r
);
455 input_free_device(power_button_idev
);
461 static void free_power_button(void)
463 input_unregister_device(power_button_idev
);
466 static int setup_ebook_switch(struct platform_device
*pdev
)
470 ebook_switch_idev
= input_allocate_device();
471 if (!ebook_switch_idev
)
474 ebook_switch_idev
->name
= "EBook Switch";
475 ebook_switch_idev
->phys
= DRV_NAME
"/input1";
476 set_bit(EV_SW
, ebook_switch_idev
->evbit
);
477 set_bit(SW_TABLET_MODE
, ebook_switch_idev
->swbit
);
479 ebook_switch_idev
->dev
.parent
= &pdev
->dev
;
480 device_set_wakeup_capable(&ebook_switch_idev
->dev
, true);
482 r
= input_register_device(ebook_switch_idev
);
484 dev_err(&pdev
->dev
, "failed to register ebook switch: %d\n", r
);
485 input_free_device(ebook_switch_idev
);
491 static void free_ebook_switch(void)
493 input_unregister_device(ebook_switch_idev
);
496 static int setup_lid_switch(struct platform_device
*pdev
)
500 lid_switch_idev
= input_allocate_device();
501 if (!lid_switch_idev
)
504 lid_switch_idev
->name
= "Lid Switch";
505 lid_switch_idev
->phys
= DRV_NAME
"/input2";
506 set_bit(EV_SW
, lid_switch_idev
->evbit
);
507 set_bit(SW_LID
, lid_switch_idev
->swbit
);
509 lid_switch_idev
->dev
.parent
= &pdev
->dev
;
510 device_set_wakeup_capable(&lid_switch_idev
->dev
, true);
512 r
= input_register_device(lid_switch_idev
);
514 dev_err(&pdev
->dev
, "failed to register lid switch: %d\n", r
);
521 input_free_device(lid_switch_idev
);
525 static void free_lid_switch(void)
527 input_unregister_device(lid_switch_idev
);
530 static int xo1_sci_probe(struct platform_device
*pdev
)
532 struct resource
*res
;
535 /* don't run on non-XOs */
536 if (!machine_is_olpc())
539 res
= platform_get_resource(pdev
, IORESOURCE_IO
, 0);
541 dev_err(&pdev
->dev
, "can't fetch device resource info\n");
544 acpi_base
= res
->start
;
546 r
= setup_power_button(pdev
);
550 r
= setup_ebook_switch(pdev
);
554 r
= setup_lid_switch(pdev
);
558 r
= setup_lid_events();
566 /* Enable PME generation for EC-generated events */
567 outl(CS5536_GPIOM6_PME_EN
| CS5536_GPIOM7_PME_EN
,
568 acpi_base
+ CS5536_PM_GPE0_EN
);
570 /* Clear pending events */
571 outl(0xffffffff, acpi_base
+ CS5536_PM_GPE0_STS
);
572 process_sci_queue(false);
579 r
= setup_sci_interrupt(pdev
);
583 /* Enable all EC events */
584 olpc_ec_mask_write(EC_SCI_SRC_ALL
);
601 static int xo1_sci_remove(struct platform_device
*pdev
)
603 free_irq(sci_irq
, pdev
);
604 cancel_work_sync(&sci_work
);
614 static struct platform_driver xo1_sci_driver
= {
616 .name
= "olpc-xo1-sci-acpi",
617 .dev_groups
= lid_groups
,
619 .probe
= xo1_sci_probe
,
620 .remove
= xo1_sci_remove
,
621 .suspend
= xo1_sci_suspend
,
622 .resume
= xo1_sci_resume
,
625 static int __init
xo1_sci_init(void)
627 return platform_driver_register(&xo1_sci_driver
);
629 arch_initcall(xo1_sci_init
);