1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
|
/* SPDX-License-Identifier: LGPL-2.1-only */
/* SPDX-FileCopyrightText: 2023-2025 Uwe Kleine-König <u.kleine-koenig@baylibre.com> */
#include "config.h"
#include <errno.h>
#include <stdlib.h>
#include <stdint.h>
#include <pwm.h>
#include "pwm-internal.h"
struct pwm_chip *pwm_chip_open_by_number(unsigned int num)
{
struct pwm_chip *chip;
chip = pwm_chip_cdev_open_by_number(num);
if (chip == NULL && errno == ENOENT)
chip = pwm_chip_sysfs_open_by_number(num);
return chip;
}
void pwm_chip_close(struct pwm_chip *chip)
{
chip->close(chip);
}
int pwm_chip_num_pwms(struct pwm_chip *chip)
{
return chip->npwm;
}
struct pwm *pwm_chip_get_pwm(struct pwm_chip *chip, unsigned int offset)
{
if (offset >= chip->npwm) {
errno = ENOENT;
return NULL;
}
return chip->get_pwm(chip, offset);
}
int pwm_round_waveform(struct pwm *pwm, struct pwm_waveform *wf)
{
if (!pwm->chip->round_waveform) {
errno = -ENOTSUP;
return -1;
}
if (wf->period_length_ns > INT64_MAX ||
wf->duty_length_ns > wf->period_length_ns ||
(wf->duty_offset_ns && wf->duty_offset_ns >= wf->period_length_ns)) {
errno = EINVAL;
return -1;
}
return pwm->chip->round_waveform(pwm, wf);
}
int pwm_set_waveform(struct pwm *pwm, const struct pwm_waveform *wf)
{
if (wf->period_length_ns > INT64_MAX ||
wf->duty_length_ns > wf->period_length_ns ||
(wf->duty_offset_ns && wf->duty_offset_ns >= wf->period_length_ns)) {
errno = EINVAL;
return -1;
}
return pwm->chip->set_waveform(pwm, wf);
}
int pwm_set_waveform_exact(struct pwm *pwm, const struct pwm_waveform *wf)
{
if (!pwm->chip->set_waveform_exact) {
errno = -ENOTSUP;
return -1;
}
if (wf->period_length_ns > INT64_MAX ||
wf->duty_length_ns > wf->period_length_ns ||
(wf->duty_offset_ns && wf->duty_offset_ns >= wf->period_length_ns)) {
errno = EINVAL;
return -1;
}
return pwm->chip->set_waveform_exact(pwm, wf);
}
int pwm_disable(struct pwm *pwm)
{
const struct pwm_waveform wf = { .period_length_ns = 0, };
return pwm->chip->set_waveform(pwm, &wf);
}
int pwm_get_waveform(struct pwm *pwm, struct pwm_waveform *wf)
{
return pwm->chip->get_waveform(pwm, wf);
}
|