aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty/serial/8250
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-17 13:44:26 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-10-17 16:21:59 -0400
commit2c62a3c899805be7f054847d80210183e4a982d9 (patch)
treed68022da0008b52ed195252ff6b1e89828c946c3 /drivers/tty/serial/8250
parent7cb92fd2a0515ea2ae905bf6c90a84aed2b78ffb (diff)
serial: 8250_pci: add support for Fintek 4, 8, and 12 port cards
This adds support for Fintek's 4, 8, and 12 port PCIE serial cards. Thanks to Fintek for the sample devices, and the spec needed in order to implement this. Cc: Amanda Ying <amanda_ying@fintek.com.tw> Cc: Felix Shih <felix_shih@fintek.com.tw> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty/serial/8250')
-rw-r--r--drivers/tty/serial/8250/8250_pci.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 0774c02d6c49..4ea45c15388c 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -1457,6 +1457,71 @@ pci_brcm_trumanage_setup(struct serial_private *priv,
1457 return ret; 1457 return ret;
1458} 1458}
1459 1459
1460static int pci_fintek_setup(struct serial_private *priv,
1461 const struct pciserial_board *board,
1462 struct uart_8250_port *port, int idx)
1463{
1464 struct pci_dev *pdev = priv->dev;
1465 unsigned long base;
1466 unsigned long iobase;
1467 unsigned long ciobase = 0;
1468 u8 config_base;
1469
1470 /*
1471 * We are supposed to be able to read these from the PCI config space,
1472 * but the values there don't seem to match what we need to use, so
1473 * just use these hard-coded values for now, as they are correct.
1474 */
1475 switch (idx) {
1476 case 0: iobase = 0xe000; config_base = 0x40; break;
1477 case 1: iobase = 0xe008; config_base = 0x48; break;
1478 case 2: iobase = 0xe010; config_base = 0x50; break;
1479 case 3: iobase = 0xe018; config_base = 0x58; break;
1480 case 4: iobase = 0xe020; config_base = 0x60; break;
1481 case 5: iobase = 0xe028; config_base = 0x68; break;
1482 case 6: iobase = 0xe030; config_base = 0x70; break;
1483 case 7: iobase = 0xe038; config_base = 0x78; break;
1484 case 8: iobase = 0xe040; config_base = 0x80; break;
1485 case 9: iobase = 0xe048; config_base = 0x88; break;
1486 case 10: iobase = 0xe050; config_base = 0x90; break;
1487 case 11: iobase = 0xe058; config_base = 0x98; break;
1488 default:
1489 /* Unknown number of ports, get out of here */
1490 return -EINVAL;
1491 }
1492
1493 if (idx < 4) {
1494 base = pci_resource_start(priv->dev, 3);
1495 ciobase = (int)(base + (0x8 * idx));
1496 }
1497
1498 dev_dbg(&pdev->dev, "%s: idx=%d iobase=0x%lx ciobase=0x%lx config_base=0x%2x\n",
1499 __func__, idx, iobase, ciobase, config_base);
1500
1501 /* Enable UART I/O port */
1502 pci_write_config_byte(pdev, config_base + 0x00, 0x01);
1503
1504 /* Select 128-byte FIFO and 8x FIFO threshold */
1505 pci_write_config_byte(pdev, config_base + 0x01, 0x33);
1506
1507 /* LSB UART */
1508 pci_write_config_byte(pdev, config_base + 0x04, (u8)(iobase & 0xff));
1509
1510 /* MSB UART */
1511 pci_write_config_byte(pdev, config_base + 0x05, (u8)((iobase & 0xff00) >> 8));
1512
1513 /* irq number, this usually fails, but the spec says to do it anyway. */
1514 pci_write_config_byte(pdev, config_base + 0x06, pdev->irq);
1515
1516 port->port.iotype = UPIO_PORT;
1517 port->port.iobase = iobase;
1518 port->port.mapbase = 0;
1519 port->port.membase = NULL;
1520 port->port.regshift = 0;
1521
1522 return 0;
1523}
1524
1460static int skip_tx_en_setup(struct serial_private *priv, 1525static int skip_tx_en_setup(struct serial_private *priv,
1461 const struct pciserial_board *board, 1526 const struct pciserial_board *board,
1462 struct uart_8250_port *port, int idx) 1527 struct uart_8250_port *port, int idx)
@@ -2380,6 +2445,27 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
2380 .subdevice = PCI_ANY_ID, 2445 .subdevice = PCI_ANY_ID,
2381 .setup = pci_brcm_trumanage_setup, 2446 .setup = pci_brcm_trumanage_setup,
2382 }, 2447 },
2448 {
2449 .vendor = 0x1c29,
2450 .device = 0x1104,
2451 .subvendor = PCI_ANY_ID,
2452 .subdevice = PCI_ANY_ID,
2453 .setup = pci_fintek_setup,
2454 },
2455 {
2456 .vendor = 0x1c29,
2457 .device = 0x1108,
2458 .subvendor = PCI_ANY_ID,
2459 .subdevice = PCI_ANY_ID,
2460 .setup = pci_fintek_setup,
2461 },
2462 {
2463 .vendor = 0x1c29,
2464 .device = 0x1112,
2465 .subvendor = PCI_ANY_ID,
2466 .subdevice = PCI_ANY_ID,
2467 .setup = pci_fintek_setup,
2468 },
2383 2469
2384 /* 2470 /*
2385 * Default "match everything" terminator entry 2471 * Default "match everything" terminator entry
@@ -2578,6 +2664,9 @@ enum pci_board_num_t {
2578 pbn_omegapci, 2664 pbn_omegapci,
2579 pbn_NETMOS9900_2s_115200, 2665 pbn_NETMOS9900_2s_115200,
2580 pbn_brcm_trumanage, 2666 pbn_brcm_trumanage,
2667 pbn_fintek_4,
2668 pbn_fintek_8,
2669 pbn_fintek_12,
2581}; 2670};
2582 2671
2583/* 2672/*
@@ -3335,6 +3424,24 @@ static struct pciserial_board pci_boards[] = {
3335 .reg_shift = 2, 3424 .reg_shift = 2,
3336 .base_baud = 115200, 3425 .base_baud = 115200,
3337 }, 3426 },
3427 [pbn_fintek_4] = {
3428 .num_ports = 4,
3429 .uart_offset = 8,
3430 .base_baud = 115200,
3431 .first_offset = 0x40,
3432 },
3433 [pbn_fintek_8] = {
3434 .num_ports = 8,
3435 .uart_offset = 8,
3436 .base_baud = 115200,
3437 .first_offset = 0x40,
3438 },
3439 [pbn_fintek_12] = {
3440 .num_ports = 12,
3441 .uart_offset = 8,
3442 .base_baud = 115200,
3443 .first_offset = 0x40,
3444 },
3338}; 3445};
3339 3446
3340static const struct pci_device_id blacklist[] = { 3447static const struct pci_device_id blacklist[] = {
@@ -5059,6 +5166,11 @@ static struct pci_device_id serial_pci_tbl[] = {
5059 0, 5166 0,
5060 0, pbn_exar_XR17V358 }, 5167 0, pbn_exar_XR17V358 },
5061 5168
5169 /* Fintek PCI serial cards */
5170 { PCI_DEVICE(0x1c29, 0x1104), .driver_data = pbn_fintek_4 },
5171 { PCI_DEVICE(0x1c29, 0x1108), .driver_data = pbn_fintek_8 },
5172 { PCI_DEVICE(0x1c29, 0x1112), .driver_data = pbn_fintek_12 },
5173
5062 /* 5174 /*
5063 * These entries match devices with class COMMUNICATION_SERIAL, 5175 * These entries match devices with class COMMUNICATION_SERIAL,
5064 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL 5176 * COMMUNICATION_MODEM or COMMUNICATION_MULTISERIAL