1 /* $NetBSD: pxa2x0_udc.c,v 1.2 2009/08/09 06:12:34 kiyohara Exp $ */
2 /* $OpenBSD: pxa27x_udc.c,v 1.5 2005/03/30 14:24:39 dlg Exp $ */
5 * Copyright (c) 2005 David Gwynne <dlg@openbsd.org>
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include <sys/param.h>
21 #include <sys/systm.h>
22 #include <sys/device.h>
23 #include <sys/kernel.h>
25 #include <machine/intr.h>
26 #include <machine/bus.h>
28 #include <arm/xscale/pxa2x0cpu.h>
29 #include <arm/xscale/pxa2x0reg.h>
30 #include <arm/xscale/pxa2x0var.h>
31 #include <arm/xscale/pxa2x0_gpio.h>
35 bus_space_tag_t sc_iot
;
36 bus_space_handle_t sc_ioh
;
42 static int pxaudc_match(struct device
*, struct cfdata
*, void *);
43 static void pxaudc_attach(struct device
*, struct device
*, void *);
44 static int pxaudc_detach(struct device
*, int);
46 CFATTACH_DECL(pxaudc
, sizeof(struct pxaudc_softc
),
47 pxaudc_match
, pxaudc_attach
, pxaudc_detach
, NULL
);
49 static void pxaudc_power(int, void *);
50 static void pxaudc_enable(struct pxaudc_softc
*);
53 pxaudc_match(struct device
*parent
, struct cfdata
*cf
, void *aux
)
55 struct pxaip_attach_args
*pxa
= aux
;
57 if (CPU_IS_PXA270
&& strcmp(pxa
->pxa_name
, cf
->cf_name
) == 0) {
58 pxa
->pxa_size
= PXA270_USBDC_SIZE
;
65 pxaudc_attach(struct device
*parent
, struct device
*self
, void *aux
)
67 struct pxaudc_softc
*sc
= (struct pxaudc_softc
*)self
;
68 struct pxaip_attach_args
*pxa
= (struct pxaip_attach_args
*)aux
;
70 sc
->sc_iot
= pxa
->pxa_iot
;
72 sc
->sc_powerhook
= NULL
;
74 if (bus_space_map(sc
->sc_iot
, pxa
->pxa_addr
, pxa
->pxa_size
, 0,
76 aprint_error(": couldn't map memory space\n");
79 sc
->sc_size
= pxa
->pxa_size
;
81 printf(": PXA2x0 USB Device Controller\n");
83 bus_space_barrier(sc
->sc_iot
, sc
->sc_ioh
, 0, sc
->sc_size
,
84 BUS_SPACE_BARRIER_READ
|BUS_SPACE_BARRIER_WRITE
);
86 pxa2x0_clkman_config(CKEN_USBDC
, 1);
90 sc
->sc_powerhook
= powerhook_establish(sc
->sc_dev
.dv_xname
,
92 if (sc
->sc_powerhook
== NULL
) {
93 aprint_error("%s: unable to establish powerhook.\n",
99 pxaudc_detach(struct device
*self
, int flags
)
101 struct pxaudc_softc
*sc
= (struct pxaudc_softc
*)self
;
103 if (sc
->sc_powerhook
)
104 powerhook_disestablish(sc
->sc_powerhook
);
107 bus_space_unmap(sc
->sc_iot
, sc
->sc_ioh
, sc
->sc_size
);
115 pxaudc_power(int why
, void *arg
)
117 struct pxaudc_softc
*sc
= (struct pxaudc_softc
*)arg
;
127 pxaudc_enable(struct pxaudc_softc
*sc
)
131 /* disable the controller */
132 hr
= bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UDCCR
);
133 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UDCCR
,
134 hr
& ~USBDC_UDCCR_UDE
);
136 hr
= bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UDCICR1
);
137 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UDCICR1
,
138 hr
| USBDC_UDCICR1_IERS
);
140 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
, 0);
141 hr
= bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
);
142 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
,
143 hr
| USBDC_UP2OCR_HXS
);
144 hr
= bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
);
145 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
,
146 hr
| USBDC_UP2OCR_HXOE
);
147 hr
= bus_space_read_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
);
148 bus_space_write_4(sc
->sc_iot
, sc
->sc_ioh
, USBDC_UP2OCR
,
149 hr
| USBDC_UP2OCR_DPPDE
|USBDC_UP2OCR_DMPDE
);