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 <dm/read.h> 9 #include <adc.h> 10 #include <common.h> 11 #include <console.h> 12 #include <errno.h> 13 #include <fdtdec.h> 14 #include <malloc.h> 15 #include <key.h> 16 #include <linux/input.h> 17 18 static int adc_keys_ofdata_to_platdata(struct udevice *dev) 19 { 20 struct input_key *key; 21 u32 adc_channels[2], microvolt; 22 int vref, ret; 23 ofnode node; 24 25 /* Get vref */ 26 vref = dev_read_u32_default(dev, "keyup-threshold-microvolt", -1); 27 if (vref < 0) { 28 printf("failed to read 'keyup-threshold-microvolt', ret=%d\n", 29 vref); 30 return -EINVAL; 31 } 32 33 /* Get IO channel */ 34 ret = dev_read_u32_array(dev, "io-channels", adc_channels, 2); 35 if (ret) { 36 printf("failed to read 'io-channels', ret=%d\n", ret); 37 return -EINVAL; 38 } 39 40 /* Parse every adc key data */ 41 dev_for_each_subnode(node, dev) { 42 key = calloc(1, sizeof(struct input_key)); 43 if (!key) 44 return -ENOMEM; 45 46 key->parent = dev; 47 key->type = ADC_KEY; 48 key->vref = vref; 49 key->channel = adc_channels[1]; 50 key->name = ofnode_read_string(node, "label"); 51 ret = ofnode_read_u32(node, "linux,code", &key->code); 52 if (ret) { 53 printf("%s: failed to read 'linux,code', ret=%d\n", 54 key->name, ret); 55 free(key); 56 continue; 57 } 58 59 ret = ofnode_read_u32(node, "press-threshold-microvolt", 60 µvolt); 61 if (ret) { 62 printf("%s: failed to read 'press-threshold-microvolt', ret=%d\n", 63 key->name, ret); 64 free(key); 65 continue; 66 } 67 68 /* Convert microvolt to adc value */ 69 key->adcval = microvolt / (key->vref / 1024); 70 key_add(key); 71 72 debug("%s: name=%s: code=%d, vref=%d, channel=%d, microvolt=%d, adcval=%d\n", 73 __func__, key->name, key->code, key->vref, 74 key->channel, microvolt, key->adcval); 75 } 76 77 return 0; 78 } 79 80 static const struct dm_key_ops key_ops = { 81 .name = "adc-keys", 82 }; 83 84 static const struct udevice_id adc_keys_ids[] = { 85 { .compatible = "adc-keys" }, 86 { }, 87 }; 88 89 U_BOOT_DRIVER(adc_keys) = { 90 .name = "adc-keys", 91 .id = UCLASS_KEY, 92 .ops = &key_ops, 93 .of_match = adc_keys_ids, 94 .ofdata_to_platdata = adc_keys_ofdata_to_platdata, 95 }; 96