1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2018 BayLibre, SAS 4 * Author: Neil Armstrong <narmstrong@baylibre.com> 5 */ 6 #include <common.h> 7 #include <command.h> 8 #include <dm.h> 9 #include <adc.h> 10 11 static int do_adc_list(cmd_tbl_t *cmdtp, int flag, int argc, 12 char *const argv[]) 13 { 14 struct udevice *dev; 15 int ret; 16 17 ret = uclass_first_device_err(UCLASS_ADC, &dev); 18 if (ret) { 19 printf("No available ADC device\n"); 20 return CMD_RET_FAILURE; 21 } 22 23 do { 24 printf("- %s\n", dev->name); 25 26 ret = uclass_next_device(&dev); 27 if (ret) 28 return CMD_RET_FAILURE; 29 } while (dev); 30 31 return CMD_RET_SUCCESS; 32 } 33 34 static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc, 35 char *const argv[]) 36 { 37 struct udevice *dev; 38 unsigned int data_mask, ch_mask; 39 int ret, vss, vdd; 40 41 if (argc < 2) 42 return CMD_RET_USAGE; 43 44 ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); 45 if (ret) { 46 printf("Unknown ADC device %s\n", argv[1]); 47 return CMD_RET_FAILURE; 48 } 49 50 printf("ADC Device '%s' :\n", argv[1]); 51 52 ret = adc_channel_mask(dev, &ch_mask); 53 if (!ret) 54 printf("channel mask: %x\n", ch_mask); 55 56 ret = adc_data_mask(dev, &data_mask); 57 if (!ret) 58 printf("data mask: %x\n", data_mask); 59 60 ret = adc_vdd_value(dev, &vdd); 61 if (!ret) 62 printf("vdd: %duV\n", vdd); 63 64 ret = adc_vss_value(dev, &vss); 65 if (!ret) 66 printf("vss: %duV\n", vss); 67 68 return CMD_RET_SUCCESS; 69 } 70 71 static int do_adc_single(cmd_tbl_t *cmdtp, int flag, int argc, 72 char *const argv[]) 73 { 74 struct udevice *dev; 75 unsigned int data; 76 int ret, uV; 77 78 if (argc < 3) 79 return CMD_RET_USAGE; 80 81 ret = adc_channel_single_shot(argv[1], simple_strtol(argv[2], NULL, 0), 82 &data); 83 if (ret) { 84 printf("Error getting single shot for device %s channel %s\n", 85 argv[1], argv[2]); 86 return CMD_RET_FAILURE; 87 } 88 89 ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); 90 if (!ret && !adc_raw_to_uV(dev, data, &uV)) 91 printf("%u, %d uV\n", data, uV); 92 else 93 printf("%u\n", data); 94 95 return CMD_RET_SUCCESS; 96 } 97 98 static int do_adc_scan(cmd_tbl_t *cmdtp, int flag, int argc, 99 char *const argv[]) 100 { 101 struct adc_channel ch[ADC_MAX_CHANNEL]; 102 struct udevice *dev; 103 unsigned int ch_mask; 104 int i, chan, ret, uV; 105 106 if (argc < 2) 107 return CMD_RET_USAGE; 108 109 ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev); 110 if (ret) { 111 pr_err("Can't get the ADC %s: %d\n", argv[1], ret); 112 return CMD_RET_FAILURE; 113 } 114 115 switch (argc) { 116 case 3: 117 ch_mask = simple_strtoul(argv[2], NULL, 0); 118 if (ch_mask) 119 break; 120 case 2: 121 ret = adc_channel_mask(dev, &ch_mask); 122 if (ret) { 123 pr_err("Can't get mask for %s: %d\n", dev->name, ret); 124 return CMD_RET_FAILURE; 125 } 126 break; 127 } 128 129 ret = adc_channels_single_shot(dev->name, ch_mask, ch); 130 if (ret) { 131 pr_err("Can't get single shot for %s (chans mask: 0x%x): %d\n", 132 dev->name, ch_mask, ret); 133 return CMD_RET_FAILURE; 134 } 135 136 for (chan = 0, i = 0; chan < ADC_MAX_CHANNEL; chan++) { 137 if (!(ch_mask & ADC_CHANNEL(chan))) 138 continue; 139 if (!adc_raw_to_uV(dev, ch[i].data, &uV)) 140 printf("[%02d]: %u, %d uV\n", ch[i].id, ch[i].data, uV); 141 else 142 printf("[%02d]: %u\n", ch[i].id, ch[i].data); 143 i++; 144 } 145 146 return CMD_RET_SUCCESS; 147 } 148 149 static char adc_help_text[] = 150 "list - list ADC devices\n" 151 "adc info <name> - Get ADC device info\n" 152 "adc single <name> <channel> - Get Single data of ADC device channel\n" 153 "adc scan <name> [channel mask] - Scan all [or masked] ADC channels"; 154 155 U_BOOT_CMD_WITH_SUBCMDS(adc, "ADC sub-system", adc_help_text, 156 U_BOOT_SUBCMD_MKENT(list, 1, 1, do_adc_list), 157 U_BOOT_SUBCMD_MKENT(info, 2, 1, do_adc_info), 158 U_BOOT_SUBCMD_MKENT(single, 3, 1, do_adc_single), 159 U_BOOT_SUBCMD_MKENT(scan, 3, 1, do_adc_scan)); 160