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