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 rk_keys_ofdata_to_platdata(struct udevice *dev) 44 { 45 struct input_key *key; 46 u32 adc_channels[2], gpios[2], adcval; 47 int irq, ret; 48 ofnode node; 49 50 /* Get IO channel */ 51 if (dev_read_u32_array(dev, "io-channels", adc_channels, 2)) { 52 printf("%s: failed to read 'io-channels'\n", __func__); 53 return -EINVAL; 54 } 55 56 dev_for_each_subnode(node, dev) { 57 key = calloc(1, sizeof(struct input_key)); 58 if (!key) 59 return -ENOMEM; 60 61 /* This is an ACD key */ 62 if (!ofnode_read_u32(node, "rockchip,adc_value", &adcval)) { 63 key->parent = dev; 64 key->name = ofnode_read_string(node, "label"); 65 key->type = ADC_KEY; 66 key->adcval = adcval; 67 key->channel = adc_channels[1]; 68 if (ofnode_read_u32(node, "linux,code", &key->code)) { 69 printf("%s: failed to read 'linux,code'\n", 70 key->name); 71 free(key); 72 continue; 73 } 74 key_add(key); 75 /* This is a GPIO key */ 76 } else { 77 key->parent = dev; 78 key->type = GPIO_KEY; 79 key->name = ofnode_read_string(node, "label"); 80 ret = ofnode_read_u32(node, "linux,code", &key->code); 81 if (ret) { 82 printf("%s: failed read 'linux,code', ret=%d\n", 83 key->name, ret); 84 free(key); 85 continue; 86 } 87 88 /* Only register power key as interrupt */ 89 if (key->code == KEY_POWER) { 90 ret = ofnode_read_u32_array(node, "gpios", 91 gpios, 2); 92 if (ret) { 93 printf("%s: failed to read 'gpios', ret=%d\n", 94 key->name, ret); 95 free(key); 96 continue; 97 } 98 99 /* Request irq */ 100 irq = phandle_gpio_to_irq(gpios[0], gpios[1]); 101 if (irq < 0) { 102 printf("%s: failed to request irq, ret=%d\n", 103 __func__, irq); 104 free(key); 105 continue; 106 } 107 key->irq = irq; 108 key_add(key); 109 irq_install_handler(irq, gpio_irq_handler, key); 110 irq_set_irq_type(irq, IRQ_TYPE_EDGE_FALLING); 111 irq_handler_enable(irq); 112 } else { 113 ret = gpio_request_by_name_nodev(node, "gpios", 114 0, &key->gpio, GPIOD_IS_IN); 115 if (ret) { 116 printf("%s: failed to request gpio, ret=%d\n", 117 key->name, ret); 118 free(key); 119 continue; 120 } 121 key_add(key); 122 } 123 } 124 125 debug("%s: name=%s: code=%d, adcval=%d, channel=%d, type=%d\n", 126 __func__, key->name, key->code, key->adcval, 127 key->channel, key->type); 128 } 129 130 return 0; 131 } 132 133 static const struct dm_key_ops key_ops = { 134 .name = "rk-keys", 135 }; 136 137 static const struct udevice_id rk_keys_ids[] = { 138 { .compatible = "rockchip,key" }, 139 { }, 140 }; 141 142 U_BOOT_DRIVER(rk_keys) = { 143 .name = "rk-keys", 144 .id = UCLASS_KEY, 145 .ops = &key_ops, 146 .of_match = rk_keys_ids, 147 .ofdata_to_platdata = rk_keys_ofdata_to_platdata, 148 }; 149