• 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     if (1) 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 #define RK2206_GPIO_NAME            "rk2206_gpio"
39 
40 static struct GpioCntlr m_gpioCntlr;
41 static struct GpioInfo *m_gpioInfo = NULL;
42 static int32_t m_groupNum = 0;
43 static int32_t m_bitNum = 0;
44 #define GPIO_MAXSIZE            256
45 static uint8_t m_gpio_init_flag[GPIO_MAXSIZE];
46 
iodrv_initgpio(uint16_t gpio)47 static int32_t iodrv_initgpio(uint16_t gpio)
48 {
49     GpioID gpio_id = (GpioID)(gpio);
50 
51     if (gpio >= GPIO_MAXSIZE) {
52         PRINT_ERR("%s: gpio(%d) >= GPIO_MAXSIZE(%d)", __func__, gpio, GPIO_MAXSIZE);
53         return HDF_FAILURE;
54     }
55 
56     if (m_gpio_init_flag[gpio] == 1) {
57         return HDF_SUCCESS;
58     }
59 
60     PinctrlSet(gpio_id, MUX_FUNC0, PULL_KEEP, DRIVE_LEVEL0);
61     LzGpioInit(gpio_id);
62     m_gpio_init_flag[gpio] = 1;
63 
64     return HDF_SUCCESS;
65 }
66 
iodrv_setdir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t dir)67 static int32_t iodrv_setdir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t dir)
68 {
69     if (cntlr == NULL) {
70         PRINT_ERR("%s: cntlr is null", __func__);
71         return HDF_FAILURE;
72     }
73     if (gpio >= cntlr->count) {
74         PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
75         return HDF_FAILURE;
76     }
77     if ((dir != GPIO_DIR_IN) && (dir != GPIO_DIR_OUT)) {
78         PRINT_ERR("%s: dir(%d) out of the range", __func__, dir);
79         return HDF_FAILURE;
80     }
81 
82     GpioID gpio_id = (GpioID)(gpio);
83     LzGpioDir gpio_dir = (dir == GPIO_DIR_IN) ? (LZGPIO_DIR_IN) : (LZGPIO_DIR_OUT);
84 
85     iodrv_initgpio(gpio);
86     LzGpioSetDir(gpio_id, gpio_dir);
87 
88     return HDF_SUCCESS;
89 }
90 
iodrv_getdir(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * dir)91 static int32_t iodrv_getdir(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *dir)
92 {
93     if (cntlr == NULL) {
94         PRINT_ERR("%s: cntlr is null", __func__);
95         return HDF_FAILURE;
96     }
97     if (gpio >= cntlr->count) {
98         PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
99         return HDF_FAILURE;
100     }
101     if (dir == NULL) {
102         PRINT_ERR("%s: dir is null", __func__);
103         return HDF_FAILURE;
104     }
105 
106     GpioID gpio_id = (GpioID)(gpio);
107     LzGpioDir gpio_dir;
108     unsigned int ret;
109 
110     iodrv_initgpio(gpio);
111 
112     ret = LzGpioGetDir(gpio_id, &gpio_dir);
113     if (ret != LZ_HARDWARE_SUCCESS) {
114         PRINT_ERR("%s: LzGpioGetDir error", __func__);
115         return HDF_FAILURE;
116     }
117 
118     *dir = (gpio_dir == LZGPIO_DIR_IN) ? (GPIO_DIR_IN) : (GPIO_DIR_OUT);
119 
120     return HDF_SUCCESS;
121 }
122 
iodrv_write(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t value)123 static int32_t iodrv_write(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t value)
124 {
125     if (cntlr == NULL) {
126         PRINT_ERR("%s: cntlr is null", __func__);
127         return HDF_FAILURE;
128     }
129     if (gpio >= cntlr->count) {
130         PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
131         return HDF_FAILURE;
132     }
133 
134     GpioID gpio_id = (GpioID)(gpio);
135     LzGpioValue gpio_value = (value == 0) ? (LZGPIO_LEVEL_LOW) : (LZGPIO_LEVEL_HIGH);
136 
137     iodrv_initgpio(gpio);
138     LzGpioSetDir(gpio_id, LZGPIO_DIR_OUT);
139     LzGpioSetVal(gpio_id, gpio_value);
140 
141     return HDF_SUCCESS;
142 }
143 
iodrv_read(struct GpioCntlr * cntlr,uint16_t gpio,uint16_t * value)144 static int32_t iodrv_read(struct GpioCntlr *cntlr, uint16_t gpio, uint16_t *value)
145 {
146     if (cntlr == NULL) {
147         PRINT_ERR("%s: cntlr is null", __func__);
148         return HDF_FAILURE;
149     }
150     if (gpio >= cntlr->count) {
151         PRINT_ERR("%s: gpio(%d) >= cntlr->count(%d)", __func__, gpio, cntlr->count);
152         return HDF_FAILURE;
153     }
154     if (value == NULL) {
155         PRINT_ERR("%s: value is null", __func__);
156         return HDF_FAILURE;
157     }
158 
159     GpioID gpio_id = (GpioID)(gpio);
160     LzGpioValue gpio_value;
161     unsigned int ret;
162 
163     iodrv_initgpio(gpio);
164 
165     ret = LzGpioGetVal(gpio_id, &gpio_value);
166     if (ret != LZ_HARDWARE_SUCCESS) {
167         PRINT_ERR("%s: LzGpioGetVal error", __func__);
168         return HDF_FAILURE;
169     }
170 
171     *value = (gpio_value == LZGPIO_LEVEL_LOW) ? (0) : (1);
172 
173     return HDF_SUCCESS;
174 }
175 
iodrv_readdrs(struct DeviceResourceNode * node,uint32_t * groupNum,uint32_t * bitNum)176 static int32_t iodrv_readdrs(struct DeviceResourceNode *node, uint32_t *groupNum, uint32_t *bitNum)
177 {
178     int32_t ret;
179     struct DeviceResourceIface *drsOps = NULL;
180 
181     drsOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);
182     if (drsOps == NULL) {
183         PRINT_ERR("%s: invalid drs ops!", __func__);
184         return HDF_FAILURE;
185     }
186     if (drsOps->GetUint32 == NULL) {
187         PRINT_ERR("%s: GetUint32 failed!", __func__);
188         return HDF_FAILURE;
189     }
190     if (groupNum == NULL) {
191         PRINT_ERR("%s: groupNum is null!", __func__);
192         return HDF_FAILURE;
193     }
194     if (bitNum == NULL) {
195         PRINT_ERR("%s: bitNum is null!", __func__);
196         return HDF_FAILURE;
197     }
198 
199     ret = drsOps->GetUint32(node, "groupNum", groupNum, 0);
200     if (ret != HDF_SUCCESS) {
201         PRINT_ERR("%s: read groupNum failed!", __func__);
202     }
203 
204     ret = drsOps->GetUint32(node, "bitNum", bitNum, 0);
205     if (ret != HDF_SUCCESS) {
206         PRINT_ERR("%s: read bitNum failed!", __func__);
207     }
208 
209     return HDF_SUCCESS;
210 }
211 
212 static struct GpioMethod m_gpio_method = {
213     .request = NULL,
214     .release = NULL,
215     .write = iodrv_write,
216     .read = iodrv_read,
217     .setDir = iodrv_setdir,
218     .getDir = iodrv_getdir,
219     .toIrq = NULL,
220     .setIrq = NULL,
221     .unsetIrq = NULL,
222     .enableIrq = NULL,
223     .disableIrq = NULL,
224 };
225 
iodrv_init(struct HdfDeviceObject * device)226 static int32_t iodrv_init(struct HdfDeviceObject *device)
227 {
228     int32_t ret;
229     struct GpioCntlr *cntlr = &m_gpioCntlr;
230     uint32_t i;
231 
232     PRINT_LOG("%s: Enter\n", __func__);
233     if ((device == NULL) || (device->property == NULL)) {
234         PRINT_ERR("%s: device or property is null!", __func__);
235         return HDF_ERR_INVALID_OBJECT;
236     }
237 
238     ret = iodrv_readdrs(device->property, &m_groupNum, &m_bitNum);
239     if (ret != HDF_SUCCESS) {
240         PRINT_ERR("%s: read drs failed(%d)", __func__, ret);
241         return ret;
242     }
243 
244     for (i = 0; i < GPIO_MAXSIZE; i++) {
245         m_gpio_init_flag[i] = 0;
246     }
247 
248     m_gpioInfo = (struct GpioInfo *)OsalMemAlloc(sizeof(struct GpioInfo));
249     if (m_gpioInfo == NULL) {
250         PRINT_ERR("m_gpioInfo OsalMemAlloc failed!\n");
251         return HDF_ERR_INVALID_OBJECT;
252     }
253 
254     memset_s(m_gpioInfo->name, GPIO_NAME_LEN, 0, GPIO_NAME_LEN - 1);
255     memcpy_s(m_gpioInfo->name, GPIO_NAME_LEN, RK2206_GPIO_NAME, strlen(RK2206_GPIO_NAME));
256 
257     cntlr->start = 0;
258     cntlr->count = m_groupNum * m_bitNum;
259     cntlr->ops = &m_gpio_method;
260     cntlr->ginfos = &m_gpioInfo;
261     cntlr->priv = (void *)device->property;
262 
263     ret = GpioCntlrAdd(cntlr);
264     if (ret != HDF_SUCCESS) {
265         PRINT_ERR("GpioCntlrAdd failed(%d)\n", ret);
266         return ret;
267     }
268 
269     PRINT_LOG("gpio service: %s init success!\n", HdfDeviceGetServiceName(device));
270     return HDF_SUCCESS;
271 }
272 
iodrv_release(struct HdfDeviceObject * device)273 static void iodrv_release(struct HdfDeviceObject *device)
274 {
275     struct Gpiocntlr *cntlr;
276 
277     if (device == NULL) {
278         PRINT_ERR("%s: device is null", __func__);
279         return;
280     }
281 
282     cntlr = GpioCntlrFromHdfDev(device);
283     if (cntlr == NULL) {
284         PRINT_ERR("%s: no service binded!\n", __func__);
285         return;
286     }
287 
288     GpioCntlrRemove(cntlr);
289     PRINT_LOG("gpio service: %s release!\n", HdfDeviceGetServiceName(device));
290 }
291 
iodrv_bind(struct HdfDeviceObject * device)292 static int32_t iodrv_bind(struct HdfDeviceObject *device)
293 {
294     (void)device;
295     return HDF_SUCCESS;
296 }
297 
298 struct HdfDriverEntry g_gpioDriverEntry = {
299     .moduleVersion = 1,
300     .moduleName = "HDF_PLATFORM_GPIO",
301     .Bind = iodrv_bind,
302     .Init = iodrv_init,
303     .Release = iodrv_release,
304 };
305 
306 HDF_INIT(g_gpioDriverEntry);
307