[rtems commit] PC386 Add RTD316 and Exar 17D15x multi-port serial card support

Joel Sherrill joel at rtems.org
Thu Mar 29 20:30:44 UTC 2012


Module:    rtems
Branch:    master
Commit:    2cc30b0d0c83d6fa9c5a84ba8d29fb0887073a0b
Changeset: http://git.rtems.org/rtems/commit/?id=2cc30b0d0c83d6fa9c5a84ba8d29fb0887073a0b

Author:    Joel Sherrill <joel.sherrill at oarcorp.com>
Date:      Thu Mar 29 15:28:13 2012 -0500

PC386 Add RTD316 and Exar 17D15x multi-port serial card support

  - RTD316 is a PC-104 board with one Z85C30 SCC for two synchronous
    or asynchronous serial ports.
      http://www.rtd.com/PC104/UM/network/CM316HR.htm
  - Exar 17D15X is a chip with 2, 4, or 8 NS16550 compatible
    serial ports with a PCI interface. It may be found on
    many multi-port serial ports including:
     http://www.rtd.com/PC104/UM/network/CM17320HR.htm

---

 c/src/lib/libbsp/i386/pc386/console/exar17d15x.c |  224 ++++++++++++++++++++++
 c/src/lib/libbsp/i386/pc386/console/exar17d15x.h |   54 +++++
 c/src/lib/libbsp/i386/pc386/console/rtd316.c     |  108 +++++++++++
 c/src/lib/libbsp/i386/pc386/console/rtd316.h     |   56 ++++++
 4 files changed, 442 insertions(+), 0 deletions(-)

diff --git a/c/src/lib/libbsp/i386/pc386/console/exar17d15x.c b/c/src/lib/libbsp/i386/pc386/console/exar17d15x.c
new file mode 100644
index 0000000..95ba3c1
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/exar17d15x.c
@@ -0,0 +1,224 @@
+/**
+ * @file
+ *
+ * @brief Driver for Exar XR17D15x Multiport UARTs
+ *
+ * This driver supports 2, 4 or 8 port Exar parts which are NS16550
+ * compatible.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <termios.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtems/termiostypes.h>
+#include <libchip/serial.h>
+#include <libchip/ns16550.h>
+#include <rtems/bspIo.h>
+#include <rtems/pci.h>
+#include <bsp/exar17d15x.h>
+#include "../../../shared/console_private.h"
+
+#define MAX_BOARDS 4
+
+/*
+ *  This is the rate for the clock internal to the parts.
+ */
+#define EXAR_CLOCK_RATE  (921600*16)
+
+/*
+ *  Supported PCI Ids
+ */
+#define PCI_VENDOR_ID_EXAR 0x13A8
+#define PCI_VENDOR_ID_EXAR_XR17D158 0x0158
+#define PCI_VENDOR_ID_EXAR_XR17D154 0x0154
+#define PCI_VENDOR_ID_EXAR_XR17D152 0x0152
+
+/*
+ * Structure to manage each instance found.
+ */
+typedef struct {
+  uint16_t  vendor;
+  uint16_t  device;
+  uint8_t   ports;
+} exar_parts_t;
+
+static exar_parts_t Supported[] = {
+  { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D158, 8 },
+  { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D154, 4 },
+  { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D152, 2 },
+  { 0, 0, 0 }
+};
+
+/*
+ * Information saved from PCI scan
+ */
+typedef struct {
+  bool      found;
+  uint32_t  base;
+  uint8_t   irq;
+  uint8_t   bus;
+  uint8_t   slot;
+  uint8_t   ports;
+} exar17d15x_conf_t;
+
+/*
+ *  Register Access Routines
+ */
+static uint8_t xr17d15x_get_register(uint32_t addr, uint8_t i)
+{
+  uint8_t          val = 0;
+  volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
+
+  val = *reg;
+  // printk( "RD %p -> 0x%02x\n", reg, val );
+  return val;
+}
+
+static void xr17d15x_set_register(uint32_t addr, uint8_t i, uint8_t val)
+{
+  volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
+
+  // printk( "WR %p <- 0x%02x\n", reg, val );
+  *reg = val;
+}
+
+rtems_device_driver exar17d15x_initialize(
+  rtems_device_major_number  major,
+  rtems_device_minor_number  minor_arg,
+  void                      *arg
+)
+{
+  // int  pbus, pdev, pfun;
+  exar17d15x_conf_t  conf[MAX_BOARDS];
+  int              boards = 0;
+  int              b = 0;
+  int              p;
+  console_tbl     *ports;
+  console_tbl     *port_p;
+  int              pbus;
+  int              pdev;
+  int              pfun;
+  int              status;
+  int              instance;
+  int              i;
+  int              total_ports = 0;
+
+  for ( b=0 ; b<MAX_BOARDS ; b++ ) {
+    conf[b].found = false;
+  }
+
+  /*
+   *  Scan for Serial port boards
+   *
+   *  NOTE: There appear to be Exar parts with 2 and 4 ports which would
+   *        be easy to support.  Just change the hard-coded 8 ports per
+   *        board to variable and adjust.
+   *
+   *  NOTE: There are likely other board vendors which could be supported
+   *        by this.
+   */
+  for ( instance=0 ; instance < MAX_BOARDS ; instance++ ) {
+
+    for ( i=0 ; Supported[i].ports != 0 ; i++ ) {
+      status = pci_find_device(
+        Supported[i].vendor,
+        Supported[i].device,
+        instance,
+        &pbus,
+        &pdev,
+        &pfun
+      );
+      if ( status == PCIB_ERR_SUCCESS ) {
+        boards++;
+        conf[instance].found = true;
+        conf[instance].ports = Supported[i].ports;
+        total_ports += conf[instance].ports;
+        break;
+      }
+    }
+
+    if ( status != PCIB_ERR_SUCCESS )
+      continue;
+
+    pci_read_config_byte(
+      pbus,
+      pdev,
+      pfun,
+      PCI_INTERRUPT_LINE,
+      &conf[instance].irq
+    );
+    pci_read_config_dword(
+      pbus,
+      pdev,
+      pfun,
+      PCI_BASE_ADDRESS_0,
+      &conf[instance].base
+    );
+    printk(
+      "Found Exar 17D15x %d at 0x%08x IRQ %d with %d ports\n",
+      instance,
+      conf[instance].base,
+      conf[instance].irq,
+      conf[instance].ports
+    );
+  }
+
+  /*
+   *  Now allocate array of device structures and fill them in
+   */
+  ports = calloc( total_ports, sizeof( console_tbl ) );
+  port_p = ports;
+  for ( b=0 ; b<MAX_BOARDS ; b++ ) {
+    if ( conf[b].found == false )
+      continue;
+    for ( p=0 ; p<conf[b].ports ; p++ ) {
+      char name[32];
+
+      sprintf( name, "/dev/exar17d15x_%d_%d", b, p );
+      //printk("Found %s\n", name );
+      port_p->sDeviceName   = strdup( name );
+      port_p->deviceType    = SERIAL_NS16550;
+      #if 1
+        port_p->pDeviceFns    = &ns16550_fns_polled;
+      #else
+        port_p->pDeviceFns    = &ns16550_fns;
+      #endif
+
+      port_p->deviceProbe   = NULL;
+      port_p->pDeviceFlow   = NULL;
+      port_p->ulMargin      = 16;
+      port_p->ulHysteresis  = 8;
+      port_p->pDeviceParams = (void *) 9600;
+      port_p->ulCtrlPort1   = conf[b].base + (p * 0x0200);
+      port_p->ulCtrlPort2   = 0;                   /* NA */
+      port_p->ulDataPort    = 0;                   /* NA */
+      port_p->getRegister   = xr17d15x_get_register;
+      port_p->setRegister   = xr17d15x_set_register;
+      port_p->getData       = NULL;                /* NA */
+      port_p->setData       = NULL;                /* NA */
+      port_p->ulClock       = EXAR_CLOCK_RATE;
+      port_p->ulIntVector   = conf[b].irq;
+
+      port_p++;
+    }  /* end ports */
+  }    /* end boards */
+
+  /*
+   *  Register the devices
+   */
+  if ( boards )
+    console_register_devices( ports, total_ports );
+
+  return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/exar17d15x.h b/c/src/lib/libbsp/i386/pc386/console/exar17d15x.h
new file mode 100644
index 0000000..40922e9
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/exar17d15x.h
@@ -0,0 +1,54 @@
+/**
+ * @file bsp/exar17d15x.h
+ *
+ *  This file provides the interface to the Exar Multiport
+ *  PCI UART controller.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef _BSP_EXAR17D15X__h
+#define _BSP_EXAR17D15X__h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *  This macro defines the standard device driver table entry for
+ *  a console device driver.
+ */
+#define EXAR17D15X_DRIVER_TABLE_ENTRY \
+  { exar17d15x_initialize, NULL, NULL, NULL, NULL, NULL }
+
+/**
+ *  @brief Exar 17D15x Initialization Entry Point
+ *
+ *  This method initializes the Exar XR17D15x device driver.
+ *
+ *  @param[in] major is the device driver major number
+ *  @param[in] minor is the device driver minor number
+ *  @param[in] arg is the parameters to this call
+ *
+ *  @return This method returns RTEMS_SUCCESSFUL when
+ *          the device driver is successfully initialized.
+ */
+rtems_device_driver exar17d15x_initialize(
+  rtems_device_major_number  major,
+  rtems_device_minor_number  minor,
+  void                      *arg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */
diff --git a/c/src/lib/libbsp/i386/pc386/console/rtd316.c b/c/src/lib/libbsp/i386/pc386/console/rtd316.c
new file mode 100644
index 0000000..4abffb7
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/rtd316.c
@@ -0,0 +1,108 @@
+/**
+ *  @file
+ *
+ *  @brief Driver for RTD316 ISA SCC Board
+ *
+ *  The RTD316 has a single Z85C30.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#include <bsp.h>
+#include <termios.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <rtems/termiostypes.h>
+#include <libchip/serial.h>
+#include <libchip/z85c30.h>
+#include <rtems/bspIo.h>
+#include <bsp/rtd316.h>
+#include <rtems/score/i386.h>
+
+#define RTD_CLOCK_RATE  (460800 * 32)
+
+uint8_t rtd316_com_get_register(uint32_t addr, uint8_t reg)
+{
+  register uint8_t val = 0;
+
+  outport_byte( addr, reg );
+  /* It appears the no delay is needed between the accesses. */
+  inport_byte( addr, val );
+
+  return val;
+}
+
+void rtd316_com_set_register(uint32_t addr,uint8_t reg, uint8_t val)
+{
+  outport_byte( addr, reg );
+  /* It appears the no delay is needed between the accesses. */
+  outport_byte( addr, val );
+}
+
+rtems_device_driver rtd316_initialize(
+  rtems_device_major_number  major,
+  rtems_device_minor_number  minor_arg,
+  void                      *arg
+)
+{
+  int           p;
+  console_tbl  *ports;
+  console_tbl  *port_p;
+
+  /*
+   *  Now allocate array of device structures and fill them in
+   */
+  ports = calloc( 2, sizeof( console_tbl ) );
+  port_p = ports;
+
+  for ( p=0 ; p<2 ; p++ ) {
+    char name[32];
+    sprintf( name, "/dev/rtd316_1_%d", p );
+    printk("Found %s\n", name );
+    port_p->sDeviceName   = strdup( name );
+    port_p->deviceType    = SERIAL_Z85C30;
+    #if 0
+      port_p->pDeviceFns  = &z85c30_fns_polled;
+    #else
+      port_p->pDeviceFns  = &z85c30_fns;
+    #endif
+
+    port_p->deviceProbe   = NULL;
+    port_p->pDeviceFlow   = NULL;
+    port_p->ulMargin      = 16;
+    port_p->ulHysteresis  = 8;
+    port_p->pDeviceParams = (void *) 9600;
+    port_p->getRegister   = rtd316_com_get_register;
+    port_p->setRegister   = rtd316_com_set_register;
+    port_p->getData       = NULL;
+    port_p->setData       = NULL;
+    port_p->ulClock       = RTD_CLOCK_RATE;
+    port_p->ulIntVector   = 9;
+
+    if ( p==0 ) {
+      port_p->ulDataPort    = 0;
+      port_p->ulCtrlPort1   = 0x340;
+      port_p->ulCtrlPort2   = 0x341;
+    } else {
+      port_p->ulDataPort    = 1;
+      port_p->ulCtrlPort1   = 0x342;
+      port_p->ulCtrlPort2   = 0x343;
+    }
+    port_p++;
+  }  /* end ports */
+
+  /*
+   *  Register the devices
+   */
+  console_register_devices( ports, 2 );
+
+  return RTEMS_SUCCESSFUL;
+}
diff --git a/c/src/lib/libbsp/i386/pc386/console/rtd316.h b/c/src/lib/libbsp/i386/pc386/console/rtd316.h
new file mode 100644
index 0000000..a88d001
--- /dev/null
+++ b/c/src/lib/libbsp/i386/pc386/console/rtd316.h
@@ -0,0 +1,56 @@
+/**
+ *  @file bsp/rtd316.h
+ *
+ *  @brief RTD316 Driver Interface Definition
+ *
+ *  This file provides the interface to the RTD316 Dual
+ *  serial port utility module.
+ */
+
+/*
+ *  COPYRIGHT (c) 1989-2012.
+ *  On-Line Applications Research Corporation (OAR).
+ *
+ *  The license and distribution terms for this file may be
+ *  found in the file LICENSE in this distribution or at
+ *  http://www.rtems.com/license/LICENSE.
+ */
+
+#ifndef _BSP_RTD_316_h
+#define _BSP_RTD_316_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ *  This macro defines the standard device driver table entry for
+ *  a console device driver.
+ */
+#define RTD316_DRIVER_TABLE_ENTRY \
+  { rtd316_initialize, NULL, NULL, NULL, NULL, NULL }
+
+/**
+ *  @brief RTD316 Initialization Entry Point
+ *
+ *  This method initializes the RTD316 device driver.
+ *
+ *  @param[in] major is the device driver major number
+ *  @param[in] minor is the device driver minor number
+ *  @param[in] arg is the parameters to this call
+ *
+ *  @return This method returns RTEMS_SUCCESSFUL when
+ *          the device driver is successfully initialized.
+ */
+rtems_device_driver rtd316_initialize(
+  rtems_device_major_number  major,
+  rtems_device_minor_number  minor,
+  void                      *arg
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+/* end of include file */




More information about the vc mailing list