blob: 87d840a2b9bd02bf2d79b1af98a3ea1786fdd95e [file] [log] [blame]
Pragnesh Patel9e9a5302020-12-22 11:30:05 +05301// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Control PWM channels
4 *
5 * Copyright (c) 2020 SiFive, Inc
6 * author: Pragnesh Patel <pragnesh.patel@sifive.com>
7 */
8
9#include <command.h>
10#include <dm.h>
11#include <pwm.h>
12
13enum pwm_cmd {
14 PWM_SET_INVERT,
15 PWM_SET_CONFIG,
16 PWM_SET_ENABLE,
17 PWM_SET_DISABLE,
18};
19
20static 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
Tom Rinida7991b2021-01-26 11:44:37 -050037 str_pwm = *argv;
38 argc--;
39 argv++;
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053040
41 if (!str_pwm)
42 return CMD_RET_USAGE;
43
44 switch (*str_cmd) {
45 case 'i':
46 sub_cmd = PWM_SET_INVERT;
Tom Rinida7991b2021-01-26 11:44:37 -050047 if (argc != 2)
48 return CMD_RET_USAGE;
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053049 break;
50 case 'c':
51 sub_cmd = PWM_SET_CONFIG;
Tom Rinida7991b2021-01-26 11:44:37 -050052 if (argc != 3)
53 return CMD_RET_USAGE;
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053054 break;
55 case 'e':
56 sub_cmd = PWM_SET_ENABLE;
Tom Rinida7991b2021-01-26 11:44:37 -050057 if (argc != 1)
58 return CMD_RET_USAGE;
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053059 break;
60 case 'd':
61 sub_cmd = PWM_SET_DISABLE;
Tom Rinida7991b2021-01-26 11:44:37 -050062 if (argc != 1)
63 return CMD_RET_USAGE;
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053064 break;
65 default:
66 return CMD_RET_USAGE;
67 }
68
Simon Glass0b1284e2021-07-24 09:03:30 -060069 pwm_dev = dectoul(str_pwm, NULL);
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053070 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
Tom Rinida7991b2021-01-26 11:44:37 -050076 str_channel = *argv;
Simon Glass0b1284e2021-07-24 09:03:30 -060077 channel = dectoul(str_channel, NULL);
Tom Rinida7991b2021-01-26 11:44:37 -050078 argc--;
79 argv++;
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053080
Tom Rinida7991b2021-01-26 11:44:37 -050081 if (sub_cmd == PWM_SET_INVERT) {
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053082 str_enable = *argv;
Simon Glass0b1284e2021-07-24 09:03:30 -060083 pwm_enable = dectoul(str_enable, NULL);
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053084 ret = pwm_set_invert(dev, channel, pwm_enable);
Tom Rinida7991b2021-01-26 11:44:37 -050085 } else if (sub_cmd == PWM_SET_CONFIG) {
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053086 str_period = *argv;
87 argc--;
88 argv++;
Simon Glass0b1284e2021-07-24 09:03:30 -060089 period_ns = dectoul(str_period, NULL);
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053090
Tom Rinida7991b2021-01-26 11:44:37 -050091 str_duty = *argv;
Simon Glass0b1284e2021-07-24 09:03:30 -060092 duty_ns = dectoul(str_duty, NULL);
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053093
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);
Pragnesh Patel9e9a5302020-12-22 11:30:05 +053099 }
100
101 if (ret) {
102 printf("error(%d)\n", ret);
103 return CMD_RET_FAILURE;
104 }
105
106 return CMD_RET_SUCCESS;
107}
108
109U_BOOT_CMD(pwm, 6, 0, do_pwm,
110 "control pwm channels",
111 "pwm <invert> <pwm_dev_num> <channel> <polarity>\n"
112 "pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns>\n"
113 "pwm <enable/disable> <pwm_dev_num> <channel>\n"
114 "Note: All input values are in decimal");