Merge branch 'juju' of git://git.kernel.org/pub/scm/linux/kernel/git/ieee1394/linux13...
[linux-2.6] / drivers / mmc / core / sd_ops.c
1 /*
2  *  linux/drivers/mmc/sd_ops.h
3  *
4  *  Copyright 2006-2007 Pierre Ossman
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; either version 2 of the License, or (at
9  * your option) any later version.
10  */
11
12 #include <linux/types.h>
13 #include <asm/scatterlist.h>
14 #include <linux/scatterlist.h>
15
16 #include <linux/mmc/host.h>
17 #include <linux/mmc/card.h>
18 #include <linux/mmc/mmc.h>
19 #include <linux/mmc/sd.h>
20
21 #include "core.h"
22 #include "sd_ops.h"
23
24 /**
25  *      mmc_wait_for_app_cmd - start an application command and wait for
26                                completion
27  *      @host: MMC host to start command
28  *      @rca: RCA to send MMC_APP_CMD to
29  *      @cmd: MMC command to start
30  *      @retries: maximum number of retries
31  *
32  *      Sends a MMC_APP_CMD, checks the card response, sends the command
33  *      in the parameter and waits for it to complete. Return any error
34  *      that occurred while the command was executing.  Do not attempt to
35  *      parse the response.
36  */
37 int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
38         struct mmc_command *cmd, int retries)
39 {
40         struct mmc_request mrq;
41
42         int i, err;
43
44         BUG_ON(!cmd);
45         BUG_ON(retries < 0);
46
47         err = MMC_ERR_INVALID;
48
49         /*
50          * We have to resend MMC_APP_CMD for each attempt so
51          * we cannot use the retries field in mmc_command.
52          */
53         for (i = 0;i <= retries;i++) {
54                 memset(&mrq, 0, sizeof(struct mmc_request));
55
56                 err = mmc_app_cmd(host, card);
57                 if (err != MMC_ERR_NONE)
58                         continue;
59
60                 memset(&mrq, 0, sizeof(struct mmc_request));
61
62                 memset(cmd->resp, 0, sizeof(cmd->resp));
63                 cmd->retries = 0;
64
65                 mrq.cmd = cmd;
66                 cmd->data = NULL;
67
68                 mmc_wait_for_req(host, &mrq);
69
70                 err = cmd->error;
71                 if (cmd->error == MMC_ERR_NONE)
72                         break;
73         }
74
75         return err;
76 }
77
78 EXPORT_SYMBOL(mmc_wait_for_app_cmd);
79
80 int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
81 {
82         int err;
83         struct mmc_command cmd;
84
85         BUG_ON(!host);
86         BUG_ON(card && (card->host != host));
87
88         cmd.opcode = MMC_APP_CMD;
89
90         if (card) {
91                 cmd.arg = card->rca << 16;
92                 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
93         } else {
94                 cmd.arg = 0;
95                 cmd.flags = MMC_RSP_R1 | MMC_CMD_BCR;
96         }
97
98         err = mmc_wait_for_cmd(host, &cmd, 0);
99         if (err != MMC_ERR_NONE)
100                 return err;
101
102         /* Check that card supported application commands */
103         if (!(cmd.resp[0] & R1_APP_CMD))
104                 return MMC_ERR_FAILED;
105
106         return MMC_ERR_NONE;
107 }
108
109 int mmc_app_set_bus_width(struct mmc_card *card, int width)
110 {
111         int err;
112         struct mmc_command cmd;
113
114         BUG_ON(!card);
115         BUG_ON(!card->host);
116
117         memset(&cmd, 0, sizeof(struct mmc_command));
118
119         cmd.opcode = SD_APP_SET_BUS_WIDTH;
120         cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
121
122         switch (width) {
123         case MMC_BUS_WIDTH_1:
124                 cmd.arg = SD_BUS_WIDTH_1;
125                 break;
126         case MMC_BUS_WIDTH_4:
127                 cmd.arg = SD_BUS_WIDTH_4;
128                 break;
129         default:
130                 return MMC_ERR_INVALID;
131         }
132
133         err = mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
134         if (err != MMC_ERR_NONE)
135                 return err;
136
137         return MMC_ERR_NONE;
138 }
139
140 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
141 {
142         struct mmc_command cmd;
143         int i, err = 0;
144
145         BUG_ON(!host);
146
147         memset(&cmd, 0, sizeof(struct mmc_command));
148
149         cmd.opcode = SD_APP_OP_COND;
150         cmd.arg = ocr;
151         cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
152
153         for (i = 100; i; i--) {
154                 err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
155                 if (err != MMC_ERR_NONE)
156                         break;
157
158                 if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
159                         break;
160
161                 err = MMC_ERR_TIMEOUT;
162
163                 mmc_delay(10);
164         }
165
166         if (rocr)
167                 *rocr = cmd.resp[0];
168
169         return err;
170 }
171
172 int mmc_send_if_cond(struct mmc_host *host, u32 ocr)
173 {
174         struct mmc_command cmd;
175         int err;
176         static const u8 test_pattern = 0xAA;
177
178         /*
179          * To support SD 2.0 cards, we must always invoke SD_SEND_IF_COND
180          * before SD_APP_OP_COND. This command will harmlessly fail for
181          * SD 1.0 cards.
182          */
183         cmd.opcode = SD_SEND_IF_COND;
184         cmd.arg = ((ocr & 0xFF8000) != 0) << 8 | test_pattern;
185         cmd.flags = MMC_RSP_R7 | MMC_CMD_BCR;
186
187         err = mmc_wait_for_cmd(host, &cmd, 0);
188         if (err != MMC_ERR_NONE)
189                 return err;
190
191         if ((cmd.resp[0] & 0xFF) != test_pattern)
192                 return MMC_ERR_FAILED;
193
194         return MMC_ERR_NONE;
195 }
196
197 int mmc_send_relative_addr(struct mmc_host *host, unsigned int *rca)
198 {
199         int err;
200         struct mmc_command cmd;
201
202         BUG_ON(!host);
203         BUG_ON(!rca);
204
205         memset(&cmd, 0, sizeof(struct mmc_command));
206
207         cmd.opcode = SD_SEND_RELATIVE_ADDR;
208         cmd.arg = 0;
209         cmd.flags = MMC_RSP_R6 | MMC_CMD_BCR;
210
211         err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
212         if (err != MMC_ERR_NONE)
213                 return err;
214
215         *rca = cmd.resp[0] >> 16;
216
217         return MMC_ERR_NONE;
218 }
219
220 int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
221 {
222         int err;
223         struct mmc_request mrq;
224         struct mmc_command cmd;
225         struct mmc_data data;
226         struct scatterlist sg;
227
228         BUG_ON(!card);
229         BUG_ON(!card->host);
230         BUG_ON(!scr);
231
232         err = mmc_app_cmd(card->host, card);
233         if (err != MMC_ERR_NONE)
234                 return err;
235
236         memset(&mrq, 0, sizeof(struct mmc_request));
237         memset(&cmd, 0, sizeof(struct mmc_command));
238         memset(&data, 0, sizeof(struct mmc_data));
239
240         mrq.cmd = &cmd;
241         mrq.data = &data;
242
243         cmd.opcode = SD_APP_SEND_SCR;
244         cmd.arg = 0;
245         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
246
247         data.blksz = 8;
248         data.blocks = 1;
249         data.flags = MMC_DATA_READ;
250         data.sg = &sg;
251         data.sg_len = 1;
252
253         sg_init_one(&sg, scr, 8);
254
255         mmc_set_data_timeout(&data, card, 0);
256
257         mmc_wait_for_req(card->host, &mrq);
258
259         if (cmd.error != MMC_ERR_NONE)
260                 return cmd.error;
261         if (data.error != MMC_ERR_NONE)
262                 return data.error;
263
264         scr[0] = ntohl(scr[0]);
265         scr[1] = ntohl(scr[1]);
266
267         return MMC_ERR_NONE;
268 }
269
270 int mmc_sd_switch(struct mmc_card *card, int mode, int group,
271         u8 value, u8 *resp)
272 {
273         struct mmc_request mrq;
274         struct mmc_command cmd;
275         struct mmc_data data;
276         struct scatterlist sg;
277
278         BUG_ON(!card);
279         BUG_ON(!card->host);
280
281         mode = !!mode;
282         value &= 0xF;
283
284         memset(&mrq, 0, sizeof(struct mmc_request));
285         memset(&cmd, 0, sizeof(struct mmc_command));
286         memset(&data, 0, sizeof(struct mmc_data));
287
288         mrq.cmd = &cmd;
289         mrq.data = &data;
290
291         cmd.opcode = SD_SWITCH;
292         cmd.arg = mode << 31 | 0x00FFFFFF;
293         cmd.arg &= ~(0xF << (group * 4));
294         cmd.arg |= value << (group * 4);
295         cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
296
297         data.blksz = 64;
298         data.blocks = 1;
299         data.flags = MMC_DATA_READ;
300         data.sg = &sg;
301         data.sg_len = 1;
302
303         sg_init_one(&sg, resp, 64);
304
305         mmc_set_data_timeout(&data, card, 0);
306
307         mmc_wait_for_req(card->host, &mrq);
308
309         if (cmd.error != MMC_ERR_NONE)
310                 return cmd.error;
311         if (data.error != MMC_ERR_NONE)
312                 return data.error;
313
314         return MMC_ERR_NONE;
315 }
316