aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mmc/core/mmc_ops.c
diff options
context:
space:
mode:
authorDavid Brownell <david-b@pacbell.net>2007-08-08 12:11:32 -0400
committerPierre Ossman <drzeus@drzeus.cx>2007-09-23 15:51:30 -0400
commitaf51715079e7fb6b290e1881d63d815dc4de5011 (patch)
tree324e81b2346955f130dda8515f2ad4f4ce97c864 /drivers/mmc/core/mmc_ops.c
parent7213d175e3b6f6db60f843b72e88857a350e146a (diff)
MMC core learns about SPI
Teach the MMC/SD/SDIO core about using SPI mode. - Use mmc_host_is_spi() so enumeration works through SPI signaling and protocols, not just the native versions. - Provide the SPI response type flags with each request issued, including requests from the new lock/unlock code. - Understand that cmd->resp[0] and mmc_get_status() results for SPI return different values than for "native" MMC/SD protocol; this affects resetting, checking card lock status, and some others. - Understand that some commands act a bit differently ... notably: * OP_COND command doesn't return the OCR * APP_CMD status doesn't have an R1_APP_CMD analogue Those changes required some new and updated primitives: - Provide utilities to access two SPI-only requests, and one request that wasn't previously needed: * mmc_spi_read_ocr() ... SPI only * mmc_spi_set_crc() ... SPI only (override by module parm) * mmc_send_cid() ... for use without broadcast mode - Updated internal routines: * Previous mmc_send_csd() modified into mmc_send_cxd_native(); it uses native "R2" responses, which include 16 bytes of data. * Previous mmc_send_ext_csd() becomes new mmc_send_cxd_data() helper for command-and-data access * Bugfix to that mmc_send_cxd_data() code: dma-to-stack is unsafe/nonportable, so kmalloc a bounce buffer instead. - Modified mmc_send_ext_csd() now uses mmc_send_cxd_data() helper - Modified mmc_send_csd(), and new mmc_spi_send_cid(), routines use those helper routines based on whether they're native or SPI The newest categories of cards supported by the MMC stack aren't expected to work yet with SPI: MMC or SD cards with over 4GB data, and SDIO. All those cards support SPI mode, so eventually they should work too. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Pierre Ossman <drzeus@drzeus.cx>
Diffstat (limited to 'drivers/mmc/core/mmc_ops.c')
-rw-r--r--drivers/mmc/core/mmc_ops.c166
1 files changed, 135 insertions, 31 deletions
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 39567f91a4b8..bf4bc6adcfef 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -63,23 +63,36 @@ int mmc_go_idle(struct mmc_host *host)
63 int err; 63 int err;
64 struct mmc_command cmd; 64 struct mmc_command cmd;
65 65
66 mmc_set_chip_select(host, MMC_CS_HIGH); 66 /*
67 67 * Non-SPI hosts need to prevent chipselect going active during
68 mmc_delay(1); 68 * GO_IDLE; that would put chips into SPI mode. Remind them of
69 * that in case of hardware that won't pull up DAT3/nCS otherwise.
70 *
71 * SPI hosts ignore ios.chip_select; it's managed according to
72 * rules that must accomodate non-MMC slaves which this layer
73 * won't even know about.
74 */
75 if (!mmc_host_is_spi(host)) {
76 mmc_set_chip_select(host, MMC_CS_HIGH);
77 mmc_delay(1);
78 }
69 79
70 memset(&cmd, 0, sizeof(struct mmc_command)); 80 memset(&cmd, 0, sizeof(struct mmc_command));
71 81
72 cmd.opcode = MMC_GO_IDLE_STATE; 82 cmd.opcode = MMC_GO_IDLE_STATE;
73 cmd.arg = 0; 83 cmd.arg = 0;
74 cmd.flags = MMC_RSP_NONE | MMC_CMD_BC; 84 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_NONE | MMC_CMD_BC;
75 85
76 err = mmc_wait_for_cmd(host, &cmd, 0); 86 err = mmc_wait_for_cmd(host, &cmd, 0);
77 87
78 mmc_delay(1); 88 mmc_delay(1);
79 89
80 mmc_set_chip_select(host, MMC_CS_DONTCARE); 90 if (!mmc_host_is_spi(host)) {
91 mmc_set_chip_select(host, MMC_CS_DONTCARE);
92 mmc_delay(1);
93 }
81 94
82 mmc_delay(1); 95 host->use_spi_crc = 0;
83 96
84 return err; 97 return err;
85} 98}
@@ -94,23 +107,33 @@ int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
94 memset(&cmd, 0, sizeof(struct mmc_command)); 107 memset(&cmd, 0, sizeof(struct mmc_command));
95 108
96 cmd.opcode = MMC_SEND_OP_COND; 109 cmd.opcode = MMC_SEND_OP_COND;
97 cmd.arg = ocr; 110 cmd.arg = mmc_host_is_spi(host) ? 0 : ocr;
98 cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR; 111 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
99 112
100 for (i = 100; i; i--) { 113 for (i = 100; i; i--) {
101 err = mmc_wait_for_cmd(host, &cmd, 0); 114 err = mmc_wait_for_cmd(host, &cmd, 0);
102 if (err) 115 if (err)
103 break; 116 break;
104 117
105 if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0) 118 /* if we're just probing, do a single pass */
119 if (ocr == 0)
106 break; 120 break;
107 121
122 /* otherwise wait until reset completes */
123 if (mmc_host_is_spi(host)) {
124 if (!(cmd.resp[0] & R1_SPI_IDLE))
125 break;
126 } else {
127 if (cmd.resp[0] & MMC_CARD_BUSY)
128 break;
129 }
130
108 err = -ETIMEDOUT; 131 err = -ETIMEDOUT;
109 132
110 mmc_delay(10); 133 mmc_delay(10);
111 } 134 }
112 135
113 if (rocr) 136 if (rocr && !mmc_host_is_spi(host))
114 *rocr = cmd.resp[0]; 137 *rocr = cmd.resp[0];
115 138
116 return err; 139 return err;
@@ -160,40 +183,46 @@ int mmc_set_relative_addr(struct mmc_card *card)
160 return 0; 183 return 0;
161} 184}
162 185
163int mmc_send_csd(struct mmc_card *card, u32 *csd) 186static int
187mmc_send_cxd_native(struct mmc_host *host, u32 arg, u32 *cxd, int opcode)
164{ 188{
165 int err; 189 int err;
166 struct mmc_command cmd; 190 struct mmc_command cmd;
167 191
168 BUG_ON(!card); 192 BUG_ON(!host);
169 BUG_ON(!card->host); 193 BUG_ON(!cxd);
170 BUG_ON(!csd);
171 194
172 memset(&cmd, 0, sizeof(struct mmc_command)); 195 memset(&cmd, 0, sizeof(struct mmc_command));
173 196
174 cmd.opcode = MMC_SEND_CSD; 197 cmd.opcode = opcode;
175 cmd.arg = card->rca << 16; 198 cmd.arg = arg;
176 cmd.flags = MMC_RSP_R2 | MMC_CMD_AC; 199 cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
177 200
178 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 201 err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
179 if (err) 202 if (err)
180 return err; 203 return err;
181 204
182 memcpy(csd, cmd.resp, sizeof(u32) * 4); 205 memcpy(cxd, cmd.resp, sizeof(u32) * 4);
183 206
184 return 0; 207 return 0;
185} 208}
186 209
187int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd) 210static int
211mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
212 u32 opcode, void *buf, unsigned len)
188{ 213{
189 struct mmc_request mrq; 214 struct mmc_request mrq;
190 struct mmc_command cmd; 215 struct mmc_command cmd;
191 struct mmc_data data; 216 struct mmc_data data;
192 struct scatterlist sg; 217 struct scatterlist sg;
218 void *data_buf;
193 219
194 BUG_ON(!card); 220 /* dma onto stack is unsafe/nonportable, but callers to this
195 BUG_ON(!card->host); 221 * routine normally provide temporary on-stack buffers ...
196 BUG_ON(!ext_csd); 222 */
223 data_buf = kmalloc(len, GFP_KERNEL);
224 if (data_buf == NULL)
225 return -ENOMEM;
197 226
198 memset(&mrq, 0, sizeof(struct mmc_request)); 227 memset(&mrq, 0, sizeof(struct mmc_request));
199 memset(&cmd, 0, sizeof(struct mmc_command)); 228 memset(&cmd, 0, sizeof(struct mmc_command));
@@ -202,21 +231,31 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
202 mrq.cmd = &cmd; 231 mrq.cmd = &cmd;
203 mrq.data = &data; 232 mrq.data = &data;
204 233
205 cmd.opcode = MMC_SEND_EXT_CSD; 234 cmd.opcode = opcode;
206 cmd.arg = 0; 235 cmd.arg = 0;
207 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
208 236
209 data.blksz = 512; 237 /* NOTE HACK: the MMC_RSP_SPI_R1 is always correct here, but we
238 * rely on callers to never use this with "native" calls for reading
239 * CSD or CID. Native versions of those commands use the R2 type,
240 * not R1 plus a data block.
241 */
242 cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;
243
244 data.blksz = len;
210 data.blocks = 1; 245 data.blocks = 1;
211 data.flags = MMC_DATA_READ; 246 data.flags = MMC_DATA_READ;
212 data.sg = &sg; 247 data.sg = &sg;
213 data.sg_len = 1; 248 data.sg_len = 1;
214 249
215 sg_init_one(&sg, ext_csd, 512); 250 sg_init_one(&sg, data_buf, len);
216 251
217 mmc_set_data_timeout(&data, card); 252 if (card)
253 mmc_set_data_timeout(&data, card);
218 254
219 mmc_wait_for_req(card->host, &mrq); 255 mmc_wait_for_req(host, &mrq);
256
257 memcpy(buf, data_buf, len);
258 kfree(data_buf);
220 259
221 if (cmd.error) 260 if (cmd.error)
222 return cmd.error; 261 return cmd.error;
@@ -226,6 +265,67 @@ int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
226 return 0; 265 return 0;
227} 266}
228 267
268int mmc_send_csd(struct mmc_card *card, u32 *csd)
269{
270 if (!mmc_host_is_spi(card->host))
271 return mmc_send_cxd_native(card->host, card->rca << 16,
272 csd, MMC_SEND_CSD);
273
274 return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
275}
276
277int mmc_send_cid(struct mmc_host *host, u32 *cid)
278{
279 if (!mmc_host_is_spi(host)) {
280 if (!host->card)
281 return -EINVAL;
282 return mmc_send_cxd_native(host, host->card->rca << 16,
283 cid, MMC_SEND_CID);
284 }
285
286 return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
287}
288
289int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
290{
291 return mmc_send_cxd_data(card, card->host, MMC_SEND_EXT_CSD,
292 ext_csd, 512);
293}
294
295int mmc_spi_read_ocr(struct mmc_host *host, int highcap, u32 *ocrp)
296{
297 struct mmc_command cmd;
298 int err;
299
300 memset(&cmd, 0, sizeof(struct mmc_command));
301
302 cmd.opcode = MMC_SPI_READ_OCR;
303 cmd.arg = highcap ? (1 << 30) : 0;
304 cmd.flags = MMC_RSP_SPI_R3;
305
306 err = mmc_wait_for_cmd(host, &cmd, 0);
307
308 *ocrp = cmd.resp[1];
309 return err;
310}
311
312int mmc_spi_set_crc(struct mmc_host *host, int use_crc)
313{
314 struct mmc_command cmd;
315 int err;
316
317 memset(&cmd, 0, sizeof(struct mmc_command));
318
319 cmd.opcode = MMC_SPI_CRC_ON_OFF;
320 cmd.flags = MMC_RSP_SPI_R1;
321 cmd.arg = use_crc;
322
323 err = mmc_wait_for_cmd(host, &cmd, 0);
324 if (!err)
325 host->use_spi_crc = use_crc;
326 return err;
327}
328
229int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value) 329int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
230{ 330{
231 int err; 331 int err;
@@ -241,7 +341,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
241 (index << 16) | 341 (index << 16) |
242 (value << 8) | 342 (value << 8) |
243 set; 343 set;
244 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC; 344 cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
245 345
246 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 346 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
247 if (err) 347 if (err)
@@ -261,13 +361,17 @@ int mmc_send_status(struct mmc_card *card, u32 *status)
261 memset(&cmd, 0, sizeof(struct mmc_command)); 361 memset(&cmd, 0, sizeof(struct mmc_command));
262 362
263 cmd.opcode = MMC_SEND_STATUS; 363 cmd.opcode = MMC_SEND_STATUS;
264 cmd.arg = card->rca << 16; 364 if (!mmc_host_is_spi(card->host))
265 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC; 365 cmd.arg = card->rca << 16;
366 cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
266 367
267 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES); 368 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
268 if (err) 369 if (err)
269 return err; 370 return err;
270 371
372 /* NOTE: callers are required to understand the difference
373 * between "native" and SPI format status words!
374 */
271 if (status) 375 if (status)
272 *status = cmd.resp[0]; 376 *status = cmd.resp[0];
273 377