mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-08 14:14:32 +00:00
da7991b38e
Currently, we check argc in a number of places to make sure that we have all of the required arguments for each of the pwm sub-commands. However, there's at least one place where we've got dead code as we'll never have argc == 0, due to checking that argc was at least 4 earlier and having only subtracted 3. Rework things so that when we have determined our subcommand make sure we have the right number of arguments for it, or error out. This means we can stop checking against argc again later. Reported-by: Coverity (CID: 316601) Cc: Pragnesh Patel <pragnesh.patel@sifive.com> Signed-off-by: Tom Rini <trini@konsulko.com>
114 lines
2.4 KiB
C
114 lines
2.4 KiB
C
// SPDX-License-Identifier: GPL-2.0+
|
|
/*
|
|
* Control PWM channels
|
|
*
|
|
* Copyright (c) 2020 SiFive, Inc
|
|
* author: Pragnesh Patel <pragnesh.patel@sifive.com>
|
|
*/
|
|
|
|
#include <command.h>
|
|
#include <dm.h>
|
|
#include <pwm.h>
|
|
|
|
enum pwm_cmd {
|
|
PWM_SET_INVERT,
|
|
PWM_SET_CONFIG,
|
|
PWM_SET_ENABLE,
|
|
PWM_SET_DISABLE,
|
|
};
|
|
|
|
static int do_pwm(struct cmd_tbl *cmdtp, int flag, int argc,
|
|
char *const argv[])
|
|
{
|
|
const char *str_cmd, *str_channel = NULL, *str_enable = NULL;
|
|
const char *str_pwm = NULL, *str_period = NULL, *str_duty = NULL;
|
|
enum pwm_cmd sub_cmd;
|
|
struct udevice *dev;
|
|
u32 channel, pwm_enable, pwm_dev, period_ns = 0, duty_ns = 0;
|
|
int ret;
|
|
|
|
if (argc < 4)
|
|
return CMD_RET_USAGE;
|
|
|
|
str_cmd = argv[1];
|
|
argc -= 2;
|
|
argv += 2;
|
|
|
|
str_pwm = *argv;
|
|
argc--;
|
|
argv++;
|
|
|
|
if (!str_pwm)
|
|
return CMD_RET_USAGE;
|
|
|
|
switch (*str_cmd) {
|
|
case 'i':
|
|
sub_cmd = PWM_SET_INVERT;
|
|
if (argc != 2)
|
|
return CMD_RET_USAGE;
|
|
break;
|
|
case 'c':
|
|
sub_cmd = PWM_SET_CONFIG;
|
|
if (argc != 3)
|
|
return CMD_RET_USAGE;
|
|
break;
|
|
case 'e':
|
|
sub_cmd = PWM_SET_ENABLE;
|
|
if (argc != 1)
|
|
return CMD_RET_USAGE;
|
|
break;
|
|
case 'd':
|
|
sub_cmd = PWM_SET_DISABLE;
|
|
if (argc != 1)
|
|
return CMD_RET_USAGE;
|
|
break;
|
|
default:
|
|
return CMD_RET_USAGE;
|
|
}
|
|
|
|
pwm_dev = simple_strtoul(str_pwm, NULL, 10);
|
|
ret = uclass_get_device(UCLASS_PWM, pwm_dev, &dev);
|
|
if (ret) {
|
|
printf("pwm: '%s' not found\n", str_pwm);
|
|
return cmd_process_error(cmdtp, ret);
|
|
}
|
|
|
|
str_channel = *argv;
|
|
channel = simple_strtoul(str_channel, NULL, 10);
|
|
argc--;
|
|
argv++;
|
|
|
|
if (sub_cmd == PWM_SET_INVERT) {
|
|
str_enable = *argv;
|
|
pwm_enable = simple_strtoul(str_enable, NULL, 10);
|
|
ret = pwm_set_invert(dev, channel, pwm_enable);
|
|
} else if (sub_cmd == PWM_SET_CONFIG) {
|
|
str_period = *argv;
|
|
argc--;
|
|
argv++;
|
|
period_ns = simple_strtoul(str_period, NULL, 10);
|
|
|
|
str_duty = *argv;
|
|
duty_ns = simple_strtoul(str_duty, NULL, 10);
|
|
|
|
ret = pwm_set_config(dev, channel, period_ns, duty_ns);
|
|
} else if (sub_cmd == PWM_SET_ENABLE) {
|
|
ret = pwm_set_enable(dev, channel, 1);
|
|
} else if (sub_cmd == PWM_SET_DISABLE) {
|
|
ret = pwm_set_enable(dev, channel, 0);
|
|
}
|
|
|
|
if (ret) {
|
|
printf("error(%d)\n", ret);
|
|
return CMD_RET_FAILURE;
|
|
}
|
|
|
|
return CMD_RET_SUCCESS;
|
|
}
|
|
|
|
U_BOOT_CMD(pwm, 6, 0, do_pwm,
|
|
"control pwm channels",
|
|
"pwm <invert> <pwm_dev_num> <channel> <polarity>\n"
|
|
"pwm <config> <pwm_dev_num> <channel> <period_ns> <duty_ns>\n"
|
|
"pwm <enable/disable> <pwm_dev_num> <channel>\n"
|
|
"Note: All input values are in decimal");
|