Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/drivers/s3c24xx_uart/s3c24xx_uart.c

    rf1fc83a r3d9d948  
    4040#include <genarch/drivers/s3c24xx_uart/s3c24xx_uart.h>
    4141#include <console/chardev.h>
     42#include <console/console.h>
     43#include <ddi/device.h>
    4244#include <arch/asm.h>
    4345#include <mm/slab.h>
    44 #include <console/console.h>
    4546#include <sysinfo/sysinfo.h>
    4647#include <str.h>
    4748
    48 /** S3C24xx UART register offsets */
    49 #define S3C24XX_UTRSTAT         0x10
    50 #define S3C24XX_UTXH            0x20
     49/* Bits in UTRSTAT register */
     50#define S3C24XX_UTRSTAT_TX_EMPTY        0x4
     51#define S3C24XX_UTRSTAT_RDATA           0x1
    5152
    52 /* Bits in UTXH register */
    53 #define S3C24XX_UTXH_TX_EMPTY   0x4
    54 
    55 typedef struct {
    56         ioport8_t *base;
    57 } s3c24xx_uart_instance_t;
     53#define S3C24XX_UFSTAT_TX_FULL          0x4000
     54#define S3C24XX_UFSTAT_RX_FULL          0x0040
     55#define S3C24XX_UFSTAT_RX_COUNT         0x002f
    5856
    5957static void s3c24xx_uart_sendb(outdev_t *dev, uint8_t byte)
    6058{
    61         s3c24xx_uart_instance_t *instance =
    62             (s3c24xx_uart_instance_t *) dev->data;
    63         ioport32_t *utrstat, *utxh;
     59        s3c24xx_uart_t *uart =
     60            (s3c24xx_uart_t *) dev->data;
    6461
    65         utrstat = (ioport32_t *) (instance->base + S3C24XX_UTRSTAT);
    66         utxh = (ioport32_t *) (instance->base + S3C24XX_UTXH);
    67 
    68         /* Wait for transmitter to be empty. */
    69         while ((pio_read_32(utrstat) & S3C24XX_UTXH_TX_EMPTY) == 0)
     62        /* Wait for space becoming available in Tx FIFO. */
     63        while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_TX_FULL) != 0)
    7064                ;
    7165
    72         pio_write_32(utxh, byte);
     66        pio_write_32(&uart->io->utxh, byte);
    7367}
    7468
     
    8680}
    8781
     82static irq_ownership_t s3c24xx_uart_claim(irq_t *irq)
     83{
     84        return IRQ_ACCEPT;
     85}
     86
     87static void s3c24xx_uart_irq_handler(irq_t *irq)
     88{
     89        s3c24xx_uart_t *uart = irq->instance;
     90
     91        while ((pio_read_32(&uart->io->ufstat) & S3C24XX_UFSTAT_RX_COUNT) != 0) {
     92                uint32_t data = pio_read_32(&uart->io->urxh);
     93                pio_read_32(&uart->io->uerstat);
     94                indev_push_character(uart->indev, data & 0xff);
     95        }
     96}
     97
    8898static outdev_operations_t s3c24xx_uart_ops = {
    8999        .write = s3c24xx_uart_putchar,
     
    91101};
    92102
    93 outdev_t *s3c24xx_uart_init(ioport8_t *base)
     103outdev_t *s3c24xx_uart_init(s3c24xx_uart_io_t *io, inr_t inr)
    94104{
    95105        outdev_t *uart_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC);
     
    97107                return NULL;
    98108
    99         s3c24xx_uart_instance_t *instance =
    100             malloc(sizeof(s3c24xx_uart_instance_t), FRAME_ATOMIC);
    101         if (!instance) {
     109        s3c24xx_uart_t *uart =
     110            malloc(sizeof(s3c24xx_uart_t), FRAME_ATOMIC);
     111        if (!uart) {
    102112                free(uart_dev);
    103113                return NULL;
     
    105115
    106116        outdev_initialize("s3c24xx_uart_dev", uart_dev, &s3c24xx_uart_ops);
    107         uart_dev->data = instance;
     117        uart_dev->data = uart;
    108118
    109         instance->base = base;
     119        uart->io = io;
     120        uart->indev = NULL;
     121
     122        /* Initialize IRQ structure. */
     123        irq_initialize(&uart->irq);
     124        uart->irq.devno = device_assign_devno();
     125        uart->irq.inr = inr;
     126        uart->irq.claim = s3c24xx_uart_claim;
     127        uart->irq.handler = s3c24xx_uart_irq_handler;
     128        uart->irq.instance = uart;
     129
     130        /* Enable FIFO, Tx trigger level: empty, Rx trigger level: 1 byte. */
     131        pio_write_32(&uart->io->ufcon, 0x01);
     132
     133        /* Set RX interrupt to pulse mode */
     134        pio_write_32(&uart->io->ucon,
     135            pio_read_32(&uart->io->ucon) & ~(1 << 8));
    110136
    111137        if (!fb_exported) {
     
    116142                sysinfo_set_item_val("fb", NULL, true);
    117143                sysinfo_set_item_val("fb.kind", NULL, 3);
    118                 sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(base));
     144                sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(io));
    119145
    120146                fb_exported = true;
     
    124150}
    125151
     152void s3c24xx_uart_input_wire(s3c24xx_uart_t *uart, indev_t *indev)
     153{
     154        ASSERT(uart);
     155        ASSERT(indev);
     156
     157        uart->indev = indev;
     158        irq_register(&uart->irq);
     159}
     160
    126161/** @}
    127162 */
Note: See TracChangeset for help on using the changeset viewer.