stasc.c revision 1.1
11.1Suwe/* $NetBSD: stasc.c,v 1.1 2020/07/19 23:44:36 uwe Exp $ */ 21.1Suwe/* 31.1Suwe * Copyright (c) 2020 Valery Ushakov 41.1Suwe * All rights reserved. 51.1Suwe * 61.1Suwe * Redistribution and use in source and binary forms, with or without 71.1Suwe * modification, are permitted provided that the following conditions 81.1Suwe * are met: 91.1Suwe * 1. Redistributions of source code must retain the above copyright 101.1Suwe * notice, this list of conditions and the following disclaimer. 111.1Suwe * 2. Redistributions in binary form must reproduce the above copyright 121.1Suwe * notice, this list of conditions and the following disclaimer in the 131.1Suwe * documentation and/or other materials provided with the distribution. 141.1Suwe * 151.1Suwe * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161.1Suwe * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171.1Suwe * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181.1Suwe * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191.1Suwe * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201.1Suwe * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211.1Suwe * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221.1Suwe * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231.1Suwe * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241.1Suwe * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251.1Suwe */ 261.1Suwe 271.1Suwe/* 281.1Suwe * STMicroelectronics ST40 Asynchronous Serial Controller 291.1Suwe */ 301.1Suwe#include <sys/cdefs.h> 311.1Suwe__KERNEL_RCSID(0, "$NetBSD: stasc.c,v 1.1 2020/07/19 23:44:36 uwe Exp $"); 321.1Suwe 331.1Suwe#include <sys/param.h> 341.1Suwe#include <sys/systm.h> 351.1Suwe#include <sys/conf.h> 361.1Suwe#include <sys/device.h> 371.1Suwe#include <sys/kernel.h> 381.1Suwe 391.1Suwe#include <dev/cons.h> 401.1Suwe 411.1Suwe 421.1Suwe#define STM_ASC_BASE 0xfd032000 431.1Suwe 441.1Suwe#define ASC_BAUDRATE_OFFSET 0x00 451.1Suwe#define ASC_TX_BUFF_OFFSET 0x04 461.1Suwe#define ASC_RX_BUFF_OFFSET 0x08 471.1Suwe#define ASC_CTRL_OFFSET 0x0C 481.1Suwe#define ASC_INT_EN_OFFSET 0x10 491.1Suwe#define ASC_INT_STA_OFFSET 0x14 501.1Suwe#define ASC_GUARDTIME_OFFSET 0x18 511.1Suwe#define ASC_TIMEOUT_OFFSET 0x1C 521.1Suwe#define ASC_TX_RST_OFFSET 0x20 531.1Suwe#define ASC_RX_RST_OFFSET 0x24 541.1Suwe#define ASC_RETRIES_OFFSET 0x28 551.1Suwe 561.1Suwe#define ASC_TX_BUFF (*(volatile uint32_t *)(STM_ASC_BASE + ASC_TX_BUFF_OFFSET)) 571.1Suwe#define ASC_INT_EN (*(volatile uint32_t *)(STM_ASC_BASE + ASC_INT_EN_OFFSET)) 581.1Suwe#define ASC_INT_STA (*(volatile uint32_t *)(STM_ASC_BASE + ASC_INT_STA_OFFSET)) 591.1Suwe 601.1Suwe 611.1Suwe#define ASC_CTRL_NACK_DISABLE 0x2000 621.1Suwe#define ASC_CTRL_BAUDMODE 0x1000 631.1Suwe#define ASC_CTRL_CTS_EN 0x0800 641.1Suwe#define ASC_CTRL_FIFO_EN 0x0400 651.1Suwe#define ASC_CTRL_SC_EN 0x0200 661.1Suwe#define ASC_CTRL_RX_EN 0x0100 671.1Suwe#define ASC_CTRL_RUN 0x0080 681.1Suwe#define ASC_CTRL_LOOPBACK 0x0040 691.1Suwe#define ASC_CTRL_PARITYODD 0x0020 701.1Suwe#define ASC_CTRL_STOPBITS_MASK 0x0018 711.1Suwe#define ASC_CTRL_STOPBITS_0_5 0x0000 721.1Suwe#define ASC_CTRL_STOPBITS_1_0 0x0008 731.1Suwe#define ASC_CTRL_STOPBITS_1_5 0x0010 741.1Suwe#define ASC_CTRL_STOPBITS_2_0 0x0018 751.1Suwe#define ASC_CTRL_MODE_MASK 0x0007 761.1Suwe#define ASC_CTRL_MODE_8N 0x0001 /* 8 bit */ 771.1Suwe#define ASC_CTRL_MODE_7P 0x0003 /* 7 bit + parity */ 781.1Suwe#define ASC_CTRL_MODE_9N 0x0004 /* 9 bit */ 791.1Suwe#define ASC_CTRL_MODE_8W 0x0005 /* 8 bit + wakeup */ 801.1Suwe#define ASC_CTRL_MODE_8P 0x0007 /* 8 bit + parity */ 811.1Suwe 821.1Suwe 831.1Suwe#define ASC_INT_EN_RHF 0x0100 /* ASC_INT_STA_RHF */ 841.1Suwe#define ASC_INT_EN_TOE 0x0080 /* ASC_INT_STA_TOE */ 851.1Suwe#define ASC_INT_EN_TNE 0x0040 /* ASC_INT_STA_TNE */ 861.1Suwe#define ASC_INT_EN_OE 0x0020 /* ASC_INT_STA_OE */ 871.1Suwe#define ASC_INT_EN_FE 0x0010 /* ASC_INT_STA_FE */ 881.1Suwe#define ASC_INT_EN_PE 0x0008 /* ASC_INT_STA_PE */ 891.1Suwe#define ASC_INT_EN_THE 0x0004 /* ASC_INT_STA_THE */ 901.1Suwe#define ASC_INT_EN_TE 0x0002 /* ASC_INT_STA_TE */ 911.1Suwe#define ASC_INT_EN_RBF 0x0001 /* ASC_INT_STA_RBF */ 921.1Suwe 931.1Suwe#define ASC_INT_STA_NKD 0x0400 /* Tx: NACK Data */ 941.1Suwe#define ASC_INT_STA_TF 0x0200 /* Tx: Transmitter Full */ 951.1Suwe#define ASC_INT_STA_RHF 0x0100 /* Rx: Receiver FIFO Half Full */ 961.1Suwe#define ASC_INT_STA_TOE 0x0080 /* Rx: Timeout Or Empty */ 971.1Suwe#define ASC_INT_STA_TNE 0x0040 /* Rx: Timeout Or Not Empty */ 981.1Suwe#define ASC_INT_STA_OE 0x0020 /* Rx: Overrun Error */ 991.1Suwe#define ASC_INT_STA_FE 0x0010 /* Rx: Frame Error */ 1001.1Suwe#define ASC_INT_STA_PE 0x0008 /* Rx: Parity Error */ 1011.1Suwe#define ASC_INT_STA_THE 0x0004 /* Tx: Transmitter FIFO Half Empty */ 1021.1Suwe#define ASC_INT_STA_TE 0x0002 /* Tx: Transmitter Empty */ 1031.1Suwe#define ASC_INT_STA_RBF 0x0001 /* Rx: Reciever Buffer Full */ 1041.1Suwe 1051.1Suwe 1061.1Suwe 1071.1Suwestruct stasc_softc { 1081.1Suwe device_t sc_dev; 1091.1Suwe}; 1101.1Suwe 1111.1Suwe 1121.1Suwestatic int stasc_match(device_t, cfdata_t, void *); 1131.1Suwestatic void stasc_attach(device_t, device_t, void *); 1141.1Suwe 1151.1SuweCFATTACH_DECL_NEW(stasc, sizeof(struct stasc_softc), 1161.1Suwe stasc_match, stasc_attach, NULL, NULL); 1171.1Suwe 1181.1Suwe 1191.1Suwe/* console */ 1201.1Suwecons_decl(stasc_) 1211.1Suwe 1221.1Suwe/* assign to cn_tab after cleaning bss to get printf early for the cpu setup */ 1231.1Suwestruct consdev stasc_earlycons = cons_init(stasc_); 1241.1Suwe 1251.1Suweextern struct cfdriver stasc_cd; 1261.1Suwe 1271.1Suweconst struct cdevsw stasc_cdevsw = { 1281.1Suwe .d_open = noopen, 1291.1Suwe .d_close = noclose, 1301.1Suwe .d_read = noread, 1311.1Suwe .d_write = nowrite, 1321.1Suwe .d_ioctl = noioctl, 1331.1Suwe .d_stop = nostop, 1341.1Suwe .d_tty = notty, 1351.1Suwe .d_poll = nopoll, 1361.1Suwe .d_mmap = nommap, 1371.1Suwe .d_kqfilter = nokqfilter, 1381.1Suwe .d_discard = nodiscard, 1391.1Suwe .d_flag = D_TTY 1401.1Suwe}; 1411.1Suwe 1421.1Suwe 1431.1Suwe 1441.1Suwestatic int 1451.1Suwestasc_match(device_t parent, cfdata_t cfp, void *aux) 1461.1Suwe{ 1471.1Suwe 1481.1Suwe if (strcmp(cfp->cf_name, "stasc") != 0) 1491.1Suwe return 0; 1501.1Suwe 1511.1Suwe return 0; /* just stub it out for now */ 1521.1Suwe} 1531.1Suwe 1541.1Suwe 1551.1Suwestatic void 1561.1Suwestasc_attach(device_t parent, device_t self, void *aux) 1571.1Suwe{ 1581.1Suwe struct stasc_softc *sc; 1591.1Suwe 1601.1Suwe sc = device_private(self); 1611.1Suwe sc->sc_dev = self; 1621.1Suwe 1631.1Suwe aprint_normal("\n"); 1641.1Suwe} 1651.1Suwe 1661.1Suwe 1671.1Suwevoid 1681.1Suwestasc_cnprobe(struct consdev *cp) 1691.1Suwe{ 1701.1Suwe 1711.1Suwe cp->cn_pri = CN_NORMAL; 1721.1Suwe} 1731.1Suwe 1741.1Suwe 1751.1Suwevoid 1761.1Suwestasc_cninit(struct consdev *cp) 1771.1Suwe{ 1781.1Suwe 1791.1Suwe return; 1801.1Suwe} 1811.1Suwe 1821.1Suwe 1831.1Suweint 1841.1Suwestasc_cngetc(dev_t dev) 1851.1Suwe{ 1861.1Suwe return -1; 1871.1Suwe} 1881.1Suwe 1891.1Suwe 1901.1Suwevoid 1911.1Suwestasc_cnputc(dev_t dev, int c) 1921.1Suwe{ 1931.1Suwe uint32_t status; 1941.1Suwe 1951.1Suwe /* wait for Tx FULL to become zero */ 1961.1Suwe do { 1971.1Suwe status = ASC_INT_STA; 1981.1Suwe } while ((status & ASC_INT_STA_TF) != 0); 1991.1Suwe 2001.1Suwe /* can write the character now */ 2011.1Suwe ASC_TX_BUFF = c; 2021.1Suwe} 2031.1Suwe 2041.1Suwe 2051.1Suwevoid 2061.1Suwestasc_cnpollc(dev_t dev, int on) 2071.1Suwe{ 2081.1Suwe 2091.1Suwe return; 2101.1Suwe} 211