1 #include <linux/kernel.h>
\r
2 #include <linux/platform_device.h>
\r
3 #include <linux/delay.h>
\r
4 #include <linux/dma-mapping.h>
\r
5 #include <linux/clk.h>
\r
7 #include <mach/irqs.h>
\r
8 #include <mach/gpio.h>
\r
9 #include <mach/iomux.h>
\r
10 #include <mach/cru.h>
\r
12 #include "usbdev_rk.h"
\r
13 #ifdef CONFIG_ARCH_RK30
\r
15 #define GRF_REG_BASE RK30_GRF_BASE
\r
16 #define USBOTG_SIZE RK30_USBOTG20_SIZE
\r
17 #ifdef CONFIG_ARCH_RK3066B
\r
18 #define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0xac)
\r
19 #define USBGRF_UOC0_CON2 (GRF_REG_BASE+0x118) // USBGRF_UOC0_CON3
\r
20 #define USBGRF_UOC1_CON2 (GRF_REG_BASE+0x128) // USBGRF_UOC1_CON3
\r
22 #define USBGRF_SOC_STATUS0 (GRF_REG_BASE+0x15c)
\r
23 #define USBGRF_UOC0_CON2 (GRF_REG_BASE+0x184)
\r
24 #define USBGRF_UOC1_CON2 (GRF_REG_BASE+0x190)
\r
26 //#define USB_IOMUX_INIT(a,b) rk30_mux_api_set(a,b)
\r
28 #ifdef CONFIG_USB20_OTG
\r
30 static struct resource usb20_otg_resource[] = {
\r
32 .start = IRQ_USB_OTG,
\r
34 .flags = IORESOURCE_IRQ,
\r
37 .start = RK30_USBOTG20_PHYS,
\r
38 .end = RK30_USBOTG20_PHYS + RK30_USBOTG20_SIZE - 1,
\r
39 .flags = IORESOURCE_MEM,
\r
44 void usb20otg_hw_init(void)
\r
46 #ifndef CONFIG_USB20_HOST
\r
47 // close USB 2.0 HOST phy and clock
\r
48 unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);
\r
49 *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.
\r
51 // usb phy config init
\r
53 // other haredware init
\r
54 #ifdef CONFIG_ARCH_RK3066B
\r
55 rk30_mux_api_set(GPIO3D5_PWM2_JTAGTCK_OTGDRVVBUS_NAME, GPIO3D_OTGDRVVBUS);
\r
57 rk30_mux_api_set(GPIO0A5_OTGDRVVBUS_NAME, GPIO0A_OTG_DRV_VBUS);
\r
60 void usb20otg_phy_suspend(void* pdata, int suspend)
\r
62 struct dwc_otg_platform_data *usbpdata=pdata;
\r
63 unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC0_CON2);
\r
65 *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.
\r
66 usbpdata->phy_status = 1;
\r
69 *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.
\r
70 usbpdata->phy_status = 0;
\r
73 void usb20otg_soft_reset(void)
\r
76 cru_set_soft_reset(SOFT_RST_USBOTG0, true);
\r
77 cru_set_soft_reset(SOFT_RST_USBPHY0, true);
\r
78 cru_set_soft_reset(SOFT_RST_OTGC0, true);
\r
81 cru_set_soft_reset(SOFT_RST_USBOTG0, false);
\r
82 cru_set_soft_reset(SOFT_RST_USBPHY0, false);
\r
83 cru_set_soft_reset(SOFT_RST_OTGC0, false);
\r
87 void usb20otg_clock_init(void* pdata)
\r
89 struct dwc_otg_platform_data *usbpdata=pdata;
\r
90 struct clk* ahbclk,*phyclk;
\r
91 ahbclk = clk_get(NULL, "hclk_otg0");
\r
92 phyclk = clk_get(NULL, "otgphy0");
\r
93 usbpdata->phyclk = phyclk;
\r
94 usbpdata->ahbclk = ahbclk;
\r
96 void usb20otg_clock_enable(void* pdata, int enable)
\r
98 struct dwc_otg_platform_data *usbpdata=pdata;
\r
101 clk_enable(usbpdata->ahbclk);
\r
102 clk_enable(usbpdata->phyclk);
\r
105 clk_disable(usbpdata->phyclk);
\r
106 clk_disable(usbpdata->ahbclk);
\r
110 int usb20otg_get_status(int id)
\r
113 unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);
\r
118 ret = (usbgrf_status &0x20000);
\r
122 ret = (usbgrf_status &(3<<18));
\r
126 ret = (usbgrf_status &(1<<20));
\r
133 void usb20otg_power_enable(int enable)
\r
136 struct dwc_otg_platform_data usb20otg_pdata = {
\r
141 .hw_init=usb20otg_hw_init,
\r
142 .phy_suspend=usb20otg_phy_suspend,
\r
143 .soft_reset=usb20otg_soft_reset,
\r
144 .clock_init=usb20otg_clock_init,
\r
145 .clock_enable=usb20otg_clock_enable,
\r
146 .get_status=usb20otg_get_status,
\r
149 struct platform_device device_usb20_otg = {
\r
150 .name = "usb20_otg",
\r
152 .num_resources = ARRAY_SIZE(usb20_otg_resource),
\r
153 .resource = usb20_otg_resource,
\r
155 .platform_data = &usb20otg_pdata,
\r
159 #ifdef CONFIG_USB20_HOST
\r
160 static struct resource usb20_host_resource[] = {
\r
162 .start = IRQ_USB_HOST,
\r
163 .end = IRQ_USB_HOST,
\r
164 .flags = IORESOURCE_IRQ,
\r
167 .start = RK30_USBHOST20_PHYS,
\r
168 .end = RK30_USBHOST20_PHYS + RK30_USBHOST20_SIZE - 1,
\r
169 .flags = IORESOURCE_MEM,
\r
173 void usb20host_hw_init(void)
\r
175 // usb phy config init
\r
177 // other haredware init
\r
178 #ifdef CONFIG_ARCH_RK3066B
\r
179 rk30_mux_api_set(GPIO3D6_PWM3_JTAGTMS_HOSTDRVVBUS_NAME, GPIO3D_HOSTDRVVBUS);
\r
181 rk30_mux_api_set(GPIO0A6_HOSTDRVVBUS_NAME, GPIO0A_HOST_DRV_VBUS);
\r
184 void usb20host_phy_suspend(void* pdata, int suspend)
\r
186 struct dwc_otg_platform_data *usbpdata=pdata;
\r
187 unsigned int * otg_phy_con1 = (unsigned int*)(USBGRF_UOC1_CON2);
\r
189 *otg_phy_con1 = 0x554|(0xfff<<16); // enter suspend.
\r
190 usbpdata->phy_status = 0;
\r
193 *otg_phy_con1 = ((0x01<<2)<<16); // exit suspend.
\r
194 usbpdata->phy_status = 1;
\r
197 void usb20host_soft_reset(void)
\r
200 cru_set_soft_reset(SOFT_RST_USBOTG1, true);
\r
201 cru_set_soft_reset(SOFT_RST_USBPHY1, true);
\r
202 cru_set_soft_reset(SOFT_RST_OTGC1, true);
\r
205 cru_set_soft_reset(SOFT_RST_USBOTG1, false);
\r
206 cru_set_soft_reset(SOFT_RST_USBPHY1, false);
\r
207 cru_set_soft_reset(SOFT_RST_OTGC1, false);
\r
211 void usb20host_clock_init(void* pdata)
\r
213 struct dwc_otg_platform_data *usbpdata=pdata;
\r
214 struct clk* ahbclk,*phyclk;
\r
215 ahbclk = clk_get(NULL, "hclk_otg1");
\r
216 phyclk = clk_get(NULL, "otgphy1");
\r
217 usbpdata->phyclk = phyclk;
\r
218 usbpdata->ahbclk = ahbclk;
\r
220 void usb20host_clock_enable(void* pdata, int enable)
\r
222 struct dwc_otg_platform_data *usbpdata=pdata;
\r
225 clk_enable(usbpdata->ahbclk);
\r
226 clk_enable(usbpdata->phyclk);
\r
229 clk_disable(usbpdata->phyclk);
\r
230 clk_disable(usbpdata->ahbclk);
\r
234 int usb20host_get_status(int id)
\r
237 unsigned int usbgrf_status = *(unsigned int*)(USBGRF_SOC_STATUS0);
\r
240 case USB_STATUS_BVABLID:
\r
242 ret = (usbgrf_status &(1<<22));
\r
244 case USB_STATUS_DPDM:
\r
246 ret = (usbgrf_status &(3<<23));
\r
248 case USB_STATUS_ID:
\r
257 void usb20host_power_enable(int enable)
\r
260 struct dwc_otg_platform_data usb20host_pdata = {
\r
265 .hw_init=usb20host_hw_init,
\r
266 .phy_suspend=usb20host_phy_suspend,
\r
267 .soft_reset=usb20host_soft_reset,
\r
268 .clock_init=usb20host_clock_init,
\r
269 .clock_enable=usb20host_clock_enable,
\r
270 .get_status=usb20host_get_status,
\r
273 struct platform_device device_usb20_host = {
\r
274 .name = "usb20_host",
\r
276 .num_resources = ARRAY_SIZE(usb20_host_resource),
\r
277 .resource = usb20_host_resource,
\r
279 .platform_data = &usb20host_pdata,
\r
283 static int __init usbdev_init_devices(void)
\r
285 #ifdef CONFIG_USB20_OTG
\r
286 platform_device_register(&device_usb20_otg);
\r
288 #ifdef CONFIG_USB20_HOST
\r
289 platform_device_register(&device_usb20_host);
\r
292 arch_initcall(usbdev_init_devices);
\r