xref: /openbmc/u-boot/cmd/adc.c (revision 77c07e7e)
1051ebe32SNeil Armstrong // SPDX-License-Identifier: GPL-2.0+
2051ebe32SNeil Armstrong /*
3051ebe32SNeil Armstrong  * Copyright (C) 2018 BayLibre, SAS
4051ebe32SNeil Armstrong  * Author: Neil Armstrong <narmstrong@baylibre.com>
5051ebe32SNeil Armstrong  */
6051ebe32SNeil Armstrong #include <common.h>
7051ebe32SNeil Armstrong #include <command.h>
8051ebe32SNeil Armstrong #include <dm.h>
9051ebe32SNeil Armstrong #include <adc.h>
10051ebe32SNeil Armstrong 
do_adc_list(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])11051ebe32SNeil Armstrong static int do_adc_list(cmd_tbl_t *cmdtp, int flag, int argc,
12051ebe32SNeil Armstrong 		       char *const argv[])
13051ebe32SNeil Armstrong {
14051ebe32SNeil Armstrong 	struct udevice *dev;
15051ebe32SNeil Armstrong 	int ret;
16051ebe32SNeil Armstrong 
17051ebe32SNeil Armstrong 	ret = uclass_first_device_err(UCLASS_ADC, &dev);
18051ebe32SNeil Armstrong 	if (ret) {
19051ebe32SNeil Armstrong 		printf("No available ADC device\n");
20051ebe32SNeil Armstrong 		return CMD_RET_FAILURE;
21051ebe32SNeil Armstrong 	}
22051ebe32SNeil Armstrong 
23051ebe32SNeil Armstrong 	do {
24051ebe32SNeil Armstrong 		printf("- %s\n", dev->name);
25051ebe32SNeil Armstrong 
26051ebe32SNeil Armstrong 		ret = uclass_next_device(&dev);
27051ebe32SNeil Armstrong 		if (ret)
28051ebe32SNeil Armstrong 			return CMD_RET_FAILURE;
29051ebe32SNeil Armstrong 	} while (dev);
30051ebe32SNeil Armstrong 
31051ebe32SNeil Armstrong 	return CMD_RET_SUCCESS;
32051ebe32SNeil Armstrong }
33051ebe32SNeil Armstrong 
do_adc_info(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])34051ebe32SNeil Armstrong static int do_adc_info(cmd_tbl_t *cmdtp, int flag, int argc,
35051ebe32SNeil Armstrong 		       char *const argv[])
36051ebe32SNeil Armstrong {
37051ebe32SNeil Armstrong 	struct udevice *dev;
381c84d904SFabrice Gasnier 	unsigned int data_mask, ch_mask;
39051ebe32SNeil Armstrong 	int ret, vss, vdd;
40051ebe32SNeil Armstrong 
41051ebe32SNeil Armstrong 	if (argc < 2)
42051ebe32SNeil Armstrong 		return CMD_RET_USAGE;
43051ebe32SNeil Armstrong 
44051ebe32SNeil Armstrong 	ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev);
45051ebe32SNeil Armstrong 	if (ret) {
46051ebe32SNeil Armstrong 		printf("Unknown ADC device %s\n", argv[1]);
47051ebe32SNeil Armstrong 		return CMD_RET_FAILURE;
48051ebe32SNeil Armstrong 	}
49051ebe32SNeil Armstrong 
50051ebe32SNeil Armstrong 	printf("ADC Device '%s' :\n", argv[1]);
51051ebe32SNeil Armstrong 
521c84d904SFabrice Gasnier 	ret = adc_channel_mask(dev, &ch_mask);
531c84d904SFabrice Gasnier 	if (!ret)
541c84d904SFabrice Gasnier 		printf("channel mask: %x\n", ch_mask);
551c84d904SFabrice Gasnier 
56051ebe32SNeil Armstrong 	ret = adc_data_mask(dev, &data_mask);
57051ebe32SNeil Armstrong 	if (!ret)
58051ebe32SNeil Armstrong 		printf("data mask: %x\n", data_mask);
59051ebe32SNeil Armstrong 
60051ebe32SNeil Armstrong 	ret = adc_vdd_value(dev, &vdd);
61051ebe32SNeil Armstrong 	if (!ret)
62051ebe32SNeil Armstrong 		printf("vdd: %duV\n", vdd);
63051ebe32SNeil Armstrong 
64051ebe32SNeil Armstrong 	ret = adc_vss_value(dev, &vss);
65051ebe32SNeil Armstrong 	if (!ret)
66051ebe32SNeil Armstrong 		printf("vss: %duV\n", vss);
67051ebe32SNeil Armstrong 
68051ebe32SNeil Armstrong 	return CMD_RET_SUCCESS;
69051ebe32SNeil Armstrong }
70051ebe32SNeil Armstrong 
do_adc_single(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])71051ebe32SNeil Armstrong static int do_adc_single(cmd_tbl_t *cmdtp, int flag, int argc,
72051ebe32SNeil Armstrong 			 char *const argv[])
73051ebe32SNeil Armstrong {
74c56fc49aSFabrice Gasnier 	struct udevice *dev;
75051ebe32SNeil Armstrong 	unsigned int data;
76c56fc49aSFabrice Gasnier 	int ret, uV;
77051ebe32SNeil Armstrong 
78051ebe32SNeil Armstrong 	if (argc < 3)
79051ebe32SNeil Armstrong 		return CMD_RET_USAGE;
80051ebe32SNeil Armstrong 
81051ebe32SNeil Armstrong 	ret = adc_channel_single_shot(argv[1], simple_strtol(argv[2], NULL, 0),
82051ebe32SNeil Armstrong 				      &data);
83051ebe32SNeil Armstrong 	if (ret) {
84051ebe32SNeil Armstrong 		printf("Error getting single shot for device %s channel %s\n",
85051ebe32SNeil Armstrong 		       argv[1], argv[2]);
86051ebe32SNeil Armstrong 		return CMD_RET_FAILURE;
87051ebe32SNeil Armstrong 	}
88051ebe32SNeil Armstrong 
89c56fc49aSFabrice Gasnier 	ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev);
90c56fc49aSFabrice Gasnier 	if (!ret && !adc_raw_to_uV(dev, data, &uV))
91c56fc49aSFabrice Gasnier 		printf("%u, %d uV\n", data, uV);
92c56fc49aSFabrice Gasnier 	else
93051ebe32SNeil Armstrong 		printf("%u\n", data);
94051ebe32SNeil Armstrong 
95051ebe32SNeil Armstrong 	return CMD_RET_SUCCESS;
96051ebe32SNeil Armstrong }
97051ebe32SNeil Armstrong 
do_adc_scan(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])9861927d28SFabrice Gasnier static int do_adc_scan(cmd_tbl_t *cmdtp, int flag, int argc,
9961927d28SFabrice Gasnier 		       char *const argv[])
10061927d28SFabrice Gasnier {
10161927d28SFabrice Gasnier 	struct adc_channel ch[ADC_MAX_CHANNEL];
10261927d28SFabrice Gasnier 	struct udevice *dev;
10361927d28SFabrice Gasnier 	unsigned int ch_mask;
10461927d28SFabrice Gasnier 	int i, chan, ret, uV;
10561927d28SFabrice Gasnier 
10661927d28SFabrice Gasnier 	if (argc < 2)
10761927d28SFabrice Gasnier 		return CMD_RET_USAGE;
10861927d28SFabrice Gasnier 
10961927d28SFabrice Gasnier 	ret = uclass_get_device_by_name(UCLASS_ADC, argv[1], &dev);
11061927d28SFabrice Gasnier 	if (ret) {
11161927d28SFabrice Gasnier 		pr_err("Can't get the ADC %s: %d\n", argv[1], ret);
11261927d28SFabrice Gasnier 		return CMD_RET_FAILURE;
11361927d28SFabrice Gasnier 	}
11461927d28SFabrice Gasnier 
11561927d28SFabrice Gasnier 	switch (argc) {
11661927d28SFabrice Gasnier 	case 3:
11761927d28SFabrice Gasnier 		ch_mask = simple_strtoul(argv[2], NULL, 0);
11861927d28SFabrice Gasnier 		if (ch_mask)
11961927d28SFabrice Gasnier 			break;
12061927d28SFabrice Gasnier 	case 2:
12161927d28SFabrice Gasnier 		ret = adc_channel_mask(dev, &ch_mask);
12261927d28SFabrice Gasnier 		if (ret) {
12361927d28SFabrice Gasnier 			pr_err("Can't get mask for %s: %d\n", dev->name, ret);
12461927d28SFabrice Gasnier 			return CMD_RET_FAILURE;
12561927d28SFabrice Gasnier 		}
12661927d28SFabrice Gasnier 		break;
12761927d28SFabrice Gasnier 	}
12861927d28SFabrice Gasnier 
12961927d28SFabrice Gasnier 	ret = adc_channels_single_shot(dev->name, ch_mask, ch);
13061927d28SFabrice Gasnier 	if (ret) {
13161927d28SFabrice Gasnier 		pr_err("Can't get single shot for %s (chans mask: 0x%x): %d\n",
13261927d28SFabrice Gasnier 		       dev->name, ch_mask, ret);
13361927d28SFabrice Gasnier 		return CMD_RET_FAILURE;
13461927d28SFabrice Gasnier 	}
13561927d28SFabrice Gasnier 
13661927d28SFabrice Gasnier 	for (chan = 0, i = 0; chan < ADC_MAX_CHANNEL; chan++) {
13761927d28SFabrice Gasnier 		if (!(ch_mask & ADC_CHANNEL(chan)))
13861927d28SFabrice Gasnier 			continue;
13961927d28SFabrice Gasnier 		if (!adc_raw_to_uV(dev, ch[i].data, &uV))
14061927d28SFabrice Gasnier 			printf("[%02d]: %u, %d uV\n", ch[i].id, ch[i].data, uV);
14161927d28SFabrice Gasnier 		else
14261927d28SFabrice Gasnier 			printf("[%02d]: %u\n", ch[i].id, ch[i].data);
14361927d28SFabrice Gasnier 		i++;
14461927d28SFabrice Gasnier 	}
14561927d28SFabrice Gasnier 
14661927d28SFabrice Gasnier 	return CMD_RET_SUCCESS;
14761927d28SFabrice Gasnier }
14861927d28SFabrice Gasnier 
149051ebe32SNeil Armstrong static char adc_help_text[] =
150051ebe32SNeil Armstrong 	"list - list ADC devices\n"
151051ebe32SNeil Armstrong 	"adc info <name> - Get ADC device info\n"
15261927d28SFabrice Gasnier 	"adc single <name> <channel> - Get Single data of ADC device channel\n"
15361927d28SFabrice Gasnier 	"adc scan <name> [channel mask] - Scan all [or masked] ADC channels";
154051ebe32SNeil Armstrong 
155*9652cfd9SBoris Brezillon U_BOOT_CMD_WITH_SUBCMDS(adc, "ADC sub-system", adc_help_text,
156*9652cfd9SBoris Brezillon 	U_BOOT_SUBCMD_MKENT(list, 1, 1, do_adc_list),
157*9652cfd9SBoris Brezillon 	U_BOOT_SUBCMD_MKENT(info, 2, 1, do_adc_info),
158*9652cfd9SBoris Brezillon 	U_BOOT_SUBCMD_MKENT(single, 3, 1, do_adc_single),
159*9652cfd9SBoris Brezillon 	U_BOOT_SUBCMD_MKENT(scan, 3, 1, do_adc_scan));
160