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