Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Support for OLPC XO-1 System Control Interrupts (SCI)
0004  *
0005  * Copyright (C) 2010 One Laptop per Child
0006  * Copyright (C) 2006 Red Hat, Inc.
0007  * Copyright (C) 2006 Advanced Micro Devices, Inc.
0008  */
0009 
0010 #include <linux/cs5535.h>
0011 #include <linux/device.h>
0012 #include <linux/gpio.h>
0013 #include <linux/input.h>
0014 #include <linux/interrupt.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm.h>
0017 #include <linux/pm_wakeup.h>
0018 #include <linux/power_supply.h>
0019 #include <linux/suspend.h>
0020 #include <linux/workqueue.h>
0021 #include <linux/olpc-ec.h>
0022 
0023 #include <asm/io.h>
0024 #include <asm/msr.h>
0025 #include <asm/olpc.h>
0026 
0027 #define DRV_NAME    "olpc-xo1-sci"
0028 #define PFX     DRV_NAME ": "
0029 
0030 static unsigned long acpi_base;
0031 static struct input_dev *power_button_idev;
0032 static struct input_dev *ebook_switch_idev;
0033 static struct input_dev *lid_switch_idev;
0034 
0035 static int sci_irq;
0036 
0037 static bool lid_open;
0038 static bool lid_inverted;
0039 static int lid_wake_mode;
0040 
0041 enum lid_wake_modes {
0042     LID_WAKE_ALWAYS,
0043     LID_WAKE_OPEN,
0044     LID_WAKE_CLOSE,
0045 };
0046 
0047 static const char * const lid_wake_mode_names[] = {
0048     [LID_WAKE_ALWAYS] = "always",
0049     [LID_WAKE_OPEN] = "open",
0050     [LID_WAKE_CLOSE] = "close",
0051 };
0052 
0053 static void battery_status_changed(void)
0054 {
0055     struct power_supply *psy = power_supply_get_by_name("olpc_battery");
0056 
0057     if (psy) {
0058         power_supply_changed(psy);
0059         power_supply_put(psy);
0060     }
0061 }
0062 
0063 static void ac_status_changed(void)
0064 {
0065     struct power_supply *psy = power_supply_get_by_name("olpc_ac");
0066 
0067     if (psy) {
0068         power_supply_changed(psy);
0069         power_supply_put(psy);
0070     }
0071 }
0072 
0073 /* Report current ebook switch state through input layer */
0074 static void send_ebook_state(void)
0075 {
0076     unsigned char state;
0077 
0078     if (olpc_ec_cmd(EC_READ_EB_MODE, NULL, 0, &state, 1)) {
0079         pr_err(PFX "failed to get ebook state\n");
0080         return;
0081     }
0082 
0083     if (test_bit(SW_TABLET_MODE, ebook_switch_idev->sw) == !!state)
0084         return; /* Nothing new to report. */
0085 
0086     input_report_switch(ebook_switch_idev, SW_TABLET_MODE, state);
0087     input_sync(ebook_switch_idev);
0088     pm_wakeup_event(&ebook_switch_idev->dev, 0);
0089 }
0090 
0091 static void flip_lid_inverter(void)
0092 {
0093     /* gpio is high; invert so we'll get l->h event interrupt */
0094     if (lid_inverted)
0095         cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_INPUT_INVERT);
0096     else
0097         cs5535_gpio_set(OLPC_GPIO_LID, GPIO_INPUT_INVERT);
0098     lid_inverted = !lid_inverted;
0099 }
0100 
0101 static void detect_lid_state(void)
0102 {
0103     /*
0104      * the edge detector hookup on the gpio inputs on the geode is
0105      * odd, to say the least.  See http://dev.laptop.org/ticket/5703
0106      * for details, but in a nutshell:  we don't use the edge
0107      * detectors.  instead, we make use of an anomaly:  with the both
0108      * edge detectors turned off, we still get an edge event on a
0109      * positive edge transition.  to take advantage of this, we use the
0110      * front-end inverter to ensure that that's the edge we're always
0111      * going to see next.
0112      */
0113 
0114     int state;
0115 
0116     state = cs5535_gpio_isset(OLPC_GPIO_LID, GPIO_READ_BACK);
0117     lid_open = !state ^ !lid_inverted; /* x ^^ y */
0118     if (!state)
0119         return;
0120 
0121     flip_lid_inverter();
0122 }
0123 
0124 /* Report current lid switch state through input layer */
0125 static void send_lid_state(void)
0126 {
0127     if (!!test_bit(SW_LID, lid_switch_idev->sw) == !lid_open)
0128         return; /* Nothing new to report. */
0129 
0130     input_report_switch(lid_switch_idev, SW_LID, !lid_open);
0131     input_sync(lid_switch_idev);
0132     pm_wakeup_event(&lid_switch_idev->dev, 0);
0133 }
0134 
0135 static ssize_t lid_wake_mode_show(struct device *dev,
0136                   struct device_attribute *attr, char *buf)
0137 {
0138     const char *mode = lid_wake_mode_names[lid_wake_mode];
0139     return sprintf(buf, "%s\n", mode);
0140 }
0141 static ssize_t lid_wake_mode_set(struct device *dev,
0142                  struct device_attribute *attr,
0143                  const char *buf, size_t count)
0144 {
0145     int i;
0146     for (i = 0; i < ARRAY_SIZE(lid_wake_mode_names); i++) {
0147         const char *mode = lid_wake_mode_names[i];
0148         if (strlen(mode) != count || strncasecmp(mode, buf, count))
0149             continue;
0150 
0151         lid_wake_mode = i;
0152         return count;
0153     }
0154     return -EINVAL;
0155 }
0156 static DEVICE_ATTR(lid_wake_mode, S_IWUSR | S_IRUGO, lid_wake_mode_show,
0157            lid_wake_mode_set);
0158 
0159 static struct attribute *lid_attrs[] = {
0160     &dev_attr_lid_wake_mode.attr,
0161     NULL,
0162 };
0163 ATTRIBUTE_GROUPS(lid);
0164 
0165 /*
0166  * Process all items in the EC's SCI queue.
0167  *
0168  * This is handled in a workqueue because olpc_ec_cmd can be slow (and
0169  * can even timeout).
0170  *
0171  * If propagate_events is false, the queue is drained without events being
0172  * generated for the interrupts.
0173  */
0174 static void process_sci_queue(bool propagate_events)
0175 {
0176     int r;
0177     u16 data;
0178 
0179     do {
0180         r = olpc_ec_sci_query(&data);
0181         if (r || !data)
0182             break;
0183 
0184         pr_debug(PFX "SCI 0x%x received\n", data);
0185 
0186         switch (data) {
0187         case EC_SCI_SRC_BATERR:
0188         case EC_SCI_SRC_BATSOC:
0189         case EC_SCI_SRC_BATTERY:
0190         case EC_SCI_SRC_BATCRIT:
0191             battery_status_changed();
0192             break;
0193         case EC_SCI_SRC_ACPWR:
0194             ac_status_changed();
0195             break;
0196         }
0197 
0198         if (data == EC_SCI_SRC_EBOOK && propagate_events)
0199             send_ebook_state();
0200     } while (data);
0201 
0202     if (r)
0203         pr_err(PFX "Failed to clear SCI queue");
0204 }
0205 
0206 static void process_sci_queue_work(struct work_struct *work)
0207 {
0208     process_sci_queue(true);
0209 }
0210 
0211 static DECLARE_WORK(sci_work, process_sci_queue_work);
0212 
0213 static irqreturn_t xo1_sci_intr(int irq, void *dev_id)
0214 {
0215     struct platform_device *pdev = dev_id;
0216     u32 sts;
0217     u32 gpe;
0218 
0219     sts = inl(acpi_base + CS5536_PM1_STS);
0220     outl(sts | 0xffff, acpi_base + CS5536_PM1_STS);
0221 
0222     gpe = inl(acpi_base + CS5536_PM_GPE0_STS);
0223     outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);
0224 
0225     dev_dbg(&pdev->dev, "sts %x gpe %x\n", sts, gpe);
0226 
0227     if (sts & CS5536_PWRBTN_FLAG) {
0228         if (!(sts & CS5536_WAK_FLAG)) {
0229             /* Only report power button input when it was pressed
0230              * during regular operation (as opposed to when it
0231              * was used to wake the system). */
0232             input_report_key(power_button_idev, KEY_POWER, 1);
0233             input_sync(power_button_idev);
0234             input_report_key(power_button_idev, KEY_POWER, 0);
0235             input_sync(power_button_idev);
0236         }
0237         /* Report the wakeup event in all cases. */
0238         pm_wakeup_event(&power_button_idev->dev, 0);
0239     }
0240 
0241     if ((sts & (CS5536_RTC_FLAG | CS5536_WAK_FLAG)) ==
0242             (CS5536_RTC_FLAG | CS5536_WAK_FLAG)) {
0243         /* When the system is woken by the RTC alarm, report the
0244          * event on the rtc device. */
0245         struct device *rtc = bus_find_device_by_name(
0246             &platform_bus_type, NULL, "rtc_cmos");
0247         if (rtc) {
0248             pm_wakeup_event(rtc, 0);
0249             put_device(rtc);
0250         }
0251     }
0252 
0253     if (gpe & CS5536_GPIOM7_PME_FLAG) { /* EC GPIO */
0254         cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
0255         schedule_work(&sci_work);
0256     }
0257 
0258     cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
0259     cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
0260     detect_lid_state();
0261     send_lid_state();
0262 
0263     return IRQ_HANDLED;
0264 }
0265 
0266 static int xo1_sci_suspend(struct platform_device *pdev, pm_message_t state)
0267 {
0268     if (device_may_wakeup(&power_button_idev->dev))
0269         olpc_xo1_pm_wakeup_set(CS5536_PM_PWRBTN);
0270     else
0271         olpc_xo1_pm_wakeup_clear(CS5536_PM_PWRBTN);
0272 
0273     if (device_may_wakeup(&ebook_switch_idev->dev))
0274         olpc_ec_wakeup_set(EC_SCI_SRC_EBOOK);
0275     else
0276         olpc_ec_wakeup_clear(EC_SCI_SRC_EBOOK);
0277 
0278     if (!device_may_wakeup(&lid_switch_idev->dev)) {
0279         cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
0280     } else if ((lid_open && lid_wake_mode == LID_WAKE_OPEN) ||
0281            (!lid_open && lid_wake_mode == LID_WAKE_CLOSE)) {
0282         flip_lid_inverter();
0283 
0284         /* we may have just caused an event */
0285         cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
0286         cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
0287 
0288         cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
0289     }
0290 
0291     return 0;
0292 }
0293 
0294 static int xo1_sci_resume(struct platform_device *pdev)
0295 {
0296     /*
0297      * We don't know what may have happened while we were asleep.
0298      * Reestablish our lid setup so we're sure to catch all transitions.
0299      */
0300     detect_lid_state();
0301     send_lid_state();
0302     cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
0303 
0304     /* Enable all EC events */
0305     olpc_ec_mask_write(EC_SCI_SRC_ALL);
0306 
0307     /* Power/battery status might have changed too */
0308     battery_status_changed();
0309     ac_status_changed();
0310     return 0;
0311 }
0312 
0313 static int setup_sci_interrupt(struct platform_device *pdev)
0314 {
0315     u32 lo, hi;
0316     u32 sts;
0317     int r;
0318 
0319     rdmsr(0x51400020, lo, hi);
0320     sci_irq = (lo >> 20) & 15;
0321 
0322     if (sci_irq) {
0323         dev_info(&pdev->dev, "SCI is mapped to IRQ %d\n", sci_irq);
0324     } else {
0325         /* Zero means masked */
0326         dev_info(&pdev->dev, "SCI unmapped. Mapping to IRQ 3\n");
0327         sci_irq = 3;
0328         lo |= 0x00300000;
0329         wrmsrl(0x51400020, lo);
0330     }
0331 
0332     /* Select level triggered in PIC */
0333     if (sci_irq < 8) {
0334         lo = inb(CS5536_PIC_INT_SEL1);
0335         lo |= 1 << sci_irq;
0336         outb(lo, CS5536_PIC_INT_SEL1);
0337     } else {
0338         lo = inb(CS5536_PIC_INT_SEL2);
0339         lo |= 1 << (sci_irq - 8);
0340         outb(lo, CS5536_PIC_INT_SEL2);
0341     }
0342 
0343     /* Enable interesting SCI events, and clear pending interrupts */
0344     sts = inl(acpi_base + CS5536_PM1_STS);
0345     outl(((CS5536_PM_PWRBTN | CS5536_PM_RTC) << 16) | 0xffff,
0346          acpi_base + CS5536_PM1_STS);
0347 
0348     r = request_irq(sci_irq, xo1_sci_intr, 0, DRV_NAME, pdev);
0349     if (r)
0350         dev_err(&pdev->dev, "can't request interrupt\n");
0351 
0352     return r;
0353 }
0354 
0355 static int setup_ec_sci(void)
0356 {
0357     int r;
0358 
0359     r = gpio_request(OLPC_GPIO_ECSCI, "OLPC-ECSCI");
0360     if (r)
0361         return r;
0362 
0363     gpio_direction_input(OLPC_GPIO_ECSCI);
0364 
0365     /* Clear pending EC SCI events */
0366     cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_NEGATIVE_EDGE_STS);
0367     cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_POSITIVE_EDGE_STS);
0368 
0369     /*
0370      * Enable EC SCI events, and map them to both a PME and the SCI
0371      * interrupt.
0372      *
0373      * Ordinarily, in addition to functioning as GPIOs, Geode GPIOs can
0374      * be mapped to regular interrupts *or* Geode-specific Power
0375      * Management Events (PMEs) - events that bring the system out of
0376      * suspend. In this case, we want both of those things - the system
0377      * wakeup, *and* the ability to get an interrupt when an event occurs.
0378      *
0379      * To achieve this, we map the GPIO to a PME, and then we use one
0380      * of the many generic knobs on the CS5535 PIC to additionally map the
0381      * PME to the regular SCI interrupt line.
0382      */
0383     cs5535_gpio_set(OLPC_GPIO_ECSCI, GPIO_EVENTS_ENABLE);
0384 
0385     /* Set the SCI to cause a PME event on group 7 */
0386     cs5535_gpio_setup_event(OLPC_GPIO_ECSCI, 7, 1);
0387 
0388     /* And have group 7 also fire the SCI interrupt */
0389     cs5535_pic_unreqz_select_high(7, sci_irq);
0390 
0391     return 0;
0392 }
0393 
0394 static void free_ec_sci(void)
0395 {
0396     gpio_free(OLPC_GPIO_ECSCI);
0397 }
0398 
0399 static int setup_lid_events(void)
0400 {
0401     int r;
0402 
0403     r = gpio_request(OLPC_GPIO_LID, "OLPC-LID");
0404     if (r)
0405         return r;
0406 
0407     gpio_direction_input(OLPC_GPIO_LID);
0408 
0409     cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_INPUT_INVERT);
0410     lid_inverted = 0;
0411 
0412     /* Clear edge detection and event enable for now */
0413     cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
0414     cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_EN);
0415     cs5535_gpio_clear(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_EN);
0416     cs5535_gpio_set(OLPC_GPIO_LID, GPIO_NEGATIVE_EDGE_STS);
0417     cs5535_gpio_set(OLPC_GPIO_LID, GPIO_POSITIVE_EDGE_STS);
0418 
0419     /* Set the LID to cause an PME event on group 6 */
0420     cs5535_gpio_setup_event(OLPC_GPIO_LID, 6, 1);
0421 
0422     /* Set PME group 6 to fire the SCI interrupt */
0423     cs5535_gpio_set_irq(6, sci_irq);
0424 
0425     /* Enable the event */
0426     cs5535_gpio_set(OLPC_GPIO_LID, GPIO_EVENTS_ENABLE);
0427 
0428     return 0;
0429 }
0430 
0431 static void free_lid_events(void)
0432 {
0433     gpio_free(OLPC_GPIO_LID);
0434 }
0435 
0436 static int setup_power_button(struct platform_device *pdev)
0437 {
0438     int r;
0439 
0440     power_button_idev = input_allocate_device();
0441     if (!power_button_idev)
0442         return -ENOMEM;
0443 
0444     power_button_idev->name = "Power Button";
0445     power_button_idev->phys = DRV_NAME "/input0";
0446     set_bit(EV_KEY, power_button_idev->evbit);
0447     set_bit(KEY_POWER, power_button_idev->keybit);
0448 
0449     power_button_idev->dev.parent = &pdev->dev;
0450     device_init_wakeup(&power_button_idev->dev, 1);
0451 
0452     r = input_register_device(power_button_idev);
0453     if (r) {
0454         dev_err(&pdev->dev, "failed to register power button: %d\n", r);
0455         input_free_device(power_button_idev);
0456     }
0457 
0458     return r;
0459 }
0460 
0461 static void free_power_button(void)
0462 {
0463     input_unregister_device(power_button_idev);
0464 }
0465 
0466 static int setup_ebook_switch(struct platform_device *pdev)
0467 {
0468     int r;
0469 
0470     ebook_switch_idev = input_allocate_device();
0471     if (!ebook_switch_idev)
0472         return -ENOMEM;
0473 
0474     ebook_switch_idev->name = "EBook Switch";
0475     ebook_switch_idev->phys = DRV_NAME "/input1";
0476     set_bit(EV_SW, ebook_switch_idev->evbit);
0477     set_bit(SW_TABLET_MODE, ebook_switch_idev->swbit);
0478 
0479     ebook_switch_idev->dev.parent = &pdev->dev;
0480     device_set_wakeup_capable(&ebook_switch_idev->dev, true);
0481 
0482     r = input_register_device(ebook_switch_idev);
0483     if (r) {
0484         dev_err(&pdev->dev, "failed to register ebook switch: %d\n", r);
0485         input_free_device(ebook_switch_idev);
0486     }
0487 
0488     return r;
0489 }
0490 
0491 static void free_ebook_switch(void)
0492 {
0493     input_unregister_device(ebook_switch_idev);
0494 }
0495 
0496 static int setup_lid_switch(struct platform_device *pdev)
0497 {
0498     int r;
0499 
0500     lid_switch_idev = input_allocate_device();
0501     if (!lid_switch_idev)
0502         return -ENOMEM;
0503 
0504     lid_switch_idev->name = "Lid Switch";
0505     lid_switch_idev->phys = DRV_NAME "/input2";
0506     set_bit(EV_SW, lid_switch_idev->evbit);
0507     set_bit(SW_LID, lid_switch_idev->swbit);
0508 
0509     lid_switch_idev->dev.parent = &pdev->dev;
0510     device_set_wakeup_capable(&lid_switch_idev->dev, true);
0511 
0512     r = input_register_device(lid_switch_idev);
0513     if (r) {
0514         dev_err(&pdev->dev, "failed to register lid switch: %d\n", r);
0515         goto err_register;
0516     }
0517 
0518     return 0;
0519 
0520 err_register:
0521     input_free_device(lid_switch_idev);
0522     return r;
0523 }
0524 
0525 static void free_lid_switch(void)
0526 {
0527     input_unregister_device(lid_switch_idev);
0528 }
0529 
0530 static int xo1_sci_probe(struct platform_device *pdev)
0531 {
0532     struct resource *res;
0533     int r;
0534 
0535     /* don't run on non-XOs */
0536     if (!machine_is_olpc())
0537         return -ENODEV;
0538 
0539     res = platform_get_resource(pdev, IORESOURCE_IO, 0);
0540     if (!res) {
0541         dev_err(&pdev->dev, "can't fetch device resource info\n");
0542         return -EIO;
0543     }
0544     acpi_base = res->start;
0545 
0546     r = setup_power_button(pdev);
0547     if (r)
0548         return r;
0549 
0550     r = setup_ebook_switch(pdev);
0551     if (r)
0552         goto err_ebook;
0553 
0554     r = setup_lid_switch(pdev);
0555     if (r)
0556         goto err_lid;
0557 
0558     r = setup_lid_events();
0559     if (r)
0560         goto err_lidevt;
0561 
0562     r = setup_ec_sci();
0563     if (r)
0564         goto err_ecsci;
0565 
0566     /* Enable PME generation for EC-generated events */
0567     outl(CS5536_GPIOM6_PME_EN | CS5536_GPIOM7_PME_EN,
0568         acpi_base + CS5536_PM_GPE0_EN);
0569 
0570     /* Clear pending events */
0571     outl(0xffffffff, acpi_base + CS5536_PM_GPE0_STS);
0572     process_sci_queue(false);
0573 
0574     /* Initial sync */
0575     send_ebook_state();
0576     detect_lid_state();
0577     send_lid_state();
0578 
0579     r = setup_sci_interrupt(pdev);
0580     if (r)
0581         goto err_sci;
0582 
0583     /* Enable all EC events */
0584     olpc_ec_mask_write(EC_SCI_SRC_ALL);
0585 
0586     return r;
0587 
0588 err_sci:
0589     free_ec_sci();
0590 err_ecsci:
0591     free_lid_events();
0592 err_lidevt:
0593     free_lid_switch();
0594 err_lid:
0595     free_ebook_switch();
0596 err_ebook:
0597     free_power_button();
0598     return r;
0599 }
0600 
0601 static int xo1_sci_remove(struct platform_device *pdev)
0602 {
0603     free_irq(sci_irq, pdev);
0604     cancel_work_sync(&sci_work);
0605     free_ec_sci();
0606     free_lid_events();
0607     free_lid_switch();
0608     free_ebook_switch();
0609     free_power_button();
0610     acpi_base = 0;
0611     return 0;
0612 }
0613 
0614 static struct platform_driver xo1_sci_driver = {
0615     .driver = {
0616         .name = "olpc-xo1-sci-acpi",
0617         .dev_groups = lid_groups,
0618     },
0619     .probe = xo1_sci_probe,
0620     .remove = xo1_sci_remove,
0621     .suspend = xo1_sci_suspend,
0622     .resume = xo1_sci_resume,
0623 };
0624 
0625 static int __init xo1_sci_init(void)
0626 {
0627     return platform_driver_register(&xo1_sci_driver);
0628 }
0629 arch_initcall(xo1_sci_init);