root/drivers/media/pci/mantis/mantis_uart.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mantis_uart_read
  2. mantis_uart_work
  3. mantis_uart_setup
  4. mantis_uart_init
  5. mantis_uart_exit

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3         Mantis PCI bridge driver
   4 
   5         Copyright (C) Manu Abraham (abraham.manu@gmail.com)
   6 
   7 */
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/spinlock.h>
  11 #include <asm/io.h>
  12 
  13 #include <linux/signal.h>
  14 #include <linux/sched.h>
  15 #include <linux/interrupt.h>
  16 #include <linux/pci.h>
  17 
  18 #include <media/dmxdev.h>
  19 #include <media/dvbdev.h>
  20 #include <media/dvb_demux.h>
  21 #include <media/dvb_frontend.h>
  22 #include <media/dvb_net.h>
  23 
  24 #include "mantis_common.h"
  25 #include "mantis_reg.h"
  26 #include "mantis_uart.h"
  27 #include "mantis_input.h"
  28 
  29 struct mantis_uart_params {
  30         enum mantis_baud        baud_rate;
  31         enum mantis_parity      parity;
  32 };
  33 
  34 static struct {
  35         char string[7];
  36 } rates[5] = {
  37         { "9600" },
  38         { "19200" },
  39         { "38400" },
  40         { "57600" },
  41         { "115200" }
  42 };
  43 
  44 static struct {
  45         char string[5];
  46 } parity[3] = {
  47         { "NONE" },
  48         { "ODD" },
  49         { "EVEN" }
  50 };
  51 
  52 static void mantis_uart_read(struct mantis_pci *mantis)
  53 {
  54         struct mantis_hwconfig *config = mantis->hwconfig;
  55         int i, scancode = 0, err = 0;
  56 
  57         /* get data */
  58         dprintk(MANTIS_DEBUG, 1, "UART Reading ...");
  59         for (i = 0; i < (config->bytes + 1); i++) {
  60                 int data = mmread(MANTIS_UART_RXD);
  61 
  62                 dprintk(MANTIS_DEBUG, 0, " <%02x>", data);
  63 
  64                 scancode = (scancode << 8) | (data & 0x3f);
  65                 err |= data;
  66 
  67                 if (data & (1 << 7))
  68                         dprintk(MANTIS_ERROR, 1, "UART framing error");
  69 
  70                 if (data & (1 << 6))
  71                         dprintk(MANTIS_ERROR, 1, "UART parity error");
  72         }
  73         dprintk(MANTIS_DEBUG, 0, "\n");
  74 
  75         if ((err & 0xC0) == 0)
  76                 mantis_input_process(mantis, scancode);
  77 }
  78 
  79 static void mantis_uart_work(struct work_struct *work)
  80 {
  81         struct mantis_pci *mantis = container_of(work, struct mantis_pci, uart_work);
  82         u32 stat;
  83         unsigned long timeout;
  84 
  85         stat = mmread(MANTIS_UART_STAT);
  86 
  87         if (stat & MANTIS_UART_RXFIFO_FULL)
  88                 dprintk(MANTIS_ERROR, 1, "RX Fifo FULL");
  89 
  90         /*
  91          * MANTIS_UART_RXFIFO_DATA is only set if at least
  92          * config->bytes + 1 bytes are in the FIFO.
  93          */
  94 
  95         /* FIXME: is 10ms good enough ? */
  96         timeout = jiffies +  msecs_to_jiffies(10);
  97         while (stat & MANTIS_UART_RXFIFO_DATA) {
  98                 mantis_uart_read(mantis);
  99                 stat = mmread(MANTIS_UART_STAT);
 100 
 101                 if (!time_is_after_jiffies(timeout))
 102                         break;
 103         }
 104 
 105         /* re-enable UART (RX) interrupt */
 106         mantis_unmask_ints(mantis, MANTIS_INT_IRQ1);
 107 }
 108 
 109 static int mantis_uart_setup(struct mantis_pci *mantis,
 110                              struct mantis_uart_params *params)
 111 {
 112         u32 reg;
 113 
 114         mmwrite((mmread(MANTIS_UART_CTL) | (params->parity & 0x3)), MANTIS_UART_CTL);
 115 
 116         reg = mmread(MANTIS_UART_BAUD);
 117 
 118         switch (params->baud_rate) {
 119         case MANTIS_BAUD_9600:
 120                 reg |= 0xd8;
 121                 break;
 122         case MANTIS_BAUD_19200:
 123                 reg |= 0x6c;
 124                 break;
 125         case MANTIS_BAUD_38400:
 126                 reg |= 0x36;
 127                 break;
 128         case MANTIS_BAUD_57600:
 129                 reg |= 0x23;
 130                 break;
 131         case MANTIS_BAUD_115200:
 132                 reg |= 0x11;
 133                 break;
 134         default:
 135                 return -EINVAL;
 136         }
 137 
 138         mmwrite(reg, MANTIS_UART_BAUD);
 139 
 140         return 0;
 141 }
 142 
 143 int mantis_uart_init(struct mantis_pci *mantis)
 144 {
 145         struct mantis_hwconfig *config = mantis->hwconfig;
 146         struct mantis_uart_params params;
 147 
 148         /* default parity: */
 149         params.baud_rate = config->baud_rate;
 150         params.parity = config->parity;
 151         dprintk(MANTIS_INFO, 1, "Initializing UART @ %sbps parity:%s",
 152                 rates[params.baud_rate].string,
 153                 parity[params.parity].string);
 154 
 155         INIT_WORK(&mantis->uart_work, mantis_uart_work);
 156 
 157         /* disable interrupt */
 158         mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
 159 
 160         mantis_uart_setup(mantis, &params);
 161 
 162         /* default 1 byte */
 163         mmwrite((mmread(MANTIS_UART_BAUD) | (config->bytes << 8)), MANTIS_UART_BAUD);
 164 
 165         /* flush buffer */
 166         mmwrite((mmread(MANTIS_UART_CTL) | MANTIS_UART_RXFLUSH), MANTIS_UART_CTL);
 167 
 168         /* enable interrupt */
 169         mmwrite(mmread(MANTIS_UART_CTL) | MANTIS_UART_RXINT, MANTIS_UART_CTL);
 170         mantis_unmask_ints(mantis, MANTIS_INT_IRQ1);
 171 
 172         schedule_work(&mantis->uart_work);
 173         dprintk(MANTIS_DEBUG, 1, "UART successfully initialized");
 174 
 175         return 0;
 176 }
 177 EXPORT_SYMBOL_GPL(mantis_uart_init);
 178 
 179 void mantis_uart_exit(struct mantis_pci *mantis)
 180 {
 181         /* disable interrupt */
 182         mantis_mask_ints(mantis, MANTIS_INT_IRQ1);
 183         mmwrite(mmread(MANTIS_UART_CTL) & 0xffef, MANTIS_UART_CTL);
 184         flush_work(&mantis->uart_work);
 185 }
 186 EXPORT_SYMBOL_GPL(mantis_uart_exit);

/* [<][>][^][v][top][bottom][index][help] */