1 /*
2 * Copyright (c) 2022 FuZhou Lockzhiner Electronic Co., Ltd. All rights reserved.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include <stdio.h>
16 #include <stdint.h>
17
18 #include "gpio/gpio_core.h"
19 #include "device_resource_if.h"
20 #include "hdf_device_desc.h"
21 #include "hdf_log.h"
22 #include "stdio.h"
23
24 #include "lz_hardware.h"
25
26 #define PRINT_ERR(fmt, args...) do { \
27 printf("%s, %d, error: "fmt, __func__, __LINE__, ##args); \
28 } while (0)
29
30 #define PRINT_WARR(fmt, args...) do { \
31 if (1) printf("%s, %d, warr: "fmt, __func__, __LINE__, ##args); \
32 } while (0)
33
34 #define PRINT_LOG(fmt, args...) do { \
35 if (1) printf("%s, %d, log: "fmt, __func__, __LINE__, ##args); \
36 } while (0)
37
38 static struct GpioCntlr m_gpioCntlr;
39 static int32_t m_groupNum = 0;
40 static int32_t m_bitNum = 0;
41 #define GPIO_MAXSIZE 256
42 static uint8_t m_gpio_init_flag[GPIO_MAXSIZE];
43
iodrv_initgpio(uint16_t gpio)44 static int32_t iodrv_initgpio(uint16_t gpio)
45 {
46 GpioID gpio_id = (GpioID)(gpio);
47
48 if (gpio >= GPIO_MAXSIZE) {
49 PRINT_ERR("%s: gpio(%d) >= GPIO_MAXSIZE(%d)", __func__, gpio, GPIO_MAXSIZE);
50 return HDF_FAILURE;
51 }
52
53 if (m_gpio_init_flag[gpio] == 1) {
54 return HDF_SUCCESS;
55 }
56
57 PinctrlSet(gpio_id, MUX_FUNC0, PULL_KEEP, DRIVE_LEVEL0);
58 LzGpioInit(gpio_id);
59 m_gpio_init_flag[gpio] = 1;
60
61 return HDF_SUCCESS;
62 }
63
iodrv_setdir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t dir)64 static int32_t iodrv_setdir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
65 {
66 if (cntlr == NULL) {
67 PRINT_ERR("%s: cntlr is null", __func__);
68 return HDF_FAILURE;
69 }
70 if (gpio >= cntlr->count) {
71 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
72 return HDF_FAILURE;
73 }
74 if ((dir != GPIO_DIR_IN) && (dir != GPIO_DIR_OUT)) {
75 PRINT_ERR("%s: dir(%d) out of the range", __func__, dir);
76 return HDF_FAILURE;
77 }
78
79 GpioID gpio_id = (GpioID)(gpio);
80 LzGpioDir gpio_dir = (dir == GPIO_DIR_IN) ? (LZGPIO_DIR_IN) : (LZGPIO_DIR_OUT);
81
82 iodrv_initgpio(gpio);
83 LzGpioSetDir(gpio_id, gpio_dir);
84
85 return HDF_SUCCESS;
86 }
87
iodrv_getdir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * dir)88 static int32_t iodrv_getdir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
89 {
90 if (cntlr == NULL) {
91 PRINT_ERR("%s: cntlr is null", __func__);
92 return HDF_FAILURE;
93 }
94 if (gpio >= cntlr->count) {
95 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
96 return HDF_FAILURE;
97 }
98 if (dir == NULL) {
99 PRINT_ERR("%s: dir is null", __func__);
100 return HDF_FAILURE;
101 }
102
103 GpioID gpio_id = (GpioID)(gpio);
104 LzGpioDir gpio_dir;
105 unsigned int ret;
106
107 iodrv_initgpio(gpio);
108
109 ret = LzGpioGetDir(gpio_id, &gpio_dir);
110 if (ret != LZ_HARDWARE_SUCCESS) {
111 PRINT_ERR("%s: LzGpioGetDir error", __func__);
112 return HDF_FAILURE;
113 }
114
115 *dir = (gpio_dir == LZGPIO_DIR_IN) ? (GPIO_DIR_IN) : (GPIO_DIR_OUT);
116
117 return HDF_SUCCESS;
118 }
119
iodrv_write(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t value)120 static int32_t iodrv_write(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t value)
121 {
122 if (cntlr == NULL) {
123 PRINT_ERR("%s: cntlr is null", __func__);
124 return HDF_FAILURE;
125 }
126 if (gpio >= cntlr->count) {
127 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
128 return HDF_FAILURE;
129 }
130
131 GpioID gpio_id = (GpioID)(gpio);
132 LzGpioValue gpio_value = (value == 0) ? (LZGPIO_LEVEL_LOW) : (LZGPIO_LEVEL_HIGH);
133
134 iodrv_initgpio(gpio);
135 LzGpioSetDir(gpio_id, LZGPIO_DIR_OUT);
136 LzGpioSetVal(gpio_id, gpio_value);
137
138 return HDF_SUCCESS;
139 }
140
iodrv_read(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * value)141 static int32_t iodrv_read(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *value)
142 {
143 if (cntlr == NULL) {
144 PRINT_ERR("%s: cntlr is null", __func__);
145 return HDF_FAILURE;
146 }
147 if (gpio >= cntlr->count) {
148 PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
149 return HDF_FAILURE;
150 }
151 if (value == NULL) {
152 PRINT_ERR("%s: value is null", __func__);
153 return HDF_FAILURE;
154 }
155
156 GpioID gpio_id = (GpioID)(gpio);
157 LzGpioValue gpio_value;
158 unsigned int ret;
159
160 iodrv_initgpio(gpio);
161
162 ret = LzGpioGetVal(gpio_id, &gpio_value);
163 if (ret != LZ_HARDWARE_SUCCESS) {
164 PRINT_ERR("%s: LzGpioGetVal error", __func__);
165 return HDF_FAILURE;
166 }
167
168 *value = (gpio_value == LZGPIO_LEVEL_LOW) ? (0) : (1);
169
170 return HDF_SUCCESS;
171 }
172
iodrv_readdrs(struct DeviceResourceNode * node,uint32_t * groupNum,uint32_t * bitNum)173 static int32_t iodrv_readdrs(struct DeviceResourceNode *node, uint32_t *groupNum, uint32_t *bitNum)
174 {
175 int32_t ret;
176 struct DeviceResourceIface *drsOps = NULL;
177
178 drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
179 if (drsOps == NULL) {
180 PRINT_ERR("%s: invalid drs ops!", __func__);
181 return HDF_FAILURE;
182 }
183 if (drsOps->GetUint32 == NULL) {
184 PRINT_ERR("%s: GetUint32 failed!", __func__);
185 return HDF_FAILURE;
186 }
187 if (groupNum == NULL) {
188 PRINT_ERR("%s: groupNum is null!", __func__);
189 return HDF_FAILURE;
190 }
191 if (bitNum == NULL) {
192 PRINT_ERR("%s: bitNum is null!", __func__);
193 return HDF_FAILURE;
194 }
195
196 ret = drsOps->GetUint32(node, "groupNum", groupNum, 0);
197 if (ret != HDF_SUCCESS) {
198 PRINT_ERR("%s: read groupNum failed!", __func__);
199 }
200
201 ret = drsOps->GetUint32(node, "bitNum", bitNum, 0);
202 if (ret != HDF_SUCCESS) {
203 PRINT_ERR("%s: read bitNum failed!", __func__);
204 }
205
206 return HDF_SUCCESS;
207 }
208
209 static struct GpioMethod m_gpio_method = {
210 .request = NULL,
211 .release = NULL,
212 .write = iodrv_write,
213 .read = iodrv_read,
214 .setDir = iodrv_setdir,
215 .getDir = iodrv_getdir,
216 .toIrq = NULL,
217 .setIrq = NULL,
218 .unsetIrq = NULL,
219 .enableIrq = NULL,
220 .disableIrq = NULL,
221 };
222
iodrv_init(struct HdfDeviceObject * device)223 static int32_t iodrv_init(struct HdfDeviceObject *device)
224 {
225 int32_t ret;
226 struct GpioCntlr *cntlr = &m_gpioCntlr;
227 uint32_t i;
228
229 PRINT_LOG("%s: Enter\n", __func__);
230 if ((device == NULL) || (device->property == NULL)) {
231 PRINT_ERR("%s: device or property is null!", __func__);
232 return HDF_ERR_INVALID_OBJECT;
233 }
234
235 ret = iodrv_readdrs(device->property, &m_groupNum, &m_bitNum);
236 if (ret != HDF_SUCCESS) {
237 PRINT_ERR("%s: read drs failed(%d)", __func__, ret);
238 return ret;
239 }
240
241 for (i = 0; i < GPIO_MAXSIZE; i++) {
242 m_gpio_init_flag[i] = 0;
243 }
244
245 cntlr->start = 0;
246 cntlr->count = m_groupNum * m_bitNum;
247 cntlr->ops = &m_gpio_method;
248 cntlr->priv = (void *)device->property;
249 PlatformDeviceBind(&cntlr->device, device);
250 ret = GpioCntlrAdd(cntlr);
251 if (ret != HDF_SUCCESS) {
252 HDF_LOGE("%s: err add controller %d", __func__, ret);
253 return ret;
254 }
255
256 PRINT_LOG("gpio service: %s init success!\n", HdfDeviceGetServiceName(device));
257 return HDF_SUCCESS;
258 }
259
iodrv_release(struct HdfDeviceObject * device)260 static void iodrv_release(struct HdfDeviceObject *device)
261 {
262 struct Gpiocntlr *cntlr;
263
264 if (device == NULL) {
265 PRINT_ERR("%s: device is null", __func__);
266 return;
267 }
268
269 cntlr = GpioCntlrFromHdfDev(device);
270 if (cntlr == NULL) {
271 PRINT_ERR("%s: no service binded!", __func__);
272 return;
273 }
274
275 GpioCntlrRemove(cntlr);
276 PRINT_LOG("gpio service: %s release!\n", HdfDeviceGetServiceName(device));
277 }
278
iodrv_bind(struct HdfDeviceObject * device)279 static int32_t iodrv_bind(struct HdfDeviceObject *device)
280 {
281 (void)device;
282 return HDF_SUCCESS;
283 }
284
285 struct HdfDriverEntry g_gpioDriverEntry = {
286 .moduleVersion = 1,
287 .moduleName = "HDF_PLATFORM_GPIO",
288 .Bind = iodrv_bind,
289 .Init = iodrv_init,
290 .Release = iodrv_release,
291 };
292
293 HDF_INIT(g_gpioDriverEntry);
294