diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/linux/hard_pwm.c | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/src/linux/hard_pwm.c b/src/linux/hard_pwm.c index 25bfb2e7..f14b844b 100644 --- a/src/linux/hard_pwm.c +++ b/src/linux/hard_pwm.c @@ -10,6 +10,7 @@ #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> +#include <errno.h> // errno, ENOENT #include "gpio.h" // struct gpio_pwm #include "internal.h" // NSECS_PER_TICK @@ -20,16 +21,21 @@ DECL_CONSTANT("PWM_MAX", MAX_PWM); #define HARD_PWM_START (1<<16) -#define HARD_PWM(chip, pin) (((chip)<<8) + (pin) + HARD_PWM_START) -#define HARD_PWM_TO_CHIP(hard_pwm) (((hard_pwm) - HARD_PWM_START) >> 8) -#define HARD_PWM_TO_PIN(hard_pwm) (((hard_pwm) - HARD_PWM_START) & 0xff) +#define HARD_PWM(chip, pin) (((chip)<<4) + (pin) + HARD_PWM_START) +#define HARD_PWM_TO_CHIP(hard_pwm) (((hard_pwm) - HARD_PWM_START) >> 4) +#define HARD_PWM_TO_PIN(hard_pwm) (((hard_pwm) - HARD_PWM_START) & 0xf) -DECL_ENUMERATION_RANGE("pin", "pwmchip0/pwm0", HARD_PWM(0, 0), 256); -DECL_ENUMERATION_RANGE("pin", "pwmchip1/pwm0", HARD_PWM(1, 0), 256); -DECL_ENUMERATION_RANGE("pin", "pwmchip2/pwm0", HARD_PWM(2, 0), 256); -DECL_ENUMERATION_RANGE("pin", "pwmchip3/pwm0", HARD_PWM(3, 0), 256); +DECL_ENUMERATION_RANGE("pin", "pwmchip0/pwm0", HARD_PWM(0, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip1/pwm0", HARD_PWM(1, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip2/pwm0", HARD_PWM(2, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip3/pwm0", HARD_PWM(3, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip4/pwm0", HARD_PWM(4, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip5/pwm0", HARD_PWM(5, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip6/pwm0", HARD_PWM(6, 0), 16); +DECL_ENUMERATION_RANGE("pin", "pwmchip7/pwm0", HARD_PWM(7, 0), 16); #define PWM_PATH "/sys/class/pwm/pwmchip%u/pwm%u/%s" +#define PWM_PATH_BB "/sys/class/pwm/pwm-%u:%u/%s" struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint16_t val) { @@ -37,15 +43,26 @@ struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint16_t val) char scratch[16]; uint8_t chip_id = HARD_PWM_TO_CHIP(pin); uint8_t pwm_id = HARD_PWM_TO_PIN(pin); + const char * pwm_path = PWM_PATH; struct gpio_pwm g = {}; g.period = cycle_time * NSECS_PER_TICK; // configure period/cycle time. Always in nanoseconds - snprintf(filename, sizeof(filename), PWM_PATH, chip_id, pwm_id, "period"); + snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, "period"); int fd = open(filename, O_WRONLY|O_CLOEXEC); - if (fd == -1) { - report_errno("pwm period", fd); + if (fd == -1 && errno == ENOENT) { + // upstream pwm control file does not exists try BeagleBoard scheme + pwm_path = PWM_PATH_BB; + snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, + "period"); + fd = open(filename, O_WRONLY|O_CLOEXEC); + if (fd == -1) { + report_errno("pwm " PWM_PATH_BB "period for pin", pin); + goto fail; + } + } else if (fd == -1) { + report_errno("pwm " PWM_PATH "period for pin", pin); goto fail; } snprintf(scratch, sizeof(scratch), "%u", cycle_time * NSECS_PER_TICK); @@ -53,7 +70,7 @@ struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint16_t val) close(fd); // write duty cycle - snprintf(filename, sizeof(filename), PWM_PATH, chip_id, pwm_id, + snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, "duty_cycle"); fd = open(filename, O_WRONLY|O_CLOEXEC); if (fd == -1) { @@ -65,7 +82,7 @@ struct gpio_pwm gpio_pwm_setup(uint8_t pin, uint32_t cycle_time, uint16_t val) gpio_pwm_write(g, val); // enable PWM - snprintf(filename, sizeof(filename), PWM_PATH, chip_id, pwm_id, "enable"); + snprintf(filename, sizeof(filename), pwm_path, chip_id, pwm_id, "enable"); fd = open(filename, O_WRONLY|O_CLOEXEC); if (fd == -1) { close(g.fd); |