ptcd.c revision 1.5
11.5Sthorpej/* $NetBSD: ptcd.c,v 1.5 2021/08/07 16:19:12 thorpej Exp $ */ 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 <dev/gpio/gpiovar.h> 401.1Smbalmer 411.1Smbalmer#include <dev/isa/isareg.h> 421.1Smbalmer#include <dev/isa/isavar.h> 431.1Smbalmer 441.1Smbalmer/* 451.1Smbalmer * To assert the cash drawer pulse, 0x00 must be written to I/O register 0x48f 461.1Smbalmer * To stop the cash drawer pulse, 0x02 must be written to I/O register 0x48f 471.1Smbalmer * To read out the current cash drawer state (sense pin), read bit 7 of 481.1Smbalmer * I/O register 0x48d 491.1Smbalmer */ 501.1Smbalmer 511.1Smbalmer#define PTCD_READ_REG 0x48d 521.1Smbalmer 531.1Smbalmer/* register offsets, counted from PTCD_READ_REG */ 541.1Smbalmer#define PTCD_READ 0x00 551.1Smbalmer#define PTCD_WRITE 0x02 561.1Smbalmer 571.1Smbalmer/* Read mask */ 581.1Smbalmer#define PTCD_SENSE 0x80 591.1Smbalmer 601.1Smbalmer/* Write values */ 611.1Smbalmer#define PTCD_OPEN 0x00 621.1Smbalmer#define PTCD_CLOSE 0x02 631.1Smbalmer 641.1Smbalmer#define PTCD_NPINS 2 651.1Smbalmer#define PIN_WRITE 0 661.1Smbalmer#define PIN_READ 1 671.1Smbalmer 681.1Smbalmer#define PTCD_ADDR_SIZE 0x03 691.1Smbalmer 701.1Smbalmerstruct ptcd_softc { 711.1Smbalmer bus_space_tag_t sc_iot; 721.1Smbalmer bus_space_handle_t sc_ioh; 731.1Smbalmer 741.1Smbalmer /* GPIO interface */ 751.1Smbalmer struct gpio_chipset_tag sc_gpio_gc; 761.1Smbalmer gpio_pin_t sc_gpio_pins[PTCD_NPINS]; 771.1Smbalmer}; 781.1Smbalmer 791.1Smbalmerint ptcd_match(device_t, struct cfdata *, void *); 801.1Smbalmervoid ptcd_attach(device_t, device_t, void *); 811.1Smbalmer 821.1Smbalmerint ptcd_gpio_pin_read(void *, int); 831.1Smbalmervoid ptcd_gpio_pin_write(void *, int, int); 841.1Smbalmervoid ptcd_gpio_pin_ctl(void *, int, int); 851.1Smbalmer 861.1SmbalmerCFATTACH_DECL2_NEW(ptcd, sizeof(struct ptcd_softc), ptcd_match, ptcd_attach, 871.1Smbalmer NULL, NULL, NULL, NULL); 881.1Smbalmer 891.1Smbalmerint 901.1Smbalmerptcd_match(device_t parent, struct cfdata *match, void *aux) 911.1Smbalmer{ 921.1Smbalmer struct isa_attach_args *ia = aux; 931.1Smbalmer 941.1Smbalmer if (ia->ia_nio < 1) 951.1Smbalmer return 0; 961.1Smbalmer 971.1Smbalmer if (ISA_DIRECT_CONFIG(ia)) 981.1Smbalmer return 0; 991.1Smbalmer 1001.1Smbalmer if (ia->ia_io[0].ir_addr != PTCD_READ_REG) 1011.1Smbalmer return 0; 1021.1Smbalmer 1031.1Smbalmer ia->ia_io[0].ir_size = PTCD_ADDR_SIZE; 1041.1Smbalmer ia->ia_niomem = 0; 1051.1Smbalmer ia->ia_nirq = 0; 1061.1Smbalmer ia->ia_ndrq = 0; 1071.1Smbalmer 1081.1Smbalmer return 1; 1091.1Smbalmer} 1101.1Smbalmer 1111.1Smbalmervoid 1121.1Smbalmerptcd_attach(device_t parent, device_t self, void *aux) 1131.1Smbalmer{ 1141.1Smbalmer struct ptcd_softc *sc; 1151.1Smbalmer struct isa_attach_args *ia = aux; 1161.1Smbalmer struct gpiobus_attach_args gba; 1171.1Smbalmer 1181.1Smbalmer sc = device_private(self); 1191.1Smbalmer 1201.1Smbalmer sc->sc_iot = ia->ia_iot; 1211.1Smbalmer if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, PTCD_ADDR_SIZE, 0, 1221.1Smbalmer &sc->sc_ioh)) { 1231.1Smbalmer aprint_error(": can't map i/o space\n"); 1241.1Smbalmer return; 1251.1Smbalmer } 1261.1Smbalmer 1271.1Smbalmer aprint_normal(": Protech PS3100 cash drawer\n"); 1281.1Smbalmer 1291.1Smbalmer /* Initialize pins array */ 1301.1Smbalmer sc->sc_gpio_pins[PIN_WRITE].pin_num = 0; 1311.1Smbalmer sc->sc_gpio_pins[PIN_WRITE].pin_caps = GPIO_PIN_OUTPUT; 1321.1Smbalmer sc->sc_gpio_pins[PIN_READ].pin_num = 1; 1331.1Smbalmer sc->sc_gpio_pins[PIN_READ].pin_caps = GPIO_PIN_INPUT; 1341.1Smbalmer 1351.1Smbalmer /* Create controller tag */ 1361.1Smbalmer sc->sc_gpio_gc.gp_cookie = sc; 1371.1Smbalmer sc->sc_gpio_gc.gp_pin_read = ptcd_gpio_pin_read; 1381.1Smbalmer sc->sc_gpio_gc.gp_pin_write = ptcd_gpio_pin_write; 1391.1Smbalmer sc->sc_gpio_gc.gp_pin_ctl = ptcd_gpio_pin_ctl; 1401.1Smbalmer 1411.1Smbalmer gba.gba_gc = &sc->sc_gpio_gc; 1421.1Smbalmer gba.gba_pins = sc->sc_gpio_pins; 1431.1Smbalmer gba.gba_npins = PTCD_NPINS; 1441.1Smbalmer 1451.1Smbalmer /* Attach GPIO framework */ 1461.5Sthorpej config_found(self, &gba, gpiobus_print, CFARGS_NONE); 1471.1Smbalmer} 1481.1Smbalmer 1491.1Smbalmerint 1501.1Smbalmerptcd_gpio_pin_read(void *arg, int pin) 1511.1Smbalmer{ 1521.1Smbalmer struct ptcd_softc *sc = arg; 1531.1Smbalmer uint8_t data; 1541.1Smbalmer 1551.1Smbalmer if (pin != PIN_READ) 1561.1Smbalmer return 0; 1571.1Smbalmer 1581.1Smbalmer data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, PTCD_READ); 1591.1Smbalmer return data & PTCD_SENSE ? 0 : 1; 1601.1Smbalmer} 1611.1Smbalmer 1621.1Smbalmervoid 1631.1Smbalmerptcd_gpio_pin_write(void *arg, int pin, int value) 1641.1Smbalmer{ 1651.1Smbalmer struct ptcd_softc *sc = arg; 1661.1Smbalmer 1671.1Smbalmer if (pin != PIN_WRITE) 1681.1Smbalmer return; 1691.1Smbalmer 1701.1Smbalmer bus_space_write_1(sc->sc_iot, sc->sc_ioh, PTCD_WRITE, 1711.1Smbalmer value ? PTCD_OPEN : PTCD_CLOSE); 1721.1Smbalmer} 1731.1Smbalmer 1741.1Smbalmervoid 1751.1Smbalmerptcd_gpio_pin_ctl(void *arg, int pin, int flags) 1761.1Smbalmer{ 1771.1Smbalmer /* We ignore pin control requests since the pin functions are fixed. */ 1781.1Smbalmer} 179