mmc: sdricoh_cs: Drop unused defines
[linux-2.6-microblaze.git] / drivers / mmc / host / sdricoh_cs.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  sdricoh_cs.c - driver for Ricoh Secure Digital Card Readers that can be
4  *     found on some Ricoh RL5c476 II cardbus bridge
5  *
6  *  Copyright (C) 2006 - 2008 Sascha Sommer <saschasommer@freenet.de>
7  */
8
9 /*
10 #define DEBUG
11 #define VERBOSE_DEBUG
12 */
13 #include <linux/delay.h>
14 #include <linux/highmem.h>
15 #include <linux/module.h>
16 #include <linux/pci.h>
17 #include <linux/ioport.h>
18 #include <linux/scatterlist.h>
19
20 #include <pcmcia/cistpl.h>
21 #include <pcmcia/ds.h>
22 #include <linux/io.h>
23
24 #include <linux/mmc/host.h>
25
26 #define DRIVER_NAME "sdricoh_cs"
27
28 static unsigned int switchlocked;
29
30 /* i/o region */
31 #define SDRICOH_PCI_REGION 0
32 #define SDRICOH_PCI_REGION_SIZE 0x1000
33
34 /* registers */
35 #define R104_VERSION     0x104
36 #define R200_CMD         0x200
37 #define R204_CMD_ARG     0x204
38 #define R208_DATAIO      0x208
39 #define R20C_RESP        0x20c
40 #define R21C_STATUS      0x21c
41 #define R2E0_INIT        0x2e0
42 #define R2E4_STATUS_RESP 0x2e4
43 #define R2F0_RESET       0x2f0
44 #define R224_MODE        0x224
45 #define R226_BLOCKSIZE   0x226
46 #define R228_POWER       0x228
47 #define R230_DATA        0x230
48
49 /* flags for the R21C_STATUS register */
50 #define STATUS_CMD_FINISHED      0x00000001
51 #define STATUS_TRANSFER_FINISHED 0x00000004
52 #define STATUS_CARD_INSERTED     0x00000020
53 #define STATUS_CARD_LOCKED       0x00000080
54 #define STATUS_CMD_TIMEOUT       0x00400000
55 #define STATUS_READY_TO_READ     0x01000000
56 #define STATUS_READY_TO_WRITE    0x02000000
57 #define STATUS_BUSY              0x40000000
58
59 /* timeouts */
60 #define CMD_TIMEOUT       100000
61 #define TRANSFER_TIMEOUT  100000
62
63 /* list of supported pcmcia devices */
64 static const struct pcmcia_device_id pcmcia_ids[] = {
65         /* vendor and device strings followed by their crc32 hashes */
66         PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay1Controller", 0xd9f522ed,
67                                 0xc3901202),
68         PCMCIA_DEVICE_PROD_ID12("RICOH", "Bay Controller", 0xd9f522ed,
69                                 0xace80909),
70         PCMCIA_DEVICE_NULL,
71 };
72
73 MODULE_DEVICE_TABLE(pcmcia, pcmcia_ids);
74
75 /* mmc privdata */
76 struct sdricoh_host {
77         struct device *dev;
78         struct mmc_host *mmc;   /* MMC structure */
79         unsigned char __iomem *iobase;
80         struct pci_dev *pci_dev;
81         int app_cmd;
82 };
83
84 /***************** register i/o helper functions *****************************/
85
86 static inline unsigned int sdricoh_readl(struct sdricoh_host *host,
87                                          unsigned int reg)
88 {
89         unsigned int value = readl(host->iobase + reg);
90         dev_vdbg(host->dev, "rl %x 0x%x\n", reg, value);
91         return value;
92 }
93
94 static inline void sdricoh_writel(struct sdricoh_host *host, unsigned int reg,
95                                   unsigned int value)
96 {
97         writel(value, host->iobase + reg);
98         dev_vdbg(host->dev, "wl %x 0x%x\n", reg, value);
99
100 }
101
102 static inline unsigned int sdricoh_readw(struct sdricoh_host *host,
103                                          unsigned int reg)
104 {
105         unsigned int value = readw(host->iobase + reg);
106         dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value);
107         return value;
108 }
109
110 static inline void sdricoh_writew(struct sdricoh_host *host, unsigned int reg,
111                                          unsigned short value)
112 {
113         writew(value, host->iobase + reg);
114         dev_vdbg(host->dev, "ww %x 0x%x\n", reg, value);
115 }
116
117 static inline unsigned int sdricoh_readb(struct sdricoh_host *host,
118                                          unsigned int reg)
119 {
120         unsigned int value = readb(host->iobase + reg);
121         dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value);
122         return value;
123 }
124
125 static int sdricoh_query_status(struct sdricoh_host *host, unsigned int wanted,
126                                 unsigned int timeout){
127         unsigned int loop;
128         unsigned int status = 0;
129         struct device *dev = host->dev;
130         for (loop = 0; loop < timeout; loop++) {
131                 status = sdricoh_readl(host, R21C_STATUS);
132                 sdricoh_writel(host, R2E4_STATUS_RESP, status);
133                 if (status & wanted)
134                         break;
135         }
136
137         if (loop == timeout) {
138                 dev_err(dev, "query_status: timeout waiting for %x\n", wanted);
139                 return -ETIMEDOUT;
140         }
141
142         /* do not do this check in the loop as some commands fail otherwise */
143         if (status & 0x7F0000) {
144                 dev_err(dev, "waiting for status bit %x failed\n", wanted);
145                 return -EINVAL;
146         }
147         return 0;
148
149 }
150
151 static int sdricoh_mmc_cmd(struct sdricoh_host *host, unsigned char opcode,
152                            unsigned int arg)
153 {
154         unsigned int status;
155         int result = 0;
156         unsigned int loop = 0;
157         /* reset status reg? */
158         sdricoh_writel(host, R21C_STATUS, 0x18);
159         /* fill parameters */
160         sdricoh_writel(host, R204_CMD_ARG, arg);
161         sdricoh_writel(host, R200_CMD, (0x10000 << 8) | opcode);
162         /* wait for command completion */
163         if (opcode) {
164                 for (loop = 0; loop < CMD_TIMEOUT; loop++) {
165                         status = sdricoh_readl(host, R21C_STATUS);
166                         sdricoh_writel(host, R2E4_STATUS_RESP, status);
167                         if (status  & STATUS_CMD_FINISHED)
168                                 break;
169                 }
170                 /* don't check for timeout in the loop it is not always
171                    reset correctly
172                 */
173                 if (loop == CMD_TIMEOUT || status & STATUS_CMD_TIMEOUT)
174                         result = -ETIMEDOUT;
175
176         }
177
178         return result;
179
180 }
181
182 static int sdricoh_reset(struct sdricoh_host *host)
183 {
184         dev_dbg(host->dev, "reset\n");
185         sdricoh_writel(host, R2F0_RESET, 0x10001);
186         sdricoh_writel(host, R2E0_INIT, 0x10000);
187         if (sdricoh_readl(host, R2E0_INIT) != 0x10000)
188                 return -EIO;
189         sdricoh_writel(host, R2E0_INIT, 0x10007);
190
191         sdricoh_writel(host, R224_MODE, 0x2000000);
192         sdricoh_writel(host, R228_POWER, 0xe0);
193
194
195         /* status register ? */
196         sdricoh_writel(host, R21C_STATUS, 0x18);
197
198         return 0;
199 }
200
201 static int sdricoh_blockio(struct sdricoh_host *host, int read,
202                                 u8 *buf, int len)
203 {
204         int size;
205         u32 data = 0;
206         /* wait until the data is available */
207         if (read) {
208                 if (sdricoh_query_status(host, STATUS_READY_TO_READ,
209                                                 TRANSFER_TIMEOUT))
210                         return -ETIMEDOUT;
211                 sdricoh_writel(host, R21C_STATUS, 0x18);
212                 /* read data */
213                 while (len) {
214                         data = sdricoh_readl(host, R230_DATA);
215                         size = min(len, 4);
216                         len -= size;
217                         while (size) {
218                                 *buf = data & 0xFF;
219                                 buf++;
220                                 data >>= 8;
221                                 size--;
222                         }
223                 }
224         } else {
225                 if (sdricoh_query_status(host, STATUS_READY_TO_WRITE,
226                                                 TRANSFER_TIMEOUT))
227                         return -ETIMEDOUT;
228                 sdricoh_writel(host, R21C_STATUS, 0x18);
229                 /* write data */
230                 while (len) {
231                         size = min(len, 4);
232                         len -= size;
233                         while (size) {
234                                 data >>= 8;
235                                 data |= (u32)*buf << 24;
236                                 buf++;
237                                 size--;
238                         }
239                         sdricoh_writel(host, R230_DATA, data);
240                 }
241         }
242
243         return 0;
244 }
245
246 static void sdricoh_request(struct mmc_host *mmc, struct mmc_request *mrq)
247 {
248         struct sdricoh_host *host = mmc_priv(mmc);
249         struct mmc_command *cmd = mrq->cmd;
250         struct mmc_data *data = cmd->data;
251         struct device *dev = host->dev;
252         unsigned char opcode = cmd->opcode;
253         int i;
254
255         dev_dbg(dev, "=============================\n");
256         dev_dbg(dev, "sdricoh_request opcode=%i\n", opcode);
257
258         sdricoh_writel(host, R21C_STATUS, 0x18);
259
260         /* MMC_APP_CMDs need some special handling */
261         if (host->app_cmd) {
262                 opcode |= 64;
263                 host->app_cmd = 0;
264         } else if (opcode == 55)
265                 host->app_cmd = 1;
266
267         /* read/write commands seem to require this */
268         if (data) {
269                 sdricoh_writew(host, R226_BLOCKSIZE, data->blksz);
270                 sdricoh_writel(host, R208_DATAIO, 0);
271         }
272
273         cmd->error = sdricoh_mmc_cmd(host, opcode, cmd->arg);
274
275         /* read response buffer */
276         if (cmd->flags & MMC_RSP_PRESENT) {
277                 if (cmd->flags & MMC_RSP_136) {
278                         /* CRC is stripped so we need to do some shifting. */
279                         for (i = 0; i < 4; i++) {
280                                 cmd->resp[i] =
281                                     sdricoh_readl(host,
282                                                   R20C_RESP + (3 - i) * 4) << 8;
283                                 if (i != 3)
284                                         cmd->resp[i] |=
285                                             sdricoh_readb(host, R20C_RESP +
286                                                           (3 - i) * 4 - 1);
287                         }
288                 } else
289                         cmd->resp[0] = sdricoh_readl(host, R20C_RESP);
290         }
291
292         /* transfer data */
293         if (data && cmd->error == 0) {
294                 dev_dbg(dev, "transfer: blksz %i blocks %i sg_len %i "
295                         "sg length %i\n", data->blksz, data->blocks,
296                         data->sg_len, data->sg->length);
297
298                 /* enter data reading mode */
299                 sdricoh_writel(host, R21C_STATUS, 0x837f031e);
300                 for (i = 0; i < data->blocks; i++) {
301                         size_t len = data->blksz;
302                         u8 *buf;
303                         struct page *page;
304                         int result;
305                         page = sg_page(data->sg);
306
307                         buf = kmap(page) + data->sg->offset + (len * i);
308                         result =
309                                 sdricoh_blockio(host,
310                                         data->flags & MMC_DATA_READ, buf, len);
311                         kunmap(page);
312                         flush_dcache_page(page);
313                         if (result) {
314                                 dev_err(dev, "sdricoh_request: cmd %i "
315                                         "block transfer failed\n", cmd->opcode);
316                                 cmd->error = result;
317                                 break;
318                         } else
319                                 data->bytes_xfered += len;
320                 }
321
322                 sdricoh_writel(host, R208_DATAIO, 1);
323
324                 if (sdricoh_query_status(host, STATUS_TRANSFER_FINISHED,
325                                         TRANSFER_TIMEOUT)) {
326                         dev_err(dev, "sdricoh_request: transfer end error\n");
327                         cmd->error = -EINVAL;
328                 }
329         }
330         /* FIXME check busy flag */
331
332         mmc_request_done(mmc, mrq);
333         dev_dbg(dev, "=============================\n");
334 }
335
336 static void sdricoh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
337 {
338         struct sdricoh_host *host = mmc_priv(mmc);
339         dev_dbg(host->dev, "set_ios\n");
340
341         if (ios->power_mode == MMC_POWER_ON) {
342                 sdricoh_writel(host, R228_POWER, 0xc0e0);
343
344                 if (ios->bus_width == MMC_BUS_WIDTH_4) {
345                         sdricoh_writel(host, R224_MODE, 0x2000300);
346                         sdricoh_writel(host, R228_POWER, 0x40e0);
347                 } else {
348                         sdricoh_writel(host, R224_MODE, 0x2000340);
349                 }
350
351         } else if (ios->power_mode == MMC_POWER_UP) {
352                 sdricoh_writel(host, R224_MODE, 0x2000320);
353                 sdricoh_writel(host, R228_POWER, 0xe0);
354         }
355 }
356
357 static int sdricoh_get_ro(struct mmc_host *mmc)
358 {
359         struct sdricoh_host *host = mmc_priv(mmc);
360         unsigned int status;
361
362         status = sdricoh_readl(host, R21C_STATUS);
363         sdricoh_writel(host, R2E4_STATUS_RESP, status);
364
365         /* some notebooks seem to have the locked flag switched */
366         if (switchlocked)
367                 return !(status & STATUS_CARD_LOCKED);
368
369         return (status & STATUS_CARD_LOCKED);
370 }
371
372 static const struct mmc_host_ops sdricoh_ops = {
373         .request = sdricoh_request,
374         .set_ios = sdricoh_set_ios,
375         .get_ro = sdricoh_get_ro,
376 };
377
378 /* initialize the control and register it to the mmc framework */
379 static int sdricoh_init_mmc(struct pci_dev *pci_dev,
380                             struct pcmcia_device *pcmcia_dev)
381 {
382         int result;
383         void __iomem *iobase;
384         struct mmc_host *mmc;
385         struct sdricoh_host *host;
386         struct device *dev = &pcmcia_dev->dev;
387         /* map iomem */
388         if (pci_resource_len(pci_dev, SDRICOH_PCI_REGION) !=
389             SDRICOH_PCI_REGION_SIZE) {
390                 dev_dbg(dev, "unexpected pci resource len\n");
391                 return -ENODEV;
392         }
393         iobase =
394             pci_iomap(pci_dev, SDRICOH_PCI_REGION, SDRICOH_PCI_REGION_SIZE);
395         if (!iobase) {
396                 dev_err(dev, "unable to map iobase\n");
397                 return -ENODEV;
398         }
399         /* check version? */
400         if (readl(iobase + R104_VERSION) != 0x4000) {
401                 dev_dbg(dev, "no supported mmc controller found\n");
402                 result = -ENODEV;
403                 goto unmap_io;
404         }
405         /* allocate privdata */
406         mmc = pcmcia_dev->priv =
407             mmc_alloc_host(sizeof(struct sdricoh_host), &pcmcia_dev->dev);
408         if (!mmc) {
409                 dev_err(dev, "mmc_alloc_host failed\n");
410                 result = -ENOMEM;
411                 goto unmap_io;
412         }
413         host = mmc_priv(mmc);
414
415         host->iobase = iobase;
416         host->dev = dev;
417         host->pci_dev = pci_dev;
418
419         mmc->ops = &sdricoh_ops;
420
421         /* FIXME: frequency and voltage handling is done by the controller
422          */
423         mmc->f_min = 450000;
424         mmc->f_max = 24000000;
425         mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
426         mmc->caps |= MMC_CAP_4_BIT_DATA;
427
428         mmc->max_seg_size = 1024 * 512;
429         mmc->max_blk_size = 512;
430
431         /* reset the controller */
432         if (sdricoh_reset(host)) {
433                 dev_dbg(dev, "could not reset\n");
434                 result = -EIO;
435                 goto free_host;
436         }
437
438         result = mmc_add_host(mmc);
439
440         if (!result) {
441                 dev_dbg(dev, "mmc host registered\n");
442                 return 0;
443         }
444 free_host:
445         mmc_free_host(mmc);
446 unmap_io:
447         pci_iounmap(pci_dev, iobase);
448         return result;
449 }
450
451 /* search for supported mmc controllers */
452 static int sdricoh_pcmcia_probe(struct pcmcia_device *pcmcia_dev)
453 {
454         struct pci_dev *pci_dev = NULL;
455
456         dev_info(&pcmcia_dev->dev, "Searching MMC controller for pcmcia device"
457                 " %s %s ...\n", pcmcia_dev->prod_id[0], pcmcia_dev->prod_id[1]);
458
459         /* search pci cardbus bridge that contains the mmc controller */
460         /* the io region is already claimed by yenta_socket... */
461         while ((pci_dev =
462                 pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476,
463                                pci_dev))) {
464                 /* try to init the device */
465                 if (!sdricoh_init_mmc(pci_dev, pcmcia_dev)) {
466                         dev_info(&pcmcia_dev->dev, "MMC controller found\n");
467                         return 0;
468                 }
469
470         }
471         dev_err(&pcmcia_dev->dev, "No MMC controller was found.\n");
472         return -ENODEV;
473 }
474
475 static void sdricoh_pcmcia_detach(struct pcmcia_device *link)
476 {
477         struct mmc_host *mmc = link->priv;
478
479         dev_dbg(&link->dev, "detach\n");
480
481         /* remove mmc host */
482         if (mmc) {
483                 struct sdricoh_host *host = mmc_priv(mmc);
484                 mmc_remove_host(mmc);
485                 pci_iounmap(host->pci_dev, host->iobase);
486                 pci_dev_put(host->pci_dev);
487                 mmc_free_host(mmc);
488         }
489         pcmcia_disable_device(link);
490
491 }
492
493 #ifdef CONFIG_PM
494 static int sdricoh_pcmcia_suspend(struct pcmcia_device *link)
495 {
496         dev_dbg(&link->dev, "suspend\n");
497         return 0;
498 }
499
500 static int sdricoh_pcmcia_resume(struct pcmcia_device *link)
501 {
502         struct mmc_host *mmc = link->priv;
503         dev_dbg(&link->dev, "resume\n");
504         sdricoh_reset(mmc_priv(mmc));
505         return 0;
506 }
507 #else
508 #define sdricoh_pcmcia_suspend NULL
509 #define sdricoh_pcmcia_resume NULL
510 #endif
511
512 static struct pcmcia_driver sdricoh_driver = {
513         .name = DRIVER_NAME,
514         .probe = sdricoh_pcmcia_probe,
515         .remove = sdricoh_pcmcia_detach,
516         .id_table = pcmcia_ids,
517         .suspend = sdricoh_pcmcia_suspend,
518         .resume = sdricoh_pcmcia_resume,
519 };
520 module_pcmcia_driver(sdricoh_driver);
521
522 module_param(switchlocked, uint, 0444);
523
524 MODULE_AUTHOR("Sascha Sommer <saschasommer@freenet.de>");
525 MODULE_DESCRIPTION("Ricoh PCMCIA Secure Digital Interface driver");
526 MODULE_LICENSE("GPL");
527
528 MODULE_PARM_DESC(switchlocked, "Switch the cards locked status."
529                 "Use this when unlocked cards are shown readonly (default 0)");