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/module.h> 18 #include <linux/init.h> 19 #include <linux/device.h> 20 21 #include <linux/io.h> 22 #include <asm/coldfire.h> 23 #include <asm/mcfsim.h> 24 #include <asm/mcfgpio.h> 25 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); 56 57 int __mcfgpio_direction_input(unsigned gpio) 58 { 59 unsigned long flags; 60 MCFGPIO_PORTTYPE dir; 61 62 local_irq_save(flags); 63 dir = mcfgpio_read(__mcfgpio_pddr(gpio)); 64 dir &= ~mcfgpio_bit(gpio); 65 mcfgpio_write(dir, __mcfgpio_pddr(gpio)); 66 local_irq_restore(flags); 67 68 return 0; 69 } 70 EXPORT_SYMBOL(__mcfgpio_direction_input); 71 72 int __mcfgpio_direction_output(unsigned gpio, int value) 73 { 74 unsigned long flags; 75 MCFGPIO_PORTTYPE data; 76 77 local_irq_save(flags); 78 data = mcfgpio_read(__mcfgpio_pddr(gpio)); 79 data |= mcfgpio_bit(gpio); 80 mcfgpio_write(data, __mcfgpio_pddr(gpio)); 81 82 /* now set the data to output */ 83 if (gpio < MCFGPIO_SCR_START) { 84 data = mcfgpio_read(__mcfgpio_podr(gpio)); 85 if (value) 86 data |= mcfgpio_bit(gpio); 87 else 88 data &= ~mcfgpio_bit(gpio); 89 mcfgpio_write(data, __mcfgpio_podr(gpio)); 90 } else { 91 if (value) 92 mcfgpio_write(mcfgpio_bit(gpio), 93 MCFGPIO_SETR_PORT(gpio)); 94 else 95 mcfgpio_write(~mcfgpio_bit(gpio), 96 MCFGPIO_CLRR_PORT(gpio)); 97 } 98 local_irq_restore(flags); 99 return 0; 100 } 101 EXPORT_SYMBOL(__mcfgpio_direction_output); 102 103 int __mcfgpio_request(unsigned gpio) 104 { 105 return 0; 106 } 107 EXPORT_SYMBOL(__mcfgpio_request); 108 109 void __mcfgpio_free(unsigned gpio) 110 { 111 __mcfgpio_direction_input(gpio); 112 } 113 EXPORT_SYMBOL(__mcfgpio_free); 114 115 #ifdef CONFIG_GPIOLIB 116 117 static int mcfgpio_direction_input(struct gpio_chip *chip, unsigned offset) 118 { 119 return __mcfgpio_direction_input(offset); 120 } 121 122 static int mcfgpio_get_value(struct gpio_chip *chip, unsigned offset) 123 { 124 return __mcfgpio_get_value(offset); 125 } 126 127 static int mcfgpio_direction_output(struct gpio_chip *chip, unsigned offset, 128 int value) 129 { 130 return __mcfgpio_direction_output(offset, value); 131 } 132 133 static void mcfgpio_set_value(struct gpio_chip *chip, unsigned offset, 134 int value) 135 { 136 __mcfgpio_set_value(offset, value); 137 } 138 139 static int mcfgpio_request(struct gpio_chip *chip, unsigned offset) 140 { 141 return __mcfgpio_request(offset); 142 } 143 144 static void mcfgpio_free(struct gpio_chip *chip, unsigned offset) 145 { 146 __mcfgpio_free(offset); 147 } 148 149 static int mcfgpio_to_irq(struct gpio_chip *chip, unsigned offset) 150 { 151 #if defined(MCFGPIO_IRQ_MIN) 152 if ((offset >= MCFGPIO_IRQ_MIN) && (offset < MCFGPIO_IRQ_MAX)) 153 #else 154 if (offset < MCFGPIO_IRQ_MAX) 155 #endif 156 return MCFGPIO_IRQ_VECBASE + offset; 157 else 158 return -EINVAL; 159 } 160 161 static struct bus_type mcfgpio_subsys = { 162 .name = "gpio", 163 .dev_name = "gpio", 164 }; 165 166 static struct gpio_chip mcfgpio_chip = { 167 .label = "mcfgpio", 168 .request = mcfgpio_request, 169 .free = mcfgpio_free, 170 .direction_input = mcfgpio_direction_input, 171 .direction_output = mcfgpio_direction_output, 172 .get = mcfgpio_get_value, 173 .set = mcfgpio_set_value, 174 .to_irq = mcfgpio_to_irq, 175 .base = 0, 176 .ngpio = MCFGPIO_PIN_MAX, 177 }; 178 179 static int __init mcfgpio_sysinit(void) 180 { 181 gpiochip_add(&mcfgpio_chip); 182 return subsys_system_register(&mcfgpio_subsys, NULL); 183 } 184 185 core_initcall(mcfgpio_sysinit); 186 #endif 187