1 /*
2 * Copyright (C) 2016 Allwinnertech Co.Ltd
3 * Authors: Jet Cui
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
12 #include <linux/clk-provider.h>
13 #include <linux/gpio.h>
14 #include "sunxi-gpio.h"
15 #include <linux/pinctrl/consumer.h>
16 #include <linux/pwm.h>
17 #include <linux/regulator/consumer.h>
18 #include <drm/drm_print.h>
19
20 #include "de/include.h"
21 #include "disp_sys_intf.h"
22
23 /*it is the structure that connect to sunxi display lowlevel*/
24 static struct disp_bsp_init_para disp_init_para;
25
26 /*For log printing level of sunxi disp lowlevel*/
27 static unsigned char disp_log_level;
28
sunxi_disp_bsp_init_para_init(void)29 void sunxi_disp_bsp_init_para_init(void)
30 {
31 memset(&disp_init_para, 0, sizeof(struct disp_bsp_init_para));
32 }
33
sunxi_disp_get_bsp_init_para(void)34 struct disp_bsp_init_para *sunxi_disp_get_bsp_init_para(void)
35 {
36 return &disp_init_para;
37 }
38
sunxi_drm_delayed_ms(unsigned int ms)39 void sunxi_drm_delayed_ms(unsigned int ms)
40 {
41 unsigned int timeout = msecs_to_jiffies(ms);
42
43 set_current_state(TASK_UNINTERRUPTIBLE);
44 schedule_timeout(timeout);
45 }
46
sunxi_drm_sys_power_enable(struct device * dev,const char * name)47 int sunxi_drm_sys_power_enable(struct device *dev, const char *name) /* fix me */
48 {
49 int ret = 0;
50
51 //#ifdef CONFIG_AW_AXP
52 struct regulator *regu = NULL;
53
54 regu = regulator_get(dev, name);
55
56 if (IS_ERR(regu)) {
57 DRM_ERROR("fail to get regulator %s\n", name);
58 goto exit;
59 }
60
61 ret = regulator_enable(regu);
62 if (ret) {
63 DRM_ERROR("fail to enable regulator %s!\n", name);
64 goto exit1;
65 } /*else
66 DRM_INFO("suceess to enable regulator %s!\n", name);
67 */
68 return ret;
69
70 exit1:
71 regulator_put(regu);
72 exit:
73 //#endif
74 return ret;
75 }
76
sunxi_drm_sys_power_disable(struct device * dev,const char * name)77 int sunxi_drm_sys_power_disable(struct device *dev, const char *name) /* fix me */
78 {
79 int ret = 0;
80 //#ifdef CONFIG_AW_AXP
81 struct regulator *regu = NULL;
82
83 regu = regulator_get(dev, name);
84
85 if (IS_ERR(regu)) {
86 DRM_ERROR("fail to get regulator %s\n", name);
87 goto exit;
88 }
89
90 ret = regulator_disable(regu);
91 if (ret) {
92 DRM_ERROR("fail to disable regulator %s!\n", name);
93 goto exit1;
94 } else
95 DRM_INFO("suceess to disable regulator %s!\n", name);
96
97
98 exit1:
99 regulator_put(regu);
100 exit:
101 //#endif
102 return ret;
103 }
104
sunxi_drm_sys_gpio_request(struct disp_gpio_info * gpio_info)105 int sunxi_drm_sys_gpio_request(struct disp_gpio_info *gpio_info)
106 {
107 int ret = 0;
108
109 if (!gpio_info) {
110 pr_err("%s: gpio_info is null\n", __func__);
111 return -1;
112 }
113
114 if (!strlen(gpio_info->name))
115 return 0;
116
117 if (!gpio_is_valid(gpio_info->gpio)) {
118 pr_err("%s: gpio (%d) is invalid\n", __func__, gpio_info->gpio);
119 return -1;
120 }
121
122 ret = gpio_direction_output(gpio_info->gpio, gpio_info->value);
123 if (ret) {
124 pr_err("%s failed, gpio_name=%s, gpio=%d, value=%d, ret=%d\n", __func__,
125 gpio_info->name, gpio_info->gpio, gpio_info->value, ret);
126 return -1;
127 }
128
129 DRM_INFO("%s, gpio_name=%s, gpio=%d, value=%d, ret=%d\n", __func__,
130 gpio_info->name, gpio_info->gpio, gpio_info->value, ret);
131
132 return ret;
133 }
134
135 /* direction: 0:input, 1:output */
sunxi_drm_sys_gpio_set_direction(u32 p_handler,u32 direction,const char * gpio_name)136 int sunxi_drm_sys_gpio_set_direction(u32 p_handler, u32 direction,
137 const char *gpio_name)
138 {
139 int ret = -1;
140
141 if (p_handler) {
142 if (direction) {
143 s32 value;
144
145 value = __gpio_get_value(p_handler);
146 ret = gpio_direction_output(p_handler, value);
147 if (ret != 0)
148 __wrn("gpio_direction_output fail!\n");
149 } else {
150 ret = gpio_direction_input(p_handler);
151 if (ret != 0)
152 __wrn("gpio_direction_input fail!\n");
153 }
154 } else {
155 __wrn("OSAL_GPIO_DevSetONEPIN_IO_STATUS, hdl is NULL\n");
156 ret = -1;
157 }
158 return ret;
159 }
160
sunxi_drm_sys_gpio_set_value(u32 p_handler,u32 value_to_gpio,const char * gpio_name)161 int sunxi_drm_sys_gpio_set_value(u32 p_handler, u32 value_to_gpio,
162 const char *gpio_name)
163 {
164 DRM_DEBUG_DRIVER("%s gpio_name:%s\n", __func__, gpio_name);
165
166 if (p_handler)
167 __gpio_set_value(p_handler, value_to_gpio);
168 else
169 __wrn("OSAL_GPIO_DevWRITE_ONEPIN_DATA, hdl is NULL\n");
170
171 return 0;
172 }
173
174
sunxi_drm_sys_gpio_release(int p_handler)175 int sunxi_drm_sys_gpio_release(int p_handler)
176 {
177 if (p_handler)
178 gpio_free(p_handler);
179 else
180 DRM_INFO("OSAL_GPIO_Release, hdl is NULL\n");
181
182 return 0;
183 }
184
sunxi_drm_sys_pin_set_state(char * dev_name,char * name)185 int sunxi_drm_sys_pin_set_state(char *dev_name, char *name)
186 {
187 char compat[32];
188 u32 len = 0;
189 struct device_node *node;
190 struct platform_device *pdev;
191 struct pinctrl *pctl;
192 struct pinctrl_state *state;
193 int ret = -1;
194
195 len = sprintf(compat, "allwinner,sunxi-%s", dev_name);
196 if (len > 32)
197 DRM_ERROR("size of mian_name is out of range\n");
198
199 node = of_find_compatible_node(NULL, NULL, compat);
200 if (!node) {
201 DRM_ERROR("of_find_compatible_node %s fail\n", compat);
202 goto exit;
203 }
204
205 pdev = of_find_device_by_node(node);
206 if (!node) {
207 DRM_ERROR("of_find_device_by_node for %s fail\n", compat);
208 goto exit;
209 }
210 pctl = pinctrl_get(&pdev->dev);
211 if (IS_ERR(pctl)) {
212 DRM_INFO("[WARN]can NOT get pinctrl for %s \n", compat);
213 ret = 0;
214 goto exit;
215 }
216
217 state = pinctrl_lookup_state(pctl, name);
218 if (IS_ERR(state)) {
219 DRM_ERROR("pinctrl_lookup_state for %s fail\n", compat);
220 ret = PTR_ERR(state);
221 goto exit;
222 }
223
224 ret = pinctrl_select_state(pctl, state);
225 if (ret < 0) {
226 DRM_ERROR("pinctrl_select_state(%s) for %s fail\n",
227 name, compat);
228 goto exit;
229 }
230 ret = 0;
231
232 exit:
233 return ret;
234 }
235
sunxi_drm_get_sys_item_int(struct device_node * node,char * sub_name,int * value)236 int sunxi_drm_get_sys_item_int(struct device_node *node,
237 char *sub_name, int *value)
238 {
239
240 return of_property_read_u32_array(node, sub_name, value, 1);
241 }
242
sunxi_drm_get_sys_item_char(struct device_node * node,char * sub_name,char * value)243 int sunxi_drm_get_sys_item_char(struct device_node *node,
244 char *sub_name, char *value)
245 {
246 const char *str;
247
248 if (of_property_read_string(node, sub_name, &str)) {
249 DRM_DEBUG_DRIVER("failed to get [%s] string.\n", sub_name);
250 return -EINVAL;
251 }
252
253 memcpy((void *)value, str, strlen(str)+1);
254
255 return 0;
256 }
257
sunxi_drm_get_sys_item_gpio(struct device_node * node,char * sub_name,struct disp_gpio_info * gpio_info)258 int sunxi_drm_get_sys_item_gpio(struct device_node *node,
259 char *sub_name, struct disp_gpio_info *gpio_info)
260 {
261 int gpio;
262 enum of_gpio_flags flags;
263
264 gpio = of_get_named_gpio_flags(node, sub_name, 0, &flags);
265 if (!gpio_is_valid(gpio)) {
266 DRM_DEBUG_DRIVER("There is NO gpio[%s] in DTS, "
267 "failed to get it.\n", sub_name);
268 return -EINVAL;
269 }
270
271 gpio_info->gpio = gpio;
272 gpio_info->value = (flags == OF_GPIO_ACTIVE_LOW) ? 0 : 1;
273 memcpy(gpio_info->name, sub_name, strlen(sub_name) + 1);
274
275 return 0;
276 }
277
sunxi_drm_get_name_node(char * device_name)278 struct device_node *sunxi_drm_get_name_node(char *device_name)
279 {
280 struct device_node *node = NULL;
281 char compat[32];
282 u32 len = 0;
283
284 len = sprintf(compat, "allwinner,%s", device_name);
285 if (len > 32)
286 DRM_INFO("size of mian_name is out of range\n");
287
288 node = of_find_compatible_node(NULL, NULL, compat);
289 if (!node) {
290 DRM_ERROR("There is NO dts node %s fail\n", compat);
291 return NULL;
292 }
293
294 return node;
295 }
296
bsp_disp_get_print_level(void)297 int bsp_disp_get_print_level(void)
298 {
299 return disp_log_level;
300 }
301
bsp_disp_set_print_level(unsigned char level)302 void bsp_disp_set_print_level(unsigned char level)
303 {
304 disp_log_level = level;
305 }
306
disp_delay_us(u32 us)307 int disp_delay_us(u32 us)
308 {
309 udelay(us);
310 return 0;
311 }
312
disp_delay_ms(u32 ms)313 s32 disp_delay_ms(u32 ms)
314 {
315 sunxi_drm_delayed_ms(ms);
316 return 0;
317 }
318
disp_sys_script_get_item(char * main_name,char * sub_name,int value[],int type)319 int disp_sys_script_get_item(char *main_name,
320 char *sub_name, int value[], int type)
321 {
322 struct device_node *node;
323 char compat[32];
324 u32 len = 0;
325
326 len = sprintf(compat, "sunxi-%s", main_name);
327 node = sunxi_drm_get_name_node(compat);
328 if (!node) {
329 DRM_ERROR("get [%s] item err.\n", main_name);
330 return -EINVAL;
331 }
332 switch (type) {
333 case 1:
334 if (sunxi_drm_get_sys_item_int(node, sub_name, value))
335 return 0;
336 return type;
337 case 2:
338 if (sunxi_drm_get_sys_item_char(node, sub_name, (char *)value))
339 return 0;
340 return type;
341 case 3:
342 if (sunxi_drm_get_sys_item_gpio(node, sub_name,
343 (struct disp_gpio_info *)value))
344 return 0;
345 return type;
346 default:
347 return 0;
348 }
349 }
350
351