Module Name: src Committed By: sborrill Date: Thu Oct 8 09:47:09 UTC 2009
Modified Files: src/distrib/sets/lists/man [netbsd-5]: mi src/share/man/man4 [netbsd-5]: Makefile ld.4 src/sys/arch/amd64/conf [netbsd-5]: GENERIC src/sys/arch/i386/conf [netbsd-5]: ALL GENERIC src/sys/conf [netbsd-5]: files src/sys/dev/acpi [netbsd-5]: files.acpi Added Files: src/share/man/man4 [netbsd-5]: wb.4 src/sys/dev/acpi [netbsd-5]: wb_acpi.c src/sys/dev/ic [netbsd-5]: w83l518d.c w83l518d_sdmmc.c w83l518d_sdmmc.h w83l518dreg.h w83l518dvar.h Log Message: Pull up the following revisions(s) (requested by jmcneill in ticket #1045): distrib/sets/lists/man/mi: revision 1.1160 share/man/man4/Makefile: revision 1.499 share/man/man4/wb.4: revision 1.1-1.2 share/man/man4/ld.4: revision 1.17 sys/arch/i386/conf/ALL: revision 1.215-1.216 + patch sys/arch/i386/conf/GENERIC: revision 1.946-1.947 + patch sys/arch/amd64/conf/GENERIC: revision 1.254-1.256 + patch sys/conf/files: revision 1.958 sys/dev/acpi/files.acpi: revision 1.59 sys/dev/acpi/wb_acpi.c: revision 1.1 sys/dev/ic/w83l518d.c: revision 1.1 sys/dev/ic/w83l518d_sdmmc.c: revision 1.1 sys/dev/ic/w83l518d_sdmmc.h: revision 1.1 sys/dev/ic/w83l518dreg.h: revision 1.1 sys/dev/ic/w83l518dvar.h.c: revision 1.1 wb(4): Add a driver for Winbond W83L518D SD/MMC readers. To generate a diff of this commit: cvs rdiff -u -r1.1109.2.9 -r1.1109.2.10 src/distrib/sets/lists/man/mi cvs rdiff -u -r1.482.2.6 -r1.482.2.7 src/share/man/man4/Makefile cvs rdiff -u -r1.16 -r1.16.4.1 src/share/man/man4/ld.4 cvs rdiff -u -r0 -r1.2.2.2 src/share/man/man4/wb.4 cvs rdiff -u -r1.231.4.5 -r1.231.4.6 src/sys/arch/amd64/conf/GENERIC cvs rdiff -u -r1.183.4.5 -r1.183.4.6 src/sys/arch/i386/conf/ALL cvs rdiff -u -r1.915.2.8 -r1.915.2.9 src/sys/arch/i386/conf/GENERIC cvs rdiff -u -r1.924.4.5 -r1.924.4.6 src/sys/conf/files cvs rdiff -u -r1.52.8.2 -r1.52.8.3 src/sys/dev/acpi/files.acpi cvs rdiff -u -r0 -r1.1.2.2 src/sys/dev/acpi/wb_acpi.c cvs rdiff -u -r0 -r1.1.2.2 src/sys/dev/ic/w83l518d.c \ src/sys/dev/ic/w83l518d_sdmmc.c src/sys/dev/ic/w83l518d_sdmmc.h \ src/sys/dev/ic/w83l518dreg.h src/sys/dev/ic/w83l518dvar.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/man/mi diff -u src/distrib/sets/lists/man/mi:1.1109.2.9 src/distrib/sets/lists/man/mi:1.1109.2.10 --- src/distrib/sets/lists/man/mi:1.1109.2.9 Wed Oct 7 15:41:14 2009 +++ src/distrib/sets/lists/man/mi Thu Oct 8 09:47:08 2009 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.1109.2.9 2009/10/07 15:41:14 sborrill Exp $ +# $NetBSD: mi,v 1.1109.2.10 2009/10/08 09:47:08 sborrill Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. # @@ -1646,6 +1646,7 @@ ./usr/share/man/cat4/vnd.0 man-sys-catman .cat ./usr/share/man/cat4/vr.0 man-sys-catman .cat ./usr/share/man/cat4/wapbl.0 man-sys-catman .cat +./usr/share/man/cat4/wb.0 man-sys-catman .cat ./usr/share/man/cat4/wd.0 man-sys-catman .cat ./usr/share/man/cat4/wdc.0 man-sys-catman .cat ./usr/share/man/cat4/wds.0 man-sys-catman .cat @@ -4107,6 +4108,7 @@ ./usr/share/man/html4/vnd.html man-sys-htmlman html ./usr/share/man/html4/vr.html man-sys-htmlman html ./usr/share/man/html4/wapbl.html man-sys-htmlman html +./usr/share/man/html4/wb.html man-sys-htmlman html ./usr/share/man/html4/wd.html man-sys-htmlman html ./usr/share/man/html4/wdc.html man-sys-htmlman html ./usr/share/man/html4/wds.html man-sys-htmlman html @@ -6506,6 +6508,7 @@ ./usr/share/man/man4/vnd.4 man-sys-man .man ./usr/share/man/man4/vr.4 man-sys-man .man ./usr/share/man/man4/wapbl.4 man-sys-man .man +./usr/share/man/man4/wb.4 man-sys-man .man ./usr/share/man/man4/wd.4 man-sys-man .man ./usr/share/man/man4/wdc.4 man-sys-man .man ./usr/share/man/man4/wds.4 man-sys-man .man Index: src/share/man/man4/Makefile diff -u src/share/man/man4/Makefile:1.482.2.6 src/share/man/man4/Makefile:1.482.2.7 --- src/share/man/man4/Makefile:1.482.2.6 Wed Oct 7 15:41:13 2009 +++ src/share/man/man4/Makefile Thu Oct 8 09:47:08 2009 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.482.2.6 2009/10/07 15:41:13 sborrill Exp $ +# $NetBSD: Makefile,v 1.482.2.7 2009/10/08 09:47:08 sborrill Exp $ # @(#)Makefile 8.1 (Berkeley) 6/18/93 MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 acpidalb.4 \ @@ -58,7 +58,7 @@ ubsec.4 udp.4 uep.4 ug.4 uha.4 uk.4 ukphy.4 unix.4 userconf.4 \ veriexec.4 vga.4 vge.4 viaide.4 video.4 vlan.4 vmmon.4 vmnet.4 \ vnd.4 vr.4 \ - wapbl.4 wd.4 wdc.4 wi.4 wm.4 wpi.4 wscons.4 wsdisplay.4 wsfont.4 \ + wapbl.4 wb.4 wd.4 wdc.4 wi.4 wm.4 wpi.4 wscons.4 wsdisplay.4 wsfont.4 \ wskbd.4 wsmouse.4 wsmux.4 \ xbox.4 xge.4 \ yds.4 ym.4 \ Index: src/share/man/man4/ld.4 diff -u src/share/man/man4/ld.4:1.16 src/share/man/man4/ld.4:1.16.4.1 --- src/share/man/man4/ld.4:1.16 Wed Apr 30 13:10:54 2008 +++ src/share/man/man4/ld.4 Thu Oct 8 09:47:08 2009 @@ -1,4 +1,4 @@ -.\" $NetBSD: ld.4,v 1.16 2008/04/30 13:10:54 martin Exp $ +.\" $NetBSD: ld.4,v 1.16.4.1 2009/10/08 09:47:08 sborrill Exp $ .\" .\" Copyright (c) 2000 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -40,6 +40,7 @@ .Cd "ld* at icp? unit ?" .Cd "ld* at iop? tid ?" .Cd "ld* at mlx? unit ?" +.Cd "ld* at sdmmc? unit ?" .Cd "ld* at twa? unit ?" .Cd "ld* at twe? unit ?" .Cd "ld* at ataraid? vendtype ? unit ?" @@ -69,6 +70,7 @@ .Xr intro 4 , .Xr iop 4 , .Xr mlx 4 , +.Xr sdmmc 4 , .Xr twa 4 , .Xr twe 4 .Sh HISTORY Index: src/sys/arch/amd64/conf/GENERIC diff -u src/sys/arch/amd64/conf/GENERIC:1.231.4.5 src/sys/arch/amd64/conf/GENERIC:1.231.4.6 --- src/sys/arch/amd64/conf/GENERIC:1.231.4.5 Sat Sep 26 19:52:09 2009 +++ src/sys/arch/amd64/conf/GENERIC Thu Oct 8 09:47:08 2009 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.231.4.5 2009/09/26 19:52:09 snj Exp $ +# $NetBSD: GENERIC,v 1.231.4.6 2009/10/08 09:47:08 sborrill Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.231.4.5 $" +#ident "GENERIC-$Revision: 1.231.4.6 $" maxusers 64 # estimated number of users @@ -297,7 +297,8 @@ sony* at acpi? # Sony Notebook Controller thinkpad* at acpi? # IBM/Lenovo Thinkpad hotkeys ug* at acpi? # Abit uGuru Hardware monitor -wss* at acpi? # NeoMagic 256AV in wss mode +wb* at acpi? # Winbond W83L518D SD/MMC reader +sdmmc* at wb? # SD/MMC bus #apm0 at mainbus0 # Advanced power management @@ -905,6 +906,10 @@ fwip* at ieee1394if? # IP over IEEE1394 sbp* at ieee1394if? euihi ? euilo ? +# SD/MMC/SDIO Controller and Device support + +ld* at sdmmc? + # Audio Devices # PCI audio devices Index: src/sys/arch/i386/conf/ALL diff -u src/sys/arch/i386/conf/ALL:1.183.4.5 src/sys/arch/i386/conf/ALL:1.183.4.6 --- src/sys/arch/i386/conf/ALL:1.183.4.5 Mon Oct 5 11:37:13 2009 +++ src/sys/arch/i386/conf/ALL Thu Oct 8 09:47:08 2009 @@ -1,4 +1,4 @@ -# $NetBSD: ALL,v 1.183.4.5 2009/10/05 11:37:13 sborrill Exp $ +# $NetBSD: ALL,v 1.183.4.6 2009/10/08 09:47:08 sborrill Exp $ # From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp # # ALL machine description file @@ -17,7 +17,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "ALL-$Revision: 1.183.4.5 $" +#ident "ALL-$Revision: 1.183.4.6 $" maxusers 32 # estimated number of users @@ -366,6 +366,8 @@ pcppi* at acpi? # AT-style speaker sound thinkpad* at acpi? # IBM/Lenovo Thinkpad hotkeys ug* at acpi? # Abit uGuru Hardware monitor +wb* at acpi? # Winbond W83L518D SD/MMC reader +sdmmc* at wb? # SD/MMC bus wss* at acpi? # NeoMagic 256AV in wss mode ym* at acpi? # Yamaha OPL3-SA[23] audio @@ -1255,6 +1257,9 @@ fwip* at ieee1394if? # IP over IEEE1394 sbp* at ieee1394if? euihi ? euilo ? # SCSI over IEEE1394 +# SD/MMC/SDIO Controller and Device support + +ld* at sdmmc? # Audio Devices Index: src/sys/arch/i386/conf/GENERIC diff -u src/sys/arch/i386/conf/GENERIC:1.915.2.8 src/sys/arch/i386/conf/GENERIC:1.915.2.9 --- src/sys/arch/i386/conf/GENERIC:1.915.2.8 Mon Oct 5 11:37:13 2009 +++ src/sys/arch/i386/conf/GENERIC Thu Oct 8 09:47:09 2009 @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC,v 1.915.2.8 2009/10/05 11:37:13 sborrill Exp $ +# $NetBSD: GENERIC,v 1.915.2.9 2009/10/08 09:47:09 sborrill Exp $ # # GENERIC machine description file # @@ -22,7 +22,7 @@ options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.915.2.8 $" +#ident "GENERIC-$Revision: 1.915.2.9 $" maxusers 64 # estimated number of users @@ -373,6 +373,8 @@ pcppi* at acpi? # AT-style speaker sound thinkpad* at acpi? # IBM/Lenovo Thinkpad hotkeys ug* at acpi? # Abit uGuru Hardware monitor +wb* at acpi? # Winbond W83L518D SD/MMC reader +sdmmc* at wb? # SD/MMC bus wss* at acpi? # NeoMagic 256AV in wss mode ym* at acpi? # Yamaha OPL3-SA[23] audio @@ -1251,6 +1253,9 @@ fwip* at ieee1394if? # IP over IEEE1394 sbp* at ieee1394if? euihi ? euilo ? # SCSI over IEEE1394 +# SD/MMC/SDIO Controller and Device support + +ld* at sdmmc? # Audio Devices Index: src/sys/conf/files diff -u src/sys/conf/files:1.924.4.5 src/sys/conf/files:1.924.4.6 --- src/sys/conf/files:1.924.4.5 Wed Oct 7 15:41:12 2009 +++ src/sys/conf/files Thu Oct 8 09:47:09 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files,v 1.924.4.5 2009/10/07 15:41:12 sborrill Exp $ +# $NetBSD: files,v 1.924.4.6 2009/10/08 09:47:09 sborrill Exp $ # @(#)files.newconf 7.5 (Berkeley) 5/10/93 @@ -1127,6 +1127,11 @@ device sdhc: sdmmcbus file dev/sdmmc/sdhc.c sdhc needs-flag +# Winbond Integrated Media Reader +device wb: sdmmcbus +file dev/ic/w83l518d.c wb +file dev/ic/w83l518d_sdmmc.c wb + # Myson MTD803 3-in-1 Fast Ethernet Controller device mtd: arp, ether, ifnet, mii file dev/ic/mtd803.c mtd Index: src/sys/dev/acpi/files.acpi diff -u src/sys/dev/acpi/files.acpi:1.52.8.2 src/sys/dev/acpi/files.acpi:1.52.8.3 --- src/sys/dev/acpi/files.acpi:1.52.8.2 Sat Sep 5 11:34:26 2009 +++ src/sys/dev/acpi/files.acpi Thu Oct 8 09:47:09 2009 @@ -1,4 +1,4 @@ -# $NetBSD: files.acpi,v 1.52.8.2 2009/09/05 11:34:26 bouyer Exp $ +# $NetBSD: files.acpi,v 1.52.8.3 2009/10/08 09:47:09 sborrill Exp $ include "dev/acpi/acpica/files.acpica" @@ -142,3 +142,7 @@ device acpidalb attach acpidalb at acpinodebus file dev/acpi/dalb_acpi.c acpidalb + +# Winbond Integrated Media Reader +attach wb at acpinodebus with wb_acpi +file dev/acpi/wb_acpi.c wb_acpi Added files: Index: src/share/man/man4/wb.4 diff -u /dev/null src/share/man/man4/wb.4:1.2.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/share/man/man4/wb.4 Thu Oct 8 09:47:08 2009 @@ -0,0 +1,57 @@ +.\" $NetBSD: wb.4,v 1.2.2.2 2009/10/08 09:47:08 sborrill Exp $ +.\" +.\" Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Neither the name of the author nor the names of any +.\" contributors may be used to endorse or promote products derived +.\" from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS +.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED +.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS +.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +.\" POSSIBILITY OF SUCH DAMAGE. +.\" +.Dd September 30, 2009 +.Dt WB 4 +.Os +.Sh NAME +.Nm wb +.Nd Winbond W83L518D Integrated Media Reader device driver +.Sh SYNOPSIS +.Cd "wb* at acpi?" +.Cd "sdmmc* at wb?" +.Cd "ld* at sdmmc?" +.Sh DESCRIPTION +The +.Nm +driver provides support for the Winbond W83L518D Integrated Media Reader. +.Pp +This device supports SD/MMC, Memory Stick, Memory Stick Pro, and Smart Cards. +The +.Nm +driver currently only supports the SD/MMC interface. +.Sh SEE ALSO +.Xr ld 4 , +.Xr sdmmc 4 +.Sh HISTORY +The +.Nm +device driver appeared in +.Nx 5.1 . +.Sh AUTHORS +.An Jared D. McNeill Aq jmcne...@invisible.ca +.Sh BUGS +DMA mode is not yet implemented. Index: src/sys/dev/acpi/wb_acpi.c diff -u /dev/null src/sys/dev/acpi/wb_acpi.c:1.1.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/sys/dev/acpi/wb_acpi.c Thu Oct 8 09:47:09 2009 @@ -0,0 +1,159 @@ +/* $NetBSD: wb_acpi.c,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $ */ + +/* + * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: wb_acpi.c,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <sys/bus.h> + +#include <dev/isa/isavar.h> +#include <dev/isa/isadmavar.h> + +#include <dev/acpi/acpica.h> +#include <dev/acpi/acpireg.h> +#include <dev/acpi/acpivar.h> + +#include <dev/sdmmc/sdmmcvar.h> +#include <dev/ic/w83l518dvar.h> +#include <dev/ic/w83l518dreg.h> + +static int wb_acpi_match(device_t, cfdata_t, void *); +static void wb_acpi_attach(device_t, device_t, void *); +static int wb_acpi_detach(device_t, int); + +struct wb_acpi_softc { + struct wb_softc sc_wb; + isa_chipset_tag_t sc_ic; + void *sc_ih; + int sc_ioh_length; +}; + +CFATTACH_DECL_NEW(wb_acpi, sizeof(struct wb_acpi_softc), + wb_acpi_match, + wb_acpi_attach, + wb_acpi_detach, + NULL +); + +static const char * const wb_acpi_ids[] = { +#if notyet + "WEC0515", /* Memory Stick interface */ +#endif + "WEC0517", /* SD Memory Card interface */ + NULL +}; + +static int +wb_acpi_match(device_t parent, cfdata_t match, void *opaque) +{ + struct acpi_attach_args *aa = opaque; + + if (aa->aa_node->ad_type != ACPI_TYPE_DEVICE) + return 0; + + return acpi_match_hid(aa->aa_node->ad_devinfo, wb_acpi_ids); +} + +static void +wb_acpi_attach(device_t parent, device_t self, void *opaque) +{ + struct wb_acpi_softc *sc = device_private(self); + struct acpi_attach_args *aa = opaque; + struct acpi_resources res; + struct acpi_io *io; + struct acpi_irq *irq; + bus_space_handle_t ioh; + ACPI_STATUS rv; + + sc->sc_ic = aa->aa_ic; + + rv = acpi_resource_parse(self, aa->aa_node->ad_handle, "_CRS", + &res, &acpi_resource_parse_ops_default); + if (ACPI_FAILURE(rv)) + return; + + io = acpi_res_io(&res, 0); + irq = acpi_res_irq(&res, 0); + if (io == NULL || irq == NULL) { + aprint_error_dev(self, "incomplete resources\n"); + goto cleanup; + } + + if (bus_space_map(aa->aa_iot, io->ar_base, io->ar_length, 0, &ioh)) { + aprint_error_dev(self, "couldn't map registers\n"); + goto cleanup; + } + sc->sc_ioh_length = io->ar_length; + + sc->sc_ih = isa_intr_establish(sc->sc_ic, irq->ar_irq, + (irq->ar_type == ACPI_EDGE_SENSITIVE) ? IST_EDGE : IST_LEVEL, + IPL_SDMMC, wb_intr, &sc->sc_wb); + if (sc->sc_ih == NULL) { + aprint_error_dev(self, + "couldn't establish interrupt handler\n"); + goto cleanup; + } + + sc->sc_wb.wb_dev = self; + sc->sc_wb.wb_type = WB_DEVNO_SD; + sc->sc_wb.wb_iot = aa->aa_iot; + sc->sc_wb.wb_ioh = ioh; + sc->sc_wb.wb_irq = irq->ar_irq; + sc->sc_wb.wb_base = io->ar_base; + wb_attach(&sc->sc_wb); + +cleanup: + acpi_resource_cleanup(&res); +} + +static int +wb_acpi_detach(device_t self, int flags) +{ + struct wb_acpi_softc *sc = device_private(self); + int rv; + + rv = wb_detach(&sc->sc_wb, flags); + if (rv) + return rv; + + if (sc->sc_ih) + isa_intr_disestablish(sc->sc_ic, sc->sc_ih); + + if (sc->sc_ioh_length > 0) + bus_space_unmap(sc->sc_wb.wb_iot, sc->sc_wb.wb_ioh, + sc->sc_ioh_length); + + return 0; +} Index: src/sys/dev/ic/w83l518d.c diff -u /dev/null src/sys/dev/ic/w83l518d.c:1.1.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/sys/dev/ic/w83l518d.c Thu Oct 8 09:47:09 2009 @@ -0,0 +1,139 @@ +/* $NetBSD: w83l518d.c,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $ */ + +/* + * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: w83l518d.c,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <sys/bus.h> + +#include <dev/isa/isavar.h> +#include <dev/isa/isadmavar.h> + +#include <dev/ic/w83l518dreg.h> +#include <dev/ic/w83l518dvar.h> +#include <dev/ic/w83l518d_sdmmc.h> + +uint8_t +wb_idx_read(struct wb_softc *wb, uint8_t reg) +{ + bus_space_write_1(wb->wb_iot, wb->wb_ioh, WB_SD_INDEX, reg); + return bus_space_read_1(wb->wb_iot, wb->wb_ioh, WB_SD_DATA); +} + +void +wb_idx_write(struct wb_softc *wb, uint8_t reg, uint8_t val) +{ + bus_space_write_1(wb->wb_iot, wb->wb_ioh, WB_SD_INDEX, reg); + bus_space_write_1(wb->wb_iot, wb->wb_ioh, WB_SD_DATA, val); +} + +uint8_t +wb_read(struct wb_softc *wb, uint8_t reg) +{ + return bus_space_read_1(wb->wb_iot, wb->wb_ioh, reg); +} + +void +wb_write(struct wb_softc *wb, uint8_t reg, uint8_t val) +{ + bus_space_write_1(wb->wb_iot, wb->wb_ioh, reg, val); +} + +void +wb_led(struct wb_softc *wb, bool enable) +{ + uint8_t val; + + val = wb_read(wb, WB_SD_CSR); + if (enable) + val |= WB_CSR_MS_LED; + else + val &= ~WB_CSR_MS_LED; + wb_write(wb, WB_SD_CSR, val); +} + +void +wb_attach(struct wb_softc *wb) +{ + switch (wb->wb_type) { + case WB_DEVNO_SD: + aprint_verbose_dev(wb->wb_dev, + "SD/MMC Reader\n"); + wb_sdmmc_attach(wb); + break; + case WB_DEVNO_MS: + aprint_verbose_dev(wb->wb_dev, + "Memory Stick Reader (not supported)\n"); + break; + case WB_DEVNO_SC: + aprint_verbose_dev(wb->wb_dev, + "Smart Card Reader (not supported)\n"); + break; + case WB_DEVNO_GPIO: + aprint_verbose_dev(wb->wb_dev, + "GPIO (not supported)\n"); + break; + } +} + +int +wb_detach(struct wb_softc *wb, int flags) +{ + switch (wb->wb_type) { + case WB_DEVNO_SD: + wb_sdmmc_detach(wb, flags); + break; + } + + return 0; +} + +/* + * intr handler + */ +int +wb_intr(void *opaque) +{ + struct wb_softc *wb = opaque; + + switch (wb->wb_type) { + case WB_DEVNO_SD: + return wb_sdmmc_intr(wb); + break; + } + + return 0; +} Index: src/sys/dev/ic/w83l518d_sdmmc.c diff -u /dev/null src/sys/dev/ic/w83l518d_sdmmc.c:1.1.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/sys/dev/ic/w83l518d_sdmmc.c Thu Oct 8 09:47:09 2009 @@ -0,0 +1,576 @@ +/* $NetBSD: w83l518d_sdmmc.c,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $ */ + +/* + * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: w83l518d_sdmmc.c,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/systm.h> +#include <sys/errno.h> +#include <sys/ioctl.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <sys/bus.h> + +#include <dev/sdmmc/sdmmcvar.h> +#include <dev/sdmmc/sdmmcchip.h> +#include <dev/sdmmc/sdmmc_ioreg.h> + +#include <dev/isa/isavar.h> +#include <dev/isa/isadmavar.h> + +#include <dev/ic/w83l518dreg.h> +#include <dev/ic/w83l518dvar.h> +#include <dev/ic/w83l518d_sdmmc.h> + +/* #define WB_SDMMC_DEBUG */ + +#ifdef WB_SDMMC_DEBUG +static int wb_sdmmc_debug = 1; +#else +static int wb_sdmmc_debug = 0; +#endif + +#if defined(__NetBSD__) && __NetBSD_Version__ < 599000600 +#define snprintb(b, l, f, v) bitmask_snprintf((v), (f), (b), (l)) +#endif + +#define REPORT(_wb, ...) \ + if (wb_sdmmc_debug > 0) \ + aprint_normal_dev(((struct wb_softc *)(_wb))->wb_dev, \ + __VA_ARGS__) + +static int wb_sdmmc_host_reset(sdmmc_chipset_handle_t); +static uint32_t wb_sdmmc_host_ocr(sdmmc_chipset_handle_t); +static int wb_sdmmc_host_maxblklen(sdmmc_chipset_handle_t); +static int wb_sdmmc_card_detect(sdmmc_chipset_handle_t); +static int wb_sdmmc_write_protect(sdmmc_chipset_handle_t); +static int wb_sdmmc_bus_power(sdmmc_chipset_handle_t, uint32_t); +static int wb_sdmmc_bus_clock(sdmmc_chipset_handle_t, int); +static int wb_sdmmc_bus_width(sdmmc_chipset_handle_t, int); +static void wb_sdmmc_exec_command(sdmmc_chipset_handle_t, + struct sdmmc_command *); +static void wb_sdmmc_card_enable_intr(sdmmc_chipset_handle_t, int); +static void wb_sdmmc_card_intr_ack(sdmmc_chipset_handle_t); + +static struct sdmmc_chip_functions wb_sdmmc_chip_functions = { + .host_reset = wb_sdmmc_host_reset, + .host_ocr = wb_sdmmc_host_ocr, + .host_maxblklen = wb_sdmmc_host_maxblklen, + .card_detect = wb_sdmmc_card_detect, + .write_protect = wb_sdmmc_write_protect, + .bus_power = wb_sdmmc_bus_power, + .bus_clock = wb_sdmmc_bus_clock, + .bus_width = wb_sdmmc_bus_width, + .exec_command = wb_sdmmc_exec_command, + .card_enable_intr = wb_sdmmc_card_enable_intr, + .card_intr_ack = wb_sdmmc_card_intr_ack, +}; + +static void +wb_sdmmc_read_data(struct wb_softc *wb, uint8_t *data, int len) +{ + bus_space_read_multi_1(wb->wb_iot, wb->wb_ioh, WB_SD_FIFO, data, len); +} + +static void +wb_sdmmc_write_data(struct wb_softc *wb, uint8_t *data, int len) +{ + bus_space_write_multi_1(wb->wb_iot, wb->wb_ioh, WB_SD_FIFO, data, len); +} + +static void +wb_sdmmc_discover(void *opaque) +{ + struct wb_softc *wb = opaque; + + REPORT(wb, "TRACE: discover(wb)\n"); + + sdmmc_needs_discover(wb->wb_sdmmc_dev); +} + +static bool +wb_sdmmc_enable(struct wb_softc *wb) +{ + int i = 5000; + + REPORT(wb, "TRACE: enable(wb)\n"); + + /* put the device in a known state */ + wb_idx_write(wb, WB_INDEX_SETUP, WB_SETUP_SOFT_RST); + while (--i > 0 && wb_idx_read(wb, WB_INDEX_SETUP) & WB_SETUP_SOFT_RST) + delay(10); + if (i == 0) { + aprint_error_dev(wb->wb_dev, "timeout resetting device\n"); + return false; + } + wb_idx_write(wb, WB_INDEX_CLK, WB_CLK_375K); + wb_idx_write(wb, WB_INDEX_FIFOEN, 0); + wb_idx_write(wb, WB_INDEX_DMA, 0); + wb_idx_write(wb, WB_INDEX_PBSMSB, 0); + wb_idx_write(wb, WB_INDEX_PBSLSB, 0); + /* drain FIFO */ + while ((wb_read(wb, WB_SD_FIFOSTS) & WB_FIFO_EMPTY) == 0) + wb_read(wb, WB_SD_FIFO); + + wb_write(wb, WB_SD_CSR, 0); + + wb_write(wb, WB_SD_INTCTL, WB_INT_DEFAULT); + + wb_sdmmc_card_detect(wb); + + return true; +} + +static bool +wb_sdmmc_disable(struct wb_softc *wb) +{ + uint8_t val; + + REPORT(wb, "TRACE: disable(wb)\n"); + + val = wb_read(wb, WB_SD_CSR); + val |= WB_CSR_POWER_N; + wb_write(wb, WB_SD_CSR, val); + + return true; +} + +void +wb_sdmmc_attach(struct wb_softc *wb) +{ + struct sdmmcbus_attach_args saa; + + callout_init(&wb->wb_sdmmc_callout, 0); + callout_setfunc(&wb->wb_sdmmc_callout, wb_sdmmc_discover, wb); + + wb->wb_sdmmc_width = 1; + + if (wb_sdmmc_enable(wb) == false) + return; + + memset(&saa, 0, sizeof(saa)); + saa.saa_busname = "sdmmc"; + saa.saa_sct = &wb_sdmmc_chip_functions; + saa.saa_sch = wb; + saa.saa_clkmin = 375; + saa.saa_clkmax = 24000; + saa.saa_caps = SMC_CAPS_4BIT_MODE; + + wb->wb_sdmmc_dev = config_found(wb->wb_dev, &saa, NULL); +} + +int +wb_sdmmc_detach(struct wb_softc *wb, int flags) +{ + int rv; + + if (wb->wb_sdmmc_dev) { + rv = config_detach(wb->wb_sdmmc_dev, flags); + if (rv) + return rv; + } + wb_sdmmc_disable(wb); + + callout_halt(&wb->wb_sdmmc_callout, NULL); + callout_destroy(&wb->wb_sdmmc_callout); + + return 0; +} + +/* + * SD/MMC interface + */ +static int +wb_sdmmc_host_reset(sdmmc_chipset_handle_t sch) +{ + REPORT(sch, "TRACE: sdmmc/host_reset(wb)\n"); + + return 0; +} + +static uint32_t +wb_sdmmc_host_ocr(sdmmc_chipset_handle_t sch) +{ + REPORT(sch, "TRACE: sdmmc/host_ocr(wb)\n"); + + return MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V; +} + +static int +wb_sdmmc_host_maxblklen(sdmmc_chipset_handle_t sch) +{ + REPORT(sch, "TRACE: sdmmc/host_maxblklen(wb)\n"); + + return 512; /* XXX */ +} + +static int +wb_sdmmc_card_detect(sdmmc_chipset_handle_t sch) +{ + struct wb_softc *wb = sch; + int rv; + + wb_led(wb, true); + rv = (wb_read(wb, WB_SD_CSR) & WB_CSR_CARD_PRESENT) ? 1 : 0; + wb_led(wb, false); + + REPORT(wb, "TRACE: sdmmc/card_detect(wb) -> %d\n", rv); + + return rv; +} + +static int +wb_sdmmc_write_protect(sdmmc_chipset_handle_t sch) +{ + struct wb_softc *wb = sch; + int rv; + + wb_led(wb, true); + rv = (wb_read(wb, WB_SD_CSR) & WB_CSR_WRITE_PROTECT) ? 1 : 0; + wb_led(wb, false); + + REPORT(wb, "TRACE: sdmmc/write_protect(wb) -> %d\n", rv); + + return rv; +} + +static int +wb_sdmmc_bus_power(sdmmc_chipset_handle_t sch, uint32_t ocr) +{ + REPORT(sch, "TRACE: sdmmc/bus_power(wb, ocr=%d)\n", ocr); + + return 0; +} + +static int +wb_sdmmc_bus_clock(sdmmc_chipset_handle_t sch, int freq) +{ + struct wb_softc *wb = sch; + uint8_t clk; + + REPORT(wb, "TRACE: sdmmc/bus_clock(wb, freq=%d)\n", freq); + + if (freq >= 24000) + clk = WB_CLK_24M; + else if (freq >= 16000) + clk = WB_CLK_16M; + else if (freq >= 12000) + clk = WB_CLK_12M; + else + clk = WB_CLK_375K; + + if (wb_idx_read(wb, WB_INDEX_CLK) != clk) + wb_idx_write(wb, WB_INDEX_CLK, clk); + + return 0; +} + +static int +wb_sdmmc_bus_width(sdmmc_chipset_handle_t sch, int width) +{ + struct wb_softc *wb = sch; + + REPORT(wb, "TRACE: sdmmc/bus_width(wb, width=%d)\n", width); + + if (width != 1 && width != 4) + return 1; + + wb->wb_sdmmc_width = width; + + return 0; +} + + +static void +wb_sdmmc_rsp_read_long(struct wb_softc *wb, struct sdmmc_command *cmd) +{ + uint8_t *p = (uint8_t *)cmd->c_resp; + int i; + + if (wb_idx_read(wb, WB_INDEX_RESPLEN) != 1) { + cmd->c_error = ENXIO; + return; + } + + for (i = 12; i >= 0; i -= 4) { + p[3] = wb_idx_read(wb, WB_INDEX_RESP(i + 0)); + p[2] = wb_idx_read(wb, WB_INDEX_RESP(i + 1)); + p[1] = wb_idx_read(wb, WB_INDEX_RESP(i + 2)); + p[0] = wb_idx_read(wb, WB_INDEX_RESP(i + 3)); + p += 4; + } +} + +static void +wb_sdmmc_rsp_read_short(struct wb_softc *wb, struct sdmmc_command *cmd) +{ + uint8_t *p = (uint8_t *)cmd->c_resp; + + if (wb_idx_read(wb, WB_INDEX_RESPLEN) != 0) { + cmd->c_error = ENXIO; + return; + } + + p[3] = wb_idx_read(wb, WB_INDEX_RESP(12)); + p[2] = wb_idx_read(wb, WB_INDEX_RESP(13)); + p[1] = wb_idx_read(wb, WB_INDEX_RESP(14)); + p[0] = wb_idx_read(wb, WB_INDEX_RESP(15)); +} + +static int +wb_sdmmc_transfer_data(struct wb_softc *wb, struct sdmmc_command *cmd) +{ + uint8_t fifosts; + int datalen, retry = 5000; + + if (wb->wb_sdmmc_intsts & WB_INT_CARD) + return EIO; + + fifosts = wb_read(wb, WB_SD_FIFOSTS); + if (ISSET(cmd->c_flags, SCF_CMD_READ)) { + if (fifosts & WB_FIFO_EMPTY) { + while (--retry > 0) { + fifosts = wb_read(wb, WB_SD_FIFOSTS); + if ((fifosts & WB_FIFO_EMPTY) == 0) + break; + delay(100); + } + if (retry == 0) + return EBUSY; + } + + if (fifosts & WB_FIFO_FULL) + datalen = 16; + else + datalen = fifosts & WB_FIFO_DEPTH_MASK; + } else { + if (fifosts & WB_FIFO_FULL) { + while (--retry > 0) { + fifosts = wb_read(wb, WB_SD_FIFOSTS); + if ((fifosts & WB_FIFO_FULL) == 0) + break; + delay(100); + } + if (retry == 0) + return EBUSY; + } + + if (fifosts & WB_FIFO_EMPTY) + datalen = 16; + else + datalen = 16 - (fifosts & WB_FIFO_DEPTH_MASK); + } + + datalen = MIN(datalen, cmd->c_resid); + if (datalen > 0) { + if (ISSET(cmd->c_flags, SCF_CMD_READ)) + wb_sdmmc_read_data(wb, cmd->c_buf, datalen); + else + wb_sdmmc_write_data(wb, cmd->c_buf, datalen); + + cmd->c_buf += datalen; + cmd->c_resid -= datalen; + } + + return 0; +} + +static void +wb_sdmmc_exec_command(sdmmc_chipset_handle_t sch, struct sdmmc_command *cmd) +{ + static const int opcodes[] = { + 11, 17, 18, 20, 24, 25, 26, 27, 30, 42, 51, 56 + }; + struct wb_softc *wb = sch; + uint8_t val; + int blklen; + int error; + int i, retry; + int s; + + REPORT(wb, "TRACE: sdmmc/exec_command(wb, cmd) " + "opcode %d flags 0x%x data %p datalen %d\n", + cmd->c_opcode, cmd->c_flags, cmd->c_data, cmd->c_datalen); + + if (cmd->c_datalen > 0) { + /* controller only supports a select number of data opcodes */ + for (i = 0; i < __arraycount(opcodes); i++) + if (opcodes[i] == cmd->c_opcode) + break; + if (i == __arraycount(opcodes)) { + cmd->c_error = EINVAL; + goto done; + } + + /* Fragment the data into proper blocks */ + blklen = MIN(cmd->c_datalen, cmd->c_blklen); + + if (cmd->c_datalen % blklen > 0) { + aprint_error_dev(wb->wb_dev, + "data is not a multiple of %u bytes\n", blklen); + cmd->c_error = EINVAL; + goto done; + } + + /* setup block size registers */ + blklen = blklen + 2 * wb->wb_sdmmc_width; + wb_idx_write(wb, WB_INDEX_PBSMSB, + ((blklen >> 4) & 0xf0) | (wb->wb_sdmmc_width / 4)); + wb_idx_write(wb, WB_INDEX_PBSLSB, blklen & 0xff); + + /* clear FIFO */ + val = wb_idx_read(wb, WB_INDEX_SETUP); + val |= WB_SETUP_FIFO_RST; + wb_idx_write(wb, WB_INDEX_SETUP, val); + while (wb_idx_read(wb, WB_INDEX_SETUP) & WB_SETUP_FIFO_RST) + ; + + cmd->c_resid = cmd->c_datalen; + cmd->c_buf = cmd->c_data; + + /* setup FIFO thresholds */ + if (ISSET(cmd->c_flags, SCF_CMD_READ)) + wb_idx_write(wb, WB_INDEX_FIFOEN, WB_FIFOEN_FULL | 8); + else { + wb_idx_write(wb, WB_INDEX_FIFOEN, WB_FIFOEN_EMPTY | 8); + + /* pre-fill the FIFO on write */ + error = wb_sdmmc_transfer_data(wb, cmd); + if (error) { + cmd->c_error = error; + goto done; + } + } + } + + s = splsdmmc(); + wb->wb_sdmmc_intsts = 0; + wb_write(wb, WB_SD_COMMAND, cmd->c_opcode); + wb_write(wb, WB_SD_COMMAND, (cmd->c_arg >> 24) & 0xff); + wb_write(wb, WB_SD_COMMAND, (cmd->c_arg >> 16) & 0xff); + wb_write(wb, WB_SD_COMMAND, (cmd->c_arg >> 8) & 0xff); + wb_write(wb, WB_SD_COMMAND, (cmd->c_arg >> 0) & 0xff); + splx(s); + + retry = 100000; + while (wb_idx_read(wb, WB_INDEX_STATUS) & WB_STATUS_CARD_TRAFFIC) { + if (--retry == 0) + break; + delay(1); + } + if (wb_idx_read(wb, WB_INDEX_STATUS) & WB_STATUS_CARD_TRAFFIC) { + REPORT(wb, + "command timed out, WB_INDEX_STATUS = 0x%02x\n", + wb_idx_read(wb, WB_INDEX_STATUS)); + cmd->c_error = ETIMEDOUT; + goto done; + } + + if (ISSET(cmd->c_flags, SCF_RSP_PRESENT)) { + if (wb->wb_sdmmc_intsts & WB_INT_TIMEOUT) { + cmd->c_error = ETIMEDOUT; + goto done; + } + + if (ISSET(cmd->c_flags, SCF_RSP_136)) + wb_sdmmc_rsp_read_long(wb, cmd); + else + wb_sdmmc_rsp_read_short(wb, cmd); + } + + if (cmd->c_error == 0 && cmd->c_datalen > 0) { + wb_led(wb, true); + while (cmd->c_resid > 0) { + error = wb_sdmmc_transfer_data(wb, cmd); + if (error) { + cmd->c_error = error; + break; + } + } + wb_led(wb, false); + } + +done: + SET(cmd->c_flags, SCF_ITSDONE); + + if (cmd->c_error) { + REPORT(wb, + "cmd error = %d, op = %d [%s] " + "blklen %d datalen %d resid %d\n", + cmd->c_error, cmd->c_opcode, + ISSET(cmd->c_flags, SCF_CMD_READ) ? "rd" : "wr", + cmd->c_blklen, cmd->c_datalen, cmd->c_resid); + } +} + +static void +wb_sdmmc_card_enable_intr(sdmmc_chipset_handle_t sch, int enable) +{ + REPORT(sch, "TRACE: sdmmc/card_enable_intr(wb, enable=%d)\n", enable); +} + +static void +wb_sdmmc_card_intr_ack(sdmmc_chipset_handle_t sch) +{ + REPORT(sch, "TRACE: sdmmc/card_intr_ack(wb)\n"); +} + +/* + * intr handler + */ +int +wb_sdmmc_intr(struct wb_softc *wb) +{ + uint8_t val; + + val = wb_read(wb, WB_SD_INTSTS); + if (val == 0xff || val == 0x00) + return 0; + + if (wb->wb_sdmmc_dev == NULL) + return 1; + + wb->wb_sdmmc_intsts |= val; + + if (wb_sdmmc_debug) { + char buf[64]; + snprintb(buf, sizeof(buf), + "\20\1TC\2BUSYEND\3PROGEND\4TIMEOUT" + "\5CRC\6FIFO\7CARD\010PENDING", + val); + REPORT(wb, "WB_SD_INTSTS = %s\n", buf); + } + + if (val & WB_INT_CARD) + callout_schedule(&wb->wb_sdmmc_callout, hz / 4); + + return 1; +} Index: src/sys/dev/ic/w83l518d_sdmmc.h diff -u /dev/null src/sys/dev/ic/w83l518d_sdmmc.h:1.1.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/sys/dev/ic/w83l518d_sdmmc.h Thu Oct 8 09:47:09 2009 @@ -0,0 +1,35 @@ +/* $NetBSD: w83l518d_sdmmc.h,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $ */ + +/* + * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_DEV_IC_W83L518D_SDMMC_H +#define _SYS_DEV_IC_W83L518D_SDMMC_H + +void wb_sdmmc_attach(struct wb_softc *); +int wb_sdmmc_detach(struct wb_softc *, int); +int wb_sdmmc_intr(struct wb_softc *); + +#endif Index: src/sys/dev/ic/w83l518dreg.h diff -u /dev/null src/sys/dev/ic/w83l518dreg.h:1.1.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/sys/dev/ic/w83l518dreg.h Thu Oct 8 09:47:09 2009 @@ -0,0 +1,168 @@ +/* $NetBSD: w83l518dreg.h,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $ */ + +/* + * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_DEV_IC_W83L518DREG_H +#define _SYS_DEV_IC_W83L518DREG_H + +/* + * Global Registers + */ + +#define WB_REG_RESET 0x02 +#define WB_RESET_SWRST 0x01 /* software reset */ + +#define WB_REG_DEVNO 0x07 +#define WB_DEVNO_SC 0x00 /* Smart Card interface */ +#define WB_DEVNO_MS 0x01 /* Memory Stick interface */ +#define WB_DEVNO_GPIO 0x02 /* GPIO */ +#define WB_DEVNO_SD 0x03 /* SD memory card interface */ + +#define WB_REG_DEVID_HI 0x20 +#define WB_REG_DEVID_LO 0x21 +#define WB_DEVID_W83L518D 0x7110 +#define WB_DEVID_W83L519D 0x7120 +#define WB_DEVID_REVISION(id) ((id) & 0xf) + +#define WB_REG_POWER 0x22 +#define WB_POWER_SC 0x80 /* Smart Card interface */ +#define WB_POWER_MS 0x40 /* Memory Stick interface */ +#define WB_POWER_SD 0x20 /* SD memory card interface */ + +#define WB_REG_PME 0x23 +#define WB_PME_PME_EN 0x80 /* Global PM event enable */ +#define WB_PME_MSPME_EN 0x40 /* MS PM event enable */ +#define WB_PME_SDPME_EN 0x20 /* SD PM event enable */ +#define WB_PME_SCPME_EN 0x10 /* SC PM event enable */ + +#define WB_REG_PMESTS 0x24 /* PM event status */ +#define WB_PMESTS_MSPME_STS 0x40 /* MS PM event status */ +#define WB_PMESTS_SDPME_STS 0x20 /* SD PM event status */ +#define WB_PMESTS_SCPME_STS 0x10 /* SC PM event status */ + +#define WB_REG_CFG 0x26 +#define WB_CFG_HEFRAS 0x40 /* Extended func reg addr select */ +#define WB_CFG_LOCKREG 0x20 /* Config register access control */ + +#define WB_REG_MFSEL 0x29 /* Multi-function sel (518 only) */ + +/* + * Logical Device Interface + */ + +#define WB_REG_DEV_EN 0x30 +#define WB_DEV_EN_ACTIVE 0x01 /* Logical device active bit */ + +#define WB_REG_DEV_BASE_HI 0x60 +#define WB_REG_DEV_BASE_LO 0x61 + +#define WB_REG_DEV_IRQ 0x70 +#define WB_DEV_IRQ_MASK 0x0f + +#define WB_REG_DEV_DRQ 0x74 +#define WB_DEV_DRQ_MASK 0x0f + +#define WB_REG_DEV_MISC 0xf0 +#define WB_DEV_MISC_SCIRQ_SHR 0x80 /* SC: IRQ sharing control */ +#define WB_DEV_MISC_SCPSNT_POL 0x01 /* SC: SC present polarity */ +#define WB_DEV_MISC_MSIRQ_POLL 0x10 /* MS: IRQ polarity control (level) */ +#define WB_DEV_MISC_MSIRQ_POLP 0x08 /* MS: IRQ polarity control (pulse) */ +#define WB_DEV_MISC_MSIRQ_SHR 0x04 /* MS: IRQ sharing control */ +#define WB_DEV_MISC_MS4OUT_POL 0x02 /* MS: MS4 output polarity control */ +#define WB_DEV_MISC_MS4OUT_EN 0x01 /* MS: MS4 output enable */ +#define WB_DEV_MISC_SDDATA3_HI 0x20 /* SD: DATA3 pin will output high */ +#define WB_DEV_MISC_SDDATA3_OUT 0x10 /* SD: DATA3 pin to output pin */ +#define WB_DEV_MISC_SDGP11_HI 0x04 /* SD: GP11 card-detect pin pole */ +#define WB_DEV_MISC_SDGP11_DET 0x02 /* SD: GP11 card-detect enable */ +#define WB_DEV_MISC_SDDATA3_DET 0x01 /* SD: DATA3 card-detect enable */ + +#define WB_REG_DEV_IRQCFG 0xf1 +#define WB_DEV_IRQCFG_HI_L 0x08 +#define WB_DEV_IRQCFG_HI_P 0x04 +#define WB_DEV_IRQCFG_MODE 0x02 +#define WB_DEV_IRQCFG_DEBOUNCE 0x01 + +/* + * SD Card interface registers + */ + +#define WB_SD_COMMAND 0x00 +#define WB_SD_FIFO 0x01 +#define WB_SD_INTCTL 0x02 +#define WB_SD_INTSTS 0x03 +#define WB_INT_PENDING 0x80 +#define WB_INT_CARD 0x40 +#define WB_INT_FIFO 0x20 +#define WB_INT_CRC 0x10 +#define WB_INT_TIMEOUT 0x08 +#define WB_INT_PROGEND 0x04 +#define WB_INT_BUSYEND 0x02 +#define WB_INT_TC 0x01 +#define WB_INT_DEFAULT \ + (WB_INT_CARD|WB_INT_FIFO|WB_INT_CRC|WB_INT_TIMEOUT) +#define WB_SD_FIFOSTS 0x04 +#define WB_FIFO_EMPTY 0x80 +#define WB_FIFO_FULL 0x40 +#define WB_FIFO_EMPTY_THRES 0x20 +#define WB_FIFO_FULL_THRES 0x10 +#define WB_FIFO_DEPTH_MASK 0x0f +#define WB_SD_INDEX 0x05 +#define WB_INDEX_CLK 0x01 +#define WB_CLK_375K 0x00 +#define WB_CLK_12M 0x01 +#define WB_CLK_16M 0x02 +#define WB_CLK_24M 0x03 +#define WB_INDEX_PBSMSB 0x02 +#define WB_INDEX_TAAC 0x03 +#define WB_INDEX_NSAC 0x04 +#define WB_INDEX_PBSLSB 0x05 +#define WB_INDEX_SETUP 0x06 +#define WB_SETUP_DATA3_HI 0x08 +#define WB_SETUP_FIFO_RST 0x04 +#define WB_SETUP_SOFT_RST 0x02 +#define WB_INDEX_DMA 0x07 +#define WB_INDEX_FIFOEN 0x08 +#define WB_FIFOEN_EMPTY 0x20 +#define WB_FIFOEN_FULL 0x10 +#define WB_INDEX_STATUS 0x10 +#define WB_STATUS_BLOCK_READ 0x80 +#define WB_STATUS_BLOCK_WRITE 0x40 +#define WB_STATUS_BUSY 0x20 +#define WB_STATUS_CARD_TRAFFIC 0x04 +#define WB_STATUS_SEND_COMMAND 0x02 +#define WB_STATUS_RECV_RES 0x01 +#define WB_INDEX_RESPLEN 0x1e +#define WB_INDEX_RESP(n) (0x1f + (n)) +#define WB_INDEX_CRCSTS 0x30 +#define WB_INDEX_ISR 0x3f +#define WB_SD_DATA 0x06 +#define WB_SD_CSR 0x07 +#define WB_CSR_MS_LED 0x20 +#define WB_CSR_POWER_N 0x10 +#define WB_CSR_WRITE_PROTECT 0x04 +#define WB_CSR_CARD_PRESENT 0x01 + +#endif Index: src/sys/dev/ic/w83l518dvar.h diff -u /dev/null src/sys/dev/ic/w83l518dvar.h:1.1.2.2 --- /dev/null Thu Oct 8 09:47:10 2009 +++ src/sys/dev/ic/w83l518dvar.h Thu Oct 8 09:47:09 2009 @@ -0,0 +1,59 @@ +/* $NetBSD: w83l518dvar.h,v 1.1.2.2 2009/10/08 09:47:09 sborrill Exp $ */ + +/* + * Copyright (c) 2009 Jared D. McNeill <jmcne...@invisible.ca> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _SYS_DEV_IC_W83L518DVAR_H +#define _SYS_DEV_IC_W83L518DVAR_H + +struct wb_softc { + device_t wb_dev; + + /* to be filled in by bus driver */ + bus_space_tag_t wb_iot; + bus_space_handle_t wb_ioh; + uint8_t wb_type; + uint16_t wb_base; + uint8_t wb_irq; + + /* private */ + device_t wb_sdmmc_dev; + int wb_sdmmc_width; + uint8_t wb_sdmmc_intsts; + callout_t wb_sdmmc_callout; +}; + +void wb_attach(struct wb_softc *); +int wb_detach(struct wb_softc *, int); +int wb_intr(void *); + +uint8_t wb_read(struct wb_softc *, uint8_t); +void wb_write(struct wb_softc *, uint8_t, uint8_t); +uint8_t wb_idx_read(struct wb_softc *, uint8_t); +void wb_idx_write(struct wb_softc *, uint8_t, uint8_t); + +void wb_led(struct wb_softc *, bool); + +#endif