1 /*
2 * Allwinner SoCs display driver.
3 *
4 * Copyright (C) 2016 Allwinner.
5 *
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
9 */
10
11 #include "lcd_source.h"
12
13 /**
14 * sunxi_lcd_delay_ms.
15 * @ms: Delay time, unit: millisecond.
16 */
sunxi_lcd_delay_ms(u32 ms)17 s32 sunxi_lcd_delay_ms(u32 ms)
18 {
19 if (g_lcd_drv.src_ops.sunxi_lcd_delay_ms)
20 return g_lcd_drv.src_ops.sunxi_lcd_delay_ms(ms);
21
22 return -1;
23 }
24
25 /**
26 * sunxi_lcd_delay_us.
27 * @us: Delay time, unit: microsecond.
28 */
sunxi_lcd_delay_us(u32 us)29 s32 sunxi_lcd_delay_us(u32 us)
30 {
31 if (g_lcd_drv.src_ops.sunxi_lcd_delay_us)
32 return g_lcd_drv.src_ops.sunxi_lcd_delay_us(us);
33
34 return -1;
35 }
36
37 /**
38 * sunxi_lcd_tcon_enable - enable timing controller.
39 * @screen_id: The index of screen.
40 */
sunxi_lcd_tcon_enable(u32 screen_id)41 void sunxi_lcd_tcon_enable(u32 screen_id)
42 {
43 if (g_lcd_drv.src_ops.sunxi_lcd_tcon_enable)
44 g_lcd_drv.src_ops.sunxi_lcd_tcon_enable(screen_id);
45 }
46
47
48 /**
49 * sunxi_lcd_dsi_mode_switch
50 * @screen_id: The index of screen.
51 * @cmd_en : enable command mode
52 * @lp_en : enable low power mode for video mode
53 */
sunxi_lcd_dsi_mode_switch(u32 screen_id,u32 cmd_en,u32 lp_en)54 void sunxi_lcd_dsi_mode_switch(u32 screen_id, u32 cmd_en, u32 lp_en)
55 {
56 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_mode_switch)
57 g_lcd_drv.src_ops.sunxi_lcd_dsi_mode_switch(screen_id, cmd_en,
58 lp_en);
59 }
60
61 /**
62 * sunxi_lcd_tcon_disable - disable timing controller.
63 * @screen_id: The index of screen.
64 */
sunxi_lcd_tcon_disable(u32 screen_id)65 void sunxi_lcd_tcon_disable(u32 screen_id)
66 {
67 if (g_lcd_drv.src_ops.sunxi_lcd_tcon_disable)
68 g_lcd_drv.src_ops.sunxi_lcd_tcon_disable(screen_id);
69 }
70
71 /**
72 * sunxi_lcd_backlight_enable - enable the backlight of panel.
73 * @screen_id: The index of screen.
74 */
sunxi_lcd_backlight_enable(u32 screen_id)75 void sunxi_lcd_backlight_enable(u32 screen_id)
76 {
77 if (g_lcd_drv.src_ops.sunxi_lcd_backlight_enable)
78 g_lcd_drv.src_ops.sunxi_lcd_backlight_enable(screen_id);
79 }
80
81 /**
82 * sunxi_lcd_backlight_disable - disable the backlight of panel.
83 * @screen_id: The index of screen.
84 */
sunxi_lcd_backlight_disable(u32 screen_id)85 void sunxi_lcd_backlight_disable(u32 screen_id)
86 {
87 if (g_lcd_drv.src_ops.sunxi_lcd_backlight_disable)
88 g_lcd_drv.src_ops.sunxi_lcd_backlight_disable(screen_id);
89 }
90
91 /**
92 * sunxi_lcd_power_enable - enable the power of panel.
93 * @screen_id: The index of screen.
94 * @pwr_id: The index of power
95 */
sunxi_lcd_power_enable(u32 screen_id,u32 pwr_id)96 void sunxi_lcd_power_enable(u32 screen_id, u32 pwr_id)
97 {
98 if (g_lcd_drv.src_ops.sunxi_lcd_power_enable)
99 g_lcd_drv.src_ops.sunxi_lcd_power_enable(screen_id, pwr_id);
100 }
101
102 /**
103 * sunxi_lcd_power_disable - disable the power of panel.
104 * @screen_id: The index of screen.
105 * @pwr_id: The index of power
106 */
sunxi_lcd_power_disable(u32 screen_id,u32 pwr_id)107 void sunxi_lcd_power_disable(u32 screen_id, u32 pwr_id)
108 {
109 if (g_lcd_drv.src_ops.sunxi_lcd_power_disable)
110 g_lcd_drv.src_ops.sunxi_lcd_power_disable(screen_id, pwr_id);
111 }
112
113 /**
114 * sunxi_lcd_pwm_enable - enable pwm modules, start output pwm wave.
115 * @screen_id: The index of screen.
116 *
117 * need to conifg gpio for pwm function
118 */
sunxi_lcd_pwm_enable(u32 screen_id)119 s32 sunxi_lcd_pwm_enable(u32 screen_id)
120 {
121 if (g_lcd_drv.src_ops.sunxi_lcd_pwm_enable)
122 return g_lcd_drv.src_ops.sunxi_lcd_pwm_enable(screen_id);
123
124 return -1;
125 }
126
127 /**
128 * sunxi_lcd_pwm_disable - disable pwm modules, stop output pwm wave.
129 * @screen_id: The index of screen.
130 */
sunxi_lcd_pwm_disable(u32 screen_id)131 s32 sunxi_lcd_pwm_disable(u32 screen_id)
132 {
133 if (g_lcd_drv.src_ops.sunxi_lcd_pwm_disable)
134 return g_lcd_drv.src_ops.sunxi_lcd_pwm_disable(screen_id);
135
136 return -1;
137 }
138
139 /**
140 *
141 * sunxi_lcd_cpu_set_auto_mode
142 * @screen_id: The index of screen.
143 */
sunxi_lcd_cpu_set_auto_mode(u32 screen_id)144 s32 sunxi_lcd_cpu_set_auto_mode(u32 screen_id)
145 {
146 if (g_lcd_drv.src_ops.sunxi_lcd_cpu_set_auto_mode)
147 return g_lcd_drv.src_ops.sunxi_lcd_cpu_set_auto_mode(screen_id);
148
149 return -1;
150 }
151
152 /**
153 * sunxi_lcd_cpu_write - write command and para to cpu panel.
154 * @screen_id: The index of screen.
155 * @command: Command to be transfer.
156 * @para: The pointer to para
157 * @para_num: The number of para
158 */
sunxi_lcd_cpu_write(u32 screen_id,u32 index,u32 data)159 s32 sunxi_lcd_cpu_write(u32 screen_id, u32 index, u32 data)
160 {
161 if (g_lcd_drv.src_ops.sunxi_lcd_cpu_write)
162 return g_lcd_drv.src_ops.sunxi_lcd_cpu_write(screen_id,
163 index, data);
164
165 return -1;
166 }
167
168 /**
169 * sunxi_lcd_cpu_write_index - write command to cpu panel.
170 * @screen_id: The index of screen.
171 * @index: Command or index to be transfer.
172 */
sunxi_lcd_cpu_write_index(u32 screen_id,u32 index)173 s32 sunxi_lcd_cpu_write_index(u32 screen_id, u32 index)
174 {
175 if (g_lcd_drv.src_ops.sunxi_lcd_cpu_write_index)
176 return g_lcd_drv.src_ops.sunxi_lcd_cpu_write_index(screen_id,
177 index);
178
179 return -1;
180 }
181
182 /**
183 * sunxi_lcd_cpu_write_data - write data to cpu panel.
184 * @screen_id: The index of screen.
185 * @data: Data to be transfer.
186 */
sunxi_lcd_cpu_write_data(u32 screen_id,u32 data)187 s32 sunxi_lcd_cpu_write_data(u32 screen_id, u32 data)
188 {
189 if (g_lcd_drv.src_ops.sunxi_lcd_cpu_write_data)
190 return g_lcd_drv.src_ops.sunxi_lcd_cpu_write_data(screen_id,
191 data);
192
193 return -1;
194 }
195
196 /**
197 * sunxi_lcd_dsi_dcs_write - write command and para to mipi panel.
198 * @screen_id: The index of screen.
199 * @command: Command to be transfer.
200 * @para: The pointer to para.
201 * @para_num: The number of para
202 */
sunxi_lcd_dsi_dcs_write(u32 screen_id,u8 command,u8 * para,u32 para_num)203 s32 sunxi_lcd_dsi_dcs_write(u32 screen_id, u8 command, u8 *para, u32 para_num)
204 {
205 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_dcs_write)
206 return g_lcd_drv.src_ops.sunxi_lcd_dsi_dcs_write(screen_id,
207 command, para,
208 para_num);
209
210 return -1;
211 }
212
213 /**
214 * sunxi_lcd_dsi_dcs_write - write command and para to mipi panel.
215 * @screen_id: The index of screen.
216 * @command: Command to be transfer.
217 */
sunxi_lcd_dsi_dcs_write_0para(u32 screen_id,u8 command)218 s32 sunxi_lcd_dsi_dcs_write_0para(u32 screen_id, u8 command)
219 {
220 u8 tmp[5];
221
222 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 0);
223
224 return -1;
225 }
226
227 /**
228 * sunxi_lcd_dsi_dcs_write_1para - write command and para to mipi panel.
229 * @screen_id: The index of screen.
230 * @command: Command to be transfer.
231 * @paran: Para to be transfer.
232 */
sunxi_lcd_dsi_dcs_write_1para(u32 screen_id,u8 command,u8 para1)233 s32 sunxi_lcd_dsi_dcs_write_1para(u32 screen_id, u8 command, u8 para1)
234 {
235 u8 tmp[5];
236
237 tmp[0] = para1;
238 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 1);
239
240 return -1;
241 }
242
sunxi_lcd_dsi_dcs_write_2para(u32 screen_id,u8 command,u8 para1,u8 para2)243 s32 sunxi_lcd_dsi_dcs_write_2para(u32 screen_id, u8 command, u8 para1, u8 para2)
244 {
245 u8 tmp[5];
246
247 tmp[0] = para1;
248 tmp[1] = para2;
249 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 2);
250
251 return -1;
252 }
253
sunxi_lcd_dsi_dcs_write_3para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3)254 s32 sunxi_lcd_dsi_dcs_write_3para(u32 screen_id, u8 command, u8 para1, u8 para2,
255 u8 para3)
256 {
257 u8 tmp[5];
258
259 tmp[0] = para1;
260 tmp[1] = para2;
261 tmp[2] = para3;
262 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 3);
263
264 return -1;
265 }
266
sunxi_lcd_dsi_dcs_write_4para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3,u8 para4)267 s32 sunxi_lcd_dsi_dcs_write_4para(u32 screen_id, u8 command, u8 para1, u8 para2,
268 u8 para3, u8 para4)
269 {
270 u8 tmp[5];
271
272 tmp[0] = para1;
273 tmp[1] = para2;
274 tmp[2] = para3;
275 tmp[3] = para4;
276 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 4);
277
278 return -1;
279 }
280
sunxi_lcd_dsi_dcs_write_5para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3,u8 para4,u8 para5)281 s32 sunxi_lcd_dsi_dcs_write_5para(u32 screen_id, u8 command, u8 para1, u8 para2,
282 u8 para3, u8 para4, u8 para5)
283 {
284 u8 tmp[5];
285
286 tmp[0] = para1;
287 tmp[1] = para2;
288 tmp[2] = para3;
289 tmp[3] = para4;
290 tmp[4] = para5;
291 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 5);
292
293 return -1;
294 }
295
sunxi_lcd_dsi_dcs_write_6para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3,u8 para4,u8 para5,u8 para6)296 s32 sunxi_lcd_dsi_dcs_write_6para(u32 screen_id, u8 command, u8 para1, u8 para2,
297 u8 para3, u8 para4, u8 para5, u8 para6)
298 {
299 u8 tmp[6];
300
301 tmp[0] = para1;
302 tmp[1] = para2;
303 tmp[2] = para3;
304 tmp[3] = para4;
305 tmp[4] = para5;
306 tmp[5] = para6;
307 sunxi_lcd_dsi_dcs_write(screen_id, command, tmp, 6);
308
309 return -1;
310 }
311
312 /**
313 * sunxi_lcd_dsi_gen_write - write command and para to mipi panel.
314 * @screen_id: The index of screen.
315 * @command: Command to be transfer.
316 * @para: The pointer to para.
317 * @para_num: The number of para
318 */
sunxi_lcd_dsi_gen_write(u32 screen_id,u8 command,u8 * para,u32 para_num)319 s32 sunxi_lcd_dsi_gen_write(u32 screen_id, u8 command, u8 *para, u32 para_num)
320 {
321 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_gen_write)
322 return g_lcd_drv.src_ops.sunxi_lcd_dsi_gen_write(screen_id,
323 command, para,
324 para_num);
325
326 return -1;
327 }
328
329 /**
330 * sunxi_lcd_dsi_gen_write - write command and para to mipi panel.
331 * @screen_id: The index of screen.
332 * @command: Command to be transfer.
333 */
sunxi_lcd_dsi_gen_write_0para(u32 screen_id,u8 command)334 s32 sunxi_lcd_dsi_gen_write_0para(u32 screen_id, u8 command)
335 {
336 u8 tmp[5];
337
338 sunxi_lcd_dsi_gen_write(screen_id, command, tmp, 0);
339
340 return -1;
341 }
342
343 /**
344 * sunxi_lcd_dsi_gen_write_1para - write command and para to mipi panel.
345 * @screen_id: The index of screen.
346 * @command: Command to be transfer.
347 * @paran: Para to be transfer.
348 */
sunxi_lcd_dsi_gen_write_1para(u32 screen_id,u8 command,u8 para1)349 s32 sunxi_lcd_dsi_gen_write_1para(u32 screen_id, u8 command, u8 para1)
350 {
351 u8 tmp[5];
352
353 tmp[0] = para1;
354 sunxi_lcd_dsi_gen_write(screen_id, command, tmp, 1);
355
356 return -1;
357 }
358
sunxi_lcd_dsi_gen_write_2para(u32 screen_id,u8 command,u8 para1,u8 para2)359 s32 sunxi_lcd_dsi_gen_write_2para(u32 screen_id, u8 command, u8 para1, u8 para2)
360 {
361 u8 tmp[5];
362
363 tmp[0] = para1;
364 tmp[1] = para2;
365 sunxi_lcd_dsi_gen_write(screen_id, command, tmp, 2);
366
367 return -1;
368 }
369
sunxi_lcd_dsi_gen_write_3para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3)370 s32 sunxi_lcd_dsi_gen_write_3para(u32 screen_id, u8 command, u8 para1, u8 para2,
371 u8 para3)
372 {
373 u8 tmp[5];
374
375 tmp[0] = para1;
376 tmp[1] = para2;
377 tmp[2] = para3;
378 sunxi_lcd_dsi_gen_write(screen_id, command, tmp, 3);
379
380 return -1;
381 }
382
sunxi_lcd_dsi_gen_write_4para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3,u8 para4)383 s32 sunxi_lcd_dsi_gen_write_4para(u32 screen_id, u8 command, u8 para1, u8 para2,
384 u8 para3, u8 para4)
385 {
386 u8 tmp[5];
387
388 tmp[0] = para1;
389 tmp[1] = para2;
390 tmp[2] = para3;
391 tmp[3] = para4;
392 sunxi_lcd_dsi_gen_write(screen_id, command, tmp, 4);
393
394 return -1;
395 }
396
sunxi_lcd_dsi_gen_write_5para(u32 screen_id,u8 command,u8 para1,u8 para2,u8 para3,u8 para4,u8 para5)397 s32 sunxi_lcd_dsi_gen_write_5para(u32 screen_id, u8 command, u8 para1, u8 para2,
398 u8 para3, u8 para4, u8 para5)
399 {
400 u8 tmp[5];
401
402 tmp[0] = para1;
403 tmp[1] = para2;
404 tmp[2] = para3;
405 tmp[3] = para4;
406 tmp[4] = para5;
407 sunxi_lcd_dsi_gen_write(screen_id, command, tmp, 5);
408
409 return -1;
410 }
411
412 /**
413 * sunxi_lcd_dsi_clk_enable - enable dsi clk.
414 * @screen_id: The index of screen.
415 */
sunxi_lcd_dsi_clk_enable(u32 screen_id)416 s32 sunxi_lcd_dsi_clk_enable(u32 screen_id)
417 {
418 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_clk_enable)
419 return g_lcd_drv.src_ops.sunxi_lcd_dsi_clk_enable(screen_id, 1);
420
421 return -1;
422 }
423
424 /**
425 * sunxi_lcd_dsi_clk_disable - disable dsi clk.
426 * @screen_id: The index of screen.
427 */
sunxi_lcd_dsi_clk_disable(u32 screen_id)428 s32 sunxi_lcd_dsi_clk_disable(u32 screen_id)
429 {
430 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_clk_enable)
431 return g_lcd_drv.src_ops.sunxi_lcd_dsi_clk_enable(screen_id, 0);
432
433 return -1;
434 }
435
436 /**
437 * sunxi_lcd_dsi_gen_read - generic short read
438 * @screen_id: The index of screen.
439 * @result: pointer that store the result
440 */
sunxi_lcd_dsi_gen_short_read(u32 screen_id,u8 * para,u8 para_num,u8 * result)441 static s32 sunxi_lcd_dsi_gen_short_read(u32 screen_id, u8 *para, u8 para_num,
442 u8 *result)
443 {
444 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_gen_short_read)
445 return g_lcd_drv.src_ops.sunxi_lcd_dsi_gen_short_read(screen_id,
446 para, para_num,
447 result);
448 return -1;
449 }
450
451 /**
452 * @name :sunxi_lcd_dsi_set_max_ret_size
453 * @brief :set max ret size of dsi read
454 * @param[IN] :sel:index of dsi
455 * @param[IN] :size:number of byte of max size
456 * @return :0
457 */
sunxi_lcd_dsi_set_max_ret_size(u32 sel,u32 size)458 s32 sunxi_lcd_dsi_set_max_ret_size(u32 sel, u32 size)
459 {
460 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_dcs_read)
461 return g_lcd_drv.src_ops.sunxi_lcd_dsi_set_max_ret_size(sel,
462 size);
463 return 0;
464 }
465
466 /**
467 * @name :sunxi_lcd_dsi_dcs_read
468 * @brief :dcs read
469 * @param[IN] :sel:index of dsi
470 * @param[IN] :cmd: dcs command
471 * @param[OUT] :result: pointer of read result,larger then max ret size
472 * @param[OUT] :num_p: number of bytes have been readed
473 * @return :number of bytes have been readed
474 */
sunxi_lcd_dsi_dcs_read(u32 sel,u8 cmd,u8 * result,u32 * num_p)475 s32 sunxi_lcd_dsi_dcs_read(u32 sel, u8 cmd, u8 *result, u32 *num_p)
476 {
477 if (g_lcd_drv.src_ops.sunxi_lcd_dsi_dcs_read)
478 return g_lcd_drv.src_ops.sunxi_lcd_dsi_dcs_read(sel, cmd,
479 result, num_p);
480 return 0;
481 }
482
483 /**
484 * sunxi_lcd_dsi_gen_short_read0p - generic read without param
485 * @screen_id: The index of screen.
486 * @paran: Para to be transfer.
487 * @result: pointer that store the result
488 */
sunxi_lcd_dsi_gen_short_read0p(u32 screen_id,u8 * result)489 s32 sunxi_lcd_dsi_gen_short_read0p(u32 screen_id, u8 *result)
490 {
491 u8 tmp[2];
492
493 return sunxi_lcd_dsi_gen_short_read(screen_id, tmp, 0, result);
494 }
495
496 /**
497 * sunxi_lcd_dsi_gen_short_read1p - generic read with 1 param
498 * @screen_id: The index of screen.
499 * @paran: Para to be transfer.
500 * @result: pointer that store the result
501 */
sunxi_lcd_dsi_gen_short_read1p(u32 screen_id,u8 para0,u8 * result)502 s32 sunxi_lcd_dsi_gen_short_read1p(u32 screen_id, u8 para0, u8 *result)
503 {
504 u8 tmp[2];
505
506 tmp[0] = para0;
507 sunxi_lcd_dsi_gen_short_read(screen_id, tmp, 1, result);
508
509 return -1;
510 }
511
512 /**
513 * sunxi_lcd_dsi_gen_short_read2p - generic read with 2 param
514 * @screen_id: The index of screen.
515 * @paran: Para to be transfer.
516 * @result: pointer that store the result
517 */
sunxi_lcd_dsi_gen_short_read2p(u32 screen_id,u8 para0,u8 para1,u8 * result)518 s32 sunxi_lcd_dsi_gen_short_read2p(u32 screen_id, u8 para0, u8 para1,
519 u8 *result)
520 {
521 u8 tmp[2];
522
523 tmp[0] = para0;
524 tmp[1] = para1;
525 return sunxi_lcd_dsi_gen_short_read(screen_id, tmp, 2, result);
526 }
527
528 /**
529 * sunxi_lcd_set_panel_funs - set panel functions.
530 * @name: The panel driver name.
531 * @lcd_cfg: The functions.
532 */
sunxi_lcd_set_panel_funs(char * name,struct disp_lcd_panel_fun * lcd_cfg)533 s32 sunxi_lcd_set_panel_funs(char *name, struct disp_lcd_panel_fun *lcd_cfg)
534 {
535 if (g_lcd_drv.src_ops.sunxi_lcd_set_panel_funs)
536 return g_lcd_drv.src_ops.sunxi_lcd_set_panel_funs(name,
537 lcd_cfg);
538
539 return -1;
540 }
541
542 /**
543 * sunxi_lcd_pin_cfg - config pin panel used
544 * @screen_id: The index of screen.
545 * @bon: 1: config pin according to sys_config, 0: set disable state
546 */
sunxi_lcd_pin_cfg(u32 screen_id,u32 bon)547 s32 sunxi_lcd_pin_cfg(u32 screen_id, u32 bon)
548 {
549 if (g_lcd_drv.src_ops.sunxi_lcd_pin_cfg)
550 return g_lcd_drv.src_ops.sunxi_lcd_pin_cfg(screen_id, bon);
551
552 return -1;
553 }
554
555 /**
556 * sunxi_lcd_gpio_set_value
557 * @screen_id: The index of screen.
558 * @io_index: the index of gpio
559 * @value: value of gpio to be set
560 */
sunxi_lcd_gpio_set_value(u32 screen_id,u32 io_index,u32 value)561 s32 sunxi_lcd_gpio_set_value(u32 screen_id, u32 io_index, u32 value)
562 {
563 if (g_lcd_drv.src_ops.sunxi_lcd_gpio_set_value)
564 return g_lcd_drv.src_ops.sunxi_lcd_gpio_set_value(screen_id,
565 io_index,
566 value);
567
568 return -1;
569 }
570
571 /**
572 * sunxi_lcd_gpio_set_direction
573 * @screen_id: The index of screen.
574 * @io_index: the index of gpio
575 * @direct: value of gpio to be set
576 */
sunxi_lcd_gpio_set_direction(u32 screen_id,u32 io_index,u32 direct)577 s32 sunxi_lcd_gpio_set_direction(u32 screen_id, u32 io_index, u32 direct)
578 {
579 if (g_lcd_drv.src_ops.sunxi_lcd_gpio_set_direction)
580 return g_lcd_drv.src_ops.sunxi_lcd_gpio_set_direction(screen_id,
581 io_index,
582 direct);
583
584 return -1;
585 }
586