11.15Sdyoung/*	$NetBSD: lm_pnpbios.c,v 1.15 2011/07/01 18:14:15 dyoung Exp $ */
21.1Sgroo
31.1Sgroo/*-
41.1Sgroo * Copyright (c) 2000 The NetBSD Foundation, Inc.
51.1Sgroo * All rights reserved.
61.1Sgroo *
71.1Sgroo * This code is derived from software contributed to The NetBSD Foundation
81.1Sgroo * by Bill Squier.
91.1Sgroo *
101.1Sgroo * Redistribution and use in source and binary forms, with or without
111.1Sgroo * modification, are permitted provided that the following conditions
121.1Sgroo * are met:
131.1Sgroo * 1. Redistributions of source code must retain the above copyright
141.1Sgroo *    notice, this list of conditions and the following disclaimer.
151.1Sgroo * 2. Redistributions in binary form must reproduce the above copyright
161.1Sgroo *    notice, this list of conditions and the following disclaimer in the
171.1Sgroo *    documentation and/or other materials provided with the distribution.
181.1Sgroo *
191.1Sgroo * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
201.1Sgroo * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
211.1Sgroo * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
221.1Sgroo * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
231.1Sgroo * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
241.1Sgroo * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
251.1Sgroo * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
261.1Sgroo * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
271.1Sgroo * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
281.1Sgroo * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
291.1Sgroo * POSSIBILITY OF SUCH DAMAGE.
301.1Sgroo */
311.4Slukem
321.4Slukem#include <sys/cdefs.h>
331.15Sdyoung__KERNEL_RCSID(0, "$NetBSD: lm_pnpbios.c,v 1.15 2011/07/01 18:14:15 dyoung Exp $");
341.1Sgroo
351.1Sgroo#include <sys/param.h>
361.1Sgroo#include <sys/systm.h>
371.1Sgroo#include <sys/errno.h>
381.1Sgroo#include <sys/ioctl.h>
391.1Sgroo#include <sys/syslog.h>
401.1Sgroo#include <sys/device.h>
411.1Sgroo#include <sys/proc.h>
421.1Sgroo
431.15Sdyoung#include <sys/bus.h>
441.1Sgroo
451.1Sgroo#include <dev/isa/isavar.h>
461.1Sgroo#include <dev/isa/isadmavar.h>
471.1Sgroo
481.1Sgroo#include <i386/pnpbios/pnpbiosvar.h>
491.1Sgroo
501.3Sthorpej#include <dev/sysmon/sysmonvar.h>
511.3Sthorpej
521.1Sgroo#include <dev/ic/nslm7xvar.h>
531.1Sgroo
541.1Sgroo
551.13Sxtraemeint 	lm_pnpbios_match(device_t, cfdata_t, void *);
561.13Sxtraemevoid 	lm_pnpbios_attach(device_t, device_t, void *);
571.13Sxtraeme
581.13Sxtraemeint 	lm_pnpbios_hints_index(const char *);
591.11Sperryuint8_t lm_pnpbios_readreg(struct lm_softc *, int);
601.13Sxtraemevoid 	lm_pnpbios_writereg(struct lm_softc *, int, int);
611.1Sgroo
621.1Sgroo
631.13SxtraemeCFATTACH_DECL_NEW(lm_pnpbios, sizeof(struct lm_softc),
641.7Sthorpej    lm_pnpbios_match, lm_pnpbios_attach, NULL, NULL);
651.1Sgroo
661.1Sgroo/*
671.2Sgroo * XXX - no known pnpbios ids for lm series chips.
681.1Sgroo */
691.1Sgroostruct lm_pnpbios_hint {
701.1Sgroo	char idstr[8];
711.1Sgroo	int io_region_idx_lm7x;
721.1Sgroo};
731.1Sgroo
741.2Sgroo/*
751.2Sgroo * Currently no known valid pnpbios id's - PNP0C02 is
761.2Sgroo * for reserved motherboard resources, probing it is bad.
771.2Sgroo */
781.1Sgroostruct lm_pnpbios_hint lm_pnpbios_hints[] = {
791.1Sgroo	{ { 0 }, 0 }
801.1Sgroo};
811.1Sgroo
821.1Sgroo
831.1Sgrooint
841.13Sxtraemelm_pnpbios_hints_index(const char *idstr)
851.1Sgroo{
861.1Sgroo	int idx = 0;
871.1Sgroo
881.1Sgroo	while (lm_pnpbios_hints[idx].idstr[0] != 0) {
891.1Sgroo		if (!strcmp(lm_pnpbios_hints[idx].idstr, idstr))
901.1Sgroo			return idx;
911.1Sgroo		++idx;
921.1Sgroo	}
931.1Sgroo
941.1Sgroo	return -1;
951.1Sgroo}
961.1Sgroo
971.1Sgrooint
981.13Sxtraemelm_pnpbios_match(device_t parent, cfdata_t match, void *aux)
991.1Sgroo{
1001.1Sgroo	struct pnpbiosdev_attach_args *aa = aux;
1011.2Sgroo	struct lm_pnpbios_hint *wph;
1021.2Sgroo	bus_space_tag_t iot;
1031.2Sgroo	bus_space_handle_t ioh;
1041.2Sgroo	int rv;
1051.2Sgroo
1061.2Sgroo	int wphi;
1071.1Sgroo
1081.2Sgroo	if ((wphi = lm_pnpbios_hints_index(aa->idstr)) == -1)
1091.13Sxtraeme		return 0;
1101.1Sgroo
1111.2Sgroo	wph = &lm_pnpbios_hints[wphi];
1121.2Sgroo
1131.2Sgroo	if (pnpbios_io_map(aa->pbt, aa->resc, wph->io_region_idx_lm7x,
1141.2Sgroo			   &iot, &ioh)) {
1151.13Sxtraeme		return 0;
1161.2Sgroo	}
1171.2Sgroo
1181.2Sgroo	rv = lm_probe(iot, ioh);
1191.2Sgroo
1201.2Sgroo	pnpbios_io_unmap(aa->pbt, aa->resc, wph->io_region_idx_lm7x,
1211.2Sgroo			 iot, ioh);
1221.2Sgroo
1231.13Sxtraeme	return rv;
1241.1Sgroo}
1251.1Sgroo
1261.1Sgroovoid
1271.13Sxtraemelm_pnpbios_attach(device_t parent, device_t self, void *aux)
1281.1Sgroo{
1291.13Sxtraeme	struct lm_softc *sc = device_private(self);
1301.1Sgroo	struct pnpbiosdev_attach_args *aa = aux;
1311.1Sgroo	struct lm_pnpbios_hint *wph;
1321.1Sgroo
1331.1Sgroo	wph = &lm_pnpbios_hints[lm_pnpbios_hints_index(aa->idstr)];
1341.1Sgroo
1351.1Sgroo	if (pnpbios_io_map(aa->pbt, aa->resc, wph->io_region_idx_lm7x,
1361.1Sgroo			   &sc->lm_iot, &sc->lm_ioh)) {
1371.13Sxtraeme		aprint_error(": can't map i/o space\n");
1381.1Sgroo		return;
1391.1Sgroo	}
1401.1Sgroo
1411.13Sxtraeme	aprint_naive("\n");
1421.13Sxtraeme	aprint_normal("\n");
1431.1Sgroo	pnpbios_print_devres(self, aa);
1441.1Sgroo
1451.12Swiz	/* Bus-independent attach */
1461.8Sad	sc->lm_writereg = lm_pnpbios_writereg;
1471.8Sad	sc->lm_readreg = lm_pnpbios_readreg;
1481.8Sad
1491.1Sgroo	lm_attach(sc);
1501.1Sgroo}
1511.1Sgroo
1521.11Sperryuint8_t
1531.13Sxtraemelm_pnpbios_readreg(struct lm_softc *sc, int reg)
1541.8Sad{
1551.8Sad	bus_space_write_1(sc->lm_iot, sc->lm_ioh, LMC_ADDR, reg);
1561.8Sad	return (bus_space_read_1(sc->lm_iot, sc->lm_ioh, LMC_DATA));
1571.8Sad}
1581.8Sad
1591.8Sad
1601.8Sadvoid
1611.13Sxtraemelm_pnpbios_writereg(struct lm_softc *sc, int reg, int val)
1621.8Sad{
1631.8Sad	bus_space_write_1(sc->lm_iot, sc->lm_ioh, LMC_ADDR, reg);
1641.8Sad	bus_space_write_1(sc->lm_iot, sc->lm_ioh, LMC_DATA, val);
1651.8Sad}
166