blob: 70d5c78c33f981dc901d7cfbb958da4f35a723ec [file] [log] [blame]
Daniel Leung56bfe612015-09-21 15:39:22 -07001/*
Jeff Blaisfa095a62016-02-26 15:23:55 -05002 * Copyright (c) 2016 Intel Corporation.
Daniel Leung56bfe612015-09-21 15:39:22 -07003 *
David B. Kinderac74d8b2017-01-18 17:01:01 -08004 * SPDX-License-Identifier: Apache-2.0
Daniel Leung56bfe612015-09-21 15:39:22 -07005 */
6
7/**
Anas Nashif629e69b2015-10-04 10:01:56 -04008 * @file
9 * @brief Public PWM Driver APIs
Daniel Leung56bfe612015-09-21 15:39:22 -070010 */
11
12#ifndef __PWM_H__
13#define __PWM_H__
14
Anas Nashif75482aa2015-10-26 06:18:44 -040015/**
16 * @brief PWM Interface
17 * @defgroup pwm_interface PWM Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
Daniel Leung56bfe612015-09-21 15:39:22 -070022#ifdef __cplusplus
23extern "C" {
24#endif
25
26#define PWM_ACCESS_BY_PIN 0
27#define PWM_ACCESS_ALL 1
28
Andre Guedes245e1402016-03-09 14:54:42 -030029#include <errno.h>
Kumar Gala78908162017-04-19 10:32:08 -050030#include <zephyr/types.h>
Daniel Leung56bfe612015-09-21 15:39:22 -070031#include <stddef.h>
32#include <device.h>
33
Inaky Perez-Gonzalez05180632016-06-15 14:18:38 -070034/**
Baohong Liu56e0b532016-09-20 11:57:50 -070035 * @typedef pwm_pin_set_t
36 * @brief Callback API upon setting the pin
37 * See @a pwm_pin_set_cycles() for argument description
38 */
Kumar Galacc334c72017-04-21 10:55:34 -050039typedef int (*pwm_pin_set_t)(struct device *dev, u32_t pwm,
40 u32_t period_cycles, u32_t pulse_cycles);
Baohong Liu56e0b532016-09-20 11:57:50 -070041
42/**
43 * @typedef pwm_get_cycles_per_sec_t
44 * @brief Callback API upon getting cycles per second
45 * See @a pwm_get_cycles_per_sec() for argument description
46 */
Kumar Galacc334c72017-04-21 10:55:34 -050047typedef int (*pwm_get_cycles_per_sec_t)(struct device *dev, u32_t pwm,
48 u64_t *cycles);
Baohong Liu56e0b532016-09-20 11:57:50 -070049
Rodrigo Caballeroa7738f42016-02-07 12:56:47 -060050/** @brief PWM driver API definition. */
Daniel Leung56bfe612015-09-21 15:39:22 -070051struct pwm_driver_api {
Baohong Liu56e0b532016-09-20 11:57:50 -070052 pwm_pin_set_t pin_set;
53 pwm_get_cycles_per_sec_t get_cycles_per_sec;
Daniel Leung56bfe612015-09-21 15:39:22 -070054};
55
56/**
Baohong Liu56e0b532016-09-20 11:57:50 -070057 * @brief Set the period and pulse width for a single PWM output.
58 *
59 * @param dev Pointer to the device structure for the driver instance.
60 * @param pwm PWM pin.
61 * @param period Period (in clock cycle) set to the PWM. HW specific.
62 * @param pulse Pulse width (in clock cycle) set to the PWM. HW specific.
63 *
64 * @retval 0 If successful.
65 * @retval Negative errno code if failure.
66 */
Andrew Boie0f66b9f2017-10-25 11:27:37 -070067__syscall int pwm_pin_set_cycles(struct device *dev, u32_t pwm,
68 u32_t period, u32_t pulse);
69
70static inline int _impl_pwm_pin_set_cycles(struct device *dev, u32_t pwm,
71 u32_t period, u32_t pulse)
Baohong Liu56e0b532016-09-20 11:57:50 -070072{
73 struct pwm_driver_api *api;
74
75 api = (struct pwm_driver_api *)dev->driver_api;
76 return api->pin_set(dev, pwm, period, pulse);
77}
78
79/**
Andrew Boie0f66b9f2017-10-25 11:27:37 -070080 * @brief Get the clock rate (cycles per second) for a single PWM output.
81 *
82 * @param dev Pointer to the device structure for the driver instance.
83 * @param pwm PWM pin.
84 * @param cycles Pointer to the memory to store clock rate (cycles per sec).
85 * HW specific.
86 *
87 * @retval 0 If successful.
88 * @retval Negative errno code if failure.
89 */
90
91__syscall int pwm_get_cycles_per_sec(struct device *dev, u32_t pwm,
92 u64_t *cycles);
93
94static inline int _impl_pwm_get_cycles_per_sec(struct device *dev, u32_t pwm,
95 u64_t *cycles)
96{
97 struct pwm_driver_api *api;
98
99 api = (struct pwm_driver_api *)dev->driver_api;
100 return api->get_cycles_per_sec(dev, pwm, cycles);
101}
102
103/**
Baohong Liu56e0b532016-09-20 11:57:50 -0700104 * @brief Set the period and pulse width for a single PWM output.
105 *
106 * @param dev Pointer to the device structure for the driver instance.
107 * @param pwm PWM pin.
108 * @param period Period (in micro second) set to the PWM.
109 * @param pulse Pulse width (in micro second) set to the PWM.
110 *
111 * @retval 0 If successful.
112 * @retval Negative errno code if failure.
113 */
Kumar Galacc334c72017-04-21 10:55:34 -0500114static inline int pwm_pin_set_usec(struct device *dev, u32_t pwm,
115 u32_t period, u32_t pulse)
Baohong Liu56e0b532016-09-20 11:57:50 -0700116{
Kumar Galacc334c72017-04-21 10:55:34 -0500117 u64_t period_cycles, pulse_cycles, cycles_per_sec;
Baohong Liu56e0b532016-09-20 11:57:50 -0700118
Andrew Boie0f66b9f2017-10-25 11:27:37 -0700119 if (pwm_get_cycles_per_sec(dev, pwm, &cycles_per_sec) != 0) {
Baohong Liu56e0b532016-09-20 11:57:50 -0700120 return -EIO;
121 }
122
123 period_cycles = (period * cycles_per_sec) / USEC_PER_SEC;
Kumar Galacc334c72017-04-21 10:55:34 -0500124 if (period_cycles >= ((u64_t)1 << 32)) {
Baohong Liu56e0b532016-09-20 11:57:50 -0700125 return -ENOTSUP;
126 }
127
128 pulse_cycles = (pulse * cycles_per_sec) / USEC_PER_SEC;
Kumar Galacc334c72017-04-21 10:55:34 -0500129 if (pulse_cycles >= ((u64_t)1 << 32)) {
Baohong Liu56e0b532016-09-20 11:57:50 -0700130 return -ENOTSUP;
131 }
132
Andrew Boie0f66b9f2017-10-25 11:27:37 -0700133 return pwm_pin_set_cycles(dev, pwm, (u32_t)period_cycles,
134 (u32_t)pulse_cycles);
Baohong Liu56e0b532016-09-20 11:57:50 -0700135}
136
Daniel Leung56bfe612015-09-21 15:39:22 -0700137#ifdef __cplusplus
138}
139#endif
140
Anas Nashif75482aa2015-10-26 06:18:44 -0400141/**
142 * @}
143 */
144
Andrew Boie0f66b9f2017-10-25 11:27:37 -0700145#include <syscalls/pwm.h>
146
Daniel Leung56bfe612015-09-21 15:39:22 -0700147#endif /* __PWM_H__ */