1// 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 str_pwm = *argv; 38 argc--; 39 argv++; 40 41 if (!str_pwm) 42 return CMD_RET_USAGE; 43 44 switch (*str_cmd) { 45 case 'i': 46 sub_cmd = PWM_SET_INVERT; 47 if (argc != 2) 48 return CMD_RET_USAGE; 49 break; 50 case 'c': 51 sub_cmd = PWM_SET_CONFIG; 52 if (argc != 3) 53 return CMD_RET_USAGE; 54 break; 55 case 'e': 56 sub_cmd = PWM_SET_ENABLE; 57 if (argc != 1) 58 return CMD_RET_USAGE; 59 break; 60 case 'd': 61 sub_cmd = PWM_SET_DISABLE; 62 if (argc != 1) 63 return CMD_RET_USAGE; 64 break; 65 default: 66 return CMD_RET_USAGE; 67 } 68 69 pwm_dev = dectoul(str_pwm, NULL); 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 76 str_channel = *argv; 77 channel = dectoul(str_channel, NULL); 78 argc--; 79 argv++; 80 81 if (sub_cmd == PWM_SET_INVERT) { 82 str_enable = *argv; 83 pwm_enable = dectoul(str_enable, NULL); 84 ret = pwm_set_invert(dev, channel, pwm_enable); 85 } else if (sub_cmd == PWM_SET_CONFIG) { 86 str_period = *argv; 87 argc--; 88 argv++; 89 period_ns = dectoul(str_period, NULL); 90 91 str_duty = *argv; 92 duty_ns = dectoul(str_duty, NULL); 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 } 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 "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> - disable PWM output\n" 115 "Note: All input values are in decimal"); 116