]>
Commit | Line | Data |
---|---|---|
9e9a530a PP |
1 | // SPDX-License-Identifier: GPL-2.0+ |
2 | /* | |
3 | * Control PWM channels | |
4 | * | |
5 | * Copyright (c) 2020 SiFive, Inc | |
6 | * author: Pragnesh Patel <[email protected]> | |
7 | */ | |
8 | ||
9 | #include <command.h> | |
10 | #include <dm.h> | |
11 | #include <pwm.h> | |
12 | ||
13 | enum pwm_cmd { | |
14 | PWM_SET_INVERT, | |
15 | PWM_SET_CONFIG, | |
16 | PWM_SET_ENABLE, | |
17 | PWM_SET_DISABLE, | |
18 | }; | |
19 | ||
20 | static int do_pwm(struct cmd_tbl *cmdtp, int flag, int argc, | |
21 | char *const argv[]) | |
22 | { | |
23 | const char *str_cmd, *str_channel = NULL, *str_enable = NULL; | |
24 | const char *str_pwm = NULL, *str_period = NULL, *str_duty = NULL; | |
25 | enum pwm_cmd sub_cmd; | |
26 | struct udevice *dev; | |
27 | u32 channel, pwm_enable, pwm_dev, period_ns = 0, duty_ns = 0; | |
28 | int ret; | |
29 | ||
30 | if (argc < 4) | |
31 | return CMD_RET_USAGE; | |
32 | ||
33 | str_cmd = argv[1]; | |
34 | argc -= 2; | |
35 | argv += 2; | |
36 | ||
da7991b3 TR |
37 | str_pwm = *argv; |
38 | argc--; | |
39 | argv++; | |
9e9a530a PP |
40 | |
41 | if (!str_pwm) | |
42 | return CMD_RET_USAGE; | |
43 | ||
44 | switch (*str_cmd) { | |
45 | case 'i': | |
46 | sub_cmd = PWM_SET_INVERT; | |
da7991b3 TR |
47 | if (argc != 2) |
48 | return CMD_RET_USAGE; | |
9e9a530a PP |
49 | break; |
50 | case 'c': | |
51 | sub_cmd = PWM_SET_CONFIG; | |
da7991b3 TR |
52 | if (argc != 3) |
53 | return CMD_RET_USAGE; | |
9e9a530a PP |
54 | break; |
55 | case 'e': | |
56 | sub_cmd = PWM_SET_ENABLE; | |
da7991b3 TR |
57 | if (argc != 1) |
58 | return CMD_RET_USAGE; | |
9e9a530a PP |
59 | break; |
60 | case 'd': | |
61 | sub_cmd = PWM_SET_DISABLE; | |
da7991b3 TR |
62 | if (argc != 1) |
63 | return CMD_RET_USAGE; | |
9e9a530a PP |
64 | break; |
65 | default: | |
66 | return CMD_RET_USAGE; | |
67 | } | |
68 | ||
0b1284eb | 69 | pwm_dev = dectoul(str_pwm, NULL); |
9e9a530a PP |
70 | ret = uclass_get_device(UCLASS_PWM, pwm_dev, &dev); |
71 | if (ret) { | |
72 | printf("pwm: '%s' not found\n", str_pwm); | |
73 | return cmd_process_error(cmdtp, ret); | |
74 | } | |
75 | ||
da7991b3 | 76 | str_channel = *argv; |
0b1284eb | 77 | channel = dectoul(str_channel, NULL); |
da7991b3 TR |
78 | argc--; |
79 | argv++; | |
9e9a530a | 80 | |
da7991b3 | 81 | if (sub_cmd == PWM_SET_INVERT) { |
9e9a530a | 82 | str_enable = *argv; |
0b1284eb | 83 | pwm_enable = dectoul(str_enable, NULL); |
9e9a530a | 84 | ret = pwm_set_invert(dev, channel, pwm_enable); |
da7991b3 | 85 | } else if (sub_cmd == PWM_SET_CONFIG) { |
9e9a530a PP |
86 | str_period = *argv; |
87 | argc--; | |
88 | argv++; | |
0b1284eb | 89 | period_ns = dectoul(str_period, NULL); |
9e9a530a | 90 | |
da7991b3 | 91 | str_duty = *argv; |
0b1284eb | 92 | duty_ns = dectoul(str_duty, NULL); |
9e9a530a PP |
93 | |
94 | ret = pwm_set_config(dev, channel, period_ns, duty_ns); | |
95 | } else if (sub_cmd == PWM_SET_ENABLE) { | |
96 | ret = pwm_set_enable(dev, channel, 1); | |
97 | } else if (sub_cmd == PWM_SET_DISABLE) { | |
98 | ret = pwm_set_enable(dev, channel, 0); | |
9e9a530a PP |
99 | } |
100 | ||
101 | if (ret) { | |
102 | printf("error(%d)\n", ret); | |
103 | return CMD_RET_FAILURE; | |
104 | } | |
105 | ||
106 | return CMD_RET_SUCCESS; | |
107 | } | |
108 | ||
109 | U_BOOT_CMD(pwm, 6, 0, do_pwm, | |
110 | "control pwm channels", | |
a84d3b6c MS |
111 | "invert <pwm_dev_num> <channel> <polarity> - invert polarity\n" |
112 | "pwm config <pwm_dev_num> <channel> <period_ns> <duty_ns> - config PWM\n" | |
113 | "pwm enable <pwm_dev_num> <channel> - enable PWM output\n" | |
114 | "pwm disable <pwm_dev_num> <channel> - eisable PWM output\n" | |
9e9a530a | 115 | "Note: All input values are in decimal"); |