• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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