1 /* 2 * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <dm.h> 8 #include <adc.h> 9 #include <common.h> 10 #include <console.h> 11 #include <dm.h> 12 #include <errno.h> 13 #include <fdtdec.h> 14 #include <malloc.h> 15 #include <key.h> 16 #include <linux/input.h> 17 #include <errno.h> 18 #include <dm/read.h> 19 #include <irq-generic.h> 20 #include <irq-platform.h> 21 22 static void gpio_irq_handler(int irq, void *data) 23 { 24 struct input_key *key = data; 25 26 if (key->irq != irq) 27 return; 28 29 /* up event */ 30 if (irq_get_gpio_level(irq)) { 31 key->up_t = key_timer(0); 32 debug("%s: key down: %llu ms\n", key->name, key->down_t); 33 /* down event */ 34 } else { 35 key->down_t = key_timer(0); 36 debug("%s: key up: %llu ms\n", key->name, key->up_t); 37 } 38 /* Must delay */ 39 mdelay(10); 40 irq_revert_irq_type(irq); 41 } 42 43 static int gpio_key_ofdata_to_platdata(struct udevice *dev) 44 { 45 struct input_key *key; 46 u32 gpios[2]; 47 ofnode node; 48 int irq, ret; 49 50 dev_for_each_subnode(node, dev) { 51 key = calloc(1, sizeof(struct input_key)); 52 if (!key) 53 return -ENOMEM; 54 55 key->parent = dev; 56 key->type = GPIO_KEY; 57 key->name = ofnode_read_string(node, "label"); 58 ret = ofnode_read_u32(node, "linux,code", &key->code); 59 if (ret) { 60 printf("%s: failed read 'linux,code', ret=%d\n", 61 key->name, ret); 62 free(key); 63 continue; 64 } 65 66 /* Only register power key as interrupt */ 67 if (key->code == KEY_POWER) { 68 ret = ofnode_read_u32_array(node, "gpios", gpios, 2); 69 if (ret) { 70 printf("%s: failed to read 'gpios', ret=%d\n", 71 key->name, ret); 72 free(key); 73 continue; 74 } 75 76 /* Must register as interrupt, be able to wakeup system */ 77 irq = phandle_gpio_to_irq(gpios[0], gpios[1]); 78 if (irq < 0) { 79 printf("%s: failed to request irq, ret=%d\n", 80 key->name, irq); 81 free(key); 82 continue; 83 } 84 key->irq = irq; 85 key_add(key); 86 irq_install_handler(irq, gpio_irq_handler, key); 87 irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); 88 irq_handler_enable(irq); 89 } else { 90 ret = gpio_request_by_name_nodev(node, "gpios", 0, 91 &key->gpio, 92 GPIOD_IS_IN); 93 if (ret) { 94 printf("%s: failed to request gpio, ret=%d\n", 95 key->name, ret); 96 } 97 98 key_add(key); 99 } 100 101 debug("%s: name=%s: code=%d\n", __func__, key->name, key->code); 102 } 103 104 return 0; 105 } 106 107 static const struct dm_key_ops key_ops = { 108 .name = "gpio-keys", 109 }; 110 111 static const struct udevice_id gpio_key_ids[] = { 112 { .compatible = "gpio-keys" }, 113 { }, 114 }; 115 116 U_BOOT_DRIVER(gpio_keys) = { 117 .name = "gpio-keys", 118 .id = UCLASS_KEY, 119 .of_match = gpio_key_ids, 120 .ops = &key_ops, 121 .ofdata_to_platdata = gpio_key_ofdata_to_platdata, 122 }; 123