diff options
Diffstat (limited to 'arch/m68k/platform/coldfire/gpio.c')
-rw-r--r-- | arch/m68k/platform/coldfire/gpio.c | 172 |
1 files changed, 107 insertions, 65 deletions
diff --git a/arch/m68k/platform/coldfire/gpio.c b/arch/m68k/platform/coldfire/gpio.c index 4c8c42450a4e..9cd2b5c70519 100644 --- a/arch/m68k/platform/coldfire/gpio.c +++ b/arch/m68k/platform/coldfire/gpio.c | |||
@@ -14,119 +14,161 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/module.h> | ||
17 | #include <linux/init.h> | 18 | #include <linux/init.h> |
18 | #include <linux/device.h> | 19 | #include <linux/device.h> |
19 | 20 | ||
20 | #include <asm/gpio.h> | 21 | #include <linux/io.h> |
21 | #include <asm/pinmux.h> | 22 | #include <asm/coldfire.h> |
23 | #include <asm/mcfsim.h> | ||
22 | #include <asm/mcfgpio.h> | 24 | #include <asm/mcfgpio.h> |
23 | 25 | ||
24 | #define MCF_CHIP(chip) container_of(chip, struct mcf_gpio_chip, gpio_chip) | 26 | int __mcfgpio_get_value(unsigned gpio) |
27 | { | ||
28 | return mcfgpio_read(__mcfgpio_ppdr(gpio)) & mcfgpio_bit(gpio); | ||
29 | } | ||
30 | EXPORT_SYMBOL(__mcfgpio_get_value); | ||
31 | |||
32 | void __mcfgpio_set_value(unsigned gpio, int value) | ||
33 | { | ||
34 | if (gpio < MCFGPIO_SCR_START) { | ||
35 | unsigned long flags; | ||
36 | MCFGPIO_PORTTYPE data; | ||
37 | |||
38 | local_irq_save(flags); | ||
39 | data = mcfgpio_read(__mcfgpio_podr(gpio)); | ||
40 | if (value) | ||
41 | data |= mcfgpio_bit(gpio); | ||
42 | else | ||
43 | data &= ~mcfgpio_bit(gpio); | ||
44 | mcfgpio_write(data, __mcfgpio_podr(gpio)); | ||
45 | local_irq_restore(flags); | ||
46 | } else { | ||
47 | if (value) | ||
48 | mcfgpio_write(mcfgpio_bit(gpio), | ||
49 | MCFGPIO_SETR_PORT(gpio)); | ||
50 | else | ||
51 | mcfgpio_write(~mcfgpio_bit(gpio), | ||
52 | MCFGPIO_CLRR_PORT(gpio)); | ||
53 | } | ||
54 | } | ||
55 | EXPORT_SYMBOL(__mcfgpio_set_value); | ||
25 | 56 | ||
26 | int mcf_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 57 | int __mcfgpio_direction_input(unsigned gpio) |
27 | { | 58 | { |
28 | unsigned long flags; | 59 | unsigned long flags; |
29 | MCFGPIO_PORTTYPE dir; | 60 | MCFGPIO_PORTTYPE dir; |
30 | struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); | ||
31 | 61 | ||
32 | local_irq_save(flags); | 62 | local_irq_save(flags); |
33 | dir = mcfgpio_read(mcf_chip->pddr); | 63 | dir = mcfgpio_read(__mcfgpio_pddr(gpio)); |
34 | dir &= ~mcfgpio_bit(chip->base + offset); | 64 | dir &= ~mcfgpio_bit(gpio); |
35 | mcfgpio_write(dir, mcf_chip->pddr); | 65 | mcfgpio_write(dir, __mcfgpio_pddr(gpio)); |
36 | local_irq_restore(flags); | 66 | local_irq_restore(flags); |
37 | 67 | ||
38 | return 0; | 68 | return 0; |
39 | } | 69 | } |
70 | EXPORT_SYMBOL(__mcfgpio_direction_input); | ||
40 | 71 | ||
41 | int mcf_gpio_get_value(struct gpio_chip *chip, unsigned offset) | 72 | int __mcfgpio_direction_output(unsigned gpio, int value) |
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 | |||
48 | int mcf_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
49 | int value) | ||
50 | { | 73 | { |
51 | unsigned long flags; | 74 | unsigned long flags; |
52 | MCFGPIO_PORTTYPE data; | 75 | MCFGPIO_PORTTYPE data; |
53 | struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); | ||
54 | 76 | ||
55 | local_irq_save(flags); | 77 | local_irq_save(flags); |
56 | /* write the value to the output latch */ | 78 | data = mcfgpio_read(__mcfgpio_pddr(gpio)); |
57 | data = mcfgpio_read(mcf_chip->podr); | ||
58 | if (value) | 79 | if (value) |
59 | data |= mcfgpio_bit(chip->base + offset); | 80 | data |= mcfgpio_bit(gpio); |
60 | else | 81 | else |
61 | data &= ~mcfgpio_bit(chip->base + offset); | 82 | data &= mcfgpio_bit(gpio); |
62 | mcfgpio_write(data, mcf_chip->podr); | 83 | mcfgpio_write(data, __mcfgpio_pddr(gpio)); |
63 | 84 | ||
64 | /* now set the direction to output */ | 85 | /* now set the data to output */ |
65 | data = mcfgpio_read(mcf_chip->pddr); | 86 | if (gpio < MCFGPIO_SCR_START) { |
66 | data |= mcfgpio_bit(chip->base + offset); | 87 | data = mcfgpio_read(__mcfgpio_podr(gpio)); |
67 | mcfgpio_write(data, mcf_chip->pddr); | 88 | if (value) |
89 | data |= mcfgpio_bit(gpio); | ||
90 | else | ||
91 | data &= ~mcfgpio_bit(gpio); | ||
92 | mcfgpio_write(data, __mcfgpio_podr(gpio)); | ||
93 | } else { | ||
94 | if (value) | ||
95 | mcfgpio_write(mcfgpio_bit(gpio), | ||
96 | MCFGPIO_SETR_PORT(gpio)); | ||
97 | else | ||
98 | mcfgpio_write(~mcfgpio_bit(gpio), | ||
99 | MCFGPIO_CLRR_PORT(gpio)); | ||
100 | } | ||
68 | local_irq_restore(flags); | 101 | local_irq_restore(flags); |
102 | return 0; | ||
103 | } | ||
104 | EXPORT_SYMBOL(__mcfgpio_direction_output); | ||
69 | 105 | ||
106 | int __mcfgpio_request(unsigned gpio) | ||
107 | { | ||
70 | return 0; | 108 | return 0; |
71 | } | 109 | } |
110 | EXPORT_SYMBOL(__mcfgpio_request); | ||
72 | 111 | ||
73 | void mcf_gpio_set_value(struct gpio_chip *chip, unsigned offset, int value) | 112 | void __mcfgpio_free(unsigned gpio) |
74 | { | 113 | { |
75 | struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); | 114 | __mcfgpio_direction_input(gpio); |
115 | } | ||
116 | EXPORT_SYMBOL(__mcfgpio_free); | ||
76 | 117 | ||
77 | unsigned long flags; | 118 | #ifdef CONFIG_GPIOLIB |
78 | MCFGPIO_PORTTYPE data; | ||
79 | 119 | ||
80 | local_irq_save(flags); | 120 | int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset) |
81 | data = mcfgpio_read(mcf_chip->podr); | 121 | { |
82 | if (value) | 122 | return __mcfgpio_direction_input(offset); |
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 | } | 123 | } |
89 | 124 | ||
90 | void mcf_gpio_set_value_fast(struct gpio_chip *chip, unsigned offset, int value) | 125 | int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset) |
91 | { | 126 | { |
92 | struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); | 127 | return __mcfgpio_get_value(offset); |
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 | } | 128 | } |
99 | 129 | ||
100 | int mcf_gpio_request(struct gpio_chip *chip, unsigned offset) | 130 | int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset, int value) |
101 | { | 131 | { |
102 | struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); | 132 | return __mcfgpio_direction_output(offset, value); |
103 | |||
104 | return mcf_chip->gpio_to_pinmux ? | ||
105 | mcf_pinmux_request(mcf_chip->gpio_to_pinmux[offset], 0) : 0; | ||
106 | } | 133 | } |
107 | 134 | ||
108 | void mcf_gpio_free(struct gpio_chip *chip, unsigned offset) | 135 | void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset, int value) |
109 | { | 136 | { |
110 | struct mcf_gpio_chip *mcf_chip = MCF_CHIP(chip); | 137 | __mcfgpio_set_value(offset, value); |
138 | } | ||
111 | 139 | ||
112 | mcf_gpio_direction_input(chip, offset); | 140 | int mcfgpio_request(struct gpio_chip *chip, unsigned offset) |
141 | { | ||
142 | return __mcfgpio_request(offset); | ||
143 | } | ||
113 | 144 | ||
114 | if (mcf_chip->gpio_to_pinmux) | 145 | void mcfgpio_free(struct gpio_chip *chip, unsigned offset) |
115 | mcf_pinmux_release(mcf_chip->gpio_to_pinmux[offset], 0); | 146 | { |
147 | __mcfgpio_free(offset); | ||
116 | } | 148 | } |
117 | 149 | ||
118 | struct bus_type mcf_gpio_subsys = { | 150 | struct bus_type mcfgpio_subsys = { |
119 | .name = "gpio", | 151 | .name = "gpio", |
120 | .dev_name = "gpio", | 152 | .dev_name = "gpio", |
121 | }; | 153 | }; |
122 | 154 | ||
123 | static int __init mcf_gpio_sysinit(void) | 155 | static struct gpio_chip mcfgpio_chip = { |
124 | { | 156 | .label = "mcfgpio", |
125 | unsigned int i = 0; | 157 | .request = mcfgpio_request, |
158 | .free = mcfgpio_free, | ||
159 | .direction_input = mcfgpio_direction_input, | ||
160 | .direction_output = mcfgpio_direction_output, | ||
161 | .get = mcfgpio_get_value, | ||
162 | .set = mcfgpio_set_value, | ||
163 | .base = 0, | ||
164 | .ngpio = MCFGPIO_PIN_MAX, | ||
165 | }; | ||
126 | 166 | ||
127 | while (i < mcf_gpio_chips_size) | 167 | static int __init mcfgpio_sysinit(void) |
128 | gpiochip_add((struct gpio_chip *)&mcf_gpio_chips[i++]); | 168 | { |
129 | return subsys_system_register(&mcf_gpio_subsys, NULL); | 169 | gpiochip_add(&mcfgpio_chip); |
170 | return subsys_system_register(&mcfgpio_subsys, NULL); | ||
130 | } | 171 | } |
131 | 172 | ||
132 | core_initcall(mcf_gpio_sysinit); | 173 | core_initcall(mcfgpio_sysinit); |
174 | #endif | ||