ptcd.c revision 1.1
11.1Smbalmer/* $NetBSD */ 21.1Smbalmer 31.1Smbalmer/* 41.1Smbalmer * Copyright (c) 2012 Marc Balmer <marc@msys.ch> 51.1Smbalmer * All rights reserved. 61.1Smbalmer * 71.1Smbalmer * Redistribution and use in source and binary forms, with or without 81.1Smbalmer * modification, are permitted provided that the following conditions 91.1Smbalmer * are met: 101.1Smbalmer * 1. Redistributions of source code must retain the above copyright 111.1Smbalmer * notice, this list of conditions and the following disclaimer. 121.1Smbalmer * 2. Redistributions in binary form must reproduce the above copyright 131.1Smbalmer * notice, this list of conditions and the following disclaimer in the 141.1Smbalmer * documentation and/or other materials provided with the distribution. 151.1Smbalmer * 161.1Smbalmer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 171.1Smbalmer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 181.1Smbalmer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 191.1Smbalmer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 201.1Smbalmer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 211.1Smbalmer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 221.1Smbalmer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 231.1Smbalmer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 241.1Smbalmer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 251.1Smbalmer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 261.1Smbalmer */ 271.1Smbalmer 281.1Smbalmer/* 291.1Smbalmer * Driver for the Protech PS3100 cash drawer port. 301.1Smbalmer */ 311.1Smbalmer 321.1Smbalmer#include <sys/param.h> 331.1Smbalmer#include <sys/systm.h> 341.1Smbalmer#include <sys/device.h> 351.1Smbalmer#include <sys/gpio.h> 361.1Smbalmer#include <sys/kernel.h> 371.1Smbalmer#include <sys/bus.h> 381.1Smbalmer 391.1Smbalmer#include <machine/pio.h> 401.1Smbalmer 411.1Smbalmer#include <dev/gpio/gpiovar.h> 421.1Smbalmer 431.1Smbalmer#include <dev/isa/isareg.h> 441.1Smbalmer#include <dev/isa/isavar.h> 451.1Smbalmer 461.1Smbalmer/* 471.1Smbalmer * To assert the cash drawer pulse, 0x00 must be written to I/O register 0x48f 481.1Smbalmer * To stop the cash drawer pulse, 0x02 must be written to I/O register 0x48f 491.1Smbalmer * To read out the current cash drawer state (sense pin), read bit 7 of 501.1Smbalmer * I/O register 0x48d 511.1Smbalmer */ 521.1Smbalmer 531.1Smbalmer#define PTCD_READ_REG 0x48d 541.1Smbalmer 551.1Smbalmer/* register offsets, counted from PTCD_READ_REG */ 561.1Smbalmer#define PTCD_READ 0x00 571.1Smbalmer#define PTCD_WRITE 0x02 581.1Smbalmer 591.1Smbalmer/* Read mask */ 601.1Smbalmer#define PTCD_SENSE 0x80 611.1Smbalmer 621.1Smbalmer/* Write values */ 631.1Smbalmer#define PTCD_OPEN 0x00 641.1Smbalmer#define PTCD_CLOSE 0x02 651.1Smbalmer 661.1Smbalmer#define PTCD_NPINS 2 671.1Smbalmer#define PIN_WRITE 0 681.1Smbalmer#define PIN_READ 1 691.1Smbalmer 701.1Smbalmer#define PTCD_ADDR_SIZE 0x03 711.1Smbalmer 721.1Smbalmerstruct ptcd_softc { 731.1Smbalmer bus_space_tag_t sc_iot; 741.1Smbalmer bus_space_handle_t sc_ioh; 751.1Smbalmer 761.1Smbalmer /* GPIO interface */ 771.1Smbalmer struct gpio_chipset_tag sc_gpio_gc; 781.1Smbalmer gpio_pin_t sc_gpio_pins[PTCD_NPINS]; 791.1Smbalmer}; 801.1Smbalmer 811.1Smbalmerint ptcd_match(device_t, struct cfdata *, void *); 821.1Smbalmervoid ptcd_attach(device_t, device_t, void *); 831.1Smbalmer 841.1Smbalmerint ptcd_gpio_pin_read(void *, int); 851.1Smbalmervoid ptcd_gpio_pin_write(void *, int, int); 861.1Smbalmervoid ptcd_gpio_pin_ctl(void *, int, int); 871.1Smbalmer 881.1SmbalmerCFATTACH_DECL2_NEW(ptcd, sizeof(struct ptcd_softc), ptcd_match, ptcd_attach, 891.1Smbalmer NULL, NULL, NULL, NULL); 901.1Smbalmer 911.1Smbalmerint 921.1Smbalmerptcd_match(device_t parent, struct cfdata *match, void *aux) 931.1Smbalmer{ 941.1Smbalmer struct isa_attach_args *ia = aux; 951.1Smbalmer 961.1Smbalmer if (ia->ia_nio < 1) 971.1Smbalmer return 0; 981.1Smbalmer 991.1Smbalmer if (ISA_DIRECT_CONFIG(ia)) 1001.1Smbalmer return 0; 1011.1Smbalmer 1021.1Smbalmer if (ia->ia_io[0].ir_addr != PTCD_READ_REG) 1031.1Smbalmer return 0; 1041.1Smbalmer 1051.1Smbalmer ia->ia_io[0].ir_size = PTCD_ADDR_SIZE; 1061.1Smbalmer ia->ia_niomem = 0; 1071.1Smbalmer ia->ia_nirq = 0; 1081.1Smbalmer ia->ia_ndrq = 0; 1091.1Smbalmer 1101.1Smbalmer return 1; 1111.1Smbalmer} 1121.1Smbalmer 1131.1Smbalmervoid 1141.1Smbalmerptcd_attach(device_t parent, device_t self, void *aux) 1151.1Smbalmer{ 1161.1Smbalmer struct ptcd_softc *sc; 1171.1Smbalmer struct isa_attach_args *ia = aux; 1181.1Smbalmer struct gpiobus_attach_args gba; 1191.1Smbalmer 1201.1Smbalmer sc = device_private(self); 1211.1Smbalmer 1221.1Smbalmer sc->sc_iot = ia->ia_iot; 1231.1Smbalmer if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, PTCD_ADDR_SIZE, 0, 1241.1Smbalmer &sc->sc_ioh)) { 1251.1Smbalmer aprint_error(": can't map i/o space\n"); 1261.1Smbalmer return; 1271.1Smbalmer } 1281.1Smbalmer 1291.1Smbalmer aprint_normal(": Protech PS3100 cash drawer\n"); 1301.1Smbalmer 1311.1Smbalmer /* Initialize pins array */ 1321.1Smbalmer sc->sc_gpio_pins[PIN_WRITE].pin_num = 0; 1331.1Smbalmer sc->sc_gpio_pins[PIN_WRITE].pin_caps = GPIO_PIN_OUTPUT; 1341.1Smbalmer sc->sc_gpio_pins[PIN_READ].pin_num = 1; 1351.1Smbalmer sc->sc_gpio_pins[PIN_READ].pin_caps = GPIO_PIN_INPUT; 1361.1Smbalmer 1371.1Smbalmer /* Create controller tag */ 1381.1Smbalmer sc->sc_gpio_gc.gp_cookie = sc; 1391.1Smbalmer sc->sc_gpio_gc.gp_pin_read = ptcd_gpio_pin_read; 1401.1Smbalmer sc->sc_gpio_gc.gp_pin_write = ptcd_gpio_pin_write; 1411.1Smbalmer sc->sc_gpio_gc.gp_pin_ctl = ptcd_gpio_pin_ctl; 1421.1Smbalmer 1431.1Smbalmer gba.gba_gc = &sc->sc_gpio_gc; 1441.1Smbalmer gba.gba_pins = sc->sc_gpio_pins; 1451.1Smbalmer gba.gba_npins = PTCD_NPINS; 1461.1Smbalmer 1471.1Smbalmer /* Attach GPIO framework */ 1481.1Smbalmer config_found_ia(self, "gpiobus", &gba, gpiobus_print); 1491.1Smbalmer} 1501.1Smbalmer 1511.1Smbalmerint 1521.1Smbalmerptcd_gpio_pin_read(void *arg, int pin) 1531.1Smbalmer{ 1541.1Smbalmer struct ptcd_softc *sc = arg; 1551.1Smbalmer uint8_t data; 1561.1Smbalmer 1571.1Smbalmer if (pin != PIN_READ) 1581.1Smbalmer return 0; 1591.1Smbalmer 1601.1Smbalmer data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, PTCD_READ); 1611.1Smbalmer return data & PTCD_SENSE ? 0 : 1; 1621.1Smbalmer} 1631.1Smbalmer 1641.1Smbalmervoid 1651.1Smbalmerptcd_gpio_pin_write(void *arg, int pin, int value) 1661.1Smbalmer{ 1671.1Smbalmer struct ptcd_softc *sc = arg; 1681.1Smbalmer 1691.1Smbalmer if (pin != PIN_WRITE) 1701.1Smbalmer return; 1711.1Smbalmer 1721.1Smbalmer bus_space_write_1(sc->sc_iot, sc->sc_ioh, PTCD_WRITE, 1731.1Smbalmer value ? PTCD_OPEN : PTCD_CLOSE); 1741.1Smbalmer} 1751.1Smbalmer 1761.1Smbalmervoid 1771.1Smbalmerptcd_gpio_pin_ctl(void *arg, int pin, int flags) 1781.1Smbalmer{ 1791.1Smbalmer /* We ignore pin control requests since the pin functions are fixed. */ 1801.1Smbalmer} 181