Revert "Input: synaptics - switch touchpad on HP Laptop 15-da3001TU to RMI mode"
[platform/kernel/linux-rpi.git] / drivers / parport / parport_serial.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Support for common PCI multi-I/O cards (which is most of them)
4  *
5  * Copyright (C) 2001  Tim Waugh <twaugh@redhat.com>
6  *
7  * Multi-function PCI cards are supposed to present separate logical
8  * devices on the bus.  A common thing to do seems to be to just use
9  * one logical device with lots of base address registers for both
10  * parallel ports and serial ports.  This driver is for dealing with
11  * that.
12  */
13
14 #include <linux/interrupt.h>
15 #include <linux/module.h>
16 #include <linux/parport.h>
17 #include <linux/parport_pc.h>
18 #include <linux/pci.h>
19 #include <linux/slab.h>
20 #include <linux/types.h>
21
22 #include <linux/8250_pci.h>
23
24 enum parport_pc_pci_cards {
25         titan_110l = 0,
26         titan_210l,
27         netmos_9xx5_combo,
28         netmos_9855,
29         netmos_9855_2p,
30         netmos_9900,
31         netmos_9900_2p,
32         netmos_99xx_1p,
33         avlab_1s1p,
34         avlab_1s2p,
35         avlab_2s1p,
36         siig_1s1p_10x,
37         siig_2s1p_10x,
38         siig_2p1s_20x,
39         siig_1s1p_20x,
40         siig_2s1p_20x,
41         timedia_4078a,
42         timedia_4079h,
43         timedia_4085h,
44         timedia_4088a,
45         timedia_4089a,
46         timedia_4095a,
47         timedia_4096a,
48         timedia_4078u,
49         timedia_4079a,
50         timedia_4085u,
51         timedia_4079r,
52         timedia_4079s,
53         timedia_4079d,
54         timedia_4079e,
55         timedia_4079f,
56         timedia_9079a,
57         timedia_9079b,
58         timedia_9079c,
59         wch_ch353_1s1p,
60         wch_ch353_2s1p,
61         wch_ch382_0s1p,
62         wch_ch382_2s1p,
63         brainboxes_5s1p,
64         sunix_4008a,
65         sunix_5069a,
66         sunix_5079a,
67         sunix_5099a,
68 };
69
70 /* each element directly indexed from enum list, above */
71 struct parport_pc_pci {
72         int numports;
73         struct { /* BAR (base address registers) numbers in the config
74                     space header */
75                 int lo;
76                 int hi; /* -1 if not there, >6 for offset-method (max
77                            BAR is 6) */
78         } addr[4];
79
80         /* If set, this is called immediately after pci_enable_device.
81          * If it returns non-zero, no probing will take place and the
82          * ports will not be used. */
83         int (*preinit_hook) (struct pci_dev *pdev, struct parport_pc_pci *card,
84                                 int autoirq, int autodma);
85
86         /* If set, this is called after probing for ports.  If 'failed'
87          * is non-zero we couldn't use any of the ports. */
88         void (*postinit_hook) (struct pci_dev *pdev,
89                                 struct parport_pc_pci *card, int failed);
90 };
91
92 static int netmos_parallel_init(struct pci_dev *dev, struct parport_pc_pci *par,
93                                 int autoirq, int autodma)
94 {
95         /* the rule described below doesn't hold for this device */
96         if (dev->device == PCI_DEVICE_ID_NETMOS_9835 &&
97                         dev->subsystem_vendor == PCI_VENDOR_ID_IBM &&
98                         dev->subsystem_device == 0x0299)
99                 return -ENODEV;
100
101         if (dev->device == PCI_DEVICE_ID_NETMOS_9912) {
102                 par->numports = 1;
103         } else {
104                 /*
105                  * Netmos uses the subdevice ID to indicate the number of parallel
106                  * and serial ports.  The form is 0x00PS, where <P> is the number of
107                  * parallel ports and <S> is the number of serial ports.
108                  */
109                 par->numports = (dev->subsystem_device & 0xf0) >> 4;
110                 if (par->numports > ARRAY_SIZE(par->addr))
111                         par->numports = ARRAY_SIZE(par->addr);
112         }
113
114         return 0;
115 }
116
117 static struct parport_pc_pci cards[] = {
118         /* titan_110l */                { 1, { { 3, -1 }, } },
119         /* titan_210l */                { 1, { { 3, -1 }, } },
120         /* netmos_9xx5_combo */         { 1, { { 2, -1 }, }, netmos_parallel_init },
121         /* netmos_9855 */               { 1, { { 0, -1 }, }, netmos_parallel_init },
122         /* netmos_9855_2p */            { 2, { { 0, -1 }, { 2, -1 }, } },
123         /* netmos_9900 */               {1, { { 3, 4 }, }, netmos_parallel_init },
124         /* netmos_9900_2p */            {2, { { 0, 1 }, { 3, 4 }, } },
125         /* netmos_99xx_1p */            {1, { { 0, 1 }, } },
126         /* avlab_1s1p     */            { 1, { { 1, 2}, } },
127         /* avlab_1s2p     */            { 2, { { 1, 2}, { 3, 4 },} },
128         /* avlab_2s1p     */            { 1, { { 2, 3}, } },
129         /* siig_1s1p_10x */             { 1, { { 3, 4 }, } },
130         /* siig_2s1p_10x */             { 1, { { 4, 5 }, } },
131         /* siig_2p1s_20x */             { 2, { { 1, 2 }, { 3, 4 }, } },
132         /* siig_1s1p_20x */             { 1, { { 1, 2 }, } },
133         /* siig_2s1p_20x */             { 1, { { 2, 3 }, } },
134         /* timedia_4078a */             { 1, { { 2, -1 }, } },
135         /* timedia_4079h */             { 1, { { 2, 3 }, } },
136         /* timedia_4085h */             { 2, { { 2, -1 }, { 4, -1 }, } },
137         /* timedia_4088a */             { 2, { { 2, 3 }, { 4, 5 }, } },
138         /* timedia_4089a */             { 2, { { 2, 3 }, { 4, 5 }, } },
139         /* timedia_4095a */             { 2, { { 2, 3 }, { 4, 5 }, } },
140         /* timedia_4096a */             { 2, { { 2, 3 }, { 4, 5 }, } },
141         /* timedia_4078u */             { 1, { { 2, -1 }, } },
142         /* timedia_4079a */             { 1, { { 2, 3 }, } },
143         /* timedia_4085u */             { 2, { { 2, -1 }, { 4, -1 }, } },
144         /* timedia_4079r */             { 1, { { 2, 3 }, } },
145         /* timedia_4079s */             { 1, { { 2, 3 }, } },
146         /* timedia_4079d */             { 1, { { 2, 3 }, } },
147         /* timedia_4079e */             { 1, { { 2, 3 }, } },
148         /* timedia_4079f */             { 1, { { 2, 3 }, } },
149         /* timedia_9079a */             { 1, { { 2, 3 }, } },
150         /* timedia_9079b */             { 1, { { 2, 3 }, } },
151         /* timedia_9079c */             { 1, { { 2, 3 }, } },
152         /* wch_ch353_1s1p*/             { 1, { { 1, -1}, } },
153         /* wch_ch353_2s1p*/             { 1, { { 2, -1}, } },
154         /* wch_ch382_0s1p*/             { 1, { { 2, -1}, } },
155         /* wch_ch382_2s1p*/             { 1, { { 2, -1}, } },
156         /* brainboxes_5s1p */           { 1, { { 3, -1 }, } },
157         /* sunix_4008a */               { 1, { { 1, 2 }, } },
158         /* sunix_5069a */               { 1, { { 1, 2 }, } },
159         /* sunix_5079a */               { 1, { { 1, 2 }, } },
160         /* sunix_5099a */               { 1, { { 1, 2 }, } },
161 };
162
163 static struct pci_device_id parport_serial_pci_tbl[] = {
164         /* PCI cards */
165         { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_110L,
166           PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_110l },
167         { PCI_VENDOR_ID_TITAN, PCI_DEVICE_ID_TITAN_210L,
168           PCI_ANY_ID, PCI_ANY_ID, 0, 0, titan_210l },
169         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9735,
170           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
171         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9745,
172           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
173         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9835,
174           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
175         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9845,
176           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9xx5_combo },
177         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
178           0x1000, 0x0020, 0, 0, netmos_9855_2p },
179         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
180           0x1000, 0x0022, 0, 0, netmos_9855_2p },
181         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9855,
182           PCI_ANY_ID, PCI_ANY_ID, 0, 0, netmos_9855 },
183         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
184           0xA000, 0x3011, 0, 0, netmos_9900 },
185         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
186           0xA000, 0x3012, 0, 0, netmos_9900 },
187         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9900,
188           0xA000, 0x3020, 0, 0, netmos_9900_2p },
189         { PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9912,
190           0xA000, 0x2000, 0, 0, netmos_99xx_1p },
191         /* PCI_VENDOR_ID_AVLAB/Intek21 has another bunch of cards ...*/
192         { PCI_VENDOR_ID_AFAVLAB, 0x2110,
193           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
194         { PCI_VENDOR_ID_AFAVLAB, 0x2111,
195           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
196         { PCI_VENDOR_ID_AFAVLAB, 0x2112,
197           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s1p },
198         { PCI_VENDOR_ID_AFAVLAB, 0x2140,
199           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
200         { PCI_VENDOR_ID_AFAVLAB, 0x2141,
201           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
202         { PCI_VENDOR_ID_AFAVLAB, 0x2142,
203           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_1s2p },
204         { PCI_VENDOR_ID_AFAVLAB, 0x2160,
205           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
206         { PCI_VENDOR_ID_AFAVLAB, 0x2161,
207           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
208         { PCI_VENDOR_ID_AFAVLAB, 0x2162,
209           PCI_ANY_ID, PCI_ANY_ID, 0, 0, avlab_2s1p },
210         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_550,
211           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
212         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_650,
213           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
214         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_10x_850,
215           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_10x },
216         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_550,
217           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
218         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_650,
219           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
220         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_10x_850,
221           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_10x },
222         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_550,
223           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
224         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_650,
225           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
226         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2P1S_20x_850,
227           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2p1s_20x },
228         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_550,
229           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
230         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_650,
231           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
232         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_1S1P_20x_850,
233           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_1s1p_20x },
234         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_550,
235           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
236         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_650,
237           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
238         { PCI_VENDOR_ID_SIIG, PCI_DEVICE_ID_SIIG_2S1P_20x_850,
239           PCI_ANY_ID, PCI_ANY_ID, 0, 0, siig_2s1p_20x },
240         /* PCI_VENDOR_ID_TIMEDIA/SUNIX has many differing cards ...*/
241         { 0x1409, 0x7168, 0x1409, 0x4078, 0, 0, timedia_4078a },
242         { 0x1409, 0x7168, 0x1409, 0x4079, 0, 0, timedia_4079h },
243         { 0x1409, 0x7168, 0x1409, 0x4085, 0, 0, timedia_4085h },
244         { 0x1409, 0x7168, 0x1409, 0x4088, 0, 0, timedia_4088a },
245         { 0x1409, 0x7168, 0x1409, 0x4089, 0, 0, timedia_4089a },
246         { 0x1409, 0x7168, 0x1409, 0x4095, 0, 0, timedia_4095a },
247         { 0x1409, 0x7168, 0x1409, 0x4096, 0, 0, timedia_4096a },
248         { 0x1409, 0x7168, 0x1409, 0x5078, 0, 0, timedia_4078u },
249         { 0x1409, 0x7168, 0x1409, 0x5079, 0, 0, timedia_4079a },
250         { 0x1409, 0x7168, 0x1409, 0x5085, 0, 0, timedia_4085u },
251         { 0x1409, 0x7168, 0x1409, 0x6079, 0, 0, timedia_4079r },
252         { 0x1409, 0x7168, 0x1409, 0x7079, 0, 0, timedia_4079s },
253         { 0x1409, 0x7168, 0x1409, 0x8079, 0, 0, timedia_4079d },
254         { 0x1409, 0x7168, 0x1409, 0x9079, 0, 0, timedia_4079e },
255         { 0x1409, 0x7168, 0x1409, 0xa079, 0, 0, timedia_4079f },
256         { 0x1409, 0x7168, 0x1409, 0xb079, 0, 0, timedia_9079a },
257         { 0x1409, 0x7168, 0x1409, 0xc079, 0, 0, timedia_9079b },
258         { 0x1409, 0x7168, 0x1409, 0xd079, 0, 0, timedia_9079c },
259
260         /* WCH CARDS */
261         { 0x4348, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, wch_ch353_1s1p},
262         { 0x4348, 0x7053, 0x4348, 0x3253, 0, 0, wch_ch353_2s1p},
263         { 0x1c00, 0x3050, 0x1c00, 0x3050, 0, 0, wch_ch382_0s1p},
264         { 0x1c00, 0x3250, 0x1c00, 0x3250, 0, 0, wch_ch382_2s1p},
265
266         /* BrainBoxes PX272/PX306 MIO card */
267         { PCI_VENDOR_ID_INTASHIELD, 0x4100,
268           PCI_ANY_ID, PCI_ANY_ID, 0, 0, brainboxes_5s1p },
269
270         /* Sunix boards */
271         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
272           0x0100, 0, 0, sunix_4008a },
273         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
274           0x0101, 0, 0, sunix_5069a },
275         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
276           0x0102, 0, 0, sunix_5079a },
277         { PCI_VENDOR_ID_SUNIX, PCI_DEVICE_ID_SUNIX_1999, PCI_VENDOR_ID_SUNIX,
278           0x0104, 0, 0, sunix_5099a },
279
280         { 0, } /* terminate list */
281 };
282 MODULE_DEVICE_TABLE(pci,parport_serial_pci_tbl);
283
284 /*
285  * This table describes the serial "geometry" of these boards.  Any
286  * quirks for these can be found in drivers/serial/8250_pci.c
287  *
288  * Cards not tested are marked n/t
289  * If you have one of these cards and it works for you, please tell me..
290  */
291 static struct pciserial_board pci_parport_serial_boards[] = {
292         [titan_110l] = {
293                 .flags          = FL_BASE1 | FL_BASE_BARS,
294                 .num_ports      = 1,
295                 .base_baud      = 921600,
296                 .uart_offset    = 8,
297         },
298         [titan_210l] = {
299                 .flags          = FL_BASE1 | FL_BASE_BARS,
300                 .num_ports      = 2,
301                 .base_baud      = 921600,
302                 .uart_offset    = 8,
303         },
304         [netmos_9xx5_combo] = {
305                 .flags          = FL_BASE0 | FL_BASE_BARS,
306                 .num_ports      = 1,
307                 .base_baud      = 115200,
308                 .uart_offset    = 8,
309         },
310         [netmos_9855] = {
311                 .flags          = FL_BASE2 | FL_BASE_BARS,
312                 .num_ports      = 1,
313                 .base_baud      = 115200,
314                 .uart_offset    = 8,
315         },
316         [netmos_9855_2p] = {
317                 .flags          = FL_BASE4 | FL_BASE_BARS,
318                 .num_ports      = 1,
319                 .base_baud      = 115200,
320                 .uart_offset    = 8,
321         },
322         [netmos_9900] = { /* n/t */
323                 .flags          = FL_BASE0 | FL_BASE_BARS,
324                 .num_ports      = 1,
325                 .base_baud      = 115200,
326                 .uart_offset    = 8,
327         },
328         [netmos_9900_2p] = { /* parallel only */ /* n/t */
329                 .flags          = FL_BASE0,
330                 .num_ports      = 0,
331                 .base_baud      = 115200,
332                 .uart_offset    = 8,
333         },
334         [netmos_99xx_1p] = { /* parallel only */ /* n/t */
335                 .flags          = FL_BASE0,
336                 .num_ports      = 0,
337                 .base_baud      = 115200,
338                 .uart_offset    = 8,
339         },
340         [avlab_1s1p] = { /* n/t */
341                 .flags          = FL_BASE0 | FL_BASE_BARS,
342                 .num_ports      = 1,
343                 .base_baud      = 115200,
344                 .uart_offset    = 8,
345         },
346         [avlab_1s2p] = { /* n/t */
347                 .flags          = FL_BASE0 | FL_BASE_BARS,
348                 .num_ports      = 1,
349                 .base_baud      = 115200,
350                 .uart_offset    = 8,
351         },
352         [avlab_2s1p] = { /* n/t */
353                 .flags          = FL_BASE0 | FL_BASE_BARS,
354                 .num_ports      = 2,
355                 .base_baud      = 115200,
356                 .uart_offset    = 8,
357         },
358         [siig_1s1p_10x] = {
359                 .flags          = FL_BASE2,
360                 .num_ports      = 1,
361                 .base_baud      = 460800,
362                 .uart_offset    = 8,
363         },
364         [siig_2s1p_10x] = {
365                 .flags          = FL_BASE2,
366                 .num_ports      = 1,
367                 .base_baud      = 921600,
368                 .uart_offset    = 8,
369         },
370         [siig_2p1s_20x] = {
371                 .flags          = FL_BASE0,
372                 .num_ports      = 1,
373                 .base_baud      = 921600,
374                 .uart_offset    = 8,
375         },
376         [siig_1s1p_20x] = {
377                 .flags          = FL_BASE0,
378                 .num_ports      = 1,
379                 .base_baud      = 921600,
380                 .uart_offset    = 8,
381         },
382         [siig_2s1p_20x] = {
383                 .flags          = FL_BASE0,
384                 .num_ports      = 1,
385                 .base_baud      = 921600,
386                 .uart_offset    = 8,
387         },
388         [timedia_4078a] = {
389                 .flags          = FL_BASE0|FL_BASE_BARS,
390                 .num_ports      = 1,
391                 .base_baud      = 921600,
392                 .uart_offset    = 8,
393         },
394         [timedia_4079h] = {
395                 .flags          = FL_BASE0|FL_BASE_BARS,
396                 .num_ports      = 1,
397                 .base_baud      = 921600,
398                 .uart_offset    = 8,
399         },
400         [timedia_4085h] = {
401                 .flags          = FL_BASE0|FL_BASE_BARS,
402                 .num_ports      = 1,
403                 .base_baud      = 921600,
404                 .uart_offset    = 8,
405         },
406         [timedia_4088a] = {
407                 .flags          = FL_BASE0|FL_BASE_BARS,
408                 .num_ports      = 1,
409                 .base_baud      = 921600,
410                 .uart_offset    = 8,
411         },
412         [timedia_4089a] = {
413                 .flags          = FL_BASE0|FL_BASE_BARS,
414                 .num_ports      = 1,
415                 .base_baud      = 921600,
416                 .uart_offset    = 8,
417         },
418         [timedia_4095a] = {
419                 .flags          = FL_BASE0|FL_BASE_BARS,
420                 .num_ports      = 1,
421                 .base_baud      = 921600,
422                 .uart_offset    = 8,
423         },
424         [timedia_4096a] = {
425                 .flags          = FL_BASE0|FL_BASE_BARS,
426                 .num_ports      = 1,
427                 .base_baud      = 921600,
428                 .uart_offset    = 8,
429         },
430         [timedia_4078u] = {
431                 .flags          = FL_BASE0|FL_BASE_BARS,
432                 .num_ports      = 1,
433                 .base_baud      = 921600,
434                 .uart_offset    = 8,
435         },
436         [timedia_4079a] = {
437                 .flags          = FL_BASE0|FL_BASE_BARS,
438                 .num_ports      = 1,
439                 .base_baud      = 921600,
440                 .uart_offset    = 8,
441         },
442         [timedia_4085u] = {
443                 .flags          = FL_BASE0|FL_BASE_BARS,
444                 .num_ports      = 1,
445                 .base_baud      = 921600,
446                 .uart_offset    = 8,
447         },
448         [timedia_4079r] = {
449                 .flags          = FL_BASE0|FL_BASE_BARS,
450                 .num_ports      = 1,
451                 .base_baud      = 921600,
452                 .uart_offset    = 8,
453         },
454         [timedia_4079s] = {
455                 .flags          = FL_BASE0|FL_BASE_BARS,
456                 .num_ports      = 1,
457                 .base_baud      = 921600,
458                 .uart_offset    = 8,
459         },
460         [timedia_4079d] = {
461                 .flags          = FL_BASE0|FL_BASE_BARS,
462                 .num_ports      = 1,
463                 .base_baud      = 921600,
464                 .uart_offset    = 8,
465         },
466         [timedia_4079e] = {
467                 .flags          = FL_BASE0|FL_BASE_BARS,
468                 .num_ports      = 1,
469                 .base_baud      = 921600,
470                 .uart_offset    = 8,
471         },
472         [timedia_4079f] = {
473                 .flags          = FL_BASE0|FL_BASE_BARS,
474                 .num_ports      = 1,
475                 .base_baud      = 921600,
476                 .uart_offset    = 8,
477         },
478         [timedia_9079a] = {
479                 .flags          = FL_BASE0|FL_BASE_BARS,
480                 .num_ports      = 1,
481                 .base_baud      = 921600,
482                 .uart_offset    = 8,
483         },
484         [timedia_9079b] = {
485                 .flags          = FL_BASE0|FL_BASE_BARS,
486                 .num_ports      = 1,
487                 .base_baud      = 921600,
488                 .uart_offset    = 8,
489         },
490         [timedia_9079c] = {
491                 .flags          = FL_BASE0|FL_BASE_BARS,
492                 .num_ports      = 1,
493                 .base_baud      = 921600,
494                 .uart_offset    = 8,
495         },
496         [wch_ch353_1s1p] = {
497                 .flags          = FL_BASE0|FL_BASE_BARS,
498                 .num_ports      = 1,
499                 .base_baud      = 115200,
500                 .uart_offset    = 8,
501         },
502         [wch_ch353_2s1p] = {
503                 .flags          = FL_BASE0|FL_BASE_BARS,
504                 .num_ports      = 2,
505                 .base_baud      = 115200,
506                 .uart_offset    = 8,
507         },
508         [wch_ch382_0s1p] = {
509                 .flags          = FL_BASE0,
510                 .num_ports      = 0,
511                 .base_baud      = 115200,
512                 .uart_offset    = 8,
513         },
514         [wch_ch382_2s1p] = {
515                 .flags          = FL_BASE0,
516                 .num_ports      = 2,
517                 .base_baud      = 115200,
518                 .uart_offset    = 8,
519                 .first_offset   = 0xC0,
520         },
521         [brainboxes_5s1p] = {
522                 .flags          = FL_BASE2,
523                 .num_ports      = 5,
524                 .base_baud      = 921600,
525                 .uart_offset    = 8,
526         },
527         [sunix_4008a] = {
528                 .num_ports      = 0,
529         },
530         [sunix_5069a] = {
531                 .num_ports      = 1,
532                 .base_baud      = 921600,
533                 .uart_offset    = 0x8,
534         },
535         [sunix_5079a] = {
536                 .num_ports      = 2,
537                 .base_baud      = 921600,
538                 .uart_offset    = 0x8,
539         },
540         [sunix_5099a] = {
541                 .num_ports      = 4,
542                 .base_baud      = 921600,
543                 .uart_offset    = 0x8,
544         },
545 };
546
547 struct parport_serial_private {
548         struct serial_private   *serial;
549         int num_par;
550         struct parport *port[PARPORT_MAX];
551         struct parport_pc_pci par;
552 };
553
554 /* Register the serial port(s) of a PCI card. */
555 static int serial_register(struct pci_dev *dev, const struct pci_device_id *id)
556 {
557         struct parport_serial_private *priv = pci_get_drvdata (dev);
558         struct pciserial_board *board;
559         struct serial_private *serial;
560
561         board = &pci_parport_serial_boards[id->driver_data];
562         if (board->num_ports == 0)
563                 return 0;
564
565         serial = pciserial_init_ports(dev, board);
566         if (IS_ERR(serial))
567                 return PTR_ERR(serial);
568
569         priv->serial = serial;
570         return 0;
571 }
572
573 /* Register the parallel port(s) of a PCI card. */
574 static int parport_register(struct pci_dev *dev, const struct pci_device_id *id)
575 {
576         struct parport_pc_pci *card;
577         struct parport_serial_private *priv = pci_get_drvdata (dev);
578         int n, success = 0;
579
580         priv->par = cards[id->driver_data];
581         card = &priv->par;
582         if (card->preinit_hook &&
583             card->preinit_hook (dev, card, PARPORT_IRQ_NONE, PARPORT_DMA_NONE))
584                 return -ENODEV;
585
586         for (n = 0; n < card->numports; n++) {
587                 struct parport *port;
588                 int lo = card->addr[n].lo;
589                 int hi = card->addr[n].hi;
590                 unsigned long io_lo, io_hi;
591                 int irq;
592
593                 if (priv->num_par == ARRAY_SIZE (priv->port)) {
594                         dev_warn(&dev->dev,
595                                  "only %zu parallel ports supported (%d reported)\n",
596                                  ARRAY_SIZE(priv->port), card->numports);
597                         break;
598                 }
599
600                 io_lo = pci_resource_start (dev, lo);
601                 io_hi = 0;
602                 if ((hi >= 0) && (hi <= 6))
603                         io_hi = pci_resource_start (dev, hi);
604                 else if (hi > 6)
605                         io_lo += hi; /* Reinterpret the meaning of
606                                         "hi" as an offset (see SYBA
607                                         def.) */
608                 /* TODO: test if sharing interrupts works */
609                 irq = pci_irq_vector(dev, 0);
610                 if (irq < 0)
611                         return irq;
612                 if (irq == 0)
613                         irq = PARPORT_IRQ_NONE;
614                 if (irq == PARPORT_IRQ_NONE) {
615                         dev_dbg(&dev->dev,
616                                 "PCI parallel port detected: I/O at %#lx(%#lx)\n",
617                                 io_lo, io_hi);
618                 } else {
619                         dev_dbg(&dev->dev,
620                                 "PCI parallel port detected: I/O at %#lx(%#lx), IRQ %d\n",
621                                 io_lo, io_hi, irq);
622                 }
623                 port = parport_pc_probe_port (io_lo, io_hi, irq,
624                               PARPORT_DMA_NONE, &dev->dev, IRQF_SHARED);
625                 if (port) {
626                         priv->port[priv->num_par++] = port;
627                         success = 1;
628                 }
629         }
630
631         if (card->postinit_hook)
632                 card->postinit_hook (dev, card, !success);
633
634         return 0;
635 }
636
637 static int parport_serial_pci_probe(struct pci_dev *dev,
638                                     const struct pci_device_id *id)
639 {
640         struct parport_serial_private *priv;
641         int err;
642
643         priv = devm_kzalloc(&dev->dev, sizeof(*priv), GFP_KERNEL);
644         if (!priv)
645                 return -ENOMEM;
646
647         pci_set_drvdata (dev, priv);
648
649         err = pcim_enable_device(dev);
650         if (err)
651                 return err;
652
653         err = parport_register(dev, id);
654         if (err)
655                 return err;
656
657         err = serial_register(dev, id);
658         if (err) {
659                 int i;
660                 for (i = 0; i < priv->num_par; i++)
661                         parport_pc_unregister_port (priv->port[i]);
662                 return err;
663         }
664
665         return 0;
666 }
667
668 static void parport_serial_pci_remove(struct pci_dev *dev)
669 {
670         struct parport_serial_private *priv = pci_get_drvdata (dev);
671         int i;
672
673         // Serial ports
674         if (priv->serial)
675                 pciserial_remove_ports(priv->serial);
676
677         // Parallel ports
678         for (i = 0; i < priv->num_par; i++)
679                 parport_pc_unregister_port (priv->port[i]);
680
681         return;
682 }
683
684 static int __maybe_unused parport_serial_pci_suspend(struct device *dev)
685 {
686         struct parport_serial_private *priv = dev_get_drvdata(dev);
687
688         if (priv->serial)
689                 pciserial_suspend_ports(priv->serial);
690
691         /* FIXME: What about parport? */
692         return 0;
693 }
694
695 static int __maybe_unused parport_serial_pci_resume(struct device *dev)
696 {
697         struct parport_serial_private *priv = dev_get_drvdata(dev);
698
699         if (priv->serial)
700                 pciserial_resume_ports(priv->serial);
701
702         /* FIXME: What about parport? */
703         return 0;
704 }
705
706 static SIMPLE_DEV_PM_OPS(parport_serial_pm_ops,
707                          parport_serial_pci_suspend, parport_serial_pci_resume);
708
709 static struct pci_driver parport_serial_pci_driver = {
710         .name           = "parport_serial",
711         .id_table       = parport_serial_pci_tbl,
712         .probe          = parport_serial_pci_probe,
713         .remove         = parport_serial_pci_remove,
714         .driver         = {
715                 .pm     = &parport_serial_pm_ops,
716         },
717 };
718 module_pci_driver(parport_serial_pci_driver);
719
720 MODULE_AUTHOR("Tim Waugh <twaugh@redhat.com>");
721 MODULE_DESCRIPTION("Driver for common parallel+serial multi-I/O PCI cards");
722 MODULE_LICENSE("GPL");