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