Lines Matching +full:dld +full:- +full:gpios

1 // SPDX-License-Identifier: GPL-2.0
3 * Probe module for 8250/16550-type Exar chips PCI serial ports.
114 #define UART_EXAR_TXTRG 0x0a /* Tx FIFO trigger level write-only */
115 #define UART_EXAR_RXTRG 0x0b /* Rx FIFO trigger level write-only */
133 #define UART_EXAR_DLD_485_POLARITY 0x80 /* RS-485 Enable Signal Polarity */
150 * ---- ---- --------
154 * 3 - <reserved>
158 * 7 - <reserved>
161 * 10 - Red LED
162 * 11..15 - <unused>
239 * struct exar8250_board - board information
242 * @setup: quirk run at ->probe() stage for each port
243 * @exit: quirk run at ->remove() stage
265 writeb(value, priv->virt + reg); in exar_write_reg()
270 return readb(priv->virt + reg); in exar_read_reg()
275 struct exar8250 *priv = eeprom->data; in exar_eeprom_93cx6_reg_read()
279 eeprom->reg_data_out = regb & UART_EXAR_REGB_EEDO; in exar_eeprom_93cx6_reg_read()
284 struct exar8250 *priv = eeprom->data; in exar_eeprom_93cx6_reg_write()
287 if (eeprom->reg_data_in) in exar_eeprom_93cx6_reg_write()
289 if (eeprom->reg_data_clock) in exar_eeprom_93cx6_reg_write()
291 if (eeprom->reg_chip_select) in exar_eeprom_93cx6_reg_write()
299 priv->eeprom.data = priv; in exar_eeprom_init()
300 priv->eeprom.register_read = exar_eeprom_93cx6_reg_read; in exar_eeprom_init()
301 priv->eeprom.register_write = exar_eeprom_93cx6_reg_write; in exar_eeprom_init()
302 priv->eeprom.width = PCI_EEPROM_WIDTH_93C46; in exar_eeprom_init()
303 priv->eeprom.quirks |= PCI_EEPROM_QUIRK_EXTRA_READ_CYCLE; in exar_eeprom_init()
307 * exar_mpio_config_output() - Configure an Exar MPIO as an output
332 mpio_offset = mpio_num - 8; in exar_mpio_config_output()
334 return -EINVAL; in exar_mpio_config_output()
337 // Disable MPIO pin tri-state in exar_mpio_config_output()
350 * _exar_mpio_set() - Set an Exar MPIO output high or low
372 mpio_offset = mpio_num - 8; in _exar_mpio_set()
374 return -EINVAL; in _exar_mpio_set()
400 bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); in generic_rs485_config()
401 u8 __iomem *p = port->membase; in generic_rs485_config()
434 * XR17V35x UARTs have an extra fractional divisor register (DLD)
435 * Calculate divisor with extra 4-bit fractional portion
442 quot_16 = DIV_ROUND_CLOSEST(p->uartclk, baud); in xr17v35x_get_divisor()
453 /* Preserve bits not related to baudrate; DLD[7:4]. */ in xr17v35x_set_divisor()
483 struct tty_port *tport = &port->state->port; in exar_shutdown()
494 } while (!kfifo_is_empty(&tport->xmit_fifo) && in exar_shutdown()
504 const struct exar8250_board *board = priv->board; in default_setup()
508 err = serial8250_pci_setup_port(pcidev, port, 0, offset, board->reg_shift); in default_setup()
513 * XR17V35x UARTs have an extra divisor register, DLD that gets enabled in default_setup()
519 status = readb(port->port.membase + UART_EXAR_DVID); in default_setup()
521 port->port.type = PORT_XR17V35X; in default_setup()
523 port->port.get_divisor = xr17v35x_get_divisor; in default_setup()
524 port->port.set_divisor = xr17v35x_set_divisor; in default_setup()
526 port->port.startup = xr17v35x_startup; in default_setup()
528 port->port.type = PORT_XR17D15X; in default_setup()
531 port->port.pm = exar_pm; in default_setup()
532 port->port.shutdown = exar_shutdown; in default_setup()
546 port->port.uartclk = baud * 16; in pci_fastcom335_setup()
552 p = port->port.membase; in pci_fastcom335_setup()
566 switch (pcidev->device) { in pci_fastcom335_setup()
590 * cti_tristate_disable() - Disable RS485 transciever tristate
595 * the RS422/RS485 transceiver does not drive a multi-drop RS485 bus when it is
599 * Some Exar UARTs have an auto-tristate feature while others require setting
616 * cti_plx_int_enable() - Enable UART interrupts to PLX bridge
620 * interrupts from the UART to the PLX PCI->PCIe bridge.
636 * cti_read_osc_freq() - Read the UART oscillator frequency from EEPROM
650 eeprom_93cx6_multiread(&priv->eeprom, eeprom_offset, ee_words, ARRAY_SIZE(ee_words)); in cti_read_osc_freq()
654 return -EIO; in cti_read_osc_freq()
660 * cti_get_port_type_xr17c15x_xr17v25x() - Get port type of xr17c15x/xr17v25x
673 switch (pcidev->subsystem_device) { in cti_get_port_type_xr17c15x_xr17v25x()
730 dev_err(&pcidev->dev, "unknown/unsupported device\n"); in cti_get_port_type_xr17c15x_xr17v25x()
736 * cti_get_port_type_fpga() - Get the port type of a CTI FPGA card
749 switch (pcidev->device) { in cti_get_port_type_fpga()
755 dev_err(&pcidev->dev, "unknown/unsupported device\n"); in cti_get_port_type_fpga()
761 * cti_get_port_type_xr17v35x() - Read port type from the EEPROM
780 eeprom_93cx6_read(&priv->eeprom, offset, &port_flags); in cti_get_port_type_xr17v35x()
793 dev_warn(&pcidev->dev, "failed to get port %d type from EEPROM\n", port_num); in cti_get_port_type_xr17v35x()
802 struct exar8250 *priv = (struct exar8250 *)port->private_data; in cti_rs485_config_mpio_tristate()
809 // Disable power-on RS485 tri-state via MPIO in cti_rs485_config_mpio_tristate()
810 return cti_tristate_disable(priv, port->port_id); in cti_rs485_config_mpio_tristate()
819 dev_warn(&pcidev->dev, "failed to read OSC freq from EEPROM, using default\n"); in cti_board_init_osc_freq()
823 priv->osc_freq = osc_freq; in cti_board_init_osc_freq()
833 port->port.port_id = idx; in cti_port_setup_common()
834 port->port.uartclk = priv->osc_freq; in cti_port_setup_common()
840 port->port.private_data = (void *)priv; in cti_port_setup_common()
841 port->port.pm = exar_pm; in cti_port_setup_common()
842 port->port.shutdown = exar_shutdown; in cti_port_setup_common()
853 priv->osc_freq = CTI_DEFAULT_FPGA_OSC_FREQ; in cti_board_init_fpga()
890 port->port.type = PORT_XR17D15X; in cti_port_setup_fpga()
892 port->port.get_divisor = xr17v35x_get_divisor; in cti_port_setup_fpga()
893 port->port.set_divisor = xr17v35x_set_divisor; in cti_port_setup_fpga()
894 port->port.startup = xr17v35x_startup; in cti_port_setup_fpga()
897 port->port.rs485_config = generic_rs485_config; in cti_port_setup_fpga()
898 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_fpga()
907 priv->osc_freq = CTI_DEFAULT_PCIE_OSC_FREQ; in cti_board_init_xr17v35x()
925 port->port.type = PORT_XR17V35X; in cti_port_setup_xr17v35x()
927 port->port.get_divisor = xr17v35x_get_divisor; in cti_port_setup_xr17v35x()
928 port->port.set_divisor = xr17v35x_set_divisor; in cti_port_setup_xr17v35x()
929 port->port.startup = xr17v35x_startup; in cti_port_setup_xr17v35x()
934 port->port.rs485_config = cti_rs485_config_mpio_tristate; in cti_port_setup_xr17v35x()
935 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17v35x()
940 port->port.rs485_config = generic_rs485_config; in cti_port_setup_xr17v35x()
941 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17v35x()
964 switch (pcidev->subsystem_device) { in cti_board_init_xr17v25x()
990 port->port.type = PORT_XR17D15X; in cti_port_setup_xr17v25x()
993 port->port.get_divisor = xr17v35x_get_divisor; in cti_port_setup_xr17v25x()
994 port->port.set_divisor = xr17v35x_set_divisor; in cti_port_setup_xr17v25x()
995 port->port.startup = xr17v35x_startup; in cti_port_setup_xr17v25x()
998 switch (pcidev->subsystem_device) { in cti_port_setup_xr17v25x()
999 // These cards support power on 485 tri-state via MPIO in cti_port_setup_xr17v25x()
1011 port->port.rs485_config = cti_rs485_config_mpio_tristate; in cti_port_setup_xr17v25x()
1013 // Otherwise auto or no power on 485 tri-state support in cti_port_setup_xr17v25x()
1015 port->port.rs485_config = generic_rs485_config; in cti_port_setup_xr17v25x()
1019 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17v25x()
1039 switch (pcidev->subsystem_device) { in cti_board_init_xr17c15x()
1067 port->port.type = PORT_XR17D15X; in cti_port_setup_xr17c15x()
1070 switch (pcidev->subsystem_device) { in cti_port_setup_xr17c15x()
1071 // These cards support power on 485 tri-state via MPIO in cti_port_setup_xr17c15x()
1083 port->port.rs485_config = cti_rs485_config_mpio_tristate; in cti_port_setup_xr17c15x()
1085 // Otherwise auto or no power on 485 tri-state support in cti_port_setup_xr17c15x()
1087 port->port.rs485_config = generic_rs485_config; in cti_port_setup_xr17c15x()
1091 port->port.rs485_supported = generic_rs485_supported; in cti_port_setup_xr17c15x()
1104 port->port.uartclk = baud * 16; in pci_xr17c154_setup()
1112 * devices will export them as GPIOs, so we pre-configure them safely in setup_gpio()
1117 if ((pcidev->vendor == PCI_VENDOR_ID_EXAR) && in setup_gpio()
1118 (pcidev->subsystem_vendor != PCI_VENDOR_ID_SEALEVEL)) { in setup_gpio()
1149 pdev->dev.parent = &pcidev->dev; in __xr17v35x_register_gpio()
1150 device_set_node(&pdev->dev, dev_fwnode(&pcidev->dev)); in __xr17v35x_register_gpio()
1152 if (device_add_software_node(&pdev->dev, node) < 0 || in __xr17v35x_register_gpio()
1163 device_remove_software_node(&pdev->dev); in __xr17v35x_unregister_gpio()
1168 PROPERTY_ENTRY_U32("exar,first-pin", 0),
1179 if (pcidev->vendor == PCI_VENDOR_ID_EXAR) in xr17v35x_register_gpio()
1180 port->port.private_data = in xr17v35x_register_gpio()
1188 if (!port->port.private_data) in xr17v35x_unregister_gpio()
1191 __xr17v35x_unregister_gpio(port->port.private_data); in xr17v35x_unregister_gpio()
1192 port->port.private_data = NULL; in xr17v35x_unregister_gpio()
1198 u8 __iomem *p = port->membase; in sealevel_rs485_config()
1201 u8 dld; in sealevel_rs485_config() local
1208 if (!(rs485->flags & SER_RS485_ENABLED)) in sealevel_rs485_config()
1218 /* Set MCR to use DTR as Auto-RS485 Enable signal */ in sealevel_rs485_config()
1221 /* Set LCR[7]=1 to enable access to DLD register */ in sealevel_rs485_config()
1224 /* Set DLD[7]=1 for inverted RS485 Enable logic */ in sealevel_rs485_config()
1225 dld = readb(p + UART_EXAR_DLD); in sealevel_rs485_config()
1226 dld |= UART_EXAR_DLD_485_POLARITY; in sealevel_rs485_config()
1227 writeb(dld, p + UART_EXAR_DLD); in sealevel_rs485_config()
1244 bool is_rs485 = !!(rs485->flags & SER_RS485_ENABLED); in iot2040_rs485_config()
1245 u8 __iomem *p = port->membase; in iot2040_rs485_config()
1250 if (rs485->flags & SER_RS485_RX_DURING_TX) in iot2040_rs485_config()
1255 if (rs485->flags & SER_RS485_TERMINATE_BUS) in iot2040_rs485_config()
1261 if (port->line == 3) { in iot2040_rs485_config()
1280 PROPERTY_ENTRY_U32("exar,first-pin", 10),
1292 u8 __iomem *p = port->port.membase; in iot2040_register_gpio()
1299 port->port.private_data = in iot2040_register_gpio()
1333 return dmi_match->driver_data; in exar_get_platform()
1348 port->port.uartclk = baud * 16; in pci_xr17v35x_setup()
1349 port->port.rs485_config = platform->rs485_config; in pci_xr17v35x_setup()
1350 port->port.rs485_supported = *(platform->rs485_supported); in pci_xr17v35x_setup()
1352 if (pcidev->subsystem_vendor == PCI_VENDOR_ID_SEALEVEL) in pci_xr17v35x_setup()
1353 port->port.rs485_config = sealevel_rs485_config; in pci_xr17v35x_setup()
1360 port->port.uartclk /= 2; in pci_xr17v35x_setup()
1366 p = port->port.membase; in pci_xr17v35x_setup()
1377 ret = platform->register_gpio(pcidev, port); in pci_xr17v35x_setup()
1387 struct uart_8250_port *port = serial8250_get_port(priv->line[0]); in pci_xr17v35x_exit()
1389 platform->unregister_gpio(port); in pci_xr17v35x_exit()
1395 readb(priv->virt + UART_EXAR_INT0); in exar_misc_clear()
1398 if (priv->board->num_ports > 8) in exar_misc_clear()
1399 readb(priv->virt + 0x2000 + UART_EXAR_INT0); in exar_misc_clear()
1420 if (pcidev->vendor == PCI_VENDOR_ID_ACCESSIO) in exar_get_nr_ports()
1421 return BIT(((pcidev->device & 0x38) >> 3) - 1); in exar_get_nr_ports()
1424 if (board->num_ports > 0) in exar_get_nr_ports()
1425 return board->num_ports; in exar_get_nr_ports()
1428 if (pcidev->vendor == PCI_VENDOR_ID_EXAR) in exar_get_nr_ports()
1429 return pcidev->device & 0x0f; in exar_get_nr_ports()
1432 if (pcidev->vendor == PCI_VENDOR_ID_CONNECT_TECH) { in exar_get_nr_ports()
1433 switch (pcidev->device) { in exar_get_nr_ports()
1456 board = (struct exar8250_board *)ent->driver_data; in exar_pci_probe()
1458 return -EINVAL; in exar_pci_probe()
1464 maxnr = pci_resource_len(pcidev, bar) >> (board->reg_shift + 3); in exar_pci_probe()
1468 return dev_err_probe(&pcidev->dev, -ENODEV, "failed to get number of ports\n"); in exar_pci_probe()
1470 priv = devm_kzalloc(&pcidev->dev, struct_size(priv, line, nr_ports), GFP_KERNEL); in exar_pci_probe()
1472 return -ENOMEM; in exar_pci_probe()
1474 priv->board = board; in exar_pci_probe()
1475 priv->virt = pcim_iomap(pcidev, bar, 0); in exar_pci_probe()
1476 if (!priv->virt) in exar_pci_probe()
1477 return -ENOMEM; in exar_pci_probe()
1488 uart.port.dev = &pcidev->dev; in exar_pci_probe()
1493 rc = devm_request_irq(&pcidev->dev, uart.port.irq, exar_misc_handler, in exar_pci_probe()
1501 rc = board->setup(priv, pcidev, &uart, i); in exar_pci_probe()
1503 dev_err_probe(&pcidev->dev, rc, "Failed to setup port %u\n", i); in exar_pci_probe()
1507 dev_dbg(&pcidev->dev, "Setup PCI port: port %lx, irq %d, type %d\n", in exar_pci_probe()
1510 priv->line[i] = serial8250_register_8250_port(&uart); in exar_pci_probe()
1511 if (priv->line[i] < 0) { in exar_pci_probe()
1512 dev_err_probe(&pcidev->dev, priv->line[i], in exar_pci_probe()
1518 priv->nr = i; in exar_pci_probe()
1528 for (i = 0; i < priv->nr; i++) in exar_pci_remove()
1529 serial8250_unregister_port(priv->line[i]); in exar_pci_remove()
1532 if (priv->board->exit) in exar_pci_remove()
1533 priv->board->exit(pcidev); in exar_pci_remove()
1541 for (i = 0; i < priv->nr; i++) in exar_suspend()
1542 if (priv->line[i] >= 0) in exar_suspend()
1543 serial8250_suspend_port(priv->line[i]); in exar_suspend()
1555 for (i = 0; i < priv->nr; i++) in exar_resume()
1556 if (priv->line[i] >= 0) in exar_resume()
1557 serial8250_resume_port(priv->line[i]); in exar_resume()
1703 /* USRobotics USR298x-OEM PCI Modems */