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