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; 21 int range; 22 uint val; 23 u32 chn[2]; 24 #ifdef CONFIG_SARADC_ROCKCHIP_V2 25 range = 4096; /* 12-bit adc */ 26 margin = 120; 27 #else 28 range = 1024; /* 10-bit adc */ 29 margin = 30; 30 #endif 31 adc_node = fdt_node_offset_by_compatible(fdt_blob, 0, "adc-keys"); 32 if (adc_node < 0) { 33 debug("No 'adc-keys' node, ret=%d\n", adc_node); 34 return 0; 35 } 36 37 ret = fdtdec_get_int_array(fdt_blob, adc_node, "io-channels", 38 chn, ARRAY_SIZE(chn)); 39 if (ret) { 40 debug("Can't read 'io-channels', ret=%d\n", ret); 41 return 0; 42 } 43 44 vref = fdtdec_get_int(fdt_blob, adc_node, 45 "keyup-threshold-microvolt", -1); 46 if (vref < 0) { 47 debug("Can't read 'keyup-threshold-microvolt'\n"); 48 return 0; 49 } 50 51 channel = chn[1]; 52 53 for (offset = fdt_first_subnode(fdt_blob, adc_node); 54 offset >= 0; 55 offset = fdt_next_subnode(fdt_blob, offset)) { 56 cd = fdtdec_get_int(fdt_blob, offset, "linux,code", -1); 57 if (cd == code) { 58 mv = fdtdec_get_int(fdt_blob, offset, 59 "press-threshold-microvolt", -1); 60 if (mv < 0) { 61 debug("Can't read 'press-threshold-microvolt'\n"); 62 return 0; 63 } 64 65 adc = mv / (vref / range); 66 max = adc + margin; 67 min = adc > margin ? adc - margin : 0; 68 ret = adc_channel_single_shot("saradc", channel, &val); 69 if (ret) { 70 debug("Failed to read adc%d, ret=%d\n", 71 channel, ret); 72 return 0; 73 } 74 75 return (val >= min && val <= max); 76 } 77 } 78 79 return 0; 80 } 81