blob: 5849fc57b666f8bf9a8cd72f000a03e29b8af6f0 [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
37 if (argc > 0) {
38 str_pwm = *argv;
39 argc--;
40 argv++;
41 }
42
43 if (!str_pwm)
44 return CMD_RET_USAGE;
45
46 switch (*str_cmd) {
47 case 'i':
48 sub_cmd = PWM_SET_INVERT;
49 break;
50 case 'c':
51 sub_cmd = PWM_SET_CONFIG;
52 break;
53 case 'e':
54 sub_cmd = PWM_SET_ENABLE;
55 break;
56 case 'd':
57 sub_cmd = PWM_SET_DISABLE;
58 break;
59 default:
60 return CMD_RET_USAGE;
61 }
62
63 pwm_dev = simple_strtoul(str_pwm, NULL, 10);
64 ret = uclass_get_device(UCLASS_PWM, pwm_dev, &dev);
65 if (ret) {
66 printf("pwm: '%s' not found\n", str_pwm);
67 return cmd_process_error(cmdtp, ret);
68 }
69
70 if (argc > 0) {
71 str_channel = *argv;
72 channel = simple_strtoul(str_channel, NULL, 10);
73 argc--;
74 argv++;
75 } else {
76 return CMD_RET_USAGE;
77 }
78
79 if (sub_cmd == PWM_SET_INVERT && argc > 0) {
80 str_enable = *argv;
81 pwm_enable = simple_strtoul(str_enable, NULL, 10);
82 ret = pwm_set_invert(dev, channel, pwm_enable);
83 } else if (sub_cmd == PWM_SET_CONFIG && argc == 2) {
84 str_period = *argv;
85 argc--;
86 argv++;
87 period_ns = simple_strtoul(str_period, NULL, 10);
88
89 if (argc > 0) {
90 str_duty = *argv;
91 duty_ns = simple_strtoul(str_duty, NULL, 10);
92 }
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);
99 } else {
100 printf("PWM arguments missing\n");
101 return CMD_RET_FAILURE;
102 }
103
104 if (ret) {
105 printf("error(%d)\n", ret);
106 return CMD_RET_FAILURE;
107 }
108
109 return CMD_RET_SUCCESS;
110}
111
112U_BOOT_CMD(pwm, 6, 0, do_pwm,
113 "control pwm channels",
114 "pwm <invert> <pwm_dev_num> <channel> <polarity>\n"
115 "pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns>\n"
116 "pwm <enable/disable> <pwm_dev_num> <channel>\n"
117 "Note: All input values are in decimal");