6
6
* This driver supports the following Diamond Systems devices: GPIO-MM and
7
7
* GPIO-MM-12.
8
8
*/
9
- #include <linux/bitmap.h>
10
- #include <linux/bitops.h>
11
9
#include <linux/device.h>
12
10
#include <linux/errno.h>
13
11
#include <linux/gpio/driver.h>
17
15
#include <linux/kernel.h>
18
16
#include <linux/module.h>
19
17
#include <linux/moduleparam.h>
20
- #include <linux/spinlock.h>
18
+
19
+ #include "gpio-i8255.h"
20
+
21
+ MODULE_IMPORT_NS (I8255 );
21
22
22
23
#define GPIOMM_EXTENT 8
23
24
#define MAX_NUM_GPIOMM max_num_isa_dev(GPIOMM_EXTENT)
@@ -27,32 +28,26 @@ static unsigned int num_gpiomm;
27
28
module_param_hw_array (base , uint , ioport , & num_gpiomm , 0 );
28
29
MODULE_PARM_DESC (base , "Diamond Systems GPIO-MM base addresses" );
29
30
31
+ #define GPIOMM_NUM_PPI 2
32
+
30
33
/**
31
34
* struct gpiomm_gpio - GPIO device private data structure
32
- * @chip: instance of the gpio_chip
33
- * @io_state: bit I/O state (whether bit is set to input or output)
34
- * @out_state: output bits state
35
- * @control: Control registers state
36
- * @lock: synchronization lock to prevent I/O race conditions
37
- * @base: base port address of the GPIO device
35
+ * @chip: instance of the gpio_chip
36
+ * @ppi_state: Programmable Peripheral Interface group states
37
+ * @ppi: Programmable Peripheral Interface groups
38
38
*/
39
39
struct gpiomm_gpio {
40
40
struct gpio_chip chip ;
41
- unsigned char io_state [6 ];
42
- unsigned char out_state [6 ];
43
- unsigned char control [2 ];
44
- spinlock_t lock ;
45
- void __iomem * base ;
41
+ struct i8255_state ppi_state [GPIOMM_NUM_PPI ];
42
+ struct i8255 __iomem * ppi ;
46
43
};
47
44
48
45
static int gpiomm_gpio_get_direction (struct gpio_chip * chip ,
49
46
unsigned int offset )
50
47
{
51
48
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
52
- const unsigned int port = offset / 8 ;
53
- const unsigned int mask = BIT (offset % 8 );
54
49
55
- if (gpiommgpio -> io_state [ port ] & mask )
50
+ if (i8255_get_direction ( gpiommgpio -> ppi_state , offset ) )
56
51
return GPIO_LINE_DIRECTION_IN ;
57
52
58
53
return GPIO_LINE_DIRECTION_OUT ;
@@ -62,35 +57,8 @@ static int gpiomm_gpio_direction_input(struct gpio_chip *chip,
62
57
unsigned int offset )
63
58
{
64
59
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
65
- const unsigned int io_port = offset / 8 ;
66
- const unsigned int control_port = io_port / 3 ;
67
- unsigned long flags ;
68
- unsigned int control ;
69
-
70
- spin_lock_irqsave (& gpiommgpio -> lock , flags );
71
-
72
- /* Check if configuring Port C */
73
- if (io_port == 2 || io_port == 5 ) {
74
- /* Port C can be configured by nibble */
75
- if (offset % 8 > 3 ) {
76
- gpiommgpio -> io_state [io_port ] |= 0xF0 ;
77
- gpiommgpio -> control [control_port ] |= BIT (3 );
78
- } else {
79
- gpiommgpio -> io_state [io_port ] |= 0x0F ;
80
- gpiommgpio -> control [control_port ] |= BIT (0 );
81
- }
82
- } else {
83
- gpiommgpio -> io_state [io_port ] |= 0xFF ;
84
- if (io_port == 0 || io_port == 3 )
85
- gpiommgpio -> control [control_port ] |= BIT (4 );
86
- else
87
- gpiommgpio -> control [control_port ] |= BIT (1 );
88
- }
89
60
90
- control = BIT (7 ) | gpiommgpio -> control [control_port ];
91
- iowrite8 (control , gpiommgpio -> base + 3 + control_port * 4 );
92
-
93
- spin_unlock_irqrestore (& gpiommgpio -> lock , flags );
61
+ i8255_direction_input (gpiommgpio -> ppi , gpiommgpio -> ppi_state , offset );
94
62
95
63
return 0 ;
96
64
}
@@ -99,92 +67,26 @@ static int gpiomm_gpio_direction_output(struct gpio_chip *chip,
99
67
unsigned int offset , int value )
100
68
{
101
69
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
102
- const unsigned int io_port = offset / 8 ;
103
- const unsigned int control_port = io_port / 3 ;
104
- const unsigned int mask = BIT (offset % 8 );
105
- const unsigned int out_port = (io_port > 2 ) ? io_port + 1 : io_port ;
106
- unsigned long flags ;
107
- unsigned int control ;
108
-
109
- spin_lock_irqsave (& gpiommgpio -> lock , flags );
110
-
111
- /* Check if configuring Port C */
112
- if (io_port == 2 || io_port == 5 ) {
113
- /* Port C can be configured by nibble */
114
- if (offset % 8 > 3 ) {
115
- gpiommgpio -> io_state [io_port ] &= 0x0F ;
116
- gpiommgpio -> control [control_port ] &= ~BIT (3 );
117
- } else {
118
- gpiommgpio -> io_state [io_port ] &= 0xF0 ;
119
- gpiommgpio -> control [control_port ] &= ~BIT (0 );
120
- }
121
- } else {
122
- gpiommgpio -> io_state [io_port ] &= 0x00 ;
123
- if (io_port == 0 || io_port == 3 )
124
- gpiommgpio -> control [control_port ] &= ~BIT (4 );
125
- else
126
- gpiommgpio -> control [control_port ] &= ~BIT (1 );
127
- }
128
-
129
- if (value )
130
- gpiommgpio -> out_state [io_port ] |= mask ;
131
- else
132
- gpiommgpio -> out_state [io_port ] &= ~mask ;
133
-
134
- control = BIT (7 ) | gpiommgpio -> control [control_port ];
135
- iowrite8 (control , gpiommgpio -> base + 3 + control_port * 4 );
136
70
137
- iowrite8 (gpiommgpio -> out_state [io_port ], gpiommgpio -> base + out_port );
138
-
139
- spin_unlock_irqrestore (& gpiommgpio -> lock , flags );
71
+ i8255_direction_output (gpiommgpio -> ppi , gpiommgpio -> ppi_state , offset ,
72
+ value );
140
73
141
74
return 0 ;
142
75
}
143
76
144
77
static int gpiomm_gpio_get (struct gpio_chip * chip , unsigned int offset )
145
78
{
146
79
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
147
- const unsigned int port = offset / 8 ;
148
- const unsigned int mask = BIT (offset % 8 );
149
- const unsigned int in_port = (port > 2 ) ? port + 1 : port ;
150
- unsigned long flags ;
151
- unsigned int port_state ;
152
-
153
- spin_lock_irqsave (& gpiommgpio -> lock , flags );
154
-
155
- /* ensure that GPIO is set for input */
156
- if (!(gpiommgpio -> io_state [port ] & mask )) {
157
- spin_unlock_irqrestore (& gpiommgpio -> lock , flags );
158
- return - EINVAL ;
159
- }
160
-
161
- port_state = ioread8 (gpiommgpio -> base + in_port );
162
-
163
- spin_unlock_irqrestore (& gpiommgpio -> lock , flags );
164
80
165
- return !!( port_state & mask );
81
+ return i8255_get ( gpiommgpio -> ppi , offset );
166
82
}
167
83
168
- static const size_t ports [] = { 0 , 1 , 2 , 4 , 5 , 6 };
169
-
170
84
static int gpiomm_gpio_get_multiple (struct gpio_chip * chip , unsigned long * mask ,
171
85
unsigned long * bits )
172
86
{
173
87
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
174
- unsigned long offset ;
175
- unsigned long gpio_mask ;
176
- void __iomem * port_addr ;
177
- unsigned long port_state ;
178
-
179
- /* clear bits array to a clean slate */
180
- bitmap_zero (bits , chip -> ngpio );
181
88
182
- for_each_set_clump8 (offset , gpio_mask , mask , ARRAY_SIZE (ports ) * 8 ) {
183
- port_addr = gpiommgpio -> base + ports [offset / 8 ];
184
- port_state = ioread8 (port_addr ) & gpio_mask ;
185
-
186
- bitmap_set_value8 (bits , port_state , offset );
187
- }
89
+ i8255_get_multiple (gpiommgpio -> ppi , mask , bits , chip -> ngpio );
188
90
189
91
return 0 ;
190
92
}
@@ -193,49 +95,17 @@ static void gpiomm_gpio_set(struct gpio_chip *chip, unsigned int offset,
193
95
int value )
194
96
{
195
97
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
196
- const unsigned int port = offset / 8 ;
197
- const unsigned int mask = BIT (offset % 8 );
198
- const unsigned int out_port = (port > 2 ) ? port + 1 : port ;
199
- unsigned long flags ;
200
-
201
- spin_lock_irqsave (& gpiommgpio -> lock , flags );
202
-
203
- if (value )
204
- gpiommgpio -> out_state [port ] |= mask ;
205
- else
206
- gpiommgpio -> out_state [port ] &= ~mask ;
207
-
208
- iowrite8 (gpiommgpio -> out_state [port ], gpiommgpio -> base + out_port );
209
98
210
- spin_unlock_irqrestore ( & gpiommgpio -> lock , flags );
99
+ i8255_set ( gpiommgpio -> ppi , gpiommgpio -> ppi_state , offset , value );
211
100
}
212
101
213
102
static void gpiomm_gpio_set_multiple (struct gpio_chip * chip ,
214
103
unsigned long * mask , unsigned long * bits )
215
104
{
216
105
struct gpiomm_gpio * const gpiommgpio = gpiochip_get_data (chip );
217
- unsigned long offset ;
218
- unsigned long gpio_mask ;
219
- size_t index ;
220
- void __iomem * port_addr ;
221
- unsigned long bitmask ;
222
- unsigned long flags ;
223
-
224
- for_each_set_clump8 (offset , gpio_mask , mask , ARRAY_SIZE (ports ) * 8 ) {
225
- index = offset / 8 ;
226
- port_addr = gpiommgpio -> base + ports [index ];
227
-
228
- bitmask = bitmap_get_value8 (bits , offset ) & gpio_mask ;
229
-
230
- spin_lock_irqsave (& gpiommgpio -> lock , flags );
231
106
232
- /* update output state data and set device gpio register */
233
- gpiommgpio -> out_state [index ] &= ~gpio_mask ;
234
- gpiommgpio -> out_state [index ] |= bitmask ;
235
- iowrite8 (gpiommgpio -> out_state [index ], port_addr );
236
-
237
- spin_unlock_irqrestore (& gpiommgpio -> lock , flags );
238
- }
107
+ i8255_set_multiple (gpiommgpio -> ppi , gpiommgpio -> ppi_state , mask , bits ,
108
+ chip -> ngpio );
239
109
}
240
110
241
111
#define GPIOMM_NGPIO 48
@@ -250,6 +120,21 @@ static const char *gpiomm_names[GPIOMM_NGPIO] = {
250
120
"Port 2C2" , "Port 2C3" , "Port 2C4" , "Port 2C5" , "Port 2C6" , "Port 2C7" ,
251
121
};
252
122
123
+ static void gpiomm_init_dio (struct i8255 __iomem * const ppi ,
124
+ struct i8255_state * const ppi_state )
125
+ {
126
+ const unsigned long ngpio = 24 ;
127
+ const unsigned long mask = GENMASK (ngpio - 1 , 0 );
128
+ const unsigned long bits = 0 ;
129
+ unsigned long i ;
130
+
131
+ /* Initialize all GPIO to output 0 */
132
+ for (i = 0 ; i < GPIOMM_NUM_PPI ; i ++ ) {
133
+ i8255_mode0_output (& ppi [i ]);
134
+ i8255_set_multiple (& ppi [i ], & ppi_state [i ], & mask , & bits , ngpio );
135
+ }
136
+ }
137
+
253
138
static int gpiomm_probe (struct device * dev , unsigned int id )
254
139
{
255
140
struct gpiomm_gpio * gpiommgpio ;
@@ -266,8 +151,8 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
266
151
return - EBUSY ;
267
152
}
268
153
269
- gpiommgpio -> base = devm_ioport_map (dev , base [id ], GPIOMM_EXTENT );
270
- if (!gpiommgpio -> base )
154
+ gpiommgpio -> ppi = devm_ioport_map (dev , base [id ], GPIOMM_EXTENT );
155
+ if (!gpiommgpio -> ppi )
271
156
return - ENOMEM ;
272
157
273
158
gpiommgpio -> chip .label = name ;
@@ -284,24 +169,15 @@ static int gpiomm_probe(struct device *dev, unsigned int id)
284
169
gpiommgpio -> chip .set = gpiomm_gpio_set ;
285
170
gpiommgpio -> chip .set_multiple = gpiomm_gpio_set_multiple ;
286
171
287
- spin_lock_init (& gpiommgpio -> lock );
172
+ i8255_state_init (gpiommgpio -> ppi_state , GPIOMM_NUM_PPI );
173
+ gpiomm_init_dio (gpiommgpio -> ppi , gpiommgpio -> ppi_state );
288
174
289
175
err = devm_gpiochip_add_data (dev , & gpiommgpio -> chip , gpiommgpio );
290
176
if (err ) {
291
177
dev_err (dev , "GPIO registering failed (%d)\n" , err );
292
178
return err ;
293
179
}
294
180
295
- /* initialize all GPIO as output */
296
- iowrite8 (0x80 , gpiommgpio -> base + 3 );
297
- iowrite8 (0x00 , gpiommgpio -> base );
298
- iowrite8 (0x00 , gpiommgpio -> base + 1 );
299
- iowrite8 (0x00 , gpiommgpio -> base + 2 );
300
- iowrite8 (0x80 , gpiommgpio -> base + 7 );
301
- iowrite8 (0x00 , gpiommgpio -> base + 4 );
302
- iowrite8 (0x00 , gpiommgpio -> base + 5 );
303
- iowrite8 (0x00 , gpiommgpio -> base + 6 );
304
-
305
181
return 0 ;
306
182
}
307
183
0 commit comments