1 /* 2 * Generic GPIO card-detect helper 3 * 4 * Copyright (C) 2011, Guennadi Liakhovetski <g.liakhovetski@gmx.de> 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 version 2 as 8 * published by the Free Software Foundation. 9 */ 10 11 #include <linux/err.h> 12 #include <linux/gpio.h> 13 #include <linux/gpio/consumer.h> 14 #include <linux/interrupt.h> 15 #include <linux/jiffies.h> 16 #include <linux/mmc/host.h> 17 #include <linux/mmc/slot-gpio.h> 18 #include <linux/module.h> 19 #include <linux/slab.h> 20 21 #include "slot-gpio.h" 22 23 struct mmc_gpio { 24 struct gpio_desc *ro_gpio; 25 struct gpio_desc *cd_gpio; 26 bool override_ro_active_level; 27 bool override_cd_active_level; 28 irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id); 29 char *ro_label; 30 char cd_label[0]; 31 }; 32 33 static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) 34 { 35 /* Schedule a card detection after a debounce timeout */ 36 struct mmc_host *host = dev_id; 37 38 host->trigger_card_event = true; 39 mmc_detect_change(host, msecs_to_jiffies(200)); 40 41 return IRQ_HANDLED; 42 } 43 44 int mmc_gpio_alloc(struct mmc_host *host) 45 { 46 size_t len = strlen(dev_name(host->parent)) + 4; 47 struct mmc_gpio *ctx = devm_kzalloc(host->parent, 48 sizeof(*ctx) + 2 * len, GFP_KERNEL); 49 50 if (ctx) { 51 ctx->ro_label = ctx->cd_label + len; 52 snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); 53 snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); 54 host->slot.handler_priv = ctx; 55 host->slot.cd_irq = -EINVAL; 56 } 57 58 return ctx ? 0 : -ENOMEM; 59 } 60 61 int mmc_gpio_get_ro(struct mmc_host *host) 62 { 63 struct mmc_gpio *ctx = host->slot.handler_priv; 64 65 if (!ctx || !ctx->ro_gpio) 66 return -ENOSYS; 67 68 if (ctx->override_ro_active_level) 69 return !gpiod_get_raw_value_cansleep(ctx->ro_gpio) ^ 70 !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); 71 72 return gpiod_get_value_cansleep(ctx->ro_gpio); 73 } 74 EXPORT_SYMBOL(mmc_gpio_get_ro); 75 76 int mmc_gpio_get_cd(struct mmc_host *host) 77 { 78 struct mmc_gpio *ctx = host->slot.handler_priv; 79 80 if (!ctx || !ctx->cd_gpio) 81 return -ENOSYS; 82 83 if (ctx->override_cd_active_level) 84 return !gpiod_get_raw_value_cansleep(ctx->cd_gpio) ^ 85 !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); 86 87 return gpiod_get_value_cansleep(ctx->cd_gpio); 88 } 89 EXPORT_SYMBOL(mmc_gpio_get_cd); 90 91 /** 92 * mmc_gpio_request_ro - request a gpio for write-protection 93 * @host: mmc host 94 * @gpio: gpio number requested 95 * 96 * As devm_* managed functions are used in mmc_gpio_request_ro(), client 97 * drivers do not need to worry about freeing up memory. 98 * 99 * Returns zero on success, else an error. 100 */ 101 int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) 102 { 103 struct mmc_gpio *ctx = host->slot.handler_priv; 104 int ret; 105 106 if (!gpio_is_valid(gpio)) 107 return -EINVAL; 108 109 ret = devm_gpio_request_one(host->parent, gpio, GPIOF_DIR_IN, 110 ctx->ro_label); 111 if (ret < 0) 112 return ret; 113 114 ctx->override_ro_active_level = true; 115 ctx->ro_gpio = gpio_to_desc(gpio); 116 117 return 0; 118 } 119 EXPORT_SYMBOL(mmc_gpio_request_ro); 120 121 void mmc_gpiod_request_cd_irq(struct mmc_host *host) 122 { 123 struct mmc_gpio *ctx = host->slot.handler_priv; 124 int irq = -EINVAL; 125 int ret; 126 127 if (host->slot.cd_irq >= 0 || !ctx || !ctx->cd_gpio) 128 return; 129 130 /* 131 * Do not use IRQ if the platform prefers to poll, e.g., because that 132 * IRQ number is already used by another unit and cannot be shared. 133 */ 134 if (!(host->caps & MMC_CAP_NEEDS_POLL)) 135 irq = gpiod_to_irq(ctx->cd_gpio); 136 137 if (irq >= 0) { 138 if (!ctx->cd_gpio_isr) 139 ctx->cd_gpio_isr = mmc_gpio_cd_irqt; 140 ret = devm_request_threaded_irq(host->parent, irq, 141 NULL, ctx->cd_gpio_isr, 142 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, 143 ctx->cd_label, host); 144 if (ret < 0) 145 irq = ret; 146 } 147 148 host->slot.cd_irq = irq; 149 150 if (irq < 0) 151 host->caps |= MMC_CAP_NEEDS_POLL; 152 } 153 EXPORT_SYMBOL(mmc_gpiod_request_cd_irq); 154 155 int mmc_gpio_set_cd_wake(struct mmc_host *host, bool on) 156 { 157 int ret = 0; 158 159 if (!(host->caps & MMC_CAP_CD_WAKE) || 160 host->slot.cd_irq < 0 || 161 on == host->slot.cd_wake_enabled) 162 return 0; 163 164 if (on) { 165 ret = enable_irq_wake(host->slot.cd_irq); 166 host->slot.cd_wake_enabled = !ret; 167 } else { 168 disable_irq_wake(host->slot.cd_irq); 169 host->slot.cd_wake_enabled = false; 170 } 171 172 return ret; 173 } 174 EXPORT_SYMBOL(mmc_gpio_set_cd_wake); 175 176 /* Register an alternate interrupt service routine for 177 * the card-detect GPIO. 178 */ 179 void mmc_gpio_set_cd_isr(struct mmc_host *host, 180 irqreturn_t (*isr)(int irq, void *dev_id)) 181 { 182 struct mmc_gpio *ctx = host->slot.handler_priv; 183 184 WARN_ON(ctx->cd_gpio_isr); 185 ctx->cd_gpio_isr = isr; 186 } 187 EXPORT_SYMBOL(mmc_gpio_set_cd_isr); 188 189 /** 190 * mmc_gpio_request_cd - request a gpio for card-detection 191 * @host: mmc host 192 * @gpio: gpio number requested 193 * @debounce: debounce time in microseconds 194 * 195 * As devm_* managed functions are used in mmc_gpio_request_cd(), client 196 * drivers do not need to worry about freeing up memory. 197 * 198 * If GPIO debouncing is desired, set the debounce parameter to a non-zero 199 * value. The caller is responsible for ensuring that the GPIO driver associated 200 * with the GPIO supports debouncing, otherwise an error will be returned. 201 * 202 * Returns zero on success, else an error. 203 */ 204 int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, 205 unsigned int debounce) 206 { 207 struct mmc_gpio *ctx = host->slot.handler_priv; 208 int ret; 209 210 ret = devm_gpio_request_one(host->parent, gpio, GPIOF_DIR_IN, 211 ctx->cd_label); 212 if (ret < 0) 213 /* 214 * don't bother freeing memory. It might still get used by other 215 * slot functions, in any case it will be freed, when the device 216 * is destroyed. 217 */ 218 return ret; 219 220 if (debounce) { 221 ret = gpio_set_debounce(gpio, debounce); 222 if (ret < 0) 223 return ret; 224 } 225 226 ctx->override_cd_active_level = true; 227 ctx->cd_gpio = gpio_to_desc(gpio); 228 229 return 0; 230 } 231 EXPORT_SYMBOL(mmc_gpio_request_cd); 232 233 /** 234 * mmc_gpiod_request_cd - request a gpio descriptor for card-detection 235 * @host: mmc host 236 * @con_id: function within the GPIO consumer 237 * @idx: index of the GPIO to obtain in the consumer 238 * @override_active_level: ignore %GPIO_ACTIVE_LOW flag 239 * @debounce: debounce time in microseconds 240 * @gpio_invert: will return whether the GPIO line is inverted or not, set 241 * to NULL to ignore 242 * 243 * Use this function in place of mmc_gpio_request_cd() to use the GPIO 244 * descriptor API. Note that it must be called prior to mmc_add_host() 245 * otherwise the caller must also call mmc_gpiod_request_cd_irq(). 246 * 247 * Returns zero on success, else an error. 248 */ 249 int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id, 250 unsigned int idx, bool override_active_level, 251 unsigned int debounce, bool *gpio_invert) 252 { 253 struct mmc_gpio *ctx = host->slot.handler_priv; 254 struct gpio_desc *desc; 255 int ret; 256 257 desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN); 258 if (IS_ERR(desc)) 259 return PTR_ERR(desc); 260 261 if (debounce) { 262 ret = gpiod_set_debounce(desc, debounce); 263 if (ret < 0) 264 return ret; 265 } 266 267 if (gpio_invert) 268 *gpio_invert = !gpiod_is_active_low(desc); 269 270 ctx->override_cd_active_level = override_active_level; 271 ctx->cd_gpio = desc; 272 273 return 0; 274 } 275 EXPORT_SYMBOL(mmc_gpiod_request_cd); 276 277 bool mmc_can_gpio_cd(struct mmc_host *host) 278 { 279 struct mmc_gpio *ctx = host->slot.handler_priv; 280 281 return ctx->cd_gpio ? true : false; 282 } 283 EXPORT_SYMBOL(mmc_can_gpio_cd); 284 285 /** 286 * mmc_gpiod_request_ro - request a gpio descriptor for write protection 287 * @host: mmc host 288 * @con_id: function within the GPIO consumer 289 * @idx: index of the GPIO to obtain in the consumer 290 * @override_active_level: ignore %GPIO_ACTIVE_LOW flag 291 * @debounce: debounce time in microseconds 292 * @gpio_invert: will return whether the GPIO line is inverted or not, 293 * set to NULL to ignore 294 * 295 * Use this function in place of mmc_gpio_request_ro() to use the GPIO 296 * descriptor API. 297 * 298 * Returns zero on success, else an error. 299 */ 300 int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id, 301 unsigned int idx, bool override_active_level, 302 unsigned int debounce, bool *gpio_invert) 303 { 304 struct mmc_gpio *ctx = host->slot.handler_priv; 305 struct gpio_desc *desc; 306 int ret; 307 308 desc = devm_gpiod_get_index(host->parent, con_id, idx, GPIOD_IN); 309 if (IS_ERR(desc)) 310 return PTR_ERR(desc); 311 312 if (debounce) { 313 ret = gpiod_set_debounce(desc, debounce); 314 if (ret < 0) 315 return ret; 316 } 317 318 if (gpio_invert) 319 *gpio_invert = !gpiod_is_active_low(desc); 320 321 ctx->override_ro_active_level = override_active_level; 322 ctx->ro_gpio = desc; 323 324 return 0; 325 } 326 EXPORT_SYMBOL(mmc_gpiod_request_ro); 327 328 bool mmc_can_gpio_ro(struct mmc_host *host) 329 { 330 struct mmc_gpio *ctx = host->slot.handler_priv; 331 332 return ctx->ro_gpio ? true : false; 333 } 334 EXPORT_SYMBOL(mmc_can_gpio_ro); 335