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