1158124Smarcel/*- 2158124Smarcel * Copyright (c) 2006 Marcel Moolenaar 3158124Smarcel * All rights reserved. 4158124Smarcel * 5158124Smarcel * Redistribution and use in source and binary forms, with or without 6158124Smarcel * modification, are permitted provided that the following conditions 7158124Smarcel * are met: 8158124Smarcel * 9158124Smarcel * 1. Redistributions of source code must retain the above copyright 10158124Smarcel * notice, this list of conditions and the following disclaimer. 11158124Smarcel * 2. Redistributions in binary form must reproduce the above copyright 12158124Smarcel * notice, this list of conditions and the following disclaimer in the 13158124Smarcel * documentation and/or other materials provided with the distribution. 14158124Smarcel * 15158124Smarcel * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16158124Smarcel * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17158124Smarcel * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18158124Smarcel * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19158124Smarcel * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20158124Smarcel * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21158124Smarcel * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22158124Smarcel * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23158124Smarcel * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24158124Smarcel * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25158124Smarcel */ 26158124Smarcel 27158124Smarcel#include <sys/cdefs.h> 28158124Smarcel__FBSDID("$FreeBSD$"); 29158124Smarcel 30158124Smarcel#include <sys/param.h> 31158124Smarcel#include <sys/systm.h> 32158124Smarcel#include <sys/bus.h> 33158124Smarcel#include <sys/rman.h> 34158124Smarcel 35158124Smarcel#include <dev/puc/puc_bus.h> 36158124Smarcel#include <dev/puc/puc_cfg.h> 37160030Sobrien#include <dev/puc/puc_bfe.h> 38158124Smarcel 39158124Smarcelint 40158124Smarcelpuc_config(struct puc_softc *sc, enum puc_cfg_cmd cmd, int port, intptr_t *r) 41158124Smarcel{ 42158124Smarcel const struct puc_cfg *cfg = sc->sc_cfg; 43158124Smarcel int error; 44158124Smarcel 45158124Smarcel if (cfg->config_function != NULL) { 46158124Smarcel error = cfg->config_function(sc, cmd, port, r); 47158124Smarcel if (!error) 48158124Smarcel return (0); 49158124Smarcel } else 50158124Smarcel error = EDOOFUS; 51158124Smarcel 52158124Smarcel switch (cmd) { 53158124Smarcel case PUC_CFG_GET_CLOCK: 54158124Smarcel if (cfg->clock < 0) 55158124Smarcel return (error); 56158124Smarcel *r = cfg->clock; 57158124Smarcel return (0); 58158124Smarcel case PUC_CFG_GET_DESC: 59158124Smarcel if (cfg->desc == NULL) 60158124Smarcel return (error); 61158124Smarcel *r = (intptr_t)cfg->desc; 62158124Smarcel return (0); 63158124Smarcel case PUC_CFG_GET_ILR: 64158124Smarcel *r = PUC_ILR_NONE; 65158124Smarcel return (0); 66158124Smarcel case PUC_CFG_GET_LEN: 67158124Smarcel /* The length of bus space needed by the port. */ 68158124Smarcel *r = 8; 69158124Smarcel return (0); 70158124Smarcel case PUC_CFG_GET_NPORTS: 71158124Smarcel /* The number of ports on this card. */ 72158124Smarcel switch (cfg->ports) { 73158124Smarcel case PUC_PORT_NONSTANDARD: 74158124Smarcel return (error); 75158124Smarcel case PUC_PORT_1P: 76158124Smarcel case PUC_PORT_1S: 77158124Smarcel *r = 1; 78158124Smarcel return (0); 79158124Smarcel case PUC_PORT_1S1P: 80158124Smarcel case PUC_PORT_2P: 81158124Smarcel case PUC_PORT_2S: 82158124Smarcel *r = 2; 83158124Smarcel return (0); 84158124Smarcel case PUC_PORT_1S2P: 85158124Smarcel case PUC_PORT_2S1P: 86158124Smarcel case PUC_PORT_3S: 87158124Smarcel *r = 3; 88158124Smarcel return (0); 89158124Smarcel case PUC_PORT_4S: 90158124Smarcel *r = 4; 91158124Smarcel return (0); 92158124Smarcel case PUC_PORT_4S1P: 93158124Smarcel *r = 5; 94158124Smarcel return (0); 95158124Smarcel case PUC_PORT_6S: 96158124Smarcel *r = 6; 97158124Smarcel return (0); 98158124Smarcel case PUC_PORT_8S: 99158124Smarcel *r = 8; 100158124Smarcel return (0); 101158124Smarcel case PUC_PORT_12S: 102158124Smarcel *r = 12; 103158124Smarcel return (0); 104158124Smarcel case PUC_PORT_16S: 105158124Smarcel *r = 16; 106158124Smarcel return (0); 107158124Smarcel } 108158124Smarcel break; 109158124Smarcel case PUC_CFG_GET_OFS: 110158124Smarcel /* The offset relative to the RID. */ 111158124Smarcel if (cfg->d_ofs < 0) 112158124Smarcel return (error); 113158124Smarcel *r = port * cfg->d_ofs; 114158124Smarcel return (0); 115158124Smarcel case PUC_CFG_GET_RID: 116158124Smarcel /* The RID for this port. */ 117158124Smarcel if (port == 0) { 118158124Smarcel if (cfg->rid < 0) 119158124Smarcel return (error); 120158124Smarcel *r = cfg->rid; 121158124Smarcel return (0); 122158124Smarcel } 123158124Smarcel if (cfg->d_rid < 0) 124158124Smarcel return (error); 125158124Smarcel if (cfg->rid < 0) { 126158124Smarcel error = puc_config(sc, PUC_CFG_GET_RID, 0, r); 127158124Smarcel if (error) 128158124Smarcel return (error); 129158124Smarcel } else 130158124Smarcel *r = cfg->rid; 131158124Smarcel *r += port * cfg->d_rid; 132158124Smarcel return (0); 133158124Smarcel case PUC_CFG_GET_TYPE: 134158124Smarcel /* The type of this port. */ 135158124Smarcel if (cfg->ports == PUC_PORT_NONSTANDARD) 136158124Smarcel return (error); 137158124Smarcel switch (port) { 138158124Smarcel case 0: 139158124Smarcel if (cfg->ports == PUC_PORT_1P || 140158124Smarcel cfg->ports == PUC_PORT_2P) 141158124Smarcel *r = PUC_TYPE_PARALLEL; 142158124Smarcel else 143158124Smarcel *r = PUC_TYPE_SERIAL; 144158124Smarcel return (0); 145158124Smarcel case 1: 146158124Smarcel if (cfg->ports == PUC_PORT_1S1P || 147158124Smarcel cfg->ports == PUC_PORT_1S2P || 148158124Smarcel cfg->ports == PUC_PORT_2P) 149158124Smarcel *r = PUC_TYPE_PARALLEL; 150158124Smarcel else 151158124Smarcel *r = PUC_TYPE_SERIAL; 152158124Smarcel return (0); 153158124Smarcel case 2: 154158124Smarcel if (cfg->ports == PUC_PORT_1S2P || 155158124Smarcel cfg->ports == PUC_PORT_2S1P) 156158124Smarcel *r = PUC_TYPE_PARALLEL; 157158124Smarcel else 158158124Smarcel *r = PUC_TYPE_SERIAL; 159158124Smarcel return (0); 160158124Smarcel case 4: 161158124Smarcel if (cfg->ports == PUC_PORT_4S1P) 162158124Smarcel *r = PUC_TYPE_PARALLEL; 163158124Smarcel else 164158124Smarcel *r = PUC_TYPE_SERIAL; 165158124Smarcel return (0); 166158124Smarcel } 167158124Smarcel *r = PUC_TYPE_SERIAL; 168158124Smarcel return (0); 169158124Smarcel case PUC_CFG_SETUP: 170158124Smarcel *r = ENXIO; 171158124Smarcel return (0); 172158124Smarcel } 173158124Smarcel 174158124Smarcel return (ENXIO); 175158124Smarcel} 176