diff options
| author | 2012-11-29 23:36:34 +0000 | |
|---|---|---|
| committer | 2012-11-29 23:36:34 +0000 | |
| commit | f615cd67b44e84976c75886093ca5794b1689fea (patch) | |
| tree | 32cb893c341e137c6f7cb57ef28eba7357667fe4 /sys/dev/pci/rtsx_pci.c | |
| parent | Delete needless check for NULL. From Michael W. Bombardieri. (diff) | |
| download | wireguard-openbsd-f615cd67b44e84976c75886093ca5794b1689fea.tar.xz wireguard-openbsd-f615cd67b44e84976c75886093ca5794b1689fea.zip | |
Add rtsx(4), a new driver for the Realtek RTS5209 card reader.
This card reader does not comply to the standard SDHC interface
supported by sdhc(4) and hence requires a custom driver.
With help from uwe and mikeb. Useful hints were also provided by the
author of the corresponding Linux driver (wwang at realsil com cn),
thanks a lot! Tested by myself and weerd on i386 and amd64.
Diffstat (limited to 'sys/dev/pci/rtsx_pci.c')
| -rw-r--r-- | sys/dev/pci/rtsx_pci.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/sys/dev/pci/rtsx_pci.c b/sys/dev/pci/rtsx_pci.c new file mode 100644 index 00000000000..127f43f341a --- /dev/null +++ b/sys/dev/pci/rtsx_pci.c @@ -0,0 +1,105 @@ +/* $OpenBSD: rtsx_pci.c,v 1.1 2012/11/29 23:36:34 stsp Exp $ */ + +/* + * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> + * Copyright (c) 2012 Stefan Sperling <stsp@openbsd.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/systm.h> +#include <sys/malloc.h> + +#include <dev/pci/pcivar.h> +#include <dev/pci/pcidevs.h> +#include <dev/ic/rtsxreg.h> +#include <dev/ic/rtsxvar.h> +#include <dev/sdmmc/sdmmcvar.h> + +#define RTSX_PCI_BAR 0x10 + +struct rtsx_pci_softc { + struct rtsx_softc sc; + void *sc_ih; +}; + +int rtsx_pci_match(struct device *, void *, void *); +void rtsx_pci_attach(struct device *, struct device *, void *); + +struct cfattach rtsx_pci_ca = { + sizeof(struct rtsx_pci_softc), rtsx_pci_match, rtsx_pci_attach, + NULL, rtsx_activate +}; + +int +rtsx_pci_match(struct device *parent, void *match, void *aux) +{ + struct pci_attach_args *pa = aux; + + if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_REALTEK && + PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_REALTEK_RTS5209) + return 1; + + return 0; +} + +void +rtsx_pci_attach(struct device *parent, struct device *self, void *aux) +{ + struct rtsx_pci_softc *sc = (struct rtsx_pci_softc *)self; + struct pci_attach_args *pa = aux; + pci_intr_handle_t ih; + char const *intrstr; + bus_space_tag_t iot; + bus_space_handle_t ioh; + bus_size_t size; + + if ((pci_conf_read(pa->pa_pc, pa->pa_tag, RTSX_CFG_PCI) + & RTSX_CFG_ASIC) != 0) { + printf("%s: no asic\n", sc->sc.sc_dev.dv_xname); + return; + } + + if (pci_intr_map(pa, &ih)) { + printf(": can't map interrupt\n"); + return; + } + + intrstr = pci_intr_string(pa->pa_pc, ih); + sc->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_SDMMC, + rtsx_intr, sc, sc->sc.sc_dev.dv_xname); + if (sc->sc_ih == NULL) { + printf(": can't establish interrupt\n"); + return; + } + printf(": %s\n", intrstr); + + if (pci_mem_find(pa->pa_pc, pa->pa_tag, RTSX_PCI_BAR, + NULL, NULL, NULL) != 0) { + printf("%s: can't find registers\n", sc->sc.sc_dev.dv_xname); + return; + } + + if (pci_mapreg_map(pa, RTSX_PCI_BAR, PCI_MAPREG_TYPE_MEM, 0, + &iot, &ioh, NULL, &size, 0)) { + printf("%s: can't map registers\n", sc->sc.sc_dev.dv_xname); + return; + } + + pci_set_powerstate(pa->pa_pc, pa->pa_tag, PCI_PMCSR_STATE_D0); + + if (rtsx_attach(&sc->sc, iot, ioh, size, pa->pa_dmat) != 0) + printf("%s: can't initialize chip\n", sc->sc.sc_dev.dv_xname); +} |
