Commit | Line | Data |
---|---|---|
349ab524 GL |
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/interrupt.h> | |
14 | #include <linux/jiffies.h> | |
15 | #include <linux/mmc/host.h> | |
fd0ea65d | 16 | #include <linux/mmc/slot-gpio.h> |
349ab524 GL |
17 | #include <linux/module.h> |
18 | #include <linux/slab.h> | |
19 | ||
fd0ea65d | 20 | struct mmc_gpio { |
5aa7dad3 | 21 | int ro_gpio; |
befe4048 | 22 | int cd_gpio; |
5aa7dad3 | 23 | char *ro_label; |
fd0ea65d | 24 | char cd_label[0]; |
349ab524 GL |
25 | }; |
26 | ||
fd0ea65d | 27 | static irqreturn_t mmc_gpio_cd_irqt(int irq, void *dev_id) |
349ab524 GL |
28 | { |
29 | /* Schedule a card detection after a debounce timeout */ | |
451c8957 GL |
30 | struct mmc_host *host = dev_id; |
31 | ||
32 | if (host->ops->card_event) | |
33 | host->ops->card_event(host); | |
34 | ||
35 | mmc_detect_change(host, msecs_to_jiffies(200)); | |
36 | ||
349ab524 GL |
37 | return IRQ_HANDLED; |
38 | } | |
39 | ||
a7d1a1eb GL |
40 | static int mmc_gpio_alloc(struct mmc_host *host) |
41 | { | |
42 | size_t len = strlen(dev_name(host->parent)) + 4; | |
43 | struct mmc_gpio *ctx; | |
44 | ||
45 | mutex_lock(&host->slot.lock); | |
46 | ||
47 | ctx = host->slot.handler_priv; | |
48 | if (!ctx) { | |
49 | /* | |
50 | * devm_kzalloc() can be called after device_initialize(), even | |
51 | * before device_add(), i.e., between mmc_alloc_host() and | |
52 | * mmc_add_host() | |
53 | */ | |
5aa7dad3 | 54 | ctx = devm_kzalloc(&host->class_dev, sizeof(*ctx) + 2 * len, |
a7d1a1eb GL |
55 | GFP_KERNEL); |
56 | if (ctx) { | |
5aa7dad3 | 57 | ctx->ro_label = ctx->cd_label + len; |
a7d1a1eb | 58 | snprintf(ctx->cd_label, len, "%s cd", dev_name(host->parent)); |
5aa7dad3 | 59 | snprintf(ctx->ro_label, len, "%s ro", dev_name(host->parent)); |
a7d1a1eb | 60 | ctx->cd_gpio = -EINVAL; |
5aa7dad3 | 61 | ctx->ro_gpio = -EINVAL; |
a7d1a1eb GL |
62 | host->slot.handler_priv = ctx; |
63 | } | |
64 | } | |
65 | ||
66 | mutex_unlock(&host->slot.lock); | |
67 | ||
68 | return ctx ? 0 : -ENOMEM; | |
69 | } | |
70 | ||
5aa7dad3 GL |
71 | int mmc_gpio_get_ro(struct mmc_host *host) |
72 | { | |
73 | struct mmc_gpio *ctx = host->slot.handler_priv; | |
74 | ||
75 | if (!ctx || !gpio_is_valid(ctx->ro_gpio)) | |
76 | return -ENOSYS; | |
77 | ||
78 | return !gpio_get_value_cansleep(ctx->ro_gpio) ^ | |
79 | !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH); | |
80 | } | |
81 | EXPORT_SYMBOL(mmc_gpio_get_ro); | |
82 | ||
befe4048 GL |
83 | int mmc_gpio_get_cd(struct mmc_host *host) |
84 | { | |
85 | struct mmc_gpio *ctx = host->slot.handler_priv; | |
86 | ||
87 | if (!ctx || !gpio_is_valid(ctx->cd_gpio)) | |
88 | return -ENOSYS; | |
89 | ||
90 | return !gpio_get_value_cansleep(ctx->cd_gpio) ^ | |
91 | !!(host->caps2 & MMC_CAP2_CD_ACTIVE_HIGH); | |
92 | } | |
93 | EXPORT_SYMBOL(mmc_gpio_get_cd); | |
94 | ||
d65b5ae8 SG |
95 | /** |
96 | * mmc_gpio_request_ro - request a gpio for write-protection | |
97 | * @host: mmc host | |
98 | * @gpio: gpio number requested | |
99 | * | |
100 | * As devm_* managed functions are used in mmc_gpio_request_ro(), client | |
101 | * drivers do not need to explicitly call mmc_gpio_free_ro() for freeing up, | |
102 | * if the requesting and freeing are only needed at probing and unbinding time | |
103 | * for once. However, if client drivers do something special like runtime | |
104 | * switching for write-protection, they are responsible for calling | |
105 | * mmc_gpio_request_ro() and mmc_gpio_free_ro() as a pair on their own. | |
106 | * | |
107 | * Returns zero on success, else an error. | |
108 | */ | |
5aa7dad3 GL |
109 | int mmc_gpio_request_ro(struct mmc_host *host, unsigned int gpio) |
110 | { | |
111 | struct mmc_gpio *ctx; | |
112 | int ret; | |
113 | ||
114 | if (!gpio_is_valid(gpio)) | |
115 | return -EINVAL; | |
116 | ||
117 | ret = mmc_gpio_alloc(host); | |
118 | if (ret < 0) | |
119 | return ret; | |
120 | ||
121 | ctx = host->slot.handler_priv; | |
122 | ||
d65b5ae8 SG |
123 | ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, |
124 | ctx->ro_label); | |
15e8a8e4 CB |
125 | if (ret < 0) |
126 | return ret; | |
127 | ||
128 | ctx->ro_gpio = gpio; | |
129 | ||
130 | return 0; | |
5aa7dad3 GL |
131 | } |
132 | EXPORT_SYMBOL(mmc_gpio_request_ro); | |
133 | ||
d65b5ae8 SG |
134 | /** |
135 | * mmc_gpio_request_cd - request a gpio for card-detection | |
136 | * @host: mmc host | |
137 | * @gpio: gpio number requested | |
214fc309 | 138 | * @debounce: debounce time in microseconds |
d65b5ae8 SG |
139 | * |
140 | * As devm_* managed functions are used in mmc_gpio_request_cd(), client | |
141 | * drivers do not need to explicitly call mmc_gpio_free_cd() for freeing up, | |
142 | * if the requesting and freeing are only needed at probing and unbinding time | |
143 | * for once. However, if client drivers do something special like runtime | |
144 | * switching for card-detection, they are responsible for calling | |
145 | * mmc_gpio_request_cd() and mmc_gpio_free_cd() as a pair on their own. | |
146 | * | |
214fc309 LP |
147 | * If GPIO debouncing is desired, set the debounce parameter to a non-zero |
148 | * value. The caller is responsible for ensuring that the GPIO driver associated | |
149 | * with the GPIO supports debouncing, otherwise an error will be returned. | |
150 | * | |
d65b5ae8 SG |
151 | * Returns zero on success, else an error. |
152 | */ | |
214fc309 LP |
153 | int mmc_gpio_request_cd(struct mmc_host *host, unsigned int gpio, |
154 | unsigned int debounce) | |
349ab524 | 155 | { |
fd0ea65d | 156 | struct mmc_gpio *ctx; |
c9b0546a | 157 | int irq = gpio_to_irq(gpio); |
349ab524 GL |
158 | int ret; |
159 | ||
a7d1a1eb GL |
160 | ret = mmc_gpio_alloc(host); |
161 | if (ret < 0) | |
162 | return ret; | |
349ab524 | 163 | |
a7d1a1eb | 164 | ctx = host->slot.handler_priv; |
349ab524 | 165 | |
d65b5ae8 SG |
166 | ret = devm_gpio_request_one(&host->class_dev, gpio, GPIOF_DIR_IN, |
167 | ctx->cd_label); | |
349ab524 | 168 | if (ret < 0) |
a7d1a1eb GL |
169 | /* |
170 | * don't bother freeing memory. It might still get used by other | |
171 | * slot functions, in any case it will be freed, when the device | |
172 | * is destroyed. | |
173 | */ | |
174 | return ret; | |
349ab524 | 175 | |
214fc309 LP |
176 | if (debounce) { |
177 | ret = gpio_set_debounce(gpio, debounce); | |
178 | if (ret < 0) | |
179 | return ret; | |
180 | } | |
181 | ||
befe4048 GL |
182 | /* |
183 | * Even if gpio_to_irq() returns a valid IRQ number, the platform might | |
184 | * still prefer to poll, e.g., because that IRQ number is already used | |
185 | * by another unit and cannot be shared. | |
186 | */ | |
187 | if (irq >= 0 && host->caps & MMC_CAP_NEEDS_POLL) | |
188 | irq = -EINVAL; | |
189 | ||
190 | if (irq >= 0) { | |
d65b5ae8 SG |
191 | ret = devm_request_threaded_irq(&host->class_dev, irq, |
192 | NULL, mmc_gpio_cd_irqt, | |
fd0ea65d GL |
193 | IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_ONESHOT, |
194 | ctx->cd_label, host); | |
befe4048 GL |
195 | if (ret < 0) |
196 | irq = ret; | |
197 | } | |
349ab524 | 198 | |
27410ee7 | 199 | host->slot.cd_irq = irq; |
befe4048 GL |
200 | |
201 | if (irq < 0) | |
202 | host->caps |= MMC_CAP_NEEDS_POLL; | |
203 | ||
204 | ctx->cd_gpio = gpio; | |
349ab524 GL |
205 | |
206 | return 0; | |
349ab524 | 207 | } |
fd0ea65d | 208 | EXPORT_SYMBOL(mmc_gpio_request_cd); |
349ab524 | 209 | |
d65b5ae8 SG |
210 | /** |
211 | * mmc_gpio_free_ro - free the write-protection gpio | |
212 | * @host: mmc host | |
213 | * | |
214 | * It's provided only for cases that client drivers need to manually free | |
215 | * up the write-protection gpio requested by mmc_gpio_request_ro(). | |
216 | */ | |
5aa7dad3 GL |
217 | void mmc_gpio_free_ro(struct mmc_host *host) |
218 | { | |
219 | struct mmc_gpio *ctx = host->slot.handler_priv; | |
220 | int gpio; | |
221 | ||
222 | if (!ctx || !gpio_is_valid(ctx->ro_gpio)) | |
223 | return; | |
224 | ||
225 | gpio = ctx->ro_gpio; | |
226 | ctx->ro_gpio = -EINVAL; | |
227 | ||
d65b5ae8 | 228 | devm_gpio_free(&host->class_dev, gpio); |
5aa7dad3 GL |
229 | } |
230 | EXPORT_SYMBOL(mmc_gpio_free_ro); | |
231 | ||
d65b5ae8 SG |
232 | /** |
233 | * mmc_gpio_free_cd - free the card-detection gpio | |
234 | * @host: mmc host | |
235 | * | |
236 | * It's provided only for cases that client drivers need to manually free | |
237 | * up the card-detection gpio requested by mmc_gpio_request_cd(). | |
238 | */ | |
fd0ea65d | 239 | void mmc_gpio_free_cd(struct mmc_host *host) |
349ab524 | 240 | { |
27410ee7 | 241 | struct mmc_gpio *ctx = host->slot.handler_priv; |
befe4048 | 242 | int gpio; |
349ab524 | 243 | |
befe4048 | 244 | if (!ctx || !gpio_is_valid(ctx->cd_gpio)) |
0e9f480b GL |
245 | return; |
246 | ||
befe4048 | 247 | if (host->slot.cd_irq >= 0) { |
d65b5ae8 | 248 | devm_free_irq(&host->class_dev, host->slot.cd_irq, host); |
befe4048 GL |
249 | host->slot.cd_irq = -EINVAL; |
250 | } | |
251 | ||
252 | gpio = ctx->cd_gpio; | |
253 | ctx->cd_gpio = -EINVAL; | |
254 | ||
d65b5ae8 | 255 | devm_gpio_free(&host->class_dev, gpio); |
349ab524 | 256 | } |
fd0ea65d | 257 | EXPORT_SYMBOL(mmc_gpio_free_cd); |