Line data Source code
1 1 : /*
2 : * Copyright (c) 2021 Carlo Caione <ccaione@baylibre.com>
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @ingroup syscon_interface
10 : * @brief Main header file for SYSCON (System Control) driver API.
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_DRIVERS_SYSCON_H_
14 : #define ZEPHYR_INCLUDE_DRIVERS_SYSCON_H_
15 :
16 : /**
17 : * @brief Interfaces for system control registers.
18 : * @defgroup syscon_interface System control (SYSCON)
19 : * @ingroup io_interfaces
20 : * @{
21 : */
22 :
23 : #include <errno.h>
24 :
25 : #include <zephyr/types.h>
26 : #include <zephyr/device.h>
27 :
28 : #ifdef __cplusplus
29 : extern "C" {
30 : #endif
31 :
32 : /**
33 : * API template to get the base address of the syscon region.
34 : *
35 : * @see syscon_get_base
36 : */
37 1 : typedef int (*syscon_api_get_base)(const struct device *dev, uintptr_t *addr);
38 :
39 : /**
40 : * API template to read a single register.
41 : *
42 : * @see syscon_read_reg
43 : */
44 1 : typedef int (*syscon_api_read_reg)(const struct device *dev, uint16_t reg, uint32_t *val);
45 :
46 : /**
47 : * API template to write a single register.
48 : *
49 : * @see syscon_write_reg
50 : */
51 1 : typedef int (*syscon_api_write_reg)(const struct device *dev, uint16_t reg, uint32_t val);
52 :
53 : /**
54 : * API template to get the size of the syscon register.
55 : *
56 : * @see syscon_get_size
57 : */
58 1 : typedef int (*syscon_api_get_size)(const struct device *dev, size_t *size);
59 :
60 : /**
61 : * @brief System Control (syscon) register driver API
62 : */
63 1 : __subsystem struct syscon_driver_api {
64 0 : syscon_api_read_reg read;
65 0 : syscon_api_write_reg write;
66 0 : syscon_api_get_base get_base;
67 0 : syscon_api_get_size get_size;
68 : };
69 :
70 : /**
71 : * @brief Get the syscon base address
72 : *
73 : * @param dev The device to get the register size for.
74 : * @param addr Where to write the base address.
75 : * @return 0 When @a addr was written to.
76 : * @return -ENOSYS If the API or function isn't implemented.
77 : */
78 1 : __syscall int syscon_get_base(const struct device *dev, uintptr_t *addr);
79 :
80 : static inline int z_impl_syscon_get_base(const struct device *dev, uintptr_t *addr)
81 : {
82 : const struct syscon_driver_api *api = (const struct syscon_driver_api *)dev->api;
83 :
84 : if ((api == NULL) || (api->get_base == NULL)) {
85 : return -ENOSYS;
86 : }
87 :
88 : return api->get_base(dev, addr);
89 : }
90 :
91 :
92 : /**
93 : * @brief Read from syscon register
94 : *
95 : * This function reads from a specific register in the syscon area
96 : *
97 : * @param dev The device to get the register size for.
98 : * @param reg The register offset
99 : * @param val The returned value read from the syscon register
100 : *
101 : * @return 0 on success.
102 : * @return -ENOSYS If the API or function isn't implemented.
103 : */
104 1 : __syscall int syscon_read_reg(const struct device *dev, uint16_t reg, uint32_t *val);
105 :
106 : static inline int z_impl_syscon_read_reg(const struct device *dev, uint16_t reg, uint32_t *val)
107 : {
108 : const struct syscon_driver_api *api = (const struct syscon_driver_api *)dev->api;
109 :
110 : if ((api == NULL) || (api->read == NULL)) {
111 : return -ENOSYS;
112 : }
113 :
114 : return api->read(dev, reg, val);
115 : }
116 :
117 :
118 : /**
119 : * @brief Write to syscon register
120 : *
121 : * This function writes to a specific register in the syscon area
122 : *
123 : * @param dev The device to get the register size for.
124 : * @param reg The register offset
125 : * @param val The value to be written in the register
126 : *
127 : * @return 0 on success.
128 : * @return -ENOSYS If the API or function isn't implemented.
129 : */
130 1 : __syscall int syscon_write_reg(const struct device *dev, uint16_t reg, uint32_t val);
131 :
132 : static inline int z_impl_syscon_write_reg(const struct device *dev, uint16_t reg, uint32_t val)
133 : {
134 : const struct syscon_driver_api *api = (const struct syscon_driver_api *)dev->api;
135 :
136 : if ((api == NULL) || (api->write == NULL)) {
137 : return -ENOSYS;
138 : }
139 :
140 : return api->write(dev, reg, val);
141 : }
142 :
143 : /**
144 : * Get the size of the syscon register in bytes.
145 : *
146 : * @param dev The device to get the register size for.
147 : * @param size Pointer to write the size to.
148 : * @return 0 for success.
149 : * @return -ENOSYS If the API or function isn't implemented.
150 : */
151 1 : __syscall int syscon_get_size(const struct device *dev, size_t *size);
152 :
153 : static inline int z_impl_syscon_get_size(const struct device *dev, size_t *size)
154 : {
155 : const struct syscon_driver_api *api = (const struct syscon_driver_api *)dev->api;
156 :
157 : if ((api == NULL) || (api->get_size == NULL)) {
158 : return -ENOSYS;
159 : }
160 :
161 : return api->get_size(dev, size);
162 : }
163 :
164 : /**
165 : * @}
166 : */
167 :
168 : #ifdef __cplusplus
169 : }
170 : #endif
171 :
172 : #include <zephyr/syscalls/syscon.h>
173 :
174 : #endif /* ZEPHYR_INCLUDE_DRIVERS_SYSCON_H_ */
|