xref: /openbmc/u-boot/cmd/adc.c (revision 6aa2831d6d23cd305ced57c31e72b73355b3f8b5)
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