44 * Copyright (C) 2016 William Breathitt Gray
55 */
66#include <linux/bitmap.h>
7- #include <linux/bitops.h>
87#include <linux/device.h>
98#include <linux/errno.h>
109#include <linux/gpio/driver.h>
1716#include <linux/module.h>
1817#include <linux/moduleparam.h>
1918#include <linux/spinlock.h>
19+ #include <linux/types.h>
2020
21- #define WS16C48_EXTENT 16
21+ #define WS16C48_EXTENT 10
2222#define MAX_NUM_WS16C48 max_num_isa_dev(WS16C48_EXTENT)
2323
2424static unsigned int base [MAX_NUM_WS16C48 ];
@@ -30,6 +30,20 @@ static unsigned int irq[MAX_NUM_WS16C48];
3030module_param_hw_array (irq , uint , irq , NULL , 0 );
3131MODULE_PARM_DESC (irq , "WinSystems WS16C48 interrupt line numbers" );
3232
33+ /**
34+ * struct ws16c48_reg - device register structure
35+ * @port: Port 0 through 5 I/O
36+ * @int_pending: Interrupt Pending
37+ * @page_lock: Register page (Bits 7-6) and I/O port lock (Bits 5-0)
38+ * @pol_enab_int_id: Interrupt polarity, enable, and ID
39+ */
40+ struct ws16c48_reg {
41+ u8 port [6 ];
42+ u8 int_pending ;
43+ u8 page_lock ;
44+ u8 pol_enab_int_id [3 ];
45+ };
46+
3347/**
3448 * struct ws16c48_gpio - GPIO device private data structure
3549 * @chip: instance of the gpio_chip
@@ -38,7 +52,7 @@ MODULE_PARM_DESC(irq, "WinSystems WS16C48 interrupt line numbers");
3852 * @lock: synchronization lock to prevent I/O race conditions
3953 * @irq_mask: I/O bits affected by interrupts
4054 * @flow_mask: IRQ flow type mask for the respective I/O bits
41- * @base: base port address of the GPIO device
55+ * @reg: I/O address offset for the device registers
4256 */
4357struct ws16c48_gpio {
4458 struct gpio_chip chip ;
@@ -47,7 +61,7 @@ struct ws16c48_gpio {
4761 raw_spinlock_t lock ;
4862 unsigned long irq_mask ;
4963 unsigned long flow_mask ;
50- void __iomem * base ;
64+ struct ws16c48_reg __iomem * reg ;
5165};
5266
5367static int ws16c48_gpio_get_direction (struct gpio_chip * chip , unsigned offset )
@@ -73,7 +87,7 @@ static int ws16c48_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
7387
7488 ws16c48gpio -> io_state [port ] |= mask ;
7589 ws16c48gpio -> out_state [port ] &= ~mask ;
76- iowrite8 (ws16c48gpio -> out_state [port ], ws16c48gpio -> base + port );
90+ iowrite8 (ws16c48gpio -> out_state [port ], ws16c48gpio -> reg -> port + port );
7791
7892 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
7993
@@ -95,7 +109,7 @@ static int ws16c48_gpio_direction_output(struct gpio_chip *chip,
95109 ws16c48gpio -> out_state [port ] |= mask ;
96110 else
97111 ws16c48gpio -> out_state [port ] &= ~mask ;
98- iowrite8 (ws16c48gpio -> out_state [port ], ws16c48gpio -> base + port );
112+ iowrite8 (ws16c48gpio -> out_state [port ], ws16c48gpio -> reg -> port + port );
99113
100114 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
101115
@@ -118,7 +132,7 @@ static int ws16c48_gpio_get(struct gpio_chip *chip, unsigned offset)
118132 return - EINVAL ;
119133 }
120134
121- port_state = ioread8 (ws16c48gpio -> base + port );
135+ port_state = ioread8 (ws16c48gpio -> reg -> port + port );
122136
123137 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
124138
@@ -131,14 +145,16 @@ static int ws16c48_gpio_get_multiple(struct gpio_chip *chip,
131145 struct ws16c48_gpio * const ws16c48gpio = gpiochip_get_data (chip );
132146 unsigned long offset ;
133147 unsigned long gpio_mask ;
134- void __iomem * port_addr ;
148+ size_t index ;
149+ u8 __iomem * port_addr ;
135150 unsigned long port_state ;
136151
137152 /* clear bits array to a clean slate */
138153 bitmap_zero (bits , chip -> ngpio );
139154
140155 for_each_set_clump8 (offset , gpio_mask , mask , chip -> ngpio ) {
141- port_addr = ws16c48gpio -> base + offset / 8 ;
156+ index = offset / 8 ;
157+ port_addr = ws16c48gpio -> reg -> port + index ;
142158 port_state = ioread8 (port_addr ) & gpio_mask ;
143159
144160 bitmap_set_value8 (bits , port_state , offset );
@@ -166,7 +182,7 @@ static void ws16c48_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
166182 ws16c48gpio -> out_state [port ] |= mask ;
167183 else
168184 ws16c48gpio -> out_state [port ] &= ~mask ;
169- iowrite8 (ws16c48gpio -> out_state [port ], ws16c48gpio -> base + port );
185+ iowrite8 (ws16c48gpio -> out_state [port ], ws16c48gpio -> reg -> port + port );
170186
171187 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
172188}
@@ -178,13 +194,13 @@ static void ws16c48_gpio_set_multiple(struct gpio_chip *chip,
178194 unsigned long offset ;
179195 unsigned long gpio_mask ;
180196 size_t index ;
181- void __iomem * port_addr ;
197+ u8 __iomem * port_addr ;
182198 unsigned long bitmask ;
183199 unsigned long flags ;
184200
185201 for_each_set_clump8 (offset , gpio_mask , mask , chip -> ngpio ) {
186202 index = offset / 8 ;
187- port_addr = ws16c48gpio -> base + index ;
203+ port_addr = ws16c48gpio -> reg -> port + index ;
188204
189205 /* mask out GPIO configured for input */
190206 gpio_mask &= ~ws16c48gpio -> io_state [index ];
@@ -219,10 +235,15 @@ static void ws16c48_irq_ack(struct irq_data *data)
219235
220236 port_state = ws16c48gpio -> irq_mask >> (8 * port );
221237
222- iowrite8 (0x80 , ws16c48gpio -> base + 7 );
223- iowrite8 (port_state & ~mask , ws16c48gpio -> base + 8 + port );
224- iowrite8 (port_state | mask , ws16c48gpio -> base + 8 + port );
225- iowrite8 (0xC0 , ws16c48gpio -> base + 7 );
238+ /* Select Register Page 2; Unlock all I/O ports */
239+ iowrite8 (0x80 , & ws16c48gpio -> reg -> page_lock );
240+
241+ /* Clear pending interrupt */
242+ iowrite8 (port_state & ~mask , ws16c48gpio -> reg -> pol_enab_int_id + port );
243+ iowrite8 (port_state | mask , ws16c48gpio -> reg -> pol_enab_int_id + port );
244+
245+ /* Select Register Page 3; Unlock all I/O ports */
246+ iowrite8 (0xC0 , & ws16c48gpio -> reg -> page_lock );
226247
227248 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
228249}
@@ -235,6 +256,7 @@ static void ws16c48_irq_mask(struct irq_data *data)
235256 const unsigned long mask = BIT (offset );
236257 const unsigned port = offset / 8 ;
237258 unsigned long flags ;
259+ unsigned long port_state ;
238260
239261 /* only the first 3 ports support interrupts */
240262 if (port > 2 )
@@ -243,10 +265,16 @@ static void ws16c48_irq_mask(struct irq_data *data)
243265 raw_spin_lock_irqsave (& ws16c48gpio -> lock , flags );
244266
245267 ws16c48gpio -> irq_mask &= ~mask ;
268+ port_state = ws16c48gpio -> irq_mask >> (8 * port );
269+
270+ /* Select Register Page 2; Unlock all I/O ports */
271+ iowrite8 (0x80 , & ws16c48gpio -> reg -> page_lock );
246272
247- iowrite8 (0x80 , ws16c48gpio -> base + 7 );
248- iowrite8 (ws16c48gpio -> irq_mask >> (8 * port ), ws16c48gpio -> base + 8 + port );
249- iowrite8 (0xC0 , ws16c48gpio -> base + 7 );
273+ /* Disable interrupt */
274+ iowrite8 (port_state , ws16c48gpio -> reg -> pol_enab_int_id + port );
275+
276+ /* Select Register Page 3; Unlock all I/O ports */
277+ iowrite8 (0xC0 , & ws16c48gpio -> reg -> page_lock );
250278
251279 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
252280}
@@ -259,6 +287,7 @@ static void ws16c48_irq_unmask(struct irq_data *data)
259287 const unsigned long mask = BIT (offset );
260288 const unsigned port = offset / 8 ;
261289 unsigned long flags ;
290+ unsigned long port_state ;
262291
263292 /* only the first 3 ports support interrupts */
264293 if (port > 2 )
@@ -267,10 +296,16 @@ static void ws16c48_irq_unmask(struct irq_data *data)
267296 raw_spin_lock_irqsave (& ws16c48gpio -> lock , flags );
268297
269298 ws16c48gpio -> irq_mask |= mask ;
299+ port_state = ws16c48gpio -> irq_mask >> (8 * port );
300+
301+ /* Select Register Page 2; Unlock all I/O ports */
302+ iowrite8 (0x80 , & ws16c48gpio -> reg -> page_lock );
270303
271- iowrite8 (0x80 , ws16c48gpio -> base + 7 );
272- iowrite8 (ws16c48gpio -> irq_mask >> (8 * port ), ws16c48gpio -> base + 8 + port );
273- iowrite8 (0xC0 , ws16c48gpio -> base + 7 );
304+ /* Enable interrupt */
305+ iowrite8 (port_state , ws16c48gpio -> reg -> pol_enab_int_id + port );
306+
307+ /* Select Register Page 3; Unlock all I/O ports */
308+ iowrite8 (0xC0 , & ws16c48gpio -> reg -> page_lock );
274309
275310 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
276311}
@@ -283,6 +318,7 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
283318 const unsigned long mask = BIT (offset );
284319 const unsigned port = offset / 8 ;
285320 unsigned long flags ;
321+ unsigned long port_state ;
286322
287323 /* only the first 3 ports support interrupts */
288324 if (port > 2 )
@@ -304,9 +340,16 @@ static int ws16c48_irq_set_type(struct irq_data *data, unsigned flow_type)
304340 return - EINVAL ;
305341 }
306342
307- iowrite8 (0x40 , ws16c48gpio -> base + 7 );
308- iowrite8 (ws16c48gpio -> flow_mask >> (8 * port ), ws16c48gpio -> base + 8 + port );
309- iowrite8 (0xC0 , ws16c48gpio -> base + 7 );
343+ port_state = ws16c48gpio -> flow_mask >> (8 * port );
344+
345+ /* Select Register Page 1; Unlock all I/O ports */
346+ iowrite8 (0x40 , & ws16c48gpio -> reg -> page_lock );
347+
348+ /* Set interrupt polarity */
349+ iowrite8 (port_state , ws16c48gpio -> reg -> pol_enab_int_id + port );
350+
351+ /* Select Register Page 3; Unlock all I/O ports */
352+ iowrite8 (0xC0 , & ws16c48gpio -> reg -> page_lock );
310353
311354 raw_spin_unlock_irqrestore (& ws16c48gpio -> lock , flags );
312355
@@ -325,25 +368,26 @@ static irqreturn_t ws16c48_irq_handler(int irq, void *dev_id)
325368{
326369 struct ws16c48_gpio * const ws16c48gpio = dev_id ;
327370 struct gpio_chip * const chip = & ws16c48gpio -> chip ;
371+ struct ws16c48_reg __iomem * const reg = ws16c48gpio -> reg ;
328372 unsigned long int_pending ;
329373 unsigned long port ;
330374 unsigned long int_id ;
331375 unsigned long gpio ;
332376
333- int_pending = ioread8 (ws16c48gpio -> base + 6 ) & 0x7 ;
377+ int_pending = ioread8 (& reg -> int_pending ) & 0x7 ;
334378 if (!int_pending )
335379 return IRQ_NONE ;
336380
337381 /* loop until all pending interrupts are handled */
338382 do {
339383 for_each_set_bit (port , & int_pending , 3 ) {
340- int_id = ioread8 (ws16c48gpio -> base + 8 + port );
384+ int_id = ioread8 (reg -> pol_enab_int_id + port );
341385 for_each_set_bit (gpio , & int_id , 8 )
342386 generic_handle_domain_irq (chip -> irq .domain ,
343387 gpio + 8 * port );
344388 }
345389
346- int_pending = ioread8 (ws16c48gpio -> base + 6 ) & 0x7 ;
390+ int_pending = ioread8 (& reg -> int_pending ) & 0x7 ;
347391 } while (int_pending );
348392
349393 return IRQ_HANDLED ;
@@ -369,12 +413,16 @@ static int ws16c48_irq_init_hw(struct gpio_chip *gc)
369413{
370414 struct ws16c48_gpio * const ws16c48gpio = gpiochip_get_data (gc );
371415
372- /* Disable IRQ by default */
373- iowrite8 (0x80 , ws16c48gpio -> base + 7 );
374- iowrite8 (0 , ws16c48gpio -> base + 8 );
375- iowrite8 (0 , ws16c48gpio -> base + 9 );
376- iowrite8 (0 , ws16c48gpio -> base + 10 );
377- iowrite8 (0xC0 , ws16c48gpio -> base + 7 );
416+ /* Select Register Page 2; Unlock all I/O ports */
417+ iowrite8 (0x80 , & ws16c48gpio -> reg -> page_lock );
418+
419+ /* Disable interrupts for all lines */
420+ iowrite8 (0 , & ws16c48gpio -> reg -> pol_enab_int_id [0 ]);
421+ iowrite8 (0 , & ws16c48gpio -> reg -> pol_enab_int_id [1 ]);
422+ iowrite8 (0 , & ws16c48gpio -> reg -> pol_enab_int_id [2 ]);
423+
424+ /* Select Register Page 3; Unlock all I/O ports */
425+ iowrite8 (0xC0 , & ws16c48gpio -> reg -> page_lock );
378426
379427 return 0 ;
380428}
@@ -396,8 +444,8 @@ static int ws16c48_probe(struct device *dev, unsigned int id)
396444 return - EBUSY ;
397445 }
398446
399- ws16c48gpio -> base = devm_ioport_map (dev , base [id ], WS16C48_EXTENT );
400- if (!ws16c48gpio -> base )
447+ ws16c48gpio -> reg = devm_ioport_map (dev , base [id ], WS16C48_EXTENT );
448+ if (!ws16c48gpio -> reg )
401449 return - ENOMEM ;
402450
403451 ws16c48gpio -> chip .label = name ;
0 commit comments