1/* 2 * Copyright 2019, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13#include <string.h> 14#include <stdlib.h> 15#include <platsupport/serial.h> 16#include "../../chardev.h" 17 18#define RHR 0x00 19#define THR 0x00 20#define IER 0x04 21#define LSR 0x14 22#define RHR_MASK MASK(8) 23#define IER_RHRIT BIT(0) 24#define LSR_TXFIFOE BIT(5) 25#define LSR_RXFIFOE BIT(0) 26 27#define REG_PTR(base, off) ((volatile uint32_t *)((base) + (off))) 28 29int uart_getchar(ps_chardevice_t *d) 30{ 31 int ch = EOF; 32 33 if (*REG_PTR(d->vaddr, LSR) & LSR_RXFIFOE) { 34 ch = *REG_PTR(d->vaddr, RHR) & RHR_MASK; 35 } 36 return ch; 37} 38 39int uart_putchar(ps_chardevice_t* d, int c) 40{ 41 while (!(*REG_PTR(d->vaddr, LSR) & LSR_TXFIFOE)) { 42 continue; 43 } 44 *REG_PTR(d->vaddr, THR) = c; 45 if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) { 46 uart_putchar(d, '\r'); 47 } 48 49 return c; 50} 51 52static void 53uart_handle_irq(ps_chardevice_t* d UNUSED) 54{ 55 /* nothing to do */ 56} 57 58int uart_init(const struct dev_defn* defn, 59 const ps_io_ops_t* ops, 60 ps_chardevice_t* dev) 61{ 62 memset(dev, 0, sizeof(*dev)); 63 void* vaddr = chardev_map(defn, ops); 64 if (vaddr == NULL) { 65 return -1; 66 } 67 68 /* Set up all the device properties. */ 69 dev->id = defn->id; 70 dev->vaddr = (void*)vaddr; 71 dev->read = &uart_read; 72 dev->write = &uart_write; 73 dev->handle_irq = &uart_handle_irq; 74 dev->irqs = defn->irqs; 75 dev->ioops = *ops; 76 dev->flags = SERIAL_AUTO_CR; 77 78 *REG_PTR(dev->vaddr, IER) = IER_RHRIT; 79 return 0; 80} 81