| .. | .. |
|---|
| 25 | 25 | #include <linux/rfkill-bt.h> |
|---|
| 26 | 26 | #include <linux/rfkill-wlan.h> |
|---|
| 27 | 27 | #include <linux/wakelock.h> |
|---|
| 28 | | -#include <linux/input.h> |
|---|
| 29 | 28 | #include <linux/interrupt.h> |
|---|
| 30 | 29 | #include <asm/irq.h> |
|---|
| 31 | 30 | #include <linux/suspend.h> |
|---|
| .. | .. |
|---|
| 70 | 69 | struct wake_lock bt_irq_wl; |
|---|
| 71 | 70 | struct delayed_work bt_sleep_delay_work; |
|---|
| 72 | 71 | int irq_req; |
|---|
| 73 | | - bool enable_power_key; |
|---|
| 74 | 72 | }; |
|---|
| 75 | 73 | |
|---|
| 76 | 74 | static struct rfkill_rk_data *g_rfkill = NULL; |
|---|
| 77 | | -static struct input_dev *power_key_dev; |
|---|
| 78 | 75 | |
|---|
| 79 | 76 | static const char bt_name[] = |
|---|
| 80 | 77 | #if defined(CONFIG_BCM4330) |
|---|
| .. | .. |
|---|
| 116 | 113 | #endif |
|---|
| 117 | 114 | ; |
|---|
| 118 | 115 | |
|---|
| 119 | | -static int rfkill_rk_power_key_up(void) |
|---|
| 120 | | -{ |
|---|
| 121 | | - if (!power_key_dev) |
|---|
| 122 | | - return -ENODEV; |
|---|
| 123 | | - |
|---|
| 124 | | - input_report_key(power_key_dev, KEY_POWER, 1); |
|---|
| 125 | | - input_sync(power_key_dev); |
|---|
| 126 | | - msleep(20); |
|---|
| 127 | | - input_report_key(power_key_dev, KEY_POWER, 0); |
|---|
| 128 | | - input_sync(power_key_dev); |
|---|
| 129 | | - |
|---|
| 130 | | - return 0; |
|---|
| 131 | | -} |
|---|
| 132 | | - |
|---|
| 133 | 116 | static irqreturn_t rfkill_rk_wake_host_irq(int irq, void *dev) |
|---|
| 134 | 117 | { |
|---|
| 135 | 118 | struct rfkill_rk_data *rfkill = dev; |
|---|
| .. | .. |
|---|
| 140 | 123 | |
|---|
| 141 | 124 | wake_lock_timeout(&rfkill->bt_irq_wl, |
|---|
| 142 | 125 | msecs_to_jiffies(BT_IRQ_WAKELOCK_TIMEOUT)); |
|---|
| 143 | | - |
|---|
| 144 | | - if (rfkill->enable_power_key) |
|---|
| 145 | | - return IRQ_WAKE_THREAD; |
|---|
| 146 | | - |
|---|
| 147 | | - return IRQ_HANDLED; |
|---|
| 148 | | -} |
|---|
| 149 | | - |
|---|
| 150 | | -static irqreturn_t rfkill_rk_wake_host_irq_thread(int irq, void *dev) |
|---|
| 151 | | -{ |
|---|
| 152 | | - rfkill_rk_power_key_up(); |
|---|
| 153 | 126 | |
|---|
| 154 | 127 | return IRQ_HANDLED; |
|---|
| 155 | 128 | } |
|---|
| .. | .. |
|---|
| 192 | 165 | LOG("Request irq for bt wakeup host\n"); |
|---|
| 193 | 166 | irq->irq = gpio_to_irq(irq->gpio.io); |
|---|
| 194 | 167 | sprintf(irq->name, "%s_irq", irq->gpio.name); |
|---|
| 195 | | - ret = request_threaded_irq(irq->irq, rfkill_rk_wake_host_irq, |
|---|
| 196 | | - rfkill_rk_wake_host_irq_thread, |
|---|
| 197 | | - IRQF_ONESHOT | ((irq->gpio.enable == GPIO_ACTIVE_LOW) ? |
|---|
| 198 | | - IRQF_TRIGGER_FALLING : |
|---|
| 199 | | - IRQF_TRIGGER_RISING), |
|---|
| 200 | | - irq->name, rfkill); |
|---|
| 168 | + ret = request_irq(irq->irq, rfkill_rk_wake_host_irq, |
|---|
| 169 | + (irq->gpio.enable == GPIO_ACTIVE_LOW) ? |
|---|
| 170 | + IRQF_TRIGGER_FALLING : |
|---|
| 171 | + IRQF_TRIGGER_RISING, |
|---|
| 172 | + irq->name, rfkill); |
|---|
| 201 | 173 | if (ret) |
|---|
| 202 | 174 | goto fail2; |
|---|
| 203 | 175 | rfkill->irq_req = 1; |
|---|
| .. | .. |
|---|
| 255 | 227 | { |
|---|
| 256 | 228 | struct rfkill_rk_data *rfkill = g_rfkill; |
|---|
| 257 | 229 | struct rfkill_rk_gpio *wake; |
|---|
| 258 | | - bool ret; |
|---|
| 259 | 230 | |
|---|
| 260 | 231 | DBG("Enter %s\n", __func__); |
|---|
| 261 | 232 | |
|---|
| .. | .. |
|---|
| 270 | 241 | return; |
|---|
| 271 | 242 | } |
|---|
| 272 | 243 | |
|---|
| 273 | | - ret = cancel_delayed_work_sync(&rfkill->bt_sleep_delay_work); |
|---|
| 244 | + cancel_delayed_work_sync(&rfkill->bt_sleep_delay_work); |
|---|
| 274 | 245 | |
|---|
| 275 | 246 | rfkill_rk_sleep_bt_internal(rfkill, sleep); |
|---|
| 276 | 247 | |
|---|
| .. | .. |
|---|
| 342 | 313 | gpio_direction_output(poweron->io, |
|---|
| 343 | 314 | poweron->enable); |
|---|
| 344 | 315 | msleep(20); |
|---|
| 345 | | - if (gpio_is_valid(wake_host->io)) |
|---|
| 346 | | - gpio_direction_input(wake_host->io); |
|---|
| 347 | 316 | } |
|---|
| 348 | 317 | } |
|---|
| 349 | 318 | |
|---|
| .. | .. |
|---|
| 354 | 323 | msleep(20); |
|---|
| 355 | 324 | gpio_direction_output(reset->io, reset->enable); |
|---|
| 356 | 325 | } |
|---|
| 326 | + } |
|---|
| 327 | + |
|---|
| 328 | + if (gpio_is_valid(wake_host->io)) { |
|---|
| 329 | + LOG("%s: set bt wake_host input!\n", __func__); |
|---|
| 330 | + gpio_direction_input(wake_host->io); |
|---|
| 357 | 331 | } |
|---|
| 358 | 332 | |
|---|
| 359 | 333 | if (pinctrl && gpio_is_valid(rts->io)) { |
|---|
| .. | .. |
|---|
| 409 | 383 | struct rfkill_rk_data *rfkill = g_rfkill; |
|---|
| 410 | 384 | struct rfkill_rk_gpio *rts; |
|---|
| 411 | 385 | struct rfkill_rk_irq *wake_host_irq; |
|---|
| 412 | | - struct pinctrl *pinctrl = rfkill->pdata->pinctrl; |
|---|
| 413 | 386 | |
|---|
| 414 | 387 | DBG("Enter %s\n", __func__); |
|---|
| 415 | 388 | |
|---|
| .. | .. |
|---|
| 420 | 393 | wake_host_irq = &rfkill->pdata->wake_host_irq; |
|---|
| 421 | 394 | |
|---|
| 422 | 395 | //To prevent uart to receive bt data when suspended |
|---|
| 423 | | - if (pinctrl && gpio_is_valid(rts->io)) { |
|---|
| 396 | + if (rfkill->pdata->pinctrl && gpio_is_valid(rts->io)) { |
|---|
| 424 | 397 | DBG("Disable UART_RTS\n"); |
|---|
| 425 | | - pinctrl_select_state(pinctrl, rts->gpio_state); |
|---|
| 398 | + pinctrl_select_state(rfkill->pdata->pinctrl, rts->gpio_state); |
|---|
| 426 | 399 | gpio_direction_output(rts->io, !rts->enable); |
|---|
| 427 | 400 | } |
|---|
| 428 | 401 | |
|---|
| .. | .. |
|---|
| 438 | 411 | } |
|---|
| 439 | 412 | |
|---|
| 440 | 413 | #ifdef CONFIG_RFKILL_RESET |
|---|
| 441 | | - rfkill_set_states(rfkill->rfkill_dev, BT_BLOCKED, false); |
|---|
| 414 | + rfkill_init_sw_state(rfkill->rfkill_dev, BT_BLOCKED); |
|---|
| 415 | + rfkill_set_sw_state(rfkill->rfkill_dev, BT_BLOCKED); |
|---|
| 416 | + rfkill_set_hw_state(rfkill->rfkill_dev, false); |
|---|
| 442 | 417 | rfkill_rk_set_power(rfkill, BT_BLOCKED); |
|---|
| 443 | 418 | #endif |
|---|
| 444 | 419 | |
|---|
| .. | .. |
|---|
| 450 | 425 | struct rfkill_rk_data *rfkill = g_rfkill; |
|---|
| 451 | 426 | struct rfkill_rk_irq *wake_host_irq; |
|---|
| 452 | 427 | struct rfkill_rk_gpio *rts; |
|---|
| 453 | | - struct pinctrl *pinctrl = rfkill->pdata->pinctrl; |
|---|
| 454 | 428 | |
|---|
| 455 | 429 | DBG("Enter %s\n", __func__); |
|---|
| 456 | 430 | |
|---|
| .. | .. |
|---|
| 466 | 440 | disable_irq_wake(wake_host_irq->irq); |
|---|
| 467 | 441 | } |
|---|
| 468 | 442 | |
|---|
| 469 | | - if (pinctrl && gpio_is_valid(rts->io)) { |
|---|
| 443 | + if (rfkill->pdata->pinctrl && gpio_is_valid(rts->io)) { |
|---|
| 470 | 444 | DBG("Enable UART_RTS\n"); |
|---|
| 471 | 445 | gpio_direction_output(rts->io, rts->enable); |
|---|
| 472 | | - pinctrl_select_state(pinctrl, rts->default_state); |
|---|
| 446 | + pinctrl_select_state(rfkill->pdata->pinctrl, rts->default_state); |
|---|
| 473 | 447 | } |
|---|
| 474 | 448 | } |
|---|
| 475 | 449 | |
|---|
| .. | .. |
|---|
| 514 | 488 | return -EFAULT; |
|---|
| 515 | 489 | |
|---|
| 516 | 490 | DBG("btwrite %c\n", b); |
|---|
| 491 | + /* HCI_DEV_WRITE */ |
|---|
| 517 | 492 | if (b != '0') |
|---|
| 518 | 493 | rfkill_rk_sleep_bt(BT_WAKEUP); |
|---|
| 519 | 494 | else |
|---|
| 520 | 495 | rfkill_rk_sleep_bt(BT_SLEEP); |
|---|
| 521 | | - |
|---|
| 522 | | - return count; |
|---|
| 523 | | -} |
|---|
| 524 | | - |
|---|
| 525 | | -static ssize_t bluesleep_read_proc_powerupkey(struct file *file, |
|---|
| 526 | | - char __user *buffer, size_t count, |
|---|
| 527 | | - loff_t *data) |
|---|
| 528 | | -{ |
|---|
| 529 | | - struct rfkill_rk_data *rfkill = g_rfkill; |
|---|
| 530 | | - char src[2]; |
|---|
| 531 | | - |
|---|
| 532 | | - if (*data >= 1) |
|---|
| 533 | | - return 0; |
|---|
| 534 | | - |
|---|
| 535 | | - if (!rfkill) |
|---|
| 536 | | - return -EFAULT; |
|---|
| 537 | | - |
|---|
| 538 | | - src[0] = rfkill->enable_power_key ? '1' : '0'; |
|---|
| 539 | | - src[1] = '\n'; |
|---|
| 540 | | - if (copy_to_user(buffer, src, 2)) |
|---|
| 541 | | - return -EFAULT; |
|---|
| 542 | | - *data = 1; |
|---|
| 543 | | - |
|---|
| 544 | | - return 2; |
|---|
| 545 | | -} |
|---|
| 546 | | - |
|---|
| 547 | | -static ssize_t bluesleep_write_proc_powerupkey(struct file *file, |
|---|
| 548 | | - const char __user *buffer, |
|---|
| 549 | | - size_t count, loff_t *data) |
|---|
| 550 | | -{ |
|---|
| 551 | | - char b; |
|---|
| 552 | | - struct rfkill_rk_data *rfkill = g_rfkill; |
|---|
| 553 | | - |
|---|
| 554 | | - if (!rfkill) |
|---|
| 555 | | - return -EFAULT; |
|---|
| 556 | | - |
|---|
| 557 | | - if (count < 1) |
|---|
| 558 | | - return -EINVAL; |
|---|
| 559 | | - |
|---|
| 560 | | - if (copy_from_user(&b, buffer, 1)) |
|---|
| 561 | | - return -EFAULT; |
|---|
| 562 | | - |
|---|
| 563 | | - if (b != '0') |
|---|
| 564 | | - rfkill->enable_power_key = true; |
|---|
| 565 | | - else |
|---|
| 566 | | - rfkill->enable_power_key = false; |
|---|
| 567 | 496 | |
|---|
| 568 | 497 | return count; |
|---|
| 569 | 498 | } |
|---|
| .. | .. |
|---|
| 655 | 584 | } |
|---|
| 656 | 585 | #endif //CONFIG_OF |
|---|
| 657 | 586 | |
|---|
| 658 | | -static const struct file_operations bluesleep_lpm = { |
|---|
| 659 | | - .owner = THIS_MODULE, |
|---|
| 660 | | - .read = bluesleep_read_proc_lpm, |
|---|
| 661 | | - .write = bluesleep_write_proc_lpm, |
|---|
| 587 | +static const struct proc_ops bluesleep_lpm = { |
|---|
| 588 | + .proc_read = bluesleep_read_proc_lpm, |
|---|
| 589 | + .proc_write = bluesleep_write_proc_lpm, |
|---|
| 662 | 590 | }; |
|---|
| 663 | 591 | |
|---|
| 664 | | -static const struct file_operations bluesleep_btwrite = { |
|---|
| 665 | | - .owner = THIS_MODULE, |
|---|
| 666 | | - .read = bluesleep_read_proc_btwrite, |
|---|
| 667 | | - .write = bluesleep_write_proc_btwrite, |
|---|
| 592 | +static const struct proc_ops bluesleep_btwrite = { |
|---|
| 593 | + .proc_read = bluesleep_read_proc_btwrite, |
|---|
| 594 | + .proc_write = bluesleep_write_proc_btwrite, |
|---|
| 668 | 595 | }; |
|---|
| 669 | | - |
|---|
| 670 | | -static const struct file_operations bluesleep_powerupkey = { |
|---|
| 671 | | - .owner = THIS_MODULE, |
|---|
| 672 | | - .read = bluesleep_read_proc_powerupkey, |
|---|
| 673 | | - .write = bluesleep_write_proc_powerupkey, |
|---|
| 674 | | -}; |
|---|
| 675 | | - |
|---|
| 676 | | -static int rfkill_rk_register_power_key(void) |
|---|
| 677 | | -{ |
|---|
| 678 | | - int ret = 0; |
|---|
| 679 | | - |
|---|
| 680 | | - /* register input device */ |
|---|
| 681 | | - power_key_dev = input_allocate_device(); |
|---|
| 682 | | - if (!power_key_dev) { |
|---|
| 683 | | - LOG("ir_dev: not enough memory for input device\n"); |
|---|
| 684 | | - return -ENOMEM; |
|---|
| 685 | | - } |
|---|
| 686 | | - |
|---|
| 687 | | - power_key_dev->name = "bt-powerkey"; |
|---|
| 688 | | - power_key_dev->id.bustype = BUS_HOST; |
|---|
| 689 | | - |
|---|
| 690 | | - power_key_dev->evbit[0] = BIT_MASK(EV_KEY); |
|---|
| 691 | | - set_bit(KEY_POWER, power_key_dev->keybit); |
|---|
| 692 | | - |
|---|
| 693 | | - ret = input_register_device(power_key_dev); |
|---|
| 694 | | - if (ret) { |
|---|
| 695 | | - input_free_device(power_key_dev); |
|---|
| 696 | | - LOG("ir_rx_init: register input device exception, exit\n"); |
|---|
| 697 | | - return -EBUSY; |
|---|
| 698 | | - } |
|---|
| 699 | | - |
|---|
| 700 | | - return ret; |
|---|
| 701 | | -} |
|---|
| 702 | 596 | |
|---|
| 703 | 597 | static int rfkill_rk_probe(struct platform_device *pdev) |
|---|
| 704 | 598 | { |
|---|
| .. | .. |
|---|
| 751 | 645 | } |
|---|
| 752 | 646 | |
|---|
| 753 | 647 | /* read/write proc entries */ |
|---|
| 754 | | - ent = proc_create("lpm", 0, sleep_dir, &bluesleep_lpm); |
|---|
| 648 | + ent = proc_create("lpm", 0444, sleep_dir, &bluesleep_lpm); |
|---|
| 755 | 649 | if (!ent) { |
|---|
| 756 | 650 | LOG("Unable to create /proc/%s/lpm entry", PROC_DIR); |
|---|
| 757 | 651 | ret = -ENOMEM; |
|---|
| .. | .. |
|---|
| 759 | 653 | } |
|---|
| 760 | 654 | |
|---|
| 761 | 655 | /* read/write proc entries */ |
|---|
| 762 | | - ent = proc_create("btwrite", 0, sleep_dir, &bluesleep_btwrite); |
|---|
| 656 | + ent = proc_create("btwrite", 0444, sleep_dir, &bluesleep_btwrite); |
|---|
| 763 | 657 | if (!ent) { |
|---|
| 764 | 658 | LOG("Unable to create /proc/%s/btwrite entry", PROC_DIR); |
|---|
| 765 | | - ret = -ENOMEM; |
|---|
| 766 | | - goto fail_alloc; |
|---|
| 767 | | - } |
|---|
| 768 | | - |
|---|
| 769 | | - /* read/write proc entries */ |
|---|
| 770 | | - ent = proc_create("powerupkey", 0, sleep_dir, &bluesleep_powerupkey); |
|---|
| 771 | | - if (!ent) { |
|---|
| 772 | | - LOG("Unable to create /proc/%s/powerupkey entry", PROC_DIR); |
|---|
| 773 | 659 | ret = -ENOMEM; |
|---|
| 774 | 660 | goto fail_alloc; |
|---|
| 775 | 661 | } |
|---|
| .. | .. |
|---|
| 809 | 695 | if (!rfkill->rfkill_dev) |
|---|
| 810 | 696 | goto fail_alloc; |
|---|
| 811 | 697 | |
|---|
| 812 | | - rfkill_set_states(rfkill->rfkill_dev, BT_BLOCKED, false); |
|---|
| 698 | + rfkill_init_sw_state(rfkill->rfkill_dev, BT_BLOCKED); |
|---|
| 699 | + rfkill_set_sw_state(rfkill->rfkill_dev, BT_BLOCKED); |
|---|
| 700 | + rfkill_set_hw_state(rfkill->rfkill_dev, false); |
|---|
| 813 | 701 | ret = rfkill_register(rfkill->rfkill_dev); |
|---|
| 814 | 702 | if (ret < 0) |
|---|
| 815 | 703 | goto fail_rfkill; |
|---|
| .. | .. |
|---|
| 832 | 720 | |
|---|
| 833 | 721 | LOG("%s device registered.\n", pdata->name); |
|---|
| 834 | 722 | |
|---|
| 835 | | - if (rfkill_rk_register_power_key() != 0) |
|---|
| 836 | | - goto fail_rfkill; |
|---|
| 837 | | - |
|---|
| 838 | 723 | return 0; |
|---|
| 839 | 724 | |
|---|
| 840 | 725 | fail_rfkill: |
|---|
| 841 | 726 | rfkill_destroy(rfkill->rfkill_dev); |
|---|
| 842 | 727 | fail_alloc: |
|---|
| 843 | 728 | |
|---|
| 844 | | - remove_proc_entry("powerupkey", sleep_dir); |
|---|
| 845 | 729 | remove_proc_entry("btwrite", sleep_dir); |
|---|
| 846 | 730 | remove_proc_entry("lpm", sleep_dir); |
|---|
| 847 | 731 | fail_setup_wake_irq: |
|---|
| .. | .. |
|---|
| 860 | 744 | |
|---|
| 861 | 745 | rfkill_unregister(rfkill->rfkill_dev); |
|---|
| 862 | 746 | rfkill_destroy(rfkill->rfkill_dev); |
|---|
| 863 | | - remove_proc_entry("powerupkey", sleep_dir); |
|---|
| 864 | | - remove_proc_entry("btwrite", sleep_dir); |
|---|
| 865 | | - remove_proc_entry("lpm", sleep_dir); |
|---|
| 866 | 747 | |
|---|
| 867 | | - input_unregister_device(power_key_dev); |
|---|
| 868 | 748 | cancel_delayed_work_sync(&rfkill->bt_sleep_delay_work); |
|---|
| 869 | 749 | |
|---|
| 870 | 750 | // free gpio |
|---|