1 /* 2 * (C) Copyright 2020 Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <adc.h> 9 #include <fdtdec.h> 10 11 DECLARE_GLOBAL_DATA_PTR; 12 13 int key_read(int code) 14 { 15 const void *fdt_blob = gd->fdt_blob; 16 int adc_node, offset; 17 int cd, channel, adc; 18 int ret, vref, mv; 19 int min, max; 20 int margin = 30; 21 uint val; 22 u32 chn[2]; 23 24 adc_node = fdt_node_offset_by_compatible(fdt_blob, 0, "adc-keys"); 25 if (adc_node < 0) { 26 debug("No 'adc-keys' node, ret=%d\n", adc_node); 27 return 0; 28 } 29 30 ret = fdtdec_get_int_array(fdt_blob, adc_node, "io-channels", 31 chn, ARRAY_SIZE(chn)); 32 if (ret) { 33 debug("Can't read 'io-channels', ret=%d\n", ret); 34 return 0; 35 } 36 37 vref = fdtdec_get_int(fdt_blob, adc_node, 38 "keyup-threshold-microvolt", -1); 39 if (vref < 0) { 40 debug("Can't read 'keyup-threshold-microvolt'\n"); 41 return 0; 42 } 43 44 channel = chn[1]; 45 46 for (offset = fdt_first_subnode(fdt_blob, adc_node); 47 offset >= 0; 48 offset = fdt_next_subnode(fdt_blob, offset)) { 49 cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -1); 50 if (cd == code) { 51 mv = fdtdec_get_int(fdt_blob, offset, 52 "press-threshold-microvolt", -1); 53 if (mv < 0) { 54 debug("Can't read 'press-threshold-microvolt'\n"); 55 return 0; 56 } 57 58 adc = mv / (vref / 1024); /* 10-bit adc */ 59 max = adc + margin; 60 min = adc > margin ? adc - margin : 0; 61 ret = adc_channel_single_shot("saradc", channel, &val); 62 if (ret) { 63 debug("Failed to read adc%d, ret=%d\n", 64 channel, ret); 65 return 0; 66 } 67 68 return (val >= min && val <= max); 69 } 70 } 71 72 return 0; 73 } 74