• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/arch/m68knommu/platform/coldfire/
1/*
2 * Coldfire generic GPIO support.
3 *
4 * (C) Copyright 2009, Steven King <sfking@fdwdc.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 */
15
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/sysdev.h>
19
20#include <asm/gpio.h>
21#include <asm/pinmux.h>
22#include <asm/mcfgpio.h>
23
24#define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip)
25
26int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
27{
28	unsigned long flags;
29	MCFGPIO_PORTTYPE dir;
30	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
31
32	local_irq_save(flags);
33	dir = mcfgpio_read(mcf_chip->pddr);
34	dir &= ~mcfgpio_bit(chip->base + offset);
35	mcfgpio_write(dir, mcf_chip->pddr);
36	local_irq_restore(flags);
37
38	return 0;
39}
40
41int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset)
42{
43	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
44
45	return mcfgpio_read(mcf_chip->ppdr) & mcfgpio_bit(chip->base + offset);
46}
47
48int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset,
49		int value)
50{
51	unsigned long flags;
52	MCFGPIO_PORTTYPE data;
53	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
54
55	local_irq_save(flags);
56	/* write the value to the output latch */
57	data = mcfgpio_read(mcf_chip->podr);
58	if (value)
59		data |= mcfgpio_bit(chip->base + offset);
60	else
61		data &= ~mcfgpio_bit(chip->base + offset);
62	mcfgpio_write(data, mcf_chip->podr);
63
64	/* now set the direction to output */
65	data = mcfgpio_read(mcf_chip->pddr);
66	data |= mcfgpio_bit(chip->base + offset);
67	mcfgpio_write(data, mcf_chip->pddr);
68	local_irq_restore(flags);
69
70	return 0;
71}
72
73void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value)
74{
75	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
76
77	unsigned long flags;
78	MCFGPIO_PORTTYPE data;
79
80	local_irq_save(flags);
81	data = mcfgpio_read(mcf_chip->podr);
82	if (value)
83		data |= mcfgpio_bit(chip->base + offset);
84	else
85		data &= ~mcfgpio_bit(chip->base + offset);
86	mcfgpio_write(data, mcf_chip->podr);
87	local_irq_restore(flags);
88}
89
90void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value)
91{
92	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
93
94	if (value)
95		mcfgpio_write(mcfgpio_bit(chip->base + offset), mcf_chip->setr);
96	else
97		mcfgpio_write(~mcfgpio_bit(chip->base + offset), mcf_chip->clrr);
98}
99
100int mcf_gpio_request(struct gpio_chip *chip, unsigned offset)
101{
102	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
103
104	return mcf_chip->gpio_to_pinmux ?
105		mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0;
106}
107
108void mcf_gpio_free(struct gpio_chip *chip, unsigned offset)
109{
110	struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip);
111
112	mcf_gpio_direction_input(chip, offset);
113
114	if (mcf_chip->gpio_to_pinmux)
115		mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0);
116}
117
118struct sysdev_class mcf_gpio_sysclass = {
119	.name	= "gpio",
120};
121
122static int __init mcf_gpio_sysinit(void)
123{
124	return sysdev_class_register(&mcf_gpio_sysclass);
125}
126
127core_initcall(mcf_gpio_sysinit);
128