]> rtime.felk.cvut.cz Git - mcf548x/linux.git/blob - arch/m68k/coldfire/usb.c
Current (FEC from 2.6.31 port, no CAN, no I2C, no PCI)
[mcf548x/linux.git] / arch / m68k / coldfire / usb.c
1 /*
2  *
3  * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
4  *
5  *      otg_{get,set}_transceiver() are from arm/plat-omap/usb.c.
6  *      which is Copyright (C) 2004 Texas Instruments, Inc.
7  */
8
9 /*
10  * The code contained herein is licensed under the GNU General Public
11  * License. You may obtain a copy of the GNU General Public License
12  * Version 2 or later at the following locations:
13  *
14  * http://www.opensource.org/licenses/gpl-license.html
15  * http://www.gnu.org/copyleft/gpl.html
16  */
17
18 #include <linux/module.h>
19 #include <linux/kernel.h>
20 #include <linux/types.h>
21 #include <linux/errno.h>
22 #include <linux/init.h>
23 #include <linux/io.h>
24 #include <linux/err.h>
25 #include <linux/platform_device.h>
26 #include <linux/usb/otg.h>
27 #include <linux/delay.h>
28 #include <linux/fsl_devices.h>
29 #include <linux/usb/fsl_xcvr.h>
30
31
32 /* The dmamask must be set for EHCI to work */
33 static u64 ehci_dmamask = ~(u32) 0;
34
35 struct fsl_xcvr_ops *xc_ops[3] = { NULL };
36
37 void fsl_usb_enable_clk(void)
38 {
39 }
40 EXPORT_SYMBOL(fsl_usb_enable_clk);
41
42 void fsl_usb_disable_clk(void)
43 {
44 }
45 EXPORT_SYMBOL(fsl_usb_disable_clk);
46
47 void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops)
48 {
49         pr_debug("%s ctrlr=%d\n", __FUNCTION__, xcvr_ops->ctrlr);
50         xc_ops[xcvr_ops->ctrlr] = xcvr_ops;
51
52 }
53 EXPORT_SYMBOL(fsl_usb_xcvr_register);
54
55 void fsl_usb_xcvr_unregister(enum fsl_usb_ctrlr ctrlr)
56 {
57         pr_debug("%s ctrlr=%d\n", __FUNCTION__, ctrlr);
58         xc_ops[ctrlr] = NULL;
59 }
60 EXPORT_SYMBOL(fsl_usb_xcvr_unregister);
61
62 /*!
63  * Register an instance of a USB host platform device.
64  *
65  * @param       res:    resource pointer
66  * @param       n_res:  number of resources
67  * @param       config: config pointer
68  *
69  * @return      newly-registered platform_device
70  *
71  * DDD fix this comment:
72  * The USB controller supports 3 host interfaces, and the
73  * kernel can be configured to support some number of them.
74  * Each supported host interface is registered as an instance
75  * of the "fsl-ehci" device.  Call this function multiple times
76  * to register each host interface.
77  */
78 static int instance_id;
79 struct platform_device *host_pdev_register(struct resource *res, int n_res,
80                                           struct fsl_usb2_platform_data *config)
81 {
82         struct platform_device *pdev;
83
84         pr_debug("register host res=0x%p, size=%d\n", res, n_res);
85
86         pdev = platform_device_register_simple("fsl-ehci",
87                                                instance_id, res, n_res);
88         if (IS_ERR(pdev)) {
89                 printk(KERN_ERR "usb: can't register %s Host, %ld\n",
90                        config->name, PTR_ERR(pdev));
91                 return NULL;
92         }
93
94         pdev->dev.coherent_dma_mask = 0xffffffff;
95         pdev->dev.dma_mask = &ehci_dmamask;
96
97         /*
98          * platform_device_add_data() makes a copy of
99          * the platform_data passed in.  That makes it
100          * impossible to share the same config struct for
101          * all OTG devices (host,gadget,otg).  So, just
102          * set the platform_data pointer ourselves.
103          */
104         pdev->dev.platform_data = config;
105
106         printk(KERN_INFO "usb: %s Host registered\n", config->name);
107         pr_debug("pdev=0x%p  dev=0x%p  resources=0x%p  pdata=0x%p\n",
108                  pdev, &pdev->dev, pdev->resource, pdev->dev.platform_data);
109
110         instance_id++;
111
112         return pdev;
113 }
114
115
116 int fsl_usb_mem_init(struct platform_device *pdev)
117 {
118         struct resource *res;
119         struct fsl_usb2_platform_data *pdata;
120
121         pdata = (struct fsl_usb2_platform_data *)pdev->dev.platform_data;
122
123         pr_debug("%s: pdev=0x%p  pdata=0x%p\n", __FUNCTION__, pdev, pdata);
124
125         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
126         if (!res) {
127                 dev_err(&pdev->dev, "no MEM resource.\n");
128                 return -ENODEV;
129         }
130
131         pdata->r_start = res->start;
132         pdata->r_len = res->end - res->start + 1;
133         pr_debug("%s: MEM resource start=0x%x  len=0x%x\n", pdata->name,
134                  res->start, pdata->r_len);
135
136         if (!request_mem_region(pdata->r_start, pdata->r_len, "OTG")) {
137                 dev_err(&pdev->dev, "request_mem_region failed\n");
138                 return -EBUSY;
139         }
140         pdata->regs = ioremap(pdata->r_start, pdata->r_len);
141         pr_debug("ioremapped to 0x%p\n", pdata->regs);
142
143         if (pdata->regs == NULL) {
144                 dev_err(&pdev->dev, "ioremap failed\n");
145                 release_mem_region(pdata->r_start, pdata->r_len);
146                 return -EFAULT;
147         }
148
149         pr_debug("%s: success\n", __FUNCTION__);
150         return 0;
151 }
152
153
154 #if defined(CONFIG_USB_OTG)
155 static struct otg_transceiver *xceiv;
156
157 /**
158  * otg_get_transceiver - find the (single) OTG transceiver driver
159  *
160  * Returns the transceiver driver, after getting a refcount to it; or
161  * null if there is no such transceiver.  The caller is responsible for
162  * releasing that count.
163  */
164 struct otg_transceiver *otg_get_transceiver(void)
165 {
166         pr_debug("%s xceiv=0x%p\n", __FUNCTION__, xceiv);
167         if (xceiv)
168                 get_device(xceiv->dev);
169         return xceiv;
170 }
171 EXPORT_SYMBOL(otg_get_transceiver);
172
173 int otg_set_transceiver(struct otg_transceiver *x)
174 {
175         pr_debug("%s xceiv=0x%p  x=0x%p\n", __FUNCTION__, xceiv, x);
176         if (xceiv && x)
177                 return -EBUSY;
178         xceiv = x;
179         return 0;
180 }
181 EXPORT_SYMBOL(otg_set_transceiver);
182 #endif