Lines Matching +full:fpga +full:- +full:slave +full:- +full:serial
1 // SPDX-License-Identifier: GPL-2.0
3 * Probe module for 8250/16550-type Exar chips PCI serial ports.
5 * Based on drivers/tty/serial/8250/8250_pci.c,
111 #define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */
112 #define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */
130 #define UART_EXAR_DLD_485_POLARITY 0x80 /* RS-485 Enable Signal Polarity */
149 * ---- ---- --------
153 * 3 - <reserved>
157 * 7 - <reserved>
160 * 10 - Red LED
161 * 11..15 - <unused>
204 * CTI Serial port line types. These match the values stored in the first
237 * struct exar8250_board - board information
238 * @num_ports: number of serial ports
240 * @setup: quirk run at ->probe() stage for each port
241 * @exit: quirk run at ->remove() stage
262 writeb(value, priv->virt + reg); in exar_write_reg()
267 return readb(priv->virt + reg); in exar_read_reg()
322 * exar_ee_read() - Read a word from the EEPROM
344 for (i = UART_EXAR_REGB_EE_ADDR_SIZE - 1; i >= 0; i--) in exar_ee_read()
348 for (i = UART_EXAR_REGB_EE_DATA_SIZE; i >= 0; i--) { in exar_ee_read()
359 * exar_mpio_config_output() - Configure an Exar MPIO as an output
384 mpio_offset = mpio_num - 8; in exar_mpio_config_output()
386 return -EINVAL; in exar_mpio_config_output()
389 // Disable MPIO pin tri-state in exar_mpio_config_output()
402 * _exar_mpio_set() - Set an Exar MPIO output high or low
424 mpio_offset = mpio_num - 8; in _exar_mpio_set()
426 return -EINVAL; in _exar_mpio_set()
452 bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); in generic_rs485_config()
453 u8 __iomem *p = port->membase; in generic_rs485_config()
487 * Calculate divisor with extra 4-bit fractional portion
494 quot_16 = DIV_ROUND_CLOSEST(p->uartclk, baud); in xr17v35x_get_divisor()
535 struct tty_port *tport = &port->state->port; in exar_shutdown()
546 } while (!kfifo_is_empty(&tport->xmit_fifo) && in exar_shutdown()
556 const struct exar8250_board *board = priv->board; in default_setup()
560 err = serial8250_pci_setup_port(pcidev, port, 0, offset, board->reg_shift); in default_setup()
571 status = readb(port->port.membase + UART_EXAR_DVID); in default_setup()
573 port->port.type = PORT_XR17V35X; in default_setup()
575 port->port.get_divisor = xr17v35x_get_divisor; in default_setup()
576 port->port.set_divisor = xr17v35x_set_divisor; in default_setup()
578 port->port.startup = xr17v35x_startup; in default_setup()
580 port->port.type = PORT_XR17D15X; in default_setup()
583 port->port.pm = exar_pm; in default_setup()
584 port->port.shutdown = exar_shutdown; in default_setup()
598 port->port.uartclk = baud * 16; in pci_fastcom335_setup()
604 p = port->port.membase; in pci_fastcom335_setup()
618 switch (pcidev->device) { in pci_fastcom335_setup()
642 * cti_tristate_disable() - Disable RS485 transciever tristate
647 * the RS422/RS485 transceiver does not drive a multi-drop RS485 bus when it is
651 * Some Exar UARTs have an auto-tristate feature while others require setting
668 * cti_plx_int_enable() - Enable UART interrupts to PLX bridge
672 * interrupts from the UART to the PLX PCI->PCIe bridge.
688 * cti_read_osc_freq() - Read the UART oscillator frequency from EEPROM
692 * CTI XR17x15X and XR17V25X cards have the serial boards oscillator frequency
693 * stored in the EEPROM. FPGA and XR17V35X based cards use the PCI/PCIe clock.
705 return -EIO; in cti_read_osc_freq()
709 return -EIO; in cti_read_osc_freq()
716 * cti_get_port_type_xr17c15x_xr17v25x() - Get port type of xr17c15x/xr17v25x
729 switch (pcidev->subsystem_device) { in cti_get_port_type_xr17c15x_xr17v25x()
786 dev_err(&pcidev->dev, "unknown/unsupported device\n"); in cti_get_port_type_xr17c15x_xr17v25x()
792 * cti_get_port_type_fpga() - Get the port type of a CTI FPGA card
797 * FPGA based cards port types are based on PCI IDs.
805 switch (pcidev->device) { in cti_get_port_type_fpga()
811 dev_err(&pcidev->dev, "unknown/unsupported device\n"); in cti_get_port_type_fpga()
817 * cti_get_port_type_xr17v35x() - Read port type from the EEPROM
849 dev_warn(&pcidev->dev, "failed to get port %d type from EEPROM\n", port_num); in cti_get_port_type_xr17v35x()
858 struct exar8250 *priv = (struct exar8250 *)port->private_data; in cti_rs485_config_mpio_tristate()
865 // Disable power-on RS485 tri-state via MPIO in cti_rs485_config_mpio_tristate()
866 return cti_tristate_disable(priv, port->port_id); in cti_rs485_config_mpio_tristate()
875 dev_warn(&pcidev->dev, "failed to read OSC freq from EEPROM, using default\n"); in cti_board_init_osc_freq()
879 priv->osc_freq = osc_freq; in cti_board_init_osc_freq()
889 port->port.port_id = idx; in cti_port_setup_common()
890 port->port.uartclk = priv->osc_freq; in cti_port_setup_common()
896 port->port.private_data = (void *)priv; in cti_port_setup_common()
897 port->port.pm = exar_pm; in cti_port_setup_common()
898 port->port.shutdown = exar_shutdown; in cti_port_setup_common()
908 // FPGA OSC is fixed to the 33MHz PCI clock in cti_board_init_fpga()
909 priv->osc_freq = CTI_DEFAULT_FPGA_OSC_FREQ; in cti_board_init_fpga()
944 // FPGA shares port offsets with XR17C15X in cti_port_setup_fpga()
946 port->port.type = PORT_XR17D15X; in cti_port_setup_fpga()
948 port->port.get_divisor = xr17v35x_get_divisor; in cti_port_setup_fpga()
949 port->port.set_divisor = xr17v35x_set_divisor; in cti_port_setup_fpga()
950 port->port.startup = xr17v35x_startup; in cti_port_setup_fpga()
953 port->port.rs485_config = generic_rs485_config; in cti_port_setup_fpga()
954 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_fpga()
963 priv->osc_freq = CTI_DEFAULT_PCIE_OSC_FREQ; in cti_board_init_xr17v35x()
981 port->port.type = PORT_XR17V35X; in cti_port_setup_xr17v35x()
983 port->port.get_divisor = xr17v35x_get_divisor; in cti_port_setup_xr17v35x()
984 port->port.set_divisor = xr17v35x_set_divisor; in cti_port_setup_xr17v35x()
985 port->port.startup = xr17v35x_startup; in cti_port_setup_xr17v35x()
990 port->port.rs485_config = cti_rs485_config_mpio_tristate; in cti_port_setup_xr17v35x()
991 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17v35x()
996 port->port.rs485_config = generic_rs485_config; in cti_port_setup_xr17v35x()
997 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17v35x()
1020 switch (pcidev->subsystem_device) { in cti_board_init_xr17v25x()
1046 port->port.type = PORT_XR17D15X; in cti_port_setup_xr17v25x()
1049 port->port.get_divisor = xr17v35x_get_divisor; in cti_port_setup_xr17v25x()
1050 port->port.set_divisor = xr17v35x_set_divisor; in cti_port_setup_xr17v25x()
1051 port->port.startup = xr17v35x_startup; in cti_port_setup_xr17v25x()
1054 switch (pcidev->subsystem_device) { in cti_port_setup_xr17v25x()
1055 // These cards support power on 485 tri-state via MPIO in cti_port_setup_xr17v25x()
1067 port->port.rs485_config = cti_rs485_config_mpio_tristate; in cti_port_setup_xr17v25x()
1069 // Otherwise auto or no power on 485 tri-state support in cti_port_setup_xr17v25x()
1071 port->port.rs485_config = generic_rs485_config; in cti_port_setup_xr17v25x()
1075 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17v25x()
1095 switch (pcidev->subsystem_device) { in cti_board_init_xr17c15x()
1123 port->port.type = PORT_XR17D15X; in cti_port_setup_xr17c15x()
1126 switch (pcidev->subsystem_device) { in cti_port_setup_xr17c15x()
1127 // These cards support power on 485 tri-state via MPIO in cti_port_setup_xr17c15x()
1139 port->port.rs485_config = cti_rs485_config_mpio_tristate; in cti_port_setup_xr17c15x()
1141 // Otherwise auto or no power on 485 tri-state support in cti_port_setup_xr17c15x()
1143 port->port.rs485_config = generic_rs485_config; in cti_port_setup_xr17c15x()
1147 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17c15x()
1160 port->port.uartclk = baud * 16; in pci_xr17c154_setup()
1168 * devices will export them as GPIOs, so we pre-configure them safely in setup_gpio()
1173 if ((pcidev->vendor == PCI_VENDOR_ID_EXAR) && in setup_gpio()
1174 (pcidev->subsystem_vendor != PCI_VENDOR_ID_SEALEVEL)) { in setup_gpio()
1205 pdev->dev.parent = &pcidev->dev; in __xr17v35x_register_gpio()
1206 device_set_node(&pdev->dev, dev_fwnode(&pcidev->dev)); in __xr17v35x_register_gpio()
1208 if (device_add_software_node(&pdev->dev, node) < 0 || in __xr17v35x_register_gpio()
1219 device_remove_software_node(&pdev->dev); in __xr17v35x_unregister_gpio()
1224 PROPERTY_ENTRY_U32("exar,first-pin", 0),
1235 if (pcidev->vendor == PCI_VENDOR_ID_EXAR) in xr17v35x_register_gpio()
1236 port->port.private_data = in xr17v35x_register_gpio()
1244 if (!port->port.private_data) in xr17v35x_unregister_gpio()
1247 __xr17v35x_unregister_gpio(port->port.private_data); in xr17v35x_unregister_gpio()
1248 port->port.private_data = NULL; in xr17v35x_unregister_gpio()
1254 u8 __iomem *p = port->membase; in sealevel_rs485_config()
1264 if (!(rs485->flags & SER_RS485_ENABLED)) in sealevel_rs485_config()
1274 /* Set MCR to use DTR as Auto-RS485 Enable signal */ in sealevel_rs485_config()
1300 bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); in iot2040_rs485_config()
1301 u8 __iomem *p = port->membase; in iot2040_rs485_config()
1306 if (rs485->flags & SER_RS485_RX_DURING_TX) in iot2040_rs485_config()
1311 if (rs485->flags & SER_RS485_TERMINATE_BUS) in iot2040_rs485_config()
1317 if (port->line == 3) { in iot2040_rs485_config()
1336 PROPERTY_ENTRY_U32("exar,first-pin", 10),
1348 u8 __iomem *p = port->port.membase; in iot2040_register_gpio()
1355 port->port.private_data = in iot2040_register_gpio()
1389 return dmi_match->driver_data; in exar_get_platform()
1404 port->port.uartclk = baud * 16; in pci_xr17v35x_setup()
1405 port->port.rs485_config = platform->rs485_config; in pci_xr17v35x_setup()
1406 port->port.rs485_supported = *(platform->rs485_supported); in pci_xr17v35x_setup()
1408 if (pcidev->subsystem_vendor == PCI_VENDOR_ID_SEALEVEL) in pci_xr17v35x_setup()
1409 port->port.rs485_config = sealevel_rs485_config; in pci_xr17v35x_setup()
1416 port->port.uartclk /= 2; in pci_xr17v35x_setup()
1422 p = port->port.membase; in pci_xr17v35x_setup()
1433 ret = platform->register_gpio(pcidev, port); in pci_xr17v35x_setup()
1443 struct uart_8250_port *port = serial8250_get_port(priv->line[0]); in pci_xr17v35x_exit()
1445 platform->unregister_gpio(port); in pci_xr17v35x_exit()
1451 readb(priv->virt + UART_EXAR_INT0); in exar_misc_clear()
1453 /* Clear INT0 for Expansion Interface slave ports, too */ in exar_misc_clear()
1454 if (priv->board->num_ports > 8) in exar_misc_clear()
1455 readb(priv->virt + 0x2000 + UART_EXAR_INT0); in exar_misc_clear()
1476 if (pcidev->vendor == PCI_VENDOR_ID_ACCESSIO) in exar_get_nr_ports()
1477 return BIT(((pcidev->device & 0x38) >> 3) - 1); in exar_get_nr_ports()
1480 if (board->num_ports > 0) in exar_get_nr_ports()
1481 return board->num_ports; in exar_get_nr_ports()
1484 if (pcidev->vendor == PCI_VENDOR_ID_EXAR) in exar_get_nr_ports()
1485 return pcidev->device & 0x0f; in exar_get_nr_ports()
1487 // Handle CTI FPGA cards in exar_get_nr_ports()
1488 if (pcidev->vendor == PCI_VENDOR_ID_CONNECT_TECH) { in exar_get_nr_ports()
1489 switch (pcidev->device) { in exar_get_nr_ports()
1512 board = (struct exar8250_board *)ent->driver_data; in exar_pci_probe()
1514 return -EINVAL; in exar_pci_probe()
1520 maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3); in exar_pci_probe()
1524 return dev_err_probe(&pcidev->dev, -ENODEV, "failed to get number of ports\n"); in exar_pci_probe()
1526 priv = devm_kzalloc(&pcidev->dev, struct_size(priv, line, nr_ports), GFP_KERNEL); in exar_pci_probe()
1528 return -ENOMEM; in exar_pci_probe()
1530 priv->board = board; in exar_pci_probe()
1531 priv->virt = pcim_iomap(pcidev, bar, 0); in exar_pci_probe()
1532 if (!priv->virt) in exar_pci_probe()
1533 return -ENOMEM; in exar_pci_probe()
1544 uart.port.dev = &pcidev->dev; in exar_pci_probe()
1549 rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler, in exar_pci_probe()
1555 rc = board->setup(priv, pcidev, &uart, i); in exar_pci_probe()
1557 dev_err_probe(&pcidev->dev, rc, "Failed to setup port %u\n", i); in exar_pci_probe()
1561 dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", in exar_pci_probe()
1564 priv->line[i] = serial8250_register_8250_port(&uart); in exar_pci_probe()
1565 if (priv->line[i] < 0) { in exar_pci_probe()
1566 dev_err_probe(&pcidev->dev, priv->line[i], in exar_pci_probe()
1567 "Couldn't register serial port %lx, type %d, irq %d\n", in exar_pci_probe()
1572 priv->nr = i; in exar_pci_probe()
1582 for (i = 0; i < priv->nr; i++) in exar_pci_remove()
1583 serial8250_unregister_port(priv->line[i]); in exar_pci_remove()
1586 if (priv->board->exit) in exar_pci_remove()
1587 priv->board->exit(pcidev); in exar_pci_remove()
1595 for (i = 0; i < priv->nr; i++) in exar_suspend()
1596 if (priv->line[i] >= 0) in exar_suspend()
1597 serial8250_suspend_port(priv->line[i]); in exar_suspend()
1609 for (i = 0; i < priv->nr; i++) in exar_resume()
1610 if (priv->line[i] >= 0) in exar_resume()
1611 serial8250_resume_port(priv->line[i]); in exar_resume()
1744 /* Connect Tech cards with Connect Tech vendor/device PCI IDs (FPGA based) */
1751 /* USRobotics USR298x-OEM PCI Modems */
1791 MODULE_DESCRIPTION("Exar Serial Driver");