162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Support for common PCI multi-I/O cards (which is most of them) 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2001 Tim Waugh <twaugh@redhat.com> 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Multi-function PCI cards are supposed to present separate logical 862306a36Sopenharmony_ci * devices on the bus. A common thing to do seems to be to just use 962306a36Sopenharmony_ci * one logical device with lots of base address registers for both 1062306a36Sopenharmony_ci * parallel ports and serial ports. This driver is for dealing with 1162306a36Sopenharmony_ci * that. 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/interrupt.h> 1562306a36Sopenharmony_ci#include <linux/module.h> 1662306a36Sopenharmony_ci#include <linux/parport.h> 1762306a36Sopenharmony_ci#include <linux/parport_pc.h> 1862306a36Sopenharmony_ci#include <linux/pci.h> 1962306a36Sopenharmony_ci#include <linux/slab.h> 2062306a36Sopenharmony_ci#include <linux/types.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include <linux/8250_pci.h> 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cienum parport_pc_pci_cards { 2562306a36Sopenharmony_ci titan_110l = 0, 2662306a36Sopenharmony_ci titan_210l, 2762306a36Sopenharmony_ci netmos_9xx5_combo, 2862306a36Sopenharmony_ci netmos_9855, 2962306a36Sopenharmony_ci netmos_9855_2p, 3062306a36Sopenharmony_ci netmos_9900, 3162306a36Sopenharmony_ci netmos_9900_2p, 3262306a36Sopenharmony_ci netmos_99xx_1p, 3362306a36Sopenharmony_ci avlab_1s1p, 3462306a36Sopenharmony_ci avlab_1s2p, 3562306a36Sopenharmony_ci avlab_2s1p, 3662306a36Sopenharmony_ci siig_1s1p_10x, 3762306a36Sopenharmony_ci siig_2s1p_10x, 3862306a36Sopenharmony_ci siig_2p1s_20x, 3962306a36Sopenharmony_ci siig_1s1p_20x, 4062306a36Sopenharmony_ci siig_2s1p_20x, 4162306a36Sopenharmony_ci timedia_4078a, 4262306a36Sopenharmony_ci timedia_4079h, 4362306a36Sopenharmony_ci timedia_4085h, 4462306a36Sopenharmony_ci timedia_4088a, 4562306a36Sopenharmony_ci timedia_4089a, 4662306a36Sopenharmony_ci timedia_4095a, 4762306a36Sopenharmony_ci timedia_4096a, 4862306a36Sopenharmony_ci timedia_4078u, 4962306a36Sopenharmony_ci timedia_4079a, 5062306a36Sopenharmony_ci timedia_4085u, 5162306a36Sopenharmony_ci timedia_4079r, 5262306a36Sopenharmony_ci timedia_4079s, 5362306a36Sopenharmony_ci timedia_4079d, 5462306a36Sopenharmony_ci timedia_4079e, 5562306a36Sopenharmony_ci timedia_4079f, 5662306a36Sopenharmony_ci timedia_9079a, 5762306a36Sopenharmony_ci timedia_9079b, 5862306a36Sopenharmony_ci timedia_9079c, 5962306a36Sopenharmony_ci wch_ch353_1s1p, 6062306a36Sopenharmony_ci wch_ch353_2s1p, 6162306a36Sopenharmony_ci wch_ch382_0s1p, 6262306a36Sopenharmony_ci wch_ch382_2s1p, 6362306a36Sopenharmony_ci brainboxes_5s1p, 6462306a36Sopenharmony_ci sunix_4008a, 6562306a36Sopenharmony_ci sunix_5069a, 6662306a36Sopenharmony_ci sunix_5079a, 6762306a36Sopenharmony_ci sunix_5099a, 6862306a36Sopenharmony_ci brainboxes_uc257, 6962306a36Sopenharmony_ci brainboxes_is300, 7062306a36Sopenharmony_ci brainboxes_uc414, 7162306a36Sopenharmony_ci brainboxes_px263, 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci/* each element directly indexed from enum list, above */ 7562306a36Sopenharmony_cistruct parport_pc_pci { 7662306a36Sopenharmony_ci int numports; 7762306a36Sopenharmony_ci struct { /* BAR (base address registers) numbers in the config 7862306a36Sopenharmony_ci space header */ 7962306a36Sopenharmony_ci int lo; 8062306a36Sopenharmony_ci int hi; /* -1 if not there, >6 for offset-method (max 8162306a36Sopenharmony_ci BAR is 6) */ 8262306a36Sopenharmony_ci } addr[4]; 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci /* If set, this is called immediately after pci_enable_device. 8562306a36Sopenharmony_ci * If it returns non-zero, no probing will take place and the 8662306a36Sopenharmony_ci * ports will not be used. */ 8762306a36Sopenharmony_ci int (*preinit_hook) (struct pci_dev *pdev, struct parport_pc_pci *card, 8862306a36Sopenharmony_ci int autoirq, int autodma); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* If set, this is called after probing for ports. If 'failed' 9162306a36Sopenharmony_ci * is non-zero we couldn't use any of the ports. */ 9262306a36Sopenharmony_ci void (*postinit_hook) (struct pci_dev *pdev, 9362306a36Sopenharmony_ci struct parport_pc_pci *card, int failed); 9462306a36Sopenharmony_ci}; 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_cistatic int netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par, 9762306a36Sopenharmony_ci int autoirq, int autodma) 9862306a36Sopenharmony_ci{ 9962306a36Sopenharmony_ci /* the rule described below doesn't hold for this device */ 10062306a36Sopenharmony_ci if (dev->device == PCI_DEVICE_ID_NETMOS_9835 && 10162306a36Sopenharmony_ci dev->subsystem_vendor == PCI_VENDOR_ID_IBM && 10262306a36Sopenharmony_ci dev->subsystem_device == 0x0299) 10362306a36Sopenharmony_ci return -ENODEV; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if (dev->device == PCI_DEVICE_ID_NETMOS_9912) { 10662306a36Sopenharmony_ci par->numports = 1; 10762306a36Sopenharmony_ci } else { 10862306a36Sopenharmony_ci /* 10962306a36Sopenharmony_ci * Netmos uses the subdevice ID to indicate the number of parallel 11062306a36Sopenharmony_ci * and serial ports. The form is 0x00PS, where <P> is the number of 11162306a36Sopenharmony_ci * parallel ports and <S> is the number of serial ports. 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_ci par->numports = (dev->subsystem_device & 0xf0) >> 4; 11462306a36Sopenharmony_ci if (par->numports > ARRAY_SIZE(par->addr)) 11562306a36Sopenharmony_ci par->numports = ARRAY_SIZE(par->addr); 11662306a36Sopenharmony_ci } 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci return 0; 11962306a36Sopenharmony_ci} 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_cistatic struct parport_pc_pci cards[] = { 12262306a36Sopenharmony_ci /* titan_110l */ { 1, { { 3, -1 }, } }, 12362306a36Sopenharmony_ci /* titan_210l */ { 1, { { 3, -1 }, } }, 12462306a36Sopenharmony_ci /* netmos_9xx5_combo */ { 1, { { 2, -1 }, }, netmos_parallel_init }, 12562306a36Sopenharmony_ci /* netmos_9855 */ { 1, { { 0, -1 }, }, netmos_parallel_init }, 12662306a36Sopenharmony_ci /* netmos_9855_2p */ { 2, { { 0, -1 }, { 2, -1 }, } }, 12762306a36Sopenharmony_ci /* netmos_9900 */ {1, { { 3, 4 }, }, netmos_parallel_init }, 12862306a36Sopenharmony_ci /* netmos_9900_2p */ {2, { { 0, 1 }, { 3, 4 }, } }, 12962306a36Sopenharmony_ci /* netmos_99xx_1p */ {1, { { 0, 1 }, } }, 13062306a36Sopenharmony_ci /* avlab_1s1p */ { 1, { { 1, 2}, } }, 13162306a36Sopenharmony_ci /* avlab_1s2p */ { 2, { { 1, 2}, { 3, 4 },} }, 13262306a36Sopenharmony_ci /* avlab_2s1p */ { 1, { { 2, 3}, } }, 13362306a36Sopenharmony_ci /* siig_1s1p_10x */ { 1, { { 3, 4 }, } }, 13462306a36Sopenharmony_ci /* siig_2s1p_10x */ { 1, { { 4, 5 }, } }, 13562306a36Sopenharmony_ci /* siig_2p1s_20x */ { 2, { { 1, 2 }, { 3, 4 }, } }, 13662306a36Sopenharmony_ci /* siig_1s1p_20x */ { 1, { { 1, 2 }, } }, 13762306a36Sopenharmony_ci /* siig_2s1p_20x */ { 1, { { 2, 3 }, } }, 13862306a36Sopenharmony_ci /* timedia_4078a */ { 1, { { 2, -1 }, } }, 13962306a36Sopenharmony_ci /* timedia_4079h */ { 1, { { 2, 3 }, } }, 14062306a36Sopenharmony_ci /* timedia_4085h */ { 2, { { 2, -1 }, { 4, -1 }, } }, 14162306a36Sopenharmony_ci /* timedia_4088a */ { 2, { { 2, 3 }, { 4, 5 }, } }, 14262306a36Sopenharmony_ci /* timedia_4089a */ { 2, { { 2, 3 }, { 4, 5 }, } }, 14362306a36Sopenharmony_ci /* timedia_4095a */ { 2, { { 2, 3 }, { 4, 5 }, } }, 14462306a36Sopenharmony_ci /* timedia_4096a */ { 2, { { 2, 3 }, { 4, 5 }, } }, 14562306a36Sopenharmony_ci /* timedia_4078u */ { 1, { { 2, -1 }, } }, 14662306a36Sopenharmony_ci /* timedia_4079a */ { 1, { { 2, 3 }, } }, 14762306a36Sopenharmony_ci /* timedia_4085u */ { 2, { { 2, -1 }, { 4, -1 }, } }, 14862306a36Sopenharmony_ci /* timedia_4079r */ { 1, { { 2, 3 }, } }, 14962306a36Sopenharmony_ci /* timedia_4079s */ { 1, { { 2, 3 }, } }, 15062306a36Sopenharmony_ci /* timedia_4079d */ { 1, { { 2, 3 }, } }, 15162306a36Sopenharmony_ci /* timedia_4079e */ { 1, { { 2, 3 }, } }, 15262306a36Sopenharmony_ci /* timedia_4079f */ { 1, { { 2, 3 }, } }, 15362306a36Sopenharmony_ci /* timedia_9079a */ { 1, { { 2, 3 }, } }, 15462306a36Sopenharmony_ci /* timedia_9079b */ { 1, { { 2, 3 }, } }, 15562306a36Sopenharmony_ci /* timedia_9079c */ { 1, { { 2, 3 }, } }, 15662306a36Sopenharmony_ci /* wch_ch353_1s1p*/ { 1, { { 1, -1}, } }, 15762306a36Sopenharmony_ci /* wch_ch353_2s1p*/ { 1, { { 2, -1}, } }, 15862306a36Sopenharmony_ci /* wch_ch382_0s1p*/ { 1, { { 2, -1}, } }, 15962306a36Sopenharmony_ci /* wch_ch382_2s1p*/ { 1, { { 2, -1}, } }, 16062306a36Sopenharmony_ci /* brainboxes_5s1p */ { 1, { { 3, -1 }, } }, 16162306a36Sopenharmony_ci /* sunix_4008a */ { 1, { { 1, 2 }, } }, 16262306a36Sopenharmony_ci /* sunix_5069a */ { 1, { { 1, 2 }, } }, 16362306a36Sopenharmony_ci /* sunix_5079a */ { 1, { { 1, 2 }, } }, 16462306a36Sopenharmony_ci /* sunix_5099a */ { 1, { { 1, 2 }, } }, 16562306a36Sopenharmony_ci /* brainboxes_uc257 */ { 1, { { 3, -1 }, } }, 16662306a36Sopenharmony_ci /* brainboxes_is300 */ { 1, { { 3, -1 }, } }, 16762306a36Sopenharmony_ci /* brainboxes_uc414 */ { 1, { { 3, -1 }, } }, 16862306a36Sopenharmony_ci /* brainboxes_px263 */ { 1, { { 3, -1 }, } }, 16962306a36Sopenharmony_ci}; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_cistatic struct pci_device_id parport_serial_pci_tbl[] = { 17262306a36Sopenharmony_ci /* PCI cards */ 17362306a36Sopenharmony_ci { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L, 17462306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l }, 17562306a36Sopenharmony_ci { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L, 17662306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l }, 17762306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735, 17862306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, 17962306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9745, 18062306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, 18162306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835, 18262306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, 18362306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845, 18462306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo }, 18562306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, 18662306a36Sopenharmony_ci 0x1000, 0x0020, 0, 0, netmos_9855_2p }, 18762306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, 18862306a36Sopenharmony_ci 0x1000, 0x0022, 0, 0, netmos_9855_2p }, 18962306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855, 19062306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 }, 19162306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, 19262306a36Sopenharmony_ci 0xA000, 0x3011, 0, 0, netmos_9900 }, 19362306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, 19462306a36Sopenharmony_ci 0xA000, 0x3012, 0, 0, netmos_9900 }, 19562306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900, 19662306a36Sopenharmony_ci 0xA000, 0x3020, 0, 0, netmos_9900_2p }, 19762306a36Sopenharmony_ci { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912, 19862306a36Sopenharmony_ci 0xA000, 0x2000, 0, 0, netmos_99xx_1p }, 19962306a36Sopenharmony_ci /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/ 20062306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2110, 20162306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, 20262306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2111, 20362306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, 20462306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2112, 20562306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p }, 20662306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2140, 20762306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p }, 20862306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2141, 20962306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p }, 21062306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2142, 21162306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p }, 21262306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2160, 21362306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p }, 21462306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2161, 21562306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p }, 21662306a36Sopenharmony_ci { PCI_VENDOR_ID_AFAVLAB, 0x2162, 21762306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p }, 21862306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550, 21962306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x }, 22062306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650, 22162306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x }, 22262306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850, 22362306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x }, 22462306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550, 22562306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x }, 22662306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650, 22762306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x }, 22862306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850, 22962306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x }, 23062306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550, 23162306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x }, 23262306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650, 23362306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x }, 23462306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850, 23562306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x }, 23662306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550, 23762306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x }, 23862306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650, 23962306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x }, 24062306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850, 24162306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x }, 24262306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550, 24362306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x }, 24462306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650, 24562306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x }, 24662306a36Sopenharmony_ci { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850, 24762306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x }, 24862306a36Sopenharmony_ci /* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/ 24962306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a }, 25062306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h }, 25162306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4085, 0, 0, timedia_4085h }, 25262306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4088, 0, 0, timedia_4088a }, 25362306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4089, 0, 0, timedia_4089a }, 25462306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4095, 0, 0, timedia_4095a }, 25562306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x4096, 0, 0, timedia_4096a }, 25662306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x5078, 0, 0, timedia_4078u }, 25762306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x5079, 0, 0, timedia_4079a }, 25862306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x5085, 0, 0, timedia_4085u }, 25962306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x6079, 0, 0, timedia_4079r }, 26062306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x7079, 0, 0, timedia_4079s }, 26162306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x8079, 0, 0, timedia_4079d }, 26262306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0x9079, 0, 0, timedia_4079e }, 26362306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0xa079, 0, 0, timedia_4079f }, 26462306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a }, 26562306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b }, 26662306a36Sopenharmony_ci { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c }, 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_ci /* WCH CARDS */ 26962306a36Sopenharmony_ci { 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p}, 27062306a36Sopenharmony_ci { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p}, 27162306a36Sopenharmony_ci { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382_0s1p}, 27262306a36Sopenharmony_ci { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p}, 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci /* BrainBoxes PX272/PX306 MIO card */ 27562306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x4100, 27662306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p }, 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci /* Sunix boards */ 27962306a36Sopenharmony_ci { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, 28062306a36Sopenharmony_ci 0x0100, 0, 0, sunix_4008a }, 28162306a36Sopenharmony_ci { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, 28262306a36Sopenharmony_ci 0x0101, 0, 0, sunix_5069a }, 28362306a36Sopenharmony_ci { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, 28462306a36Sopenharmony_ci 0x0102, 0, 0, sunix_5079a }, 28562306a36Sopenharmony_ci { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX, 28662306a36Sopenharmony_ci 0x0104, 0, 0, sunix_5099a }, 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci /* Brainboxes UC-203 */ 28962306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0bc1, 29062306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 29162306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0bc2, 29262306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 29362306a36Sopenharmony_ci 29462306a36Sopenharmony_ci /* Brainboxes UC-257 */ 29562306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0861, 29662306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 29762306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0862, 29862306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 29962306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0863, 30062306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 30162306a36Sopenharmony_ci 30262306a36Sopenharmony_ci /* Brainboxes UC-414 */ 30362306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0e61, 30462306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc414 }, 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci /* Brainboxes UC-475 */ 30762306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0981, 30862306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 30962306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0982, 31062306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_uc257 }, 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci /* Brainboxes IS-300/IS-500 */ 31362306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x0da0, 31462306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_is300 }, 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci /* Brainboxes PX-263/PX-295 */ 31762306a36Sopenharmony_ci { PCI_VENDOR_ID_INTASHIELD, 0x402c, 31862306a36Sopenharmony_ci PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_px263 }, 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_ci { 0, } /* terminate list */ 32162306a36Sopenharmony_ci}; 32262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci/* 32562306a36Sopenharmony_ci * This table describes the serial "geometry" of these boards. Any 32662306a36Sopenharmony_ci * quirks for these can be found in drivers/serial/8250_pci.c 32762306a36Sopenharmony_ci * 32862306a36Sopenharmony_ci * Cards not tested are marked n/t 32962306a36Sopenharmony_ci * If you have one of these cards and it works for you, please tell me.. 33062306a36Sopenharmony_ci */ 33162306a36Sopenharmony_cistatic struct pciserial_board pci_parport_serial_boards[] = { 33262306a36Sopenharmony_ci [titan_110l] = { 33362306a36Sopenharmony_ci .flags = FL_BASE1 | FL_BASE_BARS, 33462306a36Sopenharmony_ci .num_ports = 1, 33562306a36Sopenharmony_ci .base_baud = 921600, 33662306a36Sopenharmony_ci .uart_offset = 8, 33762306a36Sopenharmony_ci }, 33862306a36Sopenharmony_ci [titan_210l] = { 33962306a36Sopenharmony_ci .flags = FL_BASE1 | FL_BASE_BARS, 34062306a36Sopenharmony_ci .num_ports = 2, 34162306a36Sopenharmony_ci .base_baud = 921600, 34262306a36Sopenharmony_ci .uart_offset = 8, 34362306a36Sopenharmony_ci }, 34462306a36Sopenharmony_ci [netmos_9xx5_combo] = { 34562306a36Sopenharmony_ci .flags = FL_BASE0 | FL_BASE_BARS, 34662306a36Sopenharmony_ci .num_ports = 1, 34762306a36Sopenharmony_ci .base_baud = 115200, 34862306a36Sopenharmony_ci .uart_offset = 8, 34962306a36Sopenharmony_ci }, 35062306a36Sopenharmony_ci [netmos_9855] = { 35162306a36Sopenharmony_ci .flags = FL_BASE2 | FL_BASE_BARS, 35262306a36Sopenharmony_ci .num_ports = 1, 35362306a36Sopenharmony_ci .base_baud = 115200, 35462306a36Sopenharmony_ci .uart_offset = 8, 35562306a36Sopenharmony_ci }, 35662306a36Sopenharmony_ci [netmos_9855_2p] = { 35762306a36Sopenharmony_ci .flags = FL_BASE4 | FL_BASE_BARS, 35862306a36Sopenharmony_ci .num_ports = 1, 35962306a36Sopenharmony_ci .base_baud = 115200, 36062306a36Sopenharmony_ci .uart_offset = 8, 36162306a36Sopenharmony_ci }, 36262306a36Sopenharmony_ci [netmos_9900] = { /* n/t */ 36362306a36Sopenharmony_ci .flags = FL_BASE0 | FL_BASE_BARS, 36462306a36Sopenharmony_ci .num_ports = 1, 36562306a36Sopenharmony_ci .base_baud = 115200, 36662306a36Sopenharmony_ci .uart_offset = 8, 36762306a36Sopenharmony_ci }, 36862306a36Sopenharmony_ci [netmos_9900_2p] = { /* parallel only */ /* n/t */ 36962306a36Sopenharmony_ci .flags = FL_BASE0, 37062306a36Sopenharmony_ci .num_ports = 0, 37162306a36Sopenharmony_ci .base_baud = 115200, 37262306a36Sopenharmony_ci .uart_offset = 8, 37362306a36Sopenharmony_ci }, 37462306a36Sopenharmony_ci [netmos_99xx_1p] = { /* parallel only */ /* n/t */ 37562306a36Sopenharmony_ci .flags = FL_BASE0, 37662306a36Sopenharmony_ci .num_ports = 0, 37762306a36Sopenharmony_ci .base_baud = 115200, 37862306a36Sopenharmony_ci .uart_offset = 8, 37962306a36Sopenharmony_ci }, 38062306a36Sopenharmony_ci [avlab_1s1p] = { /* n/t */ 38162306a36Sopenharmony_ci .flags = FL_BASE0 | FL_BASE_BARS, 38262306a36Sopenharmony_ci .num_ports = 1, 38362306a36Sopenharmony_ci .base_baud = 115200, 38462306a36Sopenharmony_ci .uart_offset = 8, 38562306a36Sopenharmony_ci }, 38662306a36Sopenharmony_ci [avlab_1s2p] = { /* n/t */ 38762306a36Sopenharmony_ci .flags = FL_BASE0 | FL_BASE_BARS, 38862306a36Sopenharmony_ci .num_ports = 1, 38962306a36Sopenharmony_ci .base_baud = 115200, 39062306a36Sopenharmony_ci .uart_offset = 8, 39162306a36Sopenharmony_ci }, 39262306a36Sopenharmony_ci [avlab_2s1p] = { /* n/t */ 39362306a36Sopenharmony_ci .flags = FL_BASE0 | FL_BASE_BARS, 39462306a36Sopenharmony_ci .num_ports = 2, 39562306a36Sopenharmony_ci .base_baud = 115200, 39662306a36Sopenharmony_ci .uart_offset = 8, 39762306a36Sopenharmony_ci }, 39862306a36Sopenharmony_ci [siig_1s1p_10x] = { 39962306a36Sopenharmony_ci .flags = FL_BASE2, 40062306a36Sopenharmony_ci .num_ports = 1, 40162306a36Sopenharmony_ci .base_baud = 460800, 40262306a36Sopenharmony_ci .uart_offset = 8, 40362306a36Sopenharmony_ci }, 40462306a36Sopenharmony_ci [siig_2s1p_10x] = { 40562306a36Sopenharmony_ci .flags = FL_BASE2, 40662306a36Sopenharmony_ci .num_ports = 1, 40762306a36Sopenharmony_ci .base_baud = 921600, 40862306a36Sopenharmony_ci .uart_offset = 8, 40962306a36Sopenharmony_ci }, 41062306a36Sopenharmony_ci [siig_2p1s_20x] = { 41162306a36Sopenharmony_ci .flags = FL_BASE0, 41262306a36Sopenharmony_ci .num_ports = 1, 41362306a36Sopenharmony_ci .base_baud = 921600, 41462306a36Sopenharmony_ci .uart_offset = 8, 41562306a36Sopenharmony_ci }, 41662306a36Sopenharmony_ci [siig_1s1p_20x] = { 41762306a36Sopenharmony_ci .flags = FL_BASE0, 41862306a36Sopenharmony_ci .num_ports = 1, 41962306a36Sopenharmony_ci .base_baud = 921600, 42062306a36Sopenharmony_ci .uart_offset = 8, 42162306a36Sopenharmony_ci }, 42262306a36Sopenharmony_ci [siig_2s1p_20x] = { 42362306a36Sopenharmony_ci .flags = FL_BASE0, 42462306a36Sopenharmony_ci .num_ports = 1, 42562306a36Sopenharmony_ci .base_baud = 921600, 42662306a36Sopenharmony_ci .uart_offset = 8, 42762306a36Sopenharmony_ci }, 42862306a36Sopenharmony_ci [timedia_4078a] = { 42962306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 43062306a36Sopenharmony_ci .num_ports = 1, 43162306a36Sopenharmony_ci .base_baud = 921600, 43262306a36Sopenharmony_ci .uart_offset = 8, 43362306a36Sopenharmony_ci }, 43462306a36Sopenharmony_ci [timedia_4079h] = { 43562306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 43662306a36Sopenharmony_ci .num_ports = 1, 43762306a36Sopenharmony_ci .base_baud = 921600, 43862306a36Sopenharmony_ci .uart_offset = 8, 43962306a36Sopenharmony_ci }, 44062306a36Sopenharmony_ci [timedia_4085h] = { 44162306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 44262306a36Sopenharmony_ci .num_ports = 1, 44362306a36Sopenharmony_ci .base_baud = 921600, 44462306a36Sopenharmony_ci .uart_offset = 8, 44562306a36Sopenharmony_ci }, 44662306a36Sopenharmony_ci [timedia_4088a] = { 44762306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 44862306a36Sopenharmony_ci .num_ports = 1, 44962306a36Sopenharmony_ci .base_baud = 921600, 45062306a36Sopenharmony_ci .uart_offset = 8, 45162306a36Sopenharmony_ci }, 45262306a36Sopenharmony_ci [timedia_4089a] = { 45362306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 45462306a36Sopenharmony_ci .num_ports = 1, 45562306a36Sopenharmony_ci .base_baud = 921600, 45662306a36Sopenharmony_ci .uart_offset = 8, 45762306a36Sopenharmony_ci }, 45862306a36Sopenharmony_ci [timedia_4095a] = { 45962306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 46062306a36Sopenharmony_ci .num_ports = 1, 46162306a36Sopenharmony_ci .base_baud = 921600, 46262306a36Sopenharmony_ci .uart_offset = 8, 46362306a36Sopenharmony_ci }, 46462306a36Sopenharmony_ci [timedia_4096a] = { 46562306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 46662306a36Sopenharmony_ci .num_ports = 1, 46762306a36Sopenharmony_ci .base_baud = 921600, 46862306a36Sopenharmony_ci .uart_offset = 8, 46962306a36Sopenharmony_ci }, 47062306a36Sopenharmony_ci [timedia_4078u] = { 47162306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 47262306a36Sopenharmony_ci .num_ports = 1, 47362306a36Sopenharmony_ci .base_baud = 921600, 47462306a36Sopenharmony_ci .uart_offset = 8, 47562306a36Sopenharmony_ci }, 47662306a36Sopenharmony_ci [timedia_4079a] = { 47762306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 47862306a36Sopenharmony_ci .num_ports = 1, 47962306a36Sopenharmony_ci .base_baud = 921600, 48062306a36Sopenharmony_ci .uart_offset = 8, 48162306a36Sopenharmony_ci }, 48262306a36Sopenharmony_ci [timedia_4085u] = { 48362306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 48462306a36Sopenharmony_ci .num_ports = 1, 48562306a36Sopenharmony_ci .base_baud = 921600, 48662306a36Sopenharmony_ci .uart_offset = 8, 48762306a36Sopenharmony_ci }, 48862306a36Sopenharmony_ci [timedia_4079r] = { 48962306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 49062306a36Sopenharmony_ci .num_ports = 1, 49162306a36Sopenharmony_ci .base_baud = 921600, 49262306a36Sopenharmony_ci .uart_offset = 8, 49362306a36Sopenharmony_ci }, 49462306a36Sopenharmony_ci [timedia_4079s] = { 49562306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 49662306a36Sopenharmony_ci .num_ports = 1, 49762306a36Sopenharmony_ci .base_baud = 921600, 49862306a36Sopenharmony_ci .uart_offset = 8, 49962306a36Sopenharmony_ci }, 50062306a36Sopenharmony_ci [timedia_4079d] = { 50162306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 50262306a36Sopenharmony_ci .num_ports = 1, 50362306a36Sopenharmony_ci .base_baud = 921600, 50462306a36Sopenharmony_ci .uart_offset = 8, 50562306a36Sopenharmony_ci }, 50662306a36Sopenharmony_ci [timedia_4079e] = { 50762306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 50862306a36Sopenharmony_ci .num_ports = 1, 50962306a36Sopenharmony_ci .base_baud = 921600, 51062306a36Sopenharmony_ci .uart_offset = 8, 51162306a36Sopenharmony_ci }, 51262306a36Sopenharmony_ci [timedia_4079f] = { 51362306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 51462306a36Sopenharmony_ci .num_ports = 1, 51562306a36Sopenharmony_ci .base_baud = 921600, 51662306a36Sopenharmony_ci .uart_offset = 8, 51762306a36Sopenharmony_ci }, 51862306a36Sopenharmony_ci [timedia_9079a] = { 51962306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 52062306a36Sopenharmony_ci .num_ports = 1, 52162306a36Sopenharmony_ci .base_baud = 921600, 52262306a36Sopenharmony_ci .uart_offset = 8, 52362306a36Sopenharmony_ci }, 52462306a36Sopenharmony_ci [timedia_9079b] = { 52562306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 52662306a36Sopenharmony_ci .num_ports = 1, 52762306a36Sopenharmony_ci .base_baud = 921600, 52862306a36Sopenharmony_ci .uart_offset = 8, 52962306a36Sopenharmony_ci }, 53062306a36Sopenharmony_ci [timedia_9079c] = { 53162306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 53262306a36Sopenharmony_ci .num_ports = 1, 53362306a36Sopenharmony_ci .base_baud = 921600, 53462306a36Sopenharmony_ci .uart_offset = 8, 53562306a36Sopenharmony_ci }, 53662306a36Sopenharmony_ci [wch_ch353_1s1p] = { 53762306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 53862306a36Sopenharmony_ci .num_ports = 1, 53962306a36Sopenharmony_ci .base_baud = 115200, 54062306a36Sopenharmony_ci .uart_offset = 8, 54162306a36Sopenharmony_ci }, 54262306a36Sopenharmony_ci [wch_ch353_2s1p] = { 54362306a36Sopenharmony_ci .flags = FL_BASE0|FL_BASE_BARS, 54462306a36Sopenharmony_ci .num_ports = 2, 54562306a36Sopenharmony_ci .base_baud = 115200, 54662306a36Sopenharmony_ci .uart_offset = 8, 54762306a36Sopenharmony_ci }, 54862306a36Sopenharmony_ci [wch_ch382_0s1p] = { 54962306a36Sopenharmony_ci .flags = FL_BASE0, 55062306a36Sopenharmony_ci .num_ports = 0, 55162306a36Sopenharmony_ci .base_baud = 115200, 55262306a36Sopenharmony_ci .uart_offset = 8, 55362306a36Sopenharmony_ci }, 55462306a36Sopenharmony_ci [wch_ch382_2s1p] = { 55562306a36Sopenharmony_ci .flags = FL_BASE0, 55662306a36Sopenharmony_ci .num_ports = 2, 55762306a36Sopenharmony_ci .base_baud = 115200, 55862306a36Sopenharmony_ci .uart_offset = 8, 55962306a36Sopenharmony_ci .first_offset = 0xC0, 56062306a36Sopenharmony_ci }, 56162306a36Sopenharmony_ci [brainboxes_5s1p] = { 56262306a36Sopenharmony_ci .flags = FL_BASE2, 56362306a36Sopenharmony_ci .num_ports = 5, 56462306a36Sopenharmony_ci .base_baud = 921600, 56562306a36Sopenharmony_ci .uart_offset = 8, 56662306a36Sopenharmony_ci }, 56762306a36Sopenharmony_ci [sunix_4008a] = { 56862306a36Sopenharmony_ci .num_ports = 0, 56962306a36Sopenharmony_ci }, 57062306a36Sopenharmony_ci [sunix_5069a] = { 57162306a36Sopenharmony_ci .num_ports = 1, 57262306a36Sopenharmony_ci .base_baud = 921600, 57362306a36Sopenharmony_ci .uart_offset = 0x8, 57462306a36Sopenharmony_ci }, 57562306a36Sopenharmony_ci [sunix_5079a] = { 57662306a36Sopenharmony_ci .num_ports = 2, 57762306a36Sopenharmony_ci .base_baud = 921600, 57862306a36Sopenharmony_ci .uart_offset = 0x8, 57962306a36Sopenharmony_ci }, 58062306a36Sopenharmony_ci [sunix_5099a] = { 58162306a36Sopenharmony_ci .num_ports = 4, 58262306a36Sopenharmony_ci .base_baud = 921600, 58362306a36Sopenharmony_ci .uart_offset = 0x8, 58462306a36Sopenharmony_ci }, 58562306a36Sopenharmony_ci [brainboxes_uc257] = { 58662306a36Sopenharmony_ci .flags = FL_BASE2, 58762306a36Sopenharmony_ci .num_ports = 2, 58862306a36Sopenharmony_ci .base_baud = 115200, 58962306a36Sopenharmony_ci .uart_offset = 8, 59062306a36Sopenharmony_ci }, 59162306a36Sopenharmony_ci [brainboxes_is300] = { 59262306a36Sopenharmony_ci .flags = FL_BASE2, 59362306a36Sopenharmony_ci .num_ports = 1, 59462306a36Sopenharmony_ci .base_baud = 115200, 59562306a36Sopenharmony_ci .uart_offset = 8, 59662306a36Sopenharmony_ci }, 59762306a36Sopenharmony_ci [brainboxes_uc414] = { 59862306a36Sopenharmony_ci .flags = FL_BASE2, 59962306a36Sopenharmony_ci .num_ports = 4, 60062306a36Sopenharmony_ci .base_baud = 115200, 60162306a36Sopenharmony_ci .uart_offset = 8, 60262306a36Sopenharmony_ci }, 60362306a36Sopenharmony_ci [brainboxes_px263] = { 60462306a36Sopenharmony_ci .flags = FL_BASE2, 60562306a36Sopenharmony_ci .num_ports = 4, 60662306a36Sopenharmony_ci .base_baud = 921600, 60762306a36Sopenharmony_ci .uart_offset = 8, 60862306a36Sopenharmony_ci }, 60962306a36Sopenharmony_ci}; 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_cistruct parport_serial_private { 61262306a36Sopenharmony_ci struct serial_private *serial; 61362306a36Sopenharmony_ci int num_par; 61462306a36Sopenharmony_ci struct parport *port[PARPORT_MAX]; 61562306a36Sopenharmony_ci struct parport_pc_pci par; 61662306a36Sopenharmony_ci}; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci/* Register the serial port(s) of a PCI card. */ 61962306a36Sopenharmony_cistatic int serial_register(struct pci_dev *dev, const struct pci_device_id *id) 62062306a36Sopenharmony_ci{ 62162306a36Sopenharmony_ci struct parport_serial_private *priv = pci_get_drvdata (dev); 62262306a36Sopenharmony_ci struct pciserial_board *board; 62362306a36Sopenharmony_ci struct serial_private *serial; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci board = &pci_parport_serial_boards[id->driver_data]; 62662306a36Sopenharmony_ci if (board->num_ports == 0) 62762306a36Sopenharmony_ci return 0; 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci serial = pciserial_init_ports(dev, board); 63062306a36Sopenharmony_ci if (IS_ERR(serial)) 63162306a36Sopenharmony_ci return PTR_ERR(serial); 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_ci priv->serial = serial; 63462306a36Sopenharmony_ci return 0; 63562306a36Sopenharmony_ci} 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci/* Register the parallel port(s) of a PCI card. */ 63862306a36Sopenharmony_cistatic int parport_register(struct pci_dev *dev, const struct pci_device_id *id) 63962306a36Sopenharmony_ci{ 64062306a36Sopenharmony_ci struct parport_pc_pci *card; 64162306a36Sopenharmony_ci struct parport_serial_private *priv = pci_get_drvdata (dev); 64262306a36Sopenharmony_ci int n, success = 0; 64362306a36Sopenharmony_ci 64462306a36Sopenharmony_ci priv->par = cards[id->driver_data]; 64562306a36Sopenharmony_ci card = &priv->par; 64662306a36Sopenharmony_ci if (card->preinit_hook && 64762306a36Sopenharmony_ci card->preinit_hook (dev, card, PARPORT_IRQ_NONE, PARPORT_DMA_NONE)) 64862306a36Sopenharmony_ci return -ENODEV; 64962306a36Sopenharmony_ci 65062306a36Sopenharmony_ci for (n = 0; n < card->numports; n++) { 65162306a36Sopenharmony_ci struct parport *port; 65262306a36Sopenharmony_ci int lo = card->addr[n].lo; 65362306a36Sopenharmony_ci int hi = card->addr[n].hi; 65462306a36Sopenharmony_ci unsigned long io_lo, io_hi; 65562306a36Sopenharmony_ci int irq; 65662306a36Sopenharmony_ci 65762306a36Sopenharmony_ci if (priv->num_par == ARRAY_SIZE (priv->port)) { 65862306a36Sopenharmony_ci dev_warn(&dev->dev, 65962306a36Sopenharmony_ci "only %zu parallel ports supported (%d reported)\n", 66062306a36Sopenharmony_ci ARRAY_SIZE(priv->port), card->numports); 66162306a36Sopenharmony_ci break; 66262306a36Sopenharmony_ci } 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci io_lo = pci_resource_start (dev, lo); 66562306a36Sopenharmony_ci io_hi = 0; 66662306a36Sopenharmony_ci if ((hi >= 0) && (hi <= 6)) 66762306a36Sopenharmony_ci io_hi = pci_resource_start (dev, hi); 66862306a36Sopenharmony_ci else if (hi > 6) 66962306a36Sopenharmony_ci io_lo += hi; /* Reinterpret the meaning of 67062306a36Sopenharmony_ci "hi" as an offset (see SYBA 67162306a36Sopenharmony_ci def.) */ 67262306a36Sopenharmony_ci /* TODO: test if sharing interrupts works */ 67362306a36Sopenharmony_ci irq = pci_irq_vector(dev, 0); 67462306a36Sopenharmony_ci if (irq < 0) 67562306a36Sopenharmony_ci return irq; 67662306a36Sopenharmony_ci if (irq == 0) 67762306a36Sopenharmony_ci irq = PARPORT_IRQ_NONE; 67862306a36Sopenharmony_ci if (irq == PARPORT_IRQ_NONE) { 67962306a36Sopenharmony_ci dev_dbg(&dev->dev, 68062306a36Sopenharmony_ci "PCI parallel port detected: I/O at %#lx(%#lx)\n", 68162306a36Sopenharmony_ci io_lo, io_hi); 68262306a36Sopenharmony_ci } else { 68362306a36Sopenharmony_ci dev_dbg(&dev->dev, 68462306a36Sopenharmony_ci "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n", 68562306a36Sopenharmony_ci io_lo, io_hi, irq); 68662306a36Sopenharmony_ci } 68762306a36Sopenharmony_ci port = parport_pc_probe_port (io_lo, io_hi, irq, 68862306a36Sopenharmony_ci PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED); 68962306a36Sopenharmony_ci if (port) { 69062306a36Sopenharmony_ci priv->port[priv->num_par++] = port; 69162306a36Sopenharmony_ci success = 1; 69262306a36Sopenharmony_ci } 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci if (card->postinit_hook) 69662306a36Sopenharmony_ci card->postinit_hook (dev, card, !success); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci return 0; 69962306a36Sopenharmony_ci} 70062306a36Sopenharmony_ci 70162306a36Sopenharmony_cistatic int parport_serial_pci_probe(struct pci_dev *dev, 70262306a36Sopenharmony_ci const struct pci_device_id *id) 70362306a36Sopenharmony_ci{ 70462306a36Sopenharmony_ci struct parport_serial_private *priv; 70562306a36Sopenharmony_ci int err; 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL); 70862306a36Sopenharmony_ci if (!priv) 70962306a36Sopenharmony_ci return -ENOMEM; 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci pci_set_drvdata (dev, priv); 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_ci err = pcim_enable_device(dev); 71462306a36Sopenharmony_ci if (err) 71562306a36Sopenharmony_ci return err; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci err = parport_register(dev, id); 71862306a36Sopenharmony_ci if (err) 71962306a36Sopenharmony_ci return err; 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci err = serial_register(dev, id); 72262306a36Sopenharmony_ci if (err) { 72362306a36Sopenharmony_ci int i; 72462306a36Sopenharmony_ci for (i = 0; i < priv->num_par; i++) 72562306a36Sopenharmony_ci parport_pc_unregister_port (priv->port[i]); 72662306a36Sopenharmony_ci return err; 72762306a36Sopenharmony_ci } 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci return 0; 73062306a36Sopenharmony_ci} 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_cistatic void parport_serial_pci_remove(struct pci_dev *dev) 73362306a36Sopenharmony_ci{ 73462306a36Sopenharmony_ci struct parport_serial_private *priv = pci_get_drvdata (dev); 73562306a36Sopenharmony_ci int i; 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci // Serial ports 73862306a36Sopenharmony_ci if (priv->serial) 73962306a36Sopenharmony_ci pciserial_remove_ports(priv->serial); 74062306a36Sopenharmony_ci 74162306a36Sopenharmony_ci // Parallel ports 74262306a36Sopenharmony_ci for (i = 0; i < priv->num_par; i++) 74362306a36Sopenharmony_ci parport_pc_unregister_port (priv->port[i]); 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci return; 74662306a36Sopenharmony_ci} 74762306a36Sopenharmony_ci 74862306a36Sopenharmony_cistatic int __maybe_unused parport_serial_pci_suspend(struct device *dev) 74962306a36Sopenharmony_ci{ 75062306a36Sopenharmony_ci struct parport_serial_private *priv = dev_get_drvdata(dev); 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci if (priv->serial) 75362306a36Sopenharmony_ci pciserial_suspend_ports(priv->serial); 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci /* FIXME: What about parport? */ 75662306a36Sopenharmony_ci return 0; 75762306a36Sopenharmony_ci} 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_cistatic int __maybe_unused parport_serial_pci_resume(struct device *dev) 76062306a36Sopenharmony_ci{ 76162306a36Sopenharmony_ci struct parport_serial_private *priv = dev_get_drvdata(dev); 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci if (priv->serial) 76462306a36Sopenharmony_ci pciserial_resume_ports(priv->serial); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci /* FIXME: What about parport? */ 76762306a36Sopenharmony_ci return 0; 76862306a36Sopenharmony_ci} 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_cistatic SIMPLE_DEV_PM_OPS(parport_serial_pm_ops, 77162306a36Sopenharmony_ci parport_serial_pci_suspend, parport_serial_pci_resume); 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_cistatic struct pci_driver parport_serial_pci_driver = { 77462306a36Sopenharmony_ci .name = "parport_serial", 77562306a36Sopenharmony_ci .id_table = parport_serial_pci_tbl, 77662306a36Sopenharmony_ci .probe = parport_serial_pci_probe, 77762306a36Sopenharmony_ci .remove = parport_serial_pci_remove, 77862306a36Sopenharmony_ci .driver = { 77962306a36Sopenharmony_ci .pm = &parport_serial_pm_ops, 78062306a36Sopenharmony_ci }, 78162306a36Sopenharmony_ci}; 78262306a36Sopenharmony_cimodule_pci_driver(parport_serial_pci_driver); 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_ciMODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>"); 78562306a36Sopenharmony_ciMODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards"); 78662306a36Sopenharmony_ciMODULE_LICENSE("GPL"); 787