| .. | .. |
|---|
| 6 | 6 | |
|---|
| 7 | 7 | #include <common.h> |
|---|
| 8 | 8 | #include <adc.h> |
|---|
| 9 | +#include <div64.h> |
|---|
| 9 | 10 | #include <dm.h> |
|---|
| 10 | 11 | #include <irq-generic.h> |
|---|
| 11 | 12 | #include <key.h> |
|---|
| .. | .. |
|---|
| 37 | 38 | return (cntpct > base) ? (cntpct - base) : 0; |
|---|
| 38 | 39 | } |
|---|
| 39 | 40 | |
|---|
| 40 | | -static int key_adc_event(struct dm_key_uclass_platdata *uc_key, int adcval) |
|---|
| 41 | +#ifdef CONFIG_ADC |
|---|
| 42 | +static int adc_raw_to_mV(struct udevice *dev, unsigned int raw, int *mV) |
|---|
| 41 | 43 | { |
|---|
| 42 | | - return (adcval <= uc_key->max && adcval >= uc_key->min) ? |
|---|
| 44 | + unsigned int data_mask; |
|---|
| 45 | + int ret, vref = 1800000; |
|---|
| 46 | + u64 raw64 = raw; |
|---|
| 47 | + |
|---|
| 48 | + ret = adc_data_mask(dev, &data_mask); |
|---|
| 49 | + if (ret) |
|---|
| 50 | + return ret; |
|---|
| 51 | + |
|---|
| 52 | + raw64 *= vref; |
|---|
| 53 | + do_div(raw64, data_mask); |
|---|
| 54 | + *mV = raw64; |
|---|
| 55 | + |
|---|
| 56 | + return 0; |
|---|
| 57 | +} |
|---|
| 58 | + |
|---|
| 59 | +static int key_adc_event(struct udevice *dev, |
|---|
| 60 | + struct dm_key_uclass_platdata *uc_key, int adcval) |
|---|
| 61 | +{ |
|---|
| 62 | + int val = adcval; |
|---|
| 63 | + |
|---|
| 64 | + if (uc_key->in_volt) { |
|---|
| 65 | + if (adc_raw_to_mV(dev, adcval, &val)) |
|---|
| 66 | + return KEY_PRESS_NONE; |
|---|
| 67 | + } |
|---|
| 68 | + |
|---|
| 69 | + debug("[%s] <%d, %d, %d>: adcval=%d -> mV=%d\n", |
|---|
| 70 | + uc_key->name, uc_key->min, uc_key->center, uc_key->max, |
|---|
| 71 | + adcval, val); |
|---|
| 72 | + |
|---|
| 73 | + return (val <= uc_key->max && val >= uc_key->min) ? |
|---|
| 43 | 74 | KEY_PRESS_DOWN : KEY_PRESS_NONE; |
|---|
| 44 | 75 | } |
|---|
| 76 | +#endif |
|---|
| 45 | 77 | |
|---|
| 46 | 78 | static int key_gpio_event(struct dm_key_uclass_platdata *uc_key) |
|---|
| 47 | 79 | { |
|---|
| .. | .. |
|---|
| 108 | 140 | |
|---|
| 109 | 141 | static int key_core_read(struct dm_key_uclass_platdata *uc_key) |
|---|
| 110 | 142 | { |
|---|
| 111 | | - unsigned int adcval; |
|---|
| 112 | | - |
|---|
| 113 | 143 | if (uc_key->type == ADC_KEY) { |
|---|
| 114 | | - if (adc_channel_single_shot("saradc", |
|---|
| 115 | | - uc_key->channel, &adcval)) { |
|---|
| 116 | | - KEY_ERR("%s failed to read saradc\n", uc_key->name); |
|---|
| 144 | +#ifdef CONFIG_ADC |
|---|
| 145 | + struct udevice *dev; |
|---|
| 146 | + unsigned int adcval; |
|---|
| 147 | + int ret; |
|---|
| 148 | + |
|---|
| 149 | + ret = uclass_get_device_by_name(UCLASS_ADC, "saradc", &dev); |
|---|
| 150 | + if (ret) { |
|---|
| 151 | + KEY_ERR("%s: No saradc\n", uc_key->name); |
|---|
| 117 | 152 | return KEY_NOT_EXIST; |
|---|
| 118 | 153 | } |
|---|
| 119 | 154 | |
|---|
| 120 | | - return key_adc_event(uc_key, adcval); |
|---|
| 155 | + ret = adc_start_channel(dev, uc_key->channel); |
|---|
| 156 | + if (ret) { |
|---|
| 157 | + KEY_ERR("%s: Failed to start saradc\n", uc_key->name); |
|---|
| 158 | + return KEY_NOT_EXIST; |
|---|
| 159 | + } |
|---|
| 160 | + |
|---|
| 161 | + ret = adc_channel_data(dev, uc_key->channel, &adcval); |
|---|
| 162 | + if (ret) { |
|---|
| 163 | + KEY_ERR("%s: Failed to read saradc, %d\n", uc_key->name, ret); |
|---|
| 164 | + return KEY_NOT_EXIST; |
|---|
| 165 | + } |
|---|
| 166 | + |
|---|
| 167 | + return key_adc_event(dev, uc_key, adcval); |
|---|
| 168 | +#else |
|---|
| 169 | + return KEY_NOT_EXIST; |
|---|
| 170 | +#endif |
|---|
| 121 | 171 | } |
|---|
| 122 | 172 | |
|---|
| 123 | 173 | return (uc_key->code == KEY_POWER) ? |
|---|
| .. | .. |
|---|
| 273 | 323 | { |
|---|
| 274 | 324 | struct dm_key_uclass_platdata *uc_key; |
|---|
| 275 | 325 | int ret; |
|---|
| 276 | | -#ifdef CONFIG_SARADC_ROCKCHIP_V2 |
|---|
| 277 | | - int margin = 120; |
|---|
| 278 | | -#else |
|---|
| 279 | | - int margin = 30; |
|---|
| 280 | | -#endif |
|---|
| 326 | + |
|---|
| 281 | 327 | uc_key = dev_get_uclass_platdata(dev); |
|---|
| 282 | 328 | if (!uc_key) |
|---|
| 283 | 329 | return -ENXIO; |
|---|
| .. | .. |
|---|
| 286 | 332 | uc_key->pre_reloc = dev_read_bool(dev, "u-boot,dm-pre-reloc") || |
|---|
| 287 | 333 | dev_read_bool(dev, "u-boot,dm-spl"); |
|---|
| 288 | 334 | |
|---|
| 289 | | - if (uc_key->type == ADC_KEY) { |
|---|
| 290 | | - uc_key->max = uc_key->adcval + margin; |
|---|
| 291 | | - uc_key->min = uc_key->adcval > margin ? |
|---|
| 292 | | - uc_key->adcval - margin : 0; |
|---|
| 293 | | - } else { |
|---|
| 335 | + if (uc_key->type != ADC_KEY) { |
|---|
| 294 | 336 | if (uc_key->code == KEY_POWER) { |
|---|
| 295 | 337 | #if CONFIG_IS_ENABLED(IRQ) |
|---|
| 296 | 338 | int irq; |
|---|
| .. | .. |
|---|
| 337 | 379 | dev->parent->name); |
|---|
| 338 | 380 | |
|---|
| 339 | 381 | if (uc_key->type == ADC_KEY) { |
|---|
| 340 | | - printf(" adcval: %d (%d, %d)\n", uc_key->adcval, |
|---|
| 341 | | - uc_key->min, uc_key->max); |
|---|
| 382 | + printf(" %s: %d (%d, %d)\n", |
|---|
| 383 | + uc_key->in_volt ? "volt" : " adc", |
|---|
| 384 | + uc_key->center, uc_key->min, uc_key->max); |
|---|
| 342 | 385 | printf(" channel: %d\n\n", uc_key->channel); |
|---|
| 343 | 386 | } else { |
|---|
| 344 | 387 | const char *gpio_name = |
|---|