MOXA linux-2.6.x / linux-2.6.9-uc0 from sdlinux-moxaart.tgz
[linux-2.6.9-moxart.git] / drivers / mmc / core / mmc_ops.c
blob4855943896d53911e250279b79f33987f92e47b4
1 /*
2 * linux/drivers/mmc/core/mmc_ops.h
4 * Copyright 2006-2007 Pierre Ossman
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.
12 #include <linux/types.h>
13 #if 1 // add by VIctor Yu. 12-02-2008
14 #include <linux/pagemap.h>
15 #endif
16 #include <asm/scatterlist.h>
17 #include <linux/scatterlist.h>
19 #include <linux/mmc/host.h>
20 #include <linux/mmc/card.h>
21 #include <linux/mmc/mmc.h>
23 #include "core.h"
24 #include "mmc_ops.h"
26 static int _mmc_select_card(struct mmc_host *host, struct mmc_card *card)
28 int err;
29 struct mmc_command cmd;
31 BUG_ON(!host);
33 memset(&cmd, 0, sizeof(struct mmc_command));
35 cmd.opcode = MMC_SELECT_CARD;
37 if (card) {
38 cmd.arg = card->rca << 16;
39 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
40 } else {
41 cmd.arg = 0;
42 cmd.flags = MMC_RSP_NONE | MMC_CMD_AC;
45 err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
46 if (err != MMC_ERR_NONE)
47 return err;
49 return MMC_ERR_NONE;
52 int mmc_select_card(struct mmc_card *card)
54 BUG_ON(!card);
56 return _mmc_select_card(card->host, card);
59 int mmc_deselect_cards(struct mmc_host *host)
61 return _mmc_select_card(host, NULL);
64 int mmc_go_idle(struct mmc_host *host)
66 int err;
67 struct mmc_command cmd;
69 mmc_set_chip_select(host, MMC_CS_HIGH);
71 mmc_delay(1);
73 memset(&cmd, 0, sizeof(struct mmc_command));
75 cmd.opcode = MMC_GO_IDLE_STATE;
76 cmd.arg = 0;
77 cmd.flags = MMC_RSP_NONE | MMC_CMD_BC;
79 err = mmc_wait_for_cmd(host, &cmd, 0);
81 mmc_delay(1);
83 mmc_set_chip_select(host, MMC_CS_DONTCARE);
85 mmc_delay(1);
87 return err;
90 int mmc_send_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
92 struct mmc_command cmd;
93 int i, err = 0;
95 BUG_ON(!host);
97 memset(&cmd, 0, sizeof(struct mmc_command));
99 cmd.opcode = MMC_SEND_OP_COND;
100 cmd.arg = ocr;
101 cmd.flags = MMC_RSP_R3 | MMC_CMD_BCR;
103 for (i = 100; i; i--) {
104 err = mmc_wait_for_cmd(host, &cmd, 0);
105 if (err != MMC_ERR_NONE)
106 break;
108 if (cmd.resp[0] & MMC_CARD_BUSY || ocr == 0)
109 break;
111 err = MMC_ERR_TIMEOUT;
113 mmc_delay(10);
116 if (rocr)
117 *rocr = cmd.resp[0];
119 return err;
122 int mmc_all_send_cid(struct mmc_host *host, u32 *cid)
124 int err;
125 struct mmc_command cmd;
127 BUG_ON(!host);
128 BUG_ON(!cid);
130 memset(&cmd, 0, sizeof(struct mmc_command));
132 cmd.opcode = MMC_ALL_SEND_CID;
133 cmd.arg = 0;
134 cmd.flags = MMC_RSP_R2 | MMC_CMD_BCR;
136 err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
137 if (err != MMC_ERR_NONE)
138 return err;
140 memcpy(cid, cmd.resp, sizeof(u32) * 4);
142 return MMC_ERR_NONE;
145 int mmc_set_relative_addr(struct mmc_card *card)
147 int err;
148 struct mmc_command cmd;
150 BUG_ON(!card);
151 BUG_ON(!card->host);
153 memset(&cmd, 0, sizeof(struct mmc_command));
155 cmd.opcode = MMC_SET_RELATIVE_ADDR;
156 cmd.arg = card->rca << 16;
157 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
159 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
160 if (err != MMC_ERR_NONE)
161 return err;
163 return MMC_ERR_NONE;
166 int mmc_send_csd(struct mmc_card *card, u32 *csd)
168 int err;
169 struct mmc_command cmd;
171 BUG_ON(!card);
172 BUG_ON(!card->host);
173 BUG_ON(!csd);
175 memset(&cmd, 0, sizeof(struct mmc_command));
177 cmd.opcode = MMC_SEND_CSD;
178 cmd.arg = card->rca << 16;
179 cmd.flags = MMC_RSP_R2 | MMC_CMD_AC;
181 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
182 if (err != MMC_ERR_NONE)
183 return err;
185 memcpy(csd, cmd.resp, sizeof(u32) * 4);
187 return MMC_ERR_NONE;
190 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
192 struct mmc_request mrq;
193 struct mmc_command cmd;
194 struct mmc_data data;
195 struct scatterlist sg;
197 BUG_ON(!card);
198 BUG_ON(!card->host);
199 BUG_ON(!ext_csd);
201 memset(&mrq, 0, sizeof(struct mmc_request));
202 memset(&cmd, 0, sizeof(struct mmc_command));
203 memset(&data, 0, sizeof(struct mmc_data));
205 mrq.cmd = &cmd;
206 mrq.data = &data;
208 cmd.opcode = MMC_SEND_EXT_CSD;
209 cmd.arg = 0;
210 cmd.flags = MMC_RSP_R1 | MMC_CMD_ADTC;
212 data.blksz = 512;
213 data.blocks = 1;
214 data.flags = MMC_DATA_READ;
215 data.sg = &sg;
216 data.sg_len = 1;
218 sg_init_one(&sg, ext_csd, 512);
220 mmc_set_data_timeout(&data, card, 0);
222 mmc_wait_for_req(card->host, &mrq);
224 if (cmd.error != MMC_ERR_NONE)
225 return cmd.error;
226 if (data.error != MMC_ERR_NONE)
227 return data.error;
229 return MMC_ERR_NONE;
232 int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value)
234 int err;
235 struct mmc_command cmd;
237 BUG_ON(!card);
238 BUG_ON(!card->host);
240 memset(&cmd, 0, sizeof(struct mmc_command));
242 cmd.opcode = MMC_SWITCH;
243 cmd.arg = (MMC_SWITCH_MODE_WRITE_BYTE << 24) |
244 (index << 16) |
245 (value << 8) |
246 set;
247 cmd.flags = MMC_RSP_R1B | MMC_CMD_AC;
249 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
250 if (err != MMC_ERR_NONE)
251 return err;
253 return MMC_ERR_NONE;
256 int mmc_send_status(struct mmc_card *card, u32 *status)
258 int err;
259 struct mmc_command cmd;
261 BUG_ON(!card);
262 BUG_ON(!card->host);
264 memset(&cmd, 0, sizeof(struct mmc_command));
266 cmd.opcode = MMC_SEND_STATUS;
267 cmd.arg = card->rca << 16;
268 cmd.flags = MMC_RSP_R1 | MMC_CMD_AC;
270 err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
271 if (err != MMC_ERR_NONE)
272 return err;
274 if (status)
275 *status = cmd.resp[0];
277 return MMC_ERR_NONE;