devicetree.h: pwms: Add DT_PWMS_ macros

Add DT_PWMS macros to be used in pwm clients drivers.

Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
This commit is contained in:
Kumar Gala 2020-04-27 12:06:50 -05:00 committed by Kumar Gala
commit 689f93bc33
6 changed files with 525 additions and 0 deletions

View file

@ -14,3 +14,5 @@ properties:
gpios: {type: "phandle-array"}
foos: {type: "phandle-array"}
foo-names: {type: "string-array"}
pwms: {type: "phandle-array"}
pwm-names: {type: "string-array"}

View file

@ -0,0 +1,19 @@
# Copyright (c) 2020, Linaro Limited
# SPDX-License-Identifier: Apache-2.0
description: VND PWM controller
compatible: "vnd,pwm"
include: [pwm-controller.yaml, base.yaml]
properties:
reg:
required: true
"#pwm-cells":
const: 2
pwm-cells:
- channel
- flags

View file

@ -1535,6 +1535,7 @@
#include <devicetree/gpio.h>
#include <devicetree/spi.h>
#include <devicetree/dma.h>
#include <devicetree/pwms.h>
#include <devicetree/zephyr.h>
#endif /* DEVICETREE_H */

379
include/devicetree/pwms.h Normal file
View file

@ -0,0 +1,379 @@
/**
* @file
* @brief PWMs Devicetree macro public API header file.
*/
/*
* Copyright (c) 2020, Linaro Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DEVICETREE_PWMS_H_
#define ZEPHYR_INCLUDE_DEVICETREE_PWMS_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup devicetree-pwms Devicetree PWMs API
* @ingroup devicetree
* @{
*/
/**
* @brief Get pwm controller "name" (label property) at an index
*
* It's an error if the pwm controller referenced by the phandle
* in property "pwms" at index "idx" has no label property.
*
* Example devicetree fragment:
*
* pwm1: pwm-controller@... {
* label = "PWM_1";
* };
*
* pwm2: pwm-controller@... {
* label = "PWM_2";
* };
*
* n: node {
* pwms = <&pwm1 1 PWM_POLARITY_NORMAL>,
* <&pwm2 3 PWM_POLARITY_INVERTED>;
* };
*
* Example usage:
*
* DT_PWMS_LABEL_BY_IDX(DT_NODELABEL(n), 1) // "PWM_2"
*
* @param node_id node identifier
* @param idx logical index into the property
* @return the label property for the referenced node at index idx
* @see DT_PROP_BY_PHANDLE_IDX()
*/
#define DT_PWMS_LABEL_BY_IDX(node_id, idx) \
DT_PROP_BY_PHANDLE_IDX(node_id, pwms, idx, label)
/**
* @brief Get pwm controller "name" (label property) by name
*
* It's an error if the pwm controller referenced by the phandle
* in property "pwms" by name "name" has no label property.
*
* Example devicetree fragment:
*
* pwm1: pwm-controller@... {
* label = "PWM_1";
* };
*
* pwm2: pwm-controller@... {
* label = "PWM_2";
* };
*
* n: node {
* pwms = <&pwm1 1 PWM_POLARITY_NORMAL>,
* <&pwm2 3 PWM_POLARITY_INVERTED>;
* pwm-names = "alpha", "beta";
* };
*
* Example usage:
*
* DT_PWMS_LABEL_BY_NAME(DT_NODELABEL(n), beta) // "PWM_2"
*
* @param node_id node identifier
* @param name lowercase-and-underscores "pwm" name
* @return the label property for the referenced node by name
* @see DT_PHANDLE_BY_NAME()
*/
#define DT_PWMS_LABEL_BY_NAME(node_id, name) \
DT_PROP(DT_PHANDLE_BY_NAME(node_id, pwms, name), label)
/**
* @brief Equivalent to DT_PWMS_LABEL_BY_IDX(node_id, 0)
* @param node_id node identifier
* @return the label property for the named specifier at index 0
* @see DT_PWMS_LABEL_BY_IDX()
*/
#define DT_PWMS_LABEL(node_id) DT_PWMS_LABEL_BY_IDX(node_id, 0)
/**
* @brief Get PWM controller "cell" value at an index
*
* Example devicetree fragment:
*
* pwm1: pwm-controller@... {
* label = "PWM_1";
* #pwm-cells = <2>;
* };
*
* n: node {
* pwms = <&pwm1 1 PWM_POLARITY_NORMAL>,
* <&pwm2 3 PWM_POLARITY_INVERTED>;
* };
*
* Bindings fragment for the gpio0 node:
*
* pwm-cells:
* - channel
* - flags
*
* Example usage:
*
* DT_PWMS_CELL_BY_IDX(DT_NODELABEL(n), channel, 0) // 1
* DT_PWMS_CELL_BY_IDX(DT_NODELABEL(n), flags, 1) // PWM_POLARITY_INVERTED
*
* @param node_id node identifier
* @param cell binding's cell name within the specifier at index "idx"
* @param idx logical index into the property
* @return the value of the cell inside the specifier at index "idx"
* @see DT_PHA_PHANDLE_IDX()
*/
#define DT_PWMS_CELL_BY_IDX(node_id, cell, idx) \
DT_PHA_BY_IDX(node_id, pwms, idx, cell)
/**
* @brief Get pwm controller "cell" value by name
*
* Example devicetree fragment:
*
* pwm1: pwm-controller@... {
* label = "PWM_1";
* #pwm-cells = <2>;
* };
*
* n: node {
* pwms = <&pwm1 1 PWM_POLARITY_NORMAL>,
* <&pwm2 3 PWM_POLARITY_INVERTED>;
* pwm-names = "alpha", "beta";
* };
*
* Bindings fragment for the pwm1 node:
*
* pwm-cells:
* - channel
* - flags
*
* Example usage:
*
* DT_PWMS_CELL_BY_NAME(DT_NODELABEL(n), alpha, channel) // 1
* DT_PWMS_CELL_BY_NAME(DT_NODELABEL(n), beta, flags) // PWM_POLARITY_INVERTED
*
* @param node_id node identifier
* @param name lowercase-and-underscores specifier name
* @param cell binding's cell name within the specifier referenced as "name"
* @return the value of the cell inside the named specifier
* @see DT_PHA_BY_NAME()
*/
#define DT_PWMS_CELL_BY_NAME(node_id, name, cell) \
DT_PHA_BY_NAME(node_id, pwms, name, cell)
/**
* @brief Equivalent to DT_PWMS_CELL_BY_IDX(node_id, cell, 0)
* @param node_id node identifier
* @param cell binding's cell name within the specifier at index 0
* @return the value of the cell inside the specifier at index 0
* @see DT_PWMS_CELL_BY_IDX()
*/
#define DT_PWMS_CELL(node_id, cell) DT_PWMS_CELL_BY_IDX(node_id, cell, 0)
/**
* @brief Get pwm controller 'channel' at an index
*
* This macro only works for PWM controllers that specify a 'channel'
* field in the phandle-array specifier. Refer to the specific PWM
* controller binding if needed.
*
* @param node_id node identifier
* @param idx logical index into the property
* @return the channel value for the named specifier at index idx
* @see DT_PWMS_CELL_BY_IDX()
*/
#define DT_PWMS_CHANNEL_BY_IDX(node_id, idx) \
DT_PWMS_CELL_BY_IDX(node_id, channel, idx)
/**
* @brief Get PWM controller 'channel' by name
*
* This macro only works for PWM controllers that specify a 'channel'
* field in the phandle-array specifier. Refer to the specific PWM
* controller binding if needed.
*
* @param node_id node identifier
* @param name lowercase-and-underscores "pwm" name
* @return the channel value for the named specifier by name
* @see DT_PWMS_CELL_BY_NAME()
*/
#define DT_PWMS_CHANNEL_BY_NAME(node_id, name) \
DT_PWMS_CELL_BY_NAME(node_id, name, channel)
/**
* @brief Equivalent to DT_PWMS_CHANNEL_BY_IDX(node_id, 0)
* @param node_id node identifier
* @return the channel value for the named specifier at index 0
* @see DT_PWMS_CHANNEL_BY_IDX()
*/
#define DT_PWMS_CHANNEL(node_id) DT_PWMS_CHANNEL_BY_IDX(node_id, 0)
/**
* @brief Get pwm controller 'flags' at an index
*
* This macro only works for PWM controllers that specify a 'flags'
* field in the phandle-array specifier. Refer to the specific PWM
* controller binding if needed.
*
* @param node_id node identifier
* @param idx logical index into the property
* @return the flags value for the named specifier at index idx
* @see DT_PWMS_CELL_BY_IDX()
*/
#define DT_PWMS_FLAGS_BY_IDX(node_id, idx) \
DT_PWMS_CELL_BY_IDX(node_id, flags, idx)
/**
* @brief Get PWM controller 'flags' by name
*
* This macro only works for PWM controllers that specify a 'flags'
* field in the phandle-array specifier. Refer to the specific PWM
* controller binding if needed.
*
* @param node_id node identifier
* @param name lowercase-and-underscores "pwm" name
* @return the flags value for the named specifier by name
* @see DT_PWMS_CELL_BY_NAME()
*/
#define DT_PWMS_FLAGS_BY_NAME(node_id, name) \
DT_PWMS_CELL_BY_NAME(node_id, name, flags)
/**
* @brief Equivalent to DT_PWMS_FLAGS_BY_IDX(node_id, 0)
* @param node_id node identifier
* @return the flags value for the named specifier at index 0
* @see DT_PWMS_FLAGS_BY_IDX()
*/
#define DT_PWMS_FLAGS(node_id) DT_PWMS_FLAGS_BY_IDX(node_id, 0)
/**
* @brief Get a DT_DRV_COMPAT pwm controller "name" at an index
* (see @ref DT_PWMS_LABEL_BY_IDX)
* @param inst instance number
* @param idx logical index into the property
* @return the label property for the named specifier at index idx
*/
#define DT_INST_PWMS_LABEL_BY_IDX(inst, idx) \
DT_PWMS_LABEL_BY_IDX(DT_DRV_INST(inst), idx)
/**
* @brief Get a DT_DRV_COMPAT pwm controller "name" (label property) by name
* (see @ref DT_PWMS_LABEL_BY_NAME)
* @param inst instance number
* @param name lowercase-and-underscores specifier name
* @return the label property for the named specifier by name
*/
#define DT_INST_PWMS_LABEL_BY_NAME(inst, name) \
DT_PWMS_LABEL_BY_NAME(DT_DRV_INST(inst), name)
/**
* @brief Get a DT_DRV_COMPAT pwm controller "name"
* (see @ref DT_PWMS_LABEL_BY_IDX)
* @param inst instance number
* @return the label property for the named specifier at index 0
*/
#define DT_INST_PWMS_LABEL(inst) DT_INST_PWMS_LABEL_BY_IDX(inst, 0)
/**
* @brief Get a DT_DRV_COMPAT pwm controller "cell" value at an index
* @param inst instance number
* @param cell binding's cell name within the specifier at index "idx"
* @param idx logical index into the property
* @return the value of the cell inside the specifier at index "idx"
*/
#define DT_INST_PWMS_CELL_BY_IDX(inst, cell, idx) \
DT_PWMS_CELL_BY_IDX(DT_DRV_INST(inst), cell, idx)
/**
* @brief Get a DT_DRV_COMPAT pwm controller "cell" value by name
* (see @ref DT_PWMS_CELL_BY_NAME)
* @param inst instance number
* @param name lowercase-and-underscores specifier name
* @param cell binding's cell name within the specifier referenced as "name"
* @return the value of the cell inside the named specifier
*/
#define DT_INST_PWMS_CELL_BY_NAME(inst, name, cell) \
DT_PWMS_CELL_BY_NAME(DT_DRV_INST(inst), name, cell)
/**
* @brief Get a DT_DRV_COMPAT pwm controller "cell" value at an index 0
* @param inst instance number
* @param cell binding's cell name within the specifier at index 0
* @return the value of the cell inside the specifier at index 0
*/
#define DT_INST_PWMS_CELL(inst, cell) \
DT_INST_PWMS_CELL_BY_IDX(inst, cell, 0)
/**
* @brief Get a DT_DRV_COMPAT pwm controller 'channel' at an index
* @param inst instance number
* @param idx logical index into the property
* @return the channel value for the named specifier at index idx
* @see DT_INST_PWMS_CELL_BY_IDX()
*/
#define DT_INST_PWMS_CHANNEL_BY_IDX(inst, idx) \
DT_INST_PWMS_CELL_BY_IDX(inst, channel, idx)
/**
* @brief Get a DT_DRV_COMPAT pwm controller 'channel' by name
* @param inst instance number
* @param name lowercase-and-underscores "pwm" name
* @return the channel value for the named specifier by name
* @see DT_INST_PWMS_CELL_BY_NAME()
*/
#define DT_INST_PWMS_CHANNEL_BY_NAME(inst, name) \
DT_INST_PWMS_CELL_BY_NAME(inst, name, channel)
/**
* @brief Get a DT_DRV_COMPAT pwm controller 'channel' value at an index 0
* @param inst instance number
* @return the channel value for the named specifier at index 0
* @see DT_INST_PWMS_CHANNEL_BY_IDX()
*/
#define DT_INST_PWMS_CHANNEL(inst) DT_INST_PWMS_CHANNEL_BY_IDX(inst, 0)
/**
* @brief Get a DT_DRV_COMPAT pwm controller 'flags' at an index
* @param inst instance number
* @param idx logical index into the property
* @return the flags value for the named specifier at index idx
* @see DT_INST_PWMS_CELL_BY_IDX()
*/
#define DT_INST_PWMS_FLAGS_BY_IDX(inst, idx) \
DT_INST_PWMS_CELL_BY_IDX(inst, flags, idx)
/**
* @brief Get a DT_DRV_COMPAT pwm controller 'flags' by name
* @param inst instance number
* @param name lowercase-and-underscores "pwm" name
* @return the flags value for the named specifier by name
* @see DT_INST_PWMS_CELL_BY_NAME()
*/
#define DT_INST_PWMS_FLAGS_BY_NAME(inst, name) \
DT_INST_PWMS_CELL_BY_NAME(inst, name, flags)
/**
* @brief Get a DT_DRV_COMPAT pwm controller 'flags' value at an index 0
* @param inst instance number
* @return the flags value for the named specifier at index 0
* @see DT_INST_PWMS_FLAGS_BY_IDX()
*/
#define DT_INST_PWMS_FLAGS(inst) DT_INST_PWMS_FLAGS_BY_IDX(inst, 0)
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_DEVICETREE_PWMS_H_ */

View file

@ -40,6 +40,8 @@
pha-gpios = <&test_gpio_1 50 60>, <&test_gpio_3 70>, <&test_gpio_2 80 90>;
foos = <&test_gpio_1 100>, <&test_gpio_2 110>;
foo-names = "A", "b-c";
pwms = <&test_pwm1 8 3>, <&test_pwm2 5 1>;
pwm-names = "red", "green";
};
test_enum_0: enum-0 {
@ -278,5 +280,21 @@
label = "TEST_DMA_CTRL_2";
status = "okay";
};
test_pwm1: pwm@55551111 {
compatible = "vnd,pwm";
#pwm-cells = <2>;
reg = < 0x55551111 0x1000 >;
label = "TEST_PWM_CTRL_1";
status = "okay";
};
test_pwm2: pwm@55552222 {
compatible = "vnd,pwm";
#pwm-cells = <2>;
reg = < 0x55552222 0x1000 >;
label = "TEST_PWM_CTRL_2";
status = "okay";
};
};
};

View file

@ -948,6 +948,111 @@ static void test_dma(void)
"Idx 2 dma channel not available");
}
#undef DT_DRV_COMPAT
#define DT_DRV_COMPAT vnd_phandle_holder
static void test_pwms(void)
{
/* DT_PWMS_LABEL_BY_IDX */
zassert_true(!strcmp(DT_PWMS_LABEL_BY_IDX(TEST_PH, 0),
"TEST_PWM_CTRL_1"),
"label 0");
/* DT_PWMS_LABEL_BY_NAME */
zassert_true(!strcmp(DT_PWMS_LABEL_BY_NAME(TEST_PH, red),
"TEST_PWM_CTRL_1"),
"label red");
/* DT_PWMS_LABEL */
zassert_true(!strcmp(DT_PWMS_LABEL(TEST_PH), "TEST_PWM_CTRL_1"),
"label 0");
/* DT_PWMS_CELL_BY_IDX */
zassert_equal(DT_PWMS_CELL_BY_IDX(TEST_PH, channel, 1), 5,
"pwm 2 channel");
zassert_equal(DT_PWMS_CELL_BY_IDX(TEST_PH, flags, 1), 1,
"pwm 2 flags");
/* DT_PWMS_CELL_BY_NAME */
zassert_equal(DT_PWMS_CELL_BY_NAME(TEST_PH, red, channel), 8,
"pwm-red channel");
zassert_equal(DT_PWMS_CELL_BY_NAME(TEST_PH, red, flags), 3,
"pwm-red flags");
/* DT_PWMS_CELL */
zassert_equal(DT_PWMS_CELL(TEST_PH, channel), 8, "pwm channel");
zassert_equal(DT_PWMS_CELL(TEST_PH, flags), 3, "pwm flags");
/* DT_PWMS_CHANNEL_BY_IDX */
zassert_equal(DT_PWMS_CHANNEL_BY_IDX(TEST_PH, 1), 5, "pwm channel");
/* DT_PWMS_CHANNEL_BY_NAME */
zassert_equal(DT_PWMS_CHANNEL_BY_NAME(TEST_PH, green), 5,
"pwm channel");
/* DT_PWMS_CHANNEL */
zassert_equal(DT_PWMS_CHANNEL(TEST_PH), 8, "pwm channel");
/* DT_PWMS_FLAGS_BY_IDX */
zassert_equal(DT_PWMS_FLAGS_BY_IDX(TEST_PH, 1), 1, "pwm channel");
/* DT_PWMS_FLAGS_BY_NAME */
zassert_equal(DT_PWMS_FLAGS_BY_NAME(TEST_PH, green), 1,
"pwm channel");
/* DT_PWMS_FLAGS */
zassert_equal(DT_PWMS_FLAGS(TEST_PH), 3, "pwm channel");
/* DT_INST */
zassert_equal(DT_NUM_INST(DT_DRV_COMPAT), 1, "one instance");
/* DT_INST_PWMS_LABEL_BY_IDX */
zassert_true(!strcmp(DT_INST_PWMS_LABEL_BY_IDX(0, 0),
"TEST_PWM_CTRL_1"),
"label 0");
/* DT_INST_PWMS_LABEL_BY_NAME */
zassert_true(!strcmp(DT_INST_PWMS_LABEL_BY_NAME(0, green),
"TEST_PWM_CTRL_2"),
"label green");
/* DT_INST_PWMS_LABEL */
zassert_true(!strcmp(DT_INST_PWMS_LABEL(0), "TEST_PWM_CTRL_1"),
"label 0");
/* DT_INST_PWMS_CELL_BY_IDX */
zassert_equal(DT_INST_PWMS_CELL_BY_IDX(0, channel, 1), 5,
"pwm 2 channel");
zassert_equal(DT_INST_PWMS_CELL_BY_IDX(0, flags, 1), 1, "pwm 2 flags");
/* DT_INST_PWMS_CELL_BY_NAME */
zassert_equal(DT_INST_PWMS_CELL_BY_NAME(0, green, channel), 5,
"pwm-green channel");
zassert_equal(DT_INST_PWMS_CELL_BY_NAME(0, green, flags), 1,
"pwm-green flags");
/* DT_INST_PWMS_CELL */
zassert_equal(DT_INST_PWMS_CELL(0, channel), 8, "pwm channel");
zassert_equal(DT_INST_PWMS_CELL(0, flags), 3, "pwm flags");
/* DT_INST_PWMS_CHANNEL_BY_IDX */
zassert_equal(DT_INST_PWMS_CHANNEL_BY_IDX(0, 1), 5, "pwm channel");
/* DT_INST_PWMS_CHANNEL_BY_NAME */
zassert_equal(DT_INST_PWMS_CHANNEL_BY_NAME(0, green), 5, "pwm channel");
/* DT_INST_PWMS_CHANNEL */
zassert_equal(DT_INST_PWMS_CHANNEL(0), 8, "pwm channel");
/* DT_INST_PWMS_FLAGS_BY_IDX */
zassert_equal(DT_INST_PWMS_FLAGS_BY_IDX(0, 1), 1, "pwm channel");
/* DT_INST_PWMS_FLAGS_BY_NAME */
zassert_equal(DT_INST_PWMS_FLAGS_BY_NAME(0, red), 3, "pwm channel");
/* DT_INST_PWMS_FLAGS */
zassert_equal(DT_INST_PWMS_FLAGS(0), 3, "pwm channel");
}
#define TO_STRING(x) TO_STRING_(x)
#define TO_STRING_(x) #x
@ -1275,6 +1380,7 @@ void test_main(void)
ztest_unit_test(test_gpio),
ztest_unit_test(test_io_channels),
ztest_unit_test(test_dma),
ztest_unit_test(test_pwms),
ztest_unit_test(test_macro_names),
ztest_unit_test(test_arrays),
ztest_unit_test(test_devices),