File indexing completed on 2025-05-11 08:23:40
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 #include <bsp.h>
0039 #include <termios.h>
0040 #include <stdio.h>
0041 #include <stdlib.h>
0042
0043 #include <rtems/termiostypes.h>
0044 #include <libchip/serial.h>
0045 #include <libchip/ns16550.h>
0046 #include <rtems/bspIo.h>
0047 #include <rtems/pci.h>
0048 #include <bsp/exar17d15x.h>
0049 #include "../../shared/dev/serial/legacy-console.h"
0050
0051 #define MAX_BOARDS 4
0052
0053
0054
0055
0056 #define EXAR_CLOCK_RATE (921600*16)
0057
0058
0059
0060
0061 #define PCI_VENDOR_ID_EXAR 0x13A8
0062 #define PCI_VENDOR_ID_EXAR_XR17D158 0x0158
0063 #define PCI_VENDOR_ID_EXAR_XR17D154 0x0154
0064 #define PCI_VENDOR_ID_EXAR_XR17D152 0x0152
0065
0066
0067
0068
0069 typedef struct {
0070 uint16_t vendor;
0071 uint16_t device;
0072 uint8_t ports;
0073 } exar_parts_t;
0074
0075 static exar_parts_t Supported[] = {
0076 { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D158, 8 },
0077 { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D154, 4 },
0078 { PCI_VENDOR_ID_EXAR, PCI_VENDOR_ID_EXAR_XR17D152, 2 },
0079 { 0, 0, 0 }
0080 };
0081
0082
0083
0084
0085 typedef struct {
0086 bool found;
0087 uint32_t base;
0088 uint8_t irq;
0089 uint8_t bus;
0090 uint8_t slot;
0091 uint8_t ports;
0092 } exar17d15x_conf_t;
0093
0094
0095
0096
0097 static uint8_t xr17d15x_get_register(uintptr_t addr, uint8_t i)
0098 {
0099 uint8_t val = 0;
0100 volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
0101
0102 val = *reg;
0103
0104 return val;
0105 }
0106
0107 static void xr17d15x_set_register(uintptr_t addr, uint8_t i, uint8_t val)
0108 {
0109 volatile uint8_t *reg = (volatile uint8_t *)(addr + i);
0110
0111
0112 *reg = val;
0113 }
0114
0115 rtems_device_driver exar17d15x_initialize(
0116 rtems_device_major_number major,
0117 rtems_device_minor_number minor_arg,
0118 void *arg
0119 )
0120 {
0121
0122 exar17d15x_conf_t conf[MAX_BOARDS];
0123 int boards = 0;
0124 int b = 0;
0125 int p;
0126 console_tbl *ports;
0127 console_tbl *port_p;
0128 int pbus;
0129 int pdev;
0130 int pfun;
0131 int status;
0132 int instance;
0133 int i;
0134 int total_ports = 0;
0135
0136 for ( b=0 ; b<MAX_BOARDS ; b++ ) {
0137 conf[b].found = false;
0138 }
0139
0140
0141
0142
0143
0144
0145
0146
0147
0148
0149
0150 for ( instance=0 ; instance < MAX_BOARDS ; instance++ ) {
0151
0152 for ( i=0 ; Supported[i].ports != 0 ; i++ ) {
0153 status = pci_find_device(
0154 Supported[i].vendor,
0155 Supported[i].device,
0156 instance,
0157 &pbus,
0158 &pdev,
0159 &pfun
0160 );
0161 if ( status == PCIB_ERR_SUCCESS ) {
0162 boards++;
0163 conf[instance].found = true;
0164 conf[instance].ports = Supported[i].ports;
0165 total_ports += conf[instance].ports;
0166 break;
0167 }
0168 }
0169
0170 if ( status != PCIB_ERR_SUCCESS )
0171 continue;
0172
0173 pci_read_config_byte(
0174 pbus,
0175 pdev,
0176 pfun,
0177 PCI_INTERRUPT_LINE,
0178 &conf[instance].irq
0179 );
0180 pci_read_config_dword(
0181 pbus,
0182 pdev,
0183 pfun,
0184 PCI_BASE_ADDRESS_0,
0185 &conf[instance].base
0186 );
0187 printk(
0188 "Found Exar 17D15x %d at 0x%08lx IRQ %d with %d ports\n",
0189 instance,
0190 (uintptr_t) conf[instance].base,
0191 conf[instance].irq,
0192 conf[instance].ports
0193 );
0194 }
0195
0196
0197
0198
0199 ports = calloc( total_ports, sizeof( console_tbl ) );
0200 port_p = ports;
0201 for ( b=0 ; b<MAX_BOARDS ; b++ ) {
0202 if ( conf[b].found == false )
0203 continue;
0204 for ( p=0 ; p<conf[b].ports ; p++ ) {
0205 char name[32];
0206
0207 sprintf( name, "/dev/exar17d15x_%d_%d", b, p );
0208
0209 port_p->sDeviceName = strdup( name );
0210 port_p->deviceType = SERIAL_NS16550;
0211 #if 1
0212 port_p->pDeviceFns = &ns16550_fns_polled;
0213 #else
0214 port_p->pDeviceFns = &ns16550_fns;
0215 #endif
0216
0217 port_p->deviceProbe = NULL;
0218 port_p->pDeviceFlow = NULL;
0219 port_p->ulMargin = 16;
0220 port_p->ulHysteresis = 8;
0221 port_p->pDeviceParams = (void *) 9600;
0222 port_p->ulCtrlPort1 = conf[b].base + (p * 0x0200);
0223 port_p->ulCtrlPort2 = 0;
0224 port_p->ulDataPort = 0;
0225 port_p->getRegister = xr17d15x_get_register;
0226 port_p->setRegister = xr17d15x_set_register;
0227 port_p->getData = NULL;
0228 port_p->setData = NULL;
0229 port_p->ulClock = EXAR_CLOCK_RATE;
0230 port_p->ulIntVector = conf[b].irq;
0231
0232 port_p++;
0233 }
0234 }
0235
0236
0237
0238
0239 if ( boards )
0240 console_register_devices( ports, total_ports );
0241
0242 return RTEMS_SUCCESSFUL;
0243 }