1 /**
2 * drivers/usb/host/sunxi_hci.c
3 * (C) Copyright 2010-2015
4 * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
5 * yangnaitian, 2011-5-24, create this file
6 * javen, 2011-7-18, add clock and power switch
7 *
8 * sunxi HCI Driver
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 */
16
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 //#include <sunxi_hal_gpio.h>
21 #include <usb_os_platform.h>
22 #include <hal_osal.h>
23 #include <hal_clk.h>
24 #include <hal_reset.h>
25 #include <hal_gpio.h>
26 #include <log.h>
27 #include <usb/hal_hci.h>
28 #include <platform_usb.h>
29 #include <hal_cfg.h>
30
31 #include "sunxi-hci.h"
32
33 //static u64 sunxi_hci_dmamask = DMA_BIT_MASK(64);
34
35 #ifdef CONFIG_USB_SUNXI_USB_MANAGER
36 int usb_otg_id_status(void);
37 #endif
38
39 #define USBPHYC_REG_o_PHYCTL 0x0404
40
41 #if 0
42 static void usb_hci_utmi_phy_tune(struct sunxi_hci_hcd *sunxi_hci, int mask,
43 int offset, int val)
44 {
45 int reg_value = 0;
46
47 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_TUNE);
48 reg_value &= ~mask;
49 val = val << offset;
50 val &= mask;
51 reg_value |= val;
52 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_HCI_PHY_TUNE));
53 }
54 #endif
usb_new_phyx_tp_write(struct sunxi_hci_hcd * sunxi_hci,int addr,int data,int len)55 static int usb_new_phyx_tp_write(struct sunxi_hci_hcd *sunxi_hci, int addr, int data, int len)
56 {
57 int temp = 0;
58 int j = 0;
59 int dtmp = 0;
60
61 /*device: 0x410(phy_ctl)*/
62 dtmp = data;
63 for (j = 0; j < len; j++)
64 {
65 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
66 temp |= (0x1 << 1);
67 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
68
69 USBC_Writeb(addr + j, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL + 1);
70 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
71 temp &= ~(0x1 << 0);
72 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
73 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
74 temp &= ~(0x1 << 7);
75 temp |= (dtmp & 0x1) << 7;
76 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
77 temp |= (0x1 << 0);
78 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
79 temp &= ~(0x1 << 0);
80 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
81
82 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
83 temp &= ~(0x1 << 1);
84 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
85 dtmp >>= 1;
86 }
87 return 0;
88 }
89
usb_new_phyx_tp_read(struct sunxi_hci_hcd * sunxi_hci,int addr,int len)90 static int usb_new_phyx_tp_read(struct sunxi_hci_hcd *sunxi_hci, int addr, int len)
91 {
92 int temp = 0;
93 int i = 0;
94 int j = 0;
95 int ret = 0;
96
97 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
98 temp |= (0x1 << 1);
99 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
100
101 for (j = len; j > 0; j--)
102 {
103 USBC_Writeb((addr + j - 1), sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL + 1);
104 for (i = 0; i < 0x4; i++);
105 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_UTMI_PHY_STATUS);
106 ret <<= 1;
107 ret |= (temp & 0x1);
108 }
109
110 temp = USBC_Readb(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
111 temp &= ~(0x1 << 1);
112 USBC_Writeb(temp, sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
113 return ret;
114
115 }
116
usb_new_phy_init(struct sunxi_hci_hcd * sunxi_hci)117 static void usb_new_phy_init(struct sunxi_hci_hcd *sunxi_hci)
118 {
119 int value= 0;
120 // printf("com_tune: addr:%x, len:%x, value:%x\n", 0x30, 0x0D, usb_new_phyx_tp_read(sunxi_hci, 0x30, 0x0D));
121 usb_new_phyx_tp_write(sunxi_hci, 0x30, 0xef, 0x0D);
122 // printf("com_tune[after fix]: addr:%x, len:%x, value:%x\n", 0x30, 0x0D, usb_new_phyx_tp_read(sunxi_hci, 0x30, 0x0D));
123
124 // printf("tx_tune: addr:%x,len:%x, value:%x\n", 0x60, 0x0E, usb_new_phyx_tp_read(sunxi_hci, 0x60, 0x0E));
125 value = usb_new_phyx_tp_read(sunxi_hci, 0x60, 0x0E);
126 value = (value & (~0x0f)) | sunxi_hci->usb_driver_level;
127 usb_new_phyx_tp_write(sunxi_hci, 0x60, value, 0x0E);
128 // printf("tx_tune[after fix]: addr:%x, len:%x, value:%x\n", 0x60, 0x0E, usb_new_phyx_tp_read(sunxi_hci, 0x60, 0x0E));
129
130 // printf("res: addr:%x, len:%x, value:%x\n", 0x44, 0x04, usb_new_phyx_tp_read(sunxi_hci, 0x44, 0x04));
131 usb_new_phyx_tp_write(sunxi_hci, 0x44, 0xf, 0x04);
132 // printf("res[after fix]: addr:%x, len:%x, value:%x\n", 0x44, 0x04, usb_new_phyx_tp_read(sunxi_hci, 0x44, 0x04));
133 }
134
usb_new_phy_adjust(struct sunxi_hci_hcd * sunxi_hci,int driver_level)135 void usb_new_phy_adjust(struct sunxi_hci_hcd *sunxi_hci, int driver_level)
136 {
137 int value= 0;
138 value = usb_new_phyx_tp_read(sunxi_hci, 0x60, 0x0E);
139 printf("before value:%x\n", value);
140 value = (value & (~0x0f)) | driver_level;
141 printf("target value:%x\n", value);
142 usb_new_phyx_tp_write(sunxi_hci, 0x60, value, 0x0E);
143 value = usb_new_phyx_tp_read(sunxi_hci, 0x60, 0x0E);
144 printf("after value:%x\n", value);
145 }
146
USBC_SelectPhyToHci(struct sunxi_hci_hcd * sunxi_hci)147 static void USBC_SelectPhyToHci(struct sunxi_hci_hcd *sunxi_hci)
148 {
149 int reg_value = 0;
150
151 reg_value = USBC_Readl(sunxi_hci->otg_vbase + SUNXI_OTG_PHY_CFG);
152 reg_value &= ~(0x01);
153 USBC_Writel(reg_value, (sunxi_hci->otg_vbase + SUNXI_OTG_PHY_CFG));
154 }
155
USBC_Clean_SIDDP(struct sunxi_hci_hcd * sunxi_hci)156 static void USBC_Clean_SIDDP(struct sunxi_hci_hcd *sunxi_hci)
157 {
158 int reg_value = 0;
159
160 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
161 reg_value &= ~(0x01 << SUNXI_HCI_PHY_CTRL_SIDDQ);
162 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL));
163 }
164
165 /*
166 * Low-power mode USB standby helper functions.
167 */
168 #ifdef SUNXI_USB_STANDBY_LOW_POW_MODE
sunxi_hci_set_siddq(struct sunxi_hci_hcd * sunxi_hci,int is_on)169 void sunxi_hci_set_siddq(struct sunxi_hci_hcd *sunxi_hci, int is_on)
170 {
171 int reg_value = 0;
172
173 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL);
174
175 if (is_on)
176 reg_value |= 0x01 << SUNXI_HCI_PHY_CTRL_SIDDQ;
177 else
178 reg_value &= ~(0x01 << SUNXI_HCI_PHY_CTRL_SIDDQ);
179
180 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL));
181 }
182
sunxi_hci_set_wakeup_ctrl(struct sunxi_hci_hcd * sunxi_hci,int is_on)183 void sunxi_hci_set_wakeup_ctrl(struct sunxi_hci_hcd *sunxi_hci, int is_on)
184 {
185 int reg_value = 0;
186
187 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_HCI_CTRL_3);
188
189 if (is_on)
190 reg_value |= 0x01 << SUNXI_HCI_CTRL_3_REMOTE_WAKEUP;
191 else
192 reg_value &= ~(0x01 << SUNXI_HCI_CTRL_3_REMOTE_WAKEUP);
193
194 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_HCI_CTRL_3));
195 }
196
sunxi_hci_set_rc_clk(struct sunxi_hci_hcd * sunxi_hci,int is_on)197 void sunxi_hci_set_rc_clk(struct sunxi_hci_hcd *sunxi_hci, int is_on)
198 {
199 int reg_value = 0;
200
201 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
202
203 if (is_on)
204 reg_value |= 0x01 << SUNXI_HCI_RC16M_CLK_ENBALE;
205 else
206 reg_value &= ~(0x01 << SUNXI_HCI_RC16M_CLK_ENBALE);
207
208 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE));
209 }
210
211 #if defined(CONFIG_ARCH_SUN50IW9)
sunxi_hci_set_standby_irq(struct sunxi_hci_hcd * sunxi_hci,int is_on)212 void sunxi_hci_set_standby_irq(struct sunxi_hci_hcd *sunxi_hci, int is_on)
213 {
214 int reg_value = 0;
215
216 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_EHCI_TIME_INT);
217
218 if (is_on)
219 reg_value |= 0x01 << SUNXI_USB_EHCI_STANDBY_IRQ;
220 else
221 reg_value &= ~(0x01 << SUNXI_USB_EHCI_STANDBY_IRQ);
222
223 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_USB_EHCI_TIME_INT));
224 }
225 #endif
226
sunxi_hci_clean_standby_irq(struct sunxi_hci_hcd * sunxi_hci)227 void sunxi_hci_clean_standby_irq(struct sunxi_hci_hcd *sunxi_hci)
228 {
229 int reg_value = 0;
230
231 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_EHCI_TIME_INT);
232 reg_value |= 0x01 << SUNXI_USB_EHCI_STANDBY_IRQ_STATUS;
233 USBC_Writel(reg_value, (sunxi_hci->usb_vbase + SUNXI_USB_EHCI_TIME_INT));
234 }
235 #endif
236
hci_clock_init(struct sunxi_hci_hcd * sunxi_hci)237 int hci_clock_init(struct sunxi_hci_hcd *sunxi_hci)
238 {
239 struct platform_usb_config *hci_table = platform_get_hci_table();
240 if(sunxi_hci->usbc_no < USB_MAX_CONTROLLER_COUNT){
241
242 sunxi_hci->bus_clk_id = hci_table[sunxi_hci->usbc_no].usb_clk;
243 sunxi_hci->reset_bus_clk = hci_table[sunxi_hci->usbc_no].usb_rst;
244 sunxi_hci->phy_clk_id = hci_table[sunxi_hci->usbc_no].phy_clk;
245 sunxi_hci->reset_phy_clk = hci_table[sunxi_hci->usbc_no].phy_rst;
246 return 0;
247
248 }else{
249
250 hal_log_err("hci_clock_init failed, invalied\n");
251 return -1;
252 }
253 }
254
open_clock(struct sunxi_hci_hcd * sunxi_hci,u32 ohci)255 int open_clock(struct sunxi_hci_hcd *sunxi_hci, u32 ohci)
256 {
257 hal_reset_type_t reset_type = HAL_SUNXI_RESET;
258 hal_clk_type_t clk_type = HAL_SUNXI_CCU;
259 hal_clk_status_t ret;
260 //mutex_lock(&usb_clock_lock);
261
262 sunxi_hci->reset_phy = hal_reset_control_get(reset_type, sunxi_hci->reset_phy_clk);
263 hal_reset_control_deassert(sunxi_hci->reset_phy);
264 hal_reset_control_put(sunxi_hci->reset_phy);
265
266 sunxi_hci->reset_hci = hal_reset_control_get(reset_type, sunxi_hci->reset_bus_clk);
267 hal_reset_control_deassert(sunxi_hci->reset_hci);
268 hal_reset_control_put(sunxi_hci->reset_hci);
269
270 sunxi_hci->phy_clk = hal_clock_get(clk_type, sunxi_hci->phy_clk_id);
271 ret = hal_clock_enable(sunxi_hci->phy_clk);
272 if (ret)
273 {
274 hal_log_err("couldn't enable usb_clk!\n");
275 return -1;
276 }
277
278 sunxi_hci->bus_clk = hal_clock_get(clk_type, sunxi_hci->bus_clk_id);
279 ret = hal_clock_enable(sunxi_hci->bus_clk);
280 if (ret)
281 {
282 hal_log_err("couldn't enable hci_clk!\n");
283 return -1;
284 }
285
286 USBC_Clean_SIDDP(sunxi_hci);
287
288 /* otg and hci0 Controller Shared phy in SUN50I */
289 if (sunxi_hci->usbc_no == HCI0_USBC_NO)
290 USBC_SelectPhyToHci(sunxi_hci);
291
292 hal_log_info("--open_clock 0x810 = 0x%x\n", USBC_Readl(sunxi_hci->usb_vbase + SUNXI_HCI_PHY_CTRL));
293 //mutex_unlock(&usb_clock_lock);
294 usb_new_phy_init(sunxi_hci);
295 return 0;
296 }
297
298
close_clock(struct sunxi_hci_hcd * sunxi_hci,u32 ohci)299 int close_clock(struct sunxi_hci_hcd *sunxi_hci, u32 ohci)
300 {
301 hal_reset_type_t reset_type = HAL_SUNXI_RESET;
302 hal_clk_type_t clk_type = HAL_SUNXI_CCU;
303 hal_clk_status_t ret;
304 //if (sunxi_hci->ahb &&
305 // sunxi_hci->mod_usbphy &&
306 // sunxi_hci->clk_is_open) {
307 // sunxi_hci->clk_is_open = 0;
308 // clk_disable_unprepare(sunxi_hci->mod_usbphy);
309
310 // clk_disable_unprepare(sunxi_hci->ahb);
311 // udelay(10);
312 //} else {
313 // DMSG_PANIC("[%s]: wrn: open clock failed, (0x%p, 0x%p, %d, 0x%p)\n",
314 // sunxi_hci->hci_name,
315 // sunxi_hci->ahb,
316 // sunxi_hci->mod_usbphy,
317 // sunxi_hci->clk_is_open,
318 // sunxi_hci->mod_usb);
319 //}
320 sunxi_hci->reset_phy = hal_reset_control_get(reset_type, sunxi_hci->reset_phy_clk);
321 ret = hal_reset_control_assert(sunxi_hci->reset_phy);
322 if (ret)
323 {
324 hal_log_err("couldn't disable hci_reset_phy!\n");
325 return -1;
326 }
327
328
329 sunxi_hci->reset_hci = hal_reset_control_get(reset_type, sunxi_hci->reset_bus_clk);
330 ret = hal_reset_control_assert(sunxi_hci->reset_hci);
331 if (ret)
332 {
333 hal_log_err("couldn't disable hci_reset_bus!\n");
334 return -1;
335 }
336
337
338 sunxi_hci->phy_clk = hal_clock_get(clk_type, sunxi_hci->phy_clk_id);
339 ret = hal_clock_disable(sunxi_hci->phy_clk);
340 if (ret)
341 {
342 hal_log_err("couldn't disable phy_clk!\n");
343 return -1;
344 }
345
346 sunxi_hci->bus_clk = hal_clock_get(clk_type, sunxi_hci->bus_clk_id);
347 ret = hal_clock_disable(sunxi_hci->bus_clk);
348 if (ret)
349 {
350 hal_log_err("couldn't disable bus_clk!\n");
351 return -1;
352 }
353 return 0;
354 }
355
usb_get_hsic_phy_ctrl(int value,int enable)356 static int usb_get_hsic_phy_ctrl(int value, int enable)
357 {
358 if (enable) {
359 value |= (0x07<<8);
360 value |= (0x01<<1);
361 value |= (0x01<<0);
362 value |= (0x01<<16);
363 value |= (0x01<<20);
364 } else {
365 value &= ~(0x07<<8);
366 value &= ~(0x01<<1);
367 value &= ~(0x01<<0);
368 value &= ~(0x01<<16);
369 value &= ~(0x01<<20);
370 }
371
372 return value;
373 }
374
usb_passby(struct sunxi_hci_hcd * sunxi_hci,u32 enable)375 void usb_passby(struct sunxi_hci_hcd *sunxi_hci, u32 enable)
376 {
377 uint32_t flags;
378 hal_spinlock_t passby_lock;
379 unsigned long reg_value = 0;
380
381 flags = hal_spin_lock_irqsave(&passby_lock);
382
383 reg_value = USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE);
384 if (enable) {
385 reg_value |= (1 << 10); /* AHB Master interface INCR8 enable */
386 reg_value |= (1 << 9); /* AHB Master interface burst type INCR4 enable */
387 reg_value |= (1 << 8); /* AHB Master interface INCRX align enable */
388 reg_value |= (1 << 0); /* ULPI bypass enable */
389 hal_log_info("reg_value = 0x%x\n", reg_value);
390 } else if (!enable) {
391 reg_value &= ~(1 << 10); /* AHB Master interface INCR8 disable */
392 reg_value &= ~(1 << 9); /* AHB Master interface burst type INCR4 disable */
393 reg_value &= ~(1 << 8); /* AHB Master interface INCRX align disable */
394 reg_value &= ~(1 << 0); /* ULPI bypass disable */
395 }
396 USBC_Writel(reg_value,
397 (sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE));
398
399 hal_log_info("---usb_passby 0x800 = 0x%x\n", USBC_Readl(sunxi_hci->usb_vbase + SUNXI_USB_PMU_IRQ_ENABLE));
400
401 hal_spin_unlock_irqrestore(&passby_lock, flags);
402
403 }
404
init_pin(struct sunxi_hci_hcd * sunxi_hci)405 static int init_pin(struct sunxi_hci_hcd *sunxi_hci)
406 {
407
408 //if (strncmp(sunxi_hci->drv_vbus_name, "gpio", 4) == 0) {
409 // sunxi_hci->drv_vbus_gpio = usb_drvvbus[sunxi_hci->usbc_no];
410 // sunxi_hci->drv_vbus_gpio_valid = 1;
411 //} else
412 // sunxi_hci->drv_vbus_gpio_valid = 0;
413
414
415 //if (sunxi_hci->drv_vbus_gpio_valid) {
416 // if (hal_gpio_pinmux_set_function(sunxi_hci->drv_vbus_gpio, 0)) {
417 // DMSG_PANIC("ERR: %s set drvvbus gpio function failed\n", sunxi_hci->hci_name);
418 // return;
419 // }
420
421 // if (hal_gpio_set_pull(sunxi_hci->drv_vbus_gpio, 1)) {
422 // DMSG_PANIC("ERR: %s pull gpio failed\n", sunxi_hci->hci_name);
423 // return;
424 // }
425 //}
426
427
428 return 0;
429 }
430
free_pin(struct sunxi_hci_hcd * sunxi_hci)431 static void free_pin(struct sunxi_hci_hcd *sunxi_hci)
432 {
433 //if (sunxi_hci->drv_vbus_gpio_valid) {
434 // gpio_free(sunxi_hci->drv_vbus_gpio_set.gpio);
435 // sunxi_hci->drv_vbus_gpio_valid = 0;
436 //}
437
438 //if (sunxi_hci->hsic_flag) {
439 // /* Marvell 4G HSIC ctrl */
440 // if (sunxi_hci->usb_host_hsic_rdy_valid) {
441 // gpio_free(sunxi_hci->usb_host_hsic_rdy.gpio);
442 // sunxi_hci->usb_host_hsic_rdy_valid = 0;
443 // }
444
445 // /* SMSC usb3503 HSIC HUB ctrl */
446 // if (sunxi_hci->usb_hsic_usb3503_flag) {
447 // if (sunxi_hci->usb_hsic_hub_connect_valid) {
448 // gpio_free(sunxi_hci->usb_hsic_hub_connect.gpio);
449 // sunxi_hci->usb_hsic_hub_connect_valid = 0;
450 // }
451
452 // if (sunxi_hci->usb_hsic_int_n_valid) {
453 // gpio_free(sunxi_hci->usb_hsic_int_n.gpio);
454 // sunxi_hci->usb_hsic_int_n_valid = 0;
455 // }
456
457 // if (sunxi_hci->usb_hsic_reset_n_valid) {
458 // gpio_free(sunxi_hci->usb_hsic_reset_n.gpio);
459 // sunxi_hci->usb_hsic_reset_n_valid = 0;
460 // }
461 // }
462 //}
463 }
464
sunxi_set_host_vbus(struct sunxi_hci_hcd * sunxi_hci,int is_on)465 void sunxi_set_host_vbus(struct sunxi_hci_hcd *sunxi_hci, int is_on)
466 {
467 // int ret;
468 //
469 // if (sunxi_hci->supply) {
470 // if (is_on) {
471 // ret = regulator_enable(sunxi_hci->supply);
472 // if (ret)
473 // DMSG_PANIC("ERR: %s regulator enable failed\n",
474 // sunxi_hci->hci_name);
475 // } else {
476 // ret = regulator_disable(sunxi_hci->supply);
477 // if (ret)
478 // DMSG_PANIC("ERR: %s regulator force disable failed\n",
479 // sunxi_hci->hci_name);
480 // }
481 // }
482 // if (sunxi_hci->drv_vbus_type == USB_DRV_VBUS_TYPE_GIPO) {
483 // if (sunxi_hci->drv_vbus_gpio_valid)
484 // __gpio_set_value(sunxi_hci->drv_vbus_gpio_set.gpio,
485 // is_on);
486 // } else if (sunxi_hci->drv_vbus_type == USB_DRV_VBUS_TYPE_AXP) {
487 //#if defined(CONFIG_AW_AXP)
488 // axp_usb_vbus_output(is_on);
489 //#endif
490 // }
491 //#endif
492 }
493 //EXPORT_SYMBOL(sunxi_set_host_vbus);
494
sunxi_set_vbus(struct sunxi_hci_hcd * sunxi_hci,int is_on)495 void sunxi_set_vbus(struct sunxi_hci_hcd *sunxi_hci, int is_on)
496 {
497
498 DMSG_DEBUG("[%s]: sunxi_set_vbus cnt.\n", sunxi_hci->hci_name)
499 #if 0
500 if (is_on) {
501 ret = regulator_enable(sunxi_hci->supply);
502 if (ret)
503 DMSG_PANIC("ERR: %s regulator enable failed\n",
504 sunxi_hci->hci_name);
505 } else {
506 ret = regulator_disable(sunxi_hci->supply);
507 if (ret)
508 DMSG_PANIC("ERR: %s regulator force disable failed\n",
509 sunxi_hci->hci_name);
510 }
511 #endif
512 if (sunxi_hci->drv_vbus_type == USB_DRV_VBUS_TYPE_GIPO)
513 {
514 //hal_gpio_set_direction(sunxi_hci->drv_vbus_gpio_set, is_on);
515 hal_gpio_set_data(sunxi_hci->drv_vbus_gpio_set, is_on);
516 }
517 else if (sunxi_hci->drv_vbus_type == USB_DRV_VBUS_TYPE_AXP)
518 {
519 #if defined(CONFIG_AW_AXP)
520 axp_usb_vbus_output(is_on);
521 #endif
522 }
523 }
524
sunxi_hci_get_config_param(struct sunxi_hci_hcd * sunxi_hci)525 void sunxi_hci_get_config_param(struct sunxi_hci_hcd *sunxi_hci)
526 {
527 int ret = -1, pin_type = 0, value = 0;
528 char ehci_name[10] = {0};
529 user_gpio_set_t pin_value = {0};
530
531 sprintf(ehci_name, "usbc%1d", sunxi_hci->usbc_no);
532
533 ret = Hal_Cfg_GetKeyValue(ehci_name, KEY_USB_DRVVBUS_GPIO, (int32_t *)&pin_value, (sizeof(user_gpio_set_t) + 3) / sizeof(int));
534 if (ret) {
535 hal_log_err("%s drvvbus fetch error!", ehci_name);
536 }
537
538 ret = Hal_Cfg_GetKeyValue(ehci_name, KEY_USB_DRVVBUS_TYPE, (int32_t *)&pin_type, 1);
539 if (ret) {
540 hal_log_err("%s drvvbus fetch error!", ehci_name);
541 }
542
543 ret = Hal_Cfg_GetKeyValue(ehci_name, KEY_USB_DRIVER_LEVEL, (int32_t *)&value, 1);
544 if (ret) {
545 hal_log_err("%s %s fetch error!", ehci_name, KEY_USB_DRIVER_LEVEL);
546 value = 0xf;
547 }
548 if (value > 0xf || value < 0x0)
549 {
550 value = 0xf;
551 }
552 sunxi_hci->usb_driver_level = value;
553
554 ret = Hal_Cfg_GetKeyValue(ehci_name, KEY_USB_IRQ_FLAG, (int32_t *)&value, 1);
555 if (ret) {
556 hal_log_err("%s %s fetch error!", ehci_name, KEY_USB_IRQ_FLAG);
557 value = 0x0;
558 }
559 sunxi_hci->usb_irq_flag = value;
560
561 sunxi_hci->drv_vbus_type = pin_type;
562 sunxi_hci->drv_vbus_gpio_set = (pin_value.port - 1) * PINS_PER_BANK + pin_value.port_num;
563 hal_gpio_set_direction(sunxi_hci->drv_vbus_gpio_set, GPIO_DIRECTION_OUTPUT);
564 }
565
sunxi_get_ohci_clock_src(struct platform_device * pdev,struct sunxi_hci_hcd * sunxi_hci)566 static int sunxi_get_ohci_clock_src(struct platform_device *pdev,
567 struct sunxi_hci_hcd *sunxi_hci)
568 {
569 // struct device_node *np = pdev->dev.of_node;
570 //
571 // sunxi_hci->clk_usbohci12m = of_clk_get(np, 2);
572 // if (IS_ERR(sunxi_hci->clk_usbohci12m)) {
573 // sunxi_hci->clk_usbohci12m = NULL;
574 // DMSG_INFO("%s get usb clk_usbohci12m clk failed.\n",
575 // sunxi_hci->hci_name);
576 // }
577 //
578 // sunxi_hci->clk_hoscx2 = of_clk_get(np, 3);
579 // if (IS_ERR(sunxi_hci->clk_hoscx2)) {
580 // sunxi_hci->clk_hoscx2 = NULL;
581 // DMSG_INFO("%s get usb clk_hoscx2 clk failed.\n",
582 // sunxi_hci->hci_name);
583 // }
584 //
585 // sunxi_hci->clk_hosc = of_clk_get(np, 4);
586 // if (IS_ERR(sunxi_hci->clk_hosc)) {
587 // sunxi_hci->clk_hosc = NULL;
588 // DMSG_INFO("%s get usb clk_hosc failed.\n",
589 // sunxi_hci->hci_name);
590 // }
591 //
592 // sunxi_hci->clk_losc = of_clk_get(np, 5);
593 // if (IS_ERR(sunxi_hci->clk_losc)) {
594 // sunxi_hci->clk_losc = NULL;
595 // DMSG_INFO("%s get usb clk_losc clk failed.\n",
596 // sunxi_hci->hci_name);
597 // }
598 //
599 return 0;
600 }
601
exit_sunxi_hci(struct sunxi_hci_hcd * sunxi_hci)602 int exit_sunxi_hci(struct sunxi_hci_hcd *sunxi_hci)
603 {
604 //release_usb_regulator_io(sunxi_hci);
605 //free_pin(sunxi_hci);
606 return 0;
607 }
608 //EXPORT_SYMBOL(exit_sunxi_hci);
609
610 //int init_sunxi_hci(int usbc_type, int hci_num)
611 //{
612 // struct sunxi_hci_hcd *sunxi_hci = NULL;
613 //
614 // if (usbc_type == SUNXI_USB_EHCI) {
615 // sunxi_hci = g_sunxi_ehci[hci_num];
616 // } else if (usbc_type == SUNXI_USB_OHCI) {
617 // sunxi_hci = g_sunxi_ohci[hci_num];
618 // } else {
619 // ehci_err("usbc type is error! n");
620 // return -1;
621 // }
622 //
623 // ret = sunxi_get_hci_resource(sunxi_hci, hci_num, usbc_type);
624 //
625 //#if 0
626 // if (usbc_type == SUNXI_USB_OHCI)
627 // ret = sunxi_get_ohci_clock_src(pdev, sunxi_hci);
628 //#endif
629 // return ret;
630 //}
631
632 //static int __parse_hci_str(const char *buf, size_t size)
633 //{
634 // int ret = 0;
635 // unsigned long val;
636 //
637 // if (!buf) {
638 // pr_err("%s()%d invalid argument\n", __func__, __LINE__);
639 // return -1;
640 // }
641 //
642 // ret = kstrtoul(buf, 10, &val);
643 // if (ret) {
644 // pr_err("%s()%d failed to transfer\n", __func__, __LINE__);
645 // return -1;
646 // }
647 //
648 // return val;
649 //}
650
651
652 //static int __init init_sunxi_hci_class(void)
653 //{
654 // int ret = 0;
655 //
656 // ret = class_register(&hci_class);
657 // if (ret) {
658 // DMSG_PANIC("%s()%d register class fialed\n", __func__, __LINE__);
659 // return -1;
660 // }
661 //
662 // return 0;
663 //}
664 //
665 //static void __exit exit_sunxi_hci_class(void)
666 //{
667 // class_unregister(&hci_class);
668 //}
669
670 //late_initcall(init_sunxi_hci_class);
671 //module_exit(exit_sunxi_hci_class);
672
673 //MODULE_LICENSE("GPL");
674