/*
 * Copyright (c) 2020-2021 Vestas Wind Systems A/S
 *
 * SPDX-License-Identifier: Apache-2.0
 */


#include <zephyr/zephyr.h>
#include <zephyr/drivers/pwm.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(pwm_capture, CONFIG_PWM_LOG_LEVEL);

struct z_pwm_capture_cb_data {
	uint32_t period;
	uint32_t pulse;
	struct k_sem sem;
	int status;
};

static void z_pwm_capture_cycles_callback(const struct device *dev,
					  uint32_t channel,
					  uint32_t period_cycles,
					  uint32_t pulse_cycles, int status,
					  void *user_data)
{
	struct z_pwm_capture_cb_data *data = user_data;

	data->period = period_cycles;
	data->pulse = pulse_cycles;
	data->status = status;

	k_sem_give(&data->sem);
}

int z_impl_pwm_capture_cycles(const struct device *dev, uint32_t channel,
			      pwm_flags_t flags, uint32_t *period,
			      uint32_t *pulse, k_timeout_t timeout)
{
	struct z_pwm_capture_cb_data data;
	int err;

	if ((flags & PWM_CAPTURE_MODE_MASK) == PWM_CAPTURE_MODE_CONTINUOUS) {
		LOG_ERR("continuous capture mode only supported via callback");
		return -ENOTSUP;
	}

	flags |= PWM_CAPTURE_MODE_SINGLE;
	k_sem_init(&data.sem, 0, 1);

	err = pwm_configure_capture(dev, channel, flags,
				    z_pwm_capture_cycles_callback, &data);
	if (err) {
		LOG_ERR("failed to configure pwm capture");
		return err;
	}

	err = pwm_enable_capture(dev, channel);
	if (err) {
		LOG_ERR("failed to enable pwm capture");
		return err;
	}

	err = k_sem_take(&data.sem, timeout);
	if (err == -EAGAIN) {
		(void)pwm_disable_capture(dev, channel);
		(void)pwm_configure_capture(dev, channel, flags, NULL, NULL);
		LOG_WRN("pwm capture timed out");
		return err;
	}

	if (data.status == 0) {
		if (period != NULL) {
			*period = data.period;
		}

		if (pulse != NULL) {
			*pulse = data.pulse;
		}
	}

	return data.status;
}
