]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/gpio/gpio-it87.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/ide
[karo-tx-linux.git] / drivers / gpio / gpio-it87.c
1 /*
2  *  GPIO interface for IT87xx Super I/O chips
3  *
4  *  Author: Diego Elio Pettenò <flameeyes@flameeyes.eu>
5  *
6  *  Based on it87_wdt.c     by Oliver Schuster
7  *           gpio-it8761e.c by Denis Turischev
8  *           gpio-stmpe.c   by Rabin Vincent
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License 2 as published
12  *  by the Free Software Foundation.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; see the file COPYING.  If not, write to
21  *  the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23
24 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
25
26 #include <linux/init.h>
27 #include <linux/kernel.h>
28 #include <linux/module.h>
29 #include <linux/io.h>
30 #include <linux/errno.h>
31 #include <linux/ioport.h>
32 #include <linux/slab.h>
33 #include <linux/gpio.h>
34
35 /* Chip Id numbers */
36 #define NO_DEV_ID       0xffff
37 #define IT8728_ID       0x8728
38 #define IT8732_ID       0x8732
39 #define IT8761_ID       0x8761
40
41 /* IO Ports */
42 #define REG             0x2e
43 #define VAL             0x2f
44
45 /* Logical device Numbers LDN */
46 #define GPIO            0x07
47
48 /* Configuration Registers and Functions */
49 #define LDNREG          0x07
50 #define CHIPID          0x20
51 #define CHIPREV         0x22
52
53 /**
54  * struct it87_gpio - it87-specific GPIO chip
55  * @chip the underlying gpio_chip structure
56  * @lock a lock to avoid races between operations
57  * @io_base base address for gpio ports
58  * @io_size size of the port rage starting from io_base.
59  * @output_base Super I/O register address for Output Enable register
60  * @simple_base Super I/O 'Simple I/O' Enable register
61  * @simple_size Super IO 'Simple I/O' Enable register size; this is
62  *      required because IT87xx chips might only provide Simple I/O
63  *      switches on a subset of lines, whereas the others keep the
64  *      same status all time.
65  */
66 struct it87_gpio {
67         struct gpio_chip chip;
68         spinlock_t lock;
69         u16 io_base;
70         u16 io_size;
71         u8 output_base;
72         u8 simple_base;
73         u8 simple_size;
74 };
75
76 static struct it87_gpio it87_gpio_chip = {
77         .lock = __SPIN_LOCK_UNLOCKED(it87_gpio_chip.lock),
78 };
79
80 static inline struct it87_gpio *to_it87_gpio(struct gpio_chip *chip)
81 {
82         return container_of(chip, struct it87_gpio, chip);
83 }
84
85 /* Superio chip access functions; copied from wdt_it87 */
86
87 static inline int superio_enter(void)
88 {
89         /*
90          * Try to reserve REG and REG + 1 for exclusive access.
91          */
92         if (!request_muxed_region(REG, 2, KBUILD_MODNAME))
93                 return -EBUSY;
94
95         outb(0x87, REG);
96         outb(0x01, REG);
97         outb(0x55, REG);
98         outb(0x55, REG);
99         return 0;
100 }
101
102 static inline void superio_exit(void)
103 {
104         outb(0x02, REG);
105         outb(0x02, VAL);
106         release_region(REG, 2);
107 }
108
109 static inline void superio_select(int ldn)
110 {
111         outb(LDNREG, REG);
112         outb(ldn, VAL);
113 }
114
115 static inline int superio_inb(int reg)
116 {
117         outb(reg, REG);
118         return inb(VAL);
119 }
120
121 static inline void superio_outb(int val, int reg)
122 {
123         outb(reg, REG);
124         outb(val, VAL);
125 }
126
127 static inline int superio_inw(int reg)
128 {
129         int val;
130
131         outb(reg++, REG);
132         val = inb(VAL) << 8;
133         outb(reg, REG);
134         val |= inb(VAL);
135         return val;
136 }
137
138 static inline void superio_outw(int val, int reg)
139 {
140         outb(reg++, REG);
141         outb(val >> 8, VAL);
142         outb(reg, REG);
143         outb(val, VAL);
144 }
145
146 static inline void superio_set_mask(int mask, int reg)
147 {
148         u8 curr_val = superio_inb(reg);
149         u8 new_val = curr_val | mask;
150
151         if (curr_val != new_val)
152                 superio_outb(new_val, reg);
153 }
154
155 static inline void superio_clear_mask(int mask, int reg)
156 {
157         u8 curr_val = superio_inb(reg);
158         u8 new_val = curr_val & ~mask;
159
160         if (curr_val != new_val)
161                 superio_outb(new_val, reg);
162 }
163
164 static int it87_gpio_request(struct gpio_chip *chip, unsigned gpio_num)
165 {
166         u8 mask, group;
167         int rc = 0;
168         struct it87_gpio *it87_gpio = to_it87_gpio(chip);
169
170         mask = 1 << (gpio_num % 8);
171         group = (gpio_num / 8);
172
173         spin_lock(&it87_gpio->lock);
174
175         rc = superio_enter();
176         if (rc)
177                 goto exit;
178
179         /* not all the IT87xx chips support Simple I/O and not all of
180          * them allow all the lines to be set/unset to Simple I/O.
181          */
182         if (group < it87_gpio->simple_size)
183                 superio_set_mask(mask, group + it87_gpio->simple_base);
184
185         /* clear output enable, setting the pin to input, as all the
186          * newly-exported GPIO interfaces are set to input.
187          */
188         superio_clear_mask(mask, group + it87_gpio->output_base);
189
190         superio_exit();
191
192 exit:
193         spin_unlock(&it87_gpio->lock);
194         return rc;
195 }
196
197 static int it87_gpio_get(struct gpio_chip *chip, unsigned gpio_num)
198 {
199         u16 reg;
200         u8 mask;
201         struct it87_gpio *it87_gpio = to_it87_gpio(chip);
202
203         mask = 1 << (gpio_num % 8);
204         reg = (gpio_num / 8) + it87_gpio->io_base;
205
206         return !!(inb(reg) & mask);
207 }
208
209 static int it87_gpio_direction_in(struct gpio_chip *chip, unsigned gpio_num)
210 {
211         u8 mask, group;
212         int rc = 0;
213         struct it87_gpio *it87_gpio = to_it87_gpio(chip);
214
215         mask = 1 << (gpio_num % 8);
216         group = (gpio_num / 8);
217
218         spin_lock(&it87_gpio->lock);
219
220         rc = superio_enter();
221         if (rc)
222                 goto exit;
223
224         /* clear the output enable bit */
225         superio_clear_mask(mask, group + it87_gpio->output_base);
226
227         superio_exit();
228
229 exit:
230         spin_unlock(&it87_gpio->lock);
231         return rc;
232 }
233
234 static void it87_gpio_set(struct gpio_chip *chip,
235                           unsigned gpio_num, int val)
236 {
237         u8 mask, curr_vals;
238         u16 reg;
239         struct it87_gpio *it87_gpio = to_it87_gpio(chip);
240
241         mask = 1 << (gpio_num % 8);
242         reg = (gpio_num / 8) + it87_gpio->io_base;
243
244         curr_vals = inb(reg);
245         if (val)
246                 outb(curr_vals | mask, reg);
247         else
248                 outb(curr_vals & ~mask, reg);
249 }
250
251 static int it87_gpio_direction_out(struct gpio_chip *chip,
252                                    unsigned gpio_num, int val)
253 {
254         u8 mask, group;
255         int rc = 0;
256         struct it87_gpio *it87_gpio = to_it87_gpio(chip);
257
258         mask = 1 << (gpio_num % 8);
259         group = (gpio_num / 8);
260
261         spin_lock(&it87_gpio->lock);
262
263         rc = superio_enter();
264         if (rc)
265                 goto exit;
266
267         /* set the output enable bit */
268         superio_set_mask(mask, group + it87_gpio->output_base);
269
270         it87_gpio_set(chip, gpio_num, val);
271
272         superio_exit();
273
274 exit:
275         spin_unlock(&it87_gpio->lock);
276         return rc;
277 }
278
279 static struct gpio_chip it87_template_chip = {
280         .label                  = KBUILD_MODNAME,
281         .owner                  = THIS_MODULE,
282         .request                = it87_gpio_request,
283         .get                    = it87_gpio_get,
284         .direction_input        = it87_gpio_direction_in,
285         .set                    = it87_gpio_set,
286         .direction_output       = it87_gpio_direction_out,
287         .base                   = -1
288 };
289
290 static int __init it87_gpio_init(void)
291 {
292         int rc = 0, i;
293         u16 chip_type;
294         u8 chip_rev, gpio_ba_reg;
295         char *labels, **labels_table;
296
297         struct it87_gpio *it87_gpio = &it87_gpio_chip;
298
299         rc = superio_enter();
300         if (rc)
301                 return rc;
302
303         chip_type = superio_inw(CHIPID);
304         chip_rev  = superio_inb(CHIPREV) & 0x0f;
305         superio_exit();
306
307         it87_gpio->chip = it87_template_chip;
308
309         switch (chip_type) {
310         case IT8728_ID:
311         case IT8732_ID:
312                 gpio_ba_reg = 0x62;
313                 it87_gpio->io_size = 8;
314                 it87_gpio->output_base = 0xc8;
315                 it87_gpio->simple_base = 0xc0;
316                 it87_gpio->simple_size = 5;
317                 it87_gpio->chip.ngpio = 64;
318                 break;
319         case IT8761_ID:
320                 gpio_ba_reg = 0x60;
321                 it87_gpio->io_size = 4;
322                 it87_gpio->output_base = 0xf0;
323                 it87_gpio->simple_size = 0;
324                 it87_gpio->chip.ngpio = 16;
325                 break;
326         case NO_DEV_ID:
327                 pr_err("no device\n");
328                 return -ENODEV;
329         default:
330                 pr_err("Unknown Chip found, Chip %04x Revision %x\n",
331                        chip_type, chip_rev);
332                 return -ENODEV;
333         }
334
335         rc = superio_enter();
336         if (rc)
337                 return rc;
338
339         superio_select(GPIO);
340
341         /* fetch GPIO base address */
342         it87_gpio->io_base = superio_inw(gpio_ba_reg);
343
344         superio_exit();
345
346         pr_info("Found Chip IT%04x rev %x. %u GPIO lines starting at %04xh\n",
347                 chip_type, chip_rev, it87_gpio->chip.ngpio,
348                 it87_gpio->io_base);
349
350         if (!request_region(it87_gpio->io_base, it87_gpio->io_size,
351                                                         KBUILD_MODNAME))
352                 return -EBUSY;
353
354         /* Set up aliases for the GPIO connection.
355          *
356          * ITE documentation for recent chips such as the IT8728F
357          * refers to the GPIO lines as GPxy, with a coordinates system
358          * where x is the GPIO group (starting from 1) and y is the
359          * bit within the group.
360          *
361          * By creating these aliases, we make it easier to understand
362          * to which GPIO pin we're referring to.
363          */
364         labels = kcalloc(it87_gpio->chip.ngpio, sizeof("it87_gpXY"),
365                                                                 GFP_KERNEL);
366         labels_table = kcalloc(it87_gpio->chip.ngpio, sizeof(const char *),
367                                                                 GFP_KERNEL);
368
369         if (!labels || !labels_table) {
370                 rc = -ENOMEM;
371                 goto labels_free;
372         }
373
374         for (i = 0; i < it87_gpio->chip.ngpio; i++) {
375                 char *label = &labels[i * sizeof("it87_gpXY")];
376
377                 sprintf(label, "it87_gp%u%u", 1+(i/8), i%8);
378                 labels_table[i] = label;
379         }
380
381         it87_gpio->chip.names = (const char *const*)labels_table;
382
383         rc = gpiochip_add(&it87_gpio->chip);
384         if (rc)
385                 goto labels_free;
386
387         return 0;
388
389 labels_free:
390         kfree(labels_table);
391         kfree(labels);
392         release_region(it87_gpio->io_base, it87_gpio->io_size);
393         return rc;
394 }
395
396 static void __exit it87_gpio_exit(void)
397 {
398         struct it87_gpio *it87_gpio = &it87_gpio_chip;
399
400         gpiochip_remove(&it87_gpio->chip);
401         release_region(it87_gpio->io_base, it87_gpio->io_size);
402         kfree(it87_gpio->chip.names[0]);
403         kfree(it87_gpio->chip.names);
404 }
405
406 module_init(it87_gpio_init);
407 module_exit(it87_gpio_exit);
408
409 MODULE_AUTHOR("Diego Elio Pettenò <flameeyes@flameeyes.eu>");
410 MODULE_DESCRIPTION("GPIO interface for IT87xx Super I/O chips");
411 MODULE_LICENSE("GPL");