Lines Matching +full:no +full:- +full:mmc

1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * sdricoh_cs.c - driver for Ricoh Secure Digital Card Readers that can be
6 * Copyright (C) 2006 - 2008 Sascha Sommer <saschasommer@freenet.de>
25 #include <linux/mmc/host.h>
26 #include <linux/mmc/mmc.h>
77 /* mmc privdata */
80 struct mmc_host *mmc; /* MMC structure */ member
91 unsigned int value = readl(host->iobase + reg); in sdricoh_readl()
92 dev_vdbg(host->dev, "rl %x 0x%x\n", reg, value); in sdricoh_readl()
99 writel(value, host->iobase + reg); in sdricoh_writel()
100 dev_vdbg(host->dev, "wl %x 0x%x\n", reg, value); in sdricoh_writel()
107 unsigned int value = readw(host->iobase + reg); in sdricoh_readw()
108 dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value); in sdricoh_readw()
115 writew(value, host->iobase + reg); in sdricoh_writew()
116 dev_vdbg(host->dev, "ww %x 0x%x\n", reg, value); in sdricoh_writew()
122 unsigned int value = readb(host->iobase + reg); in sdricoh_readb()
123 dev_vdbg(host->dev, "rb %x 0x%x\n", reg, value); in sdricoh_readb()
138 struct device *dev = host->dev; in sdricoh_query_status()
146 return -ETIMEDOUT; in sdricoh_query_status()
152 return -EINVAL; in sdricoh_query_status()
162 unsigned char opcode = cmd->opcode; in sdricoh_mmc_cmd()
168 if (host->app_cmd) { in sdricoh_mmc_cmd()
170 host->app_cmd = 0; in sdricoh_mmc_cmd()
172 host->app_cmd = 1; in sdricoh_mmc_cmd()
175 sdricoh_writel(host, R204_CMD_ARG, cmd->arg); in sdricoh_mmc_cmd()
182 timeout_us = cmd->busy_timeout ? cmd->busy_timeout * 1000 : in sdricoh_mmc_cmd()
195 return -ETIMEDOUT; in sdricoh_mmc_cmd()
202 dev_dbg(host->dev, "reset\n"); in sdricoh_reset()
206 return -EIO; in sdricoh_reset()
227 return -ETIMEDOUT; in sdricoh_blockio()
233 len -= size; in sdricoh_blockio()
238 size--; in sdricoh_blockio()
243 return -ETIMEDOUT; in sdricoh_blockio()
248 len -= size; in sdricoh_blockio()
253 size--; in sdricoh_blockio()
262 static void sdricoh_request(struct mmc_host *mmc, struct mmc_request *mrq) in sdricoh_request() argument
264 struct sdricoh_host *host = mmc_priv(mmc); in sdricoh_request()
265 struct mmc_command *cmd = mrq->cmd; in sdricoh_request()
266 struct mmc_data *data = cmd->data; in sdricoh_request()
267 struct device *dev = host->dev; in sdricoh_request()
271 dev_dbg(dev, "sdricoh_request opcode=%i\n", cmd->opcode); in sdricoh_request()
277 sdricoh_writew(host, R226_BLOCKSIZE, data->blksz); in sdricoh_request()
281 cmd->error = sdricoh_mmc_cmd(host, cmd); in sdricoh_request()
284 if (cmd->flags & MMC_RSP_PRESENT) { in sdricoh_request()
285 if (cmd->flags & MMC_RSP_136) { in sdricoh_request()
288 cmd->resp[i] = in sdricoh_request()
290 R20C_RESP + (3 - i) * 4) << 8; in sdricoh_request()
292 cmd->resp[i] |= in sdricoh_request()
294 (3 - i) * 4 - 1); in sdricoh_request()
297 cmd->resp[0] = sdricoh_readl(host, R20C_RESP); in sdricoh_request()
301 if (data && cmd->error == 0) { in sdricoh_request()
303 "sg length %i\n", data->blksz, data->blocks, in sdricoh_request()
304 data->sg_len, data->sg->length); in sdricoh_request()
308 for (i = 0; i < data->blocks; i++) { in sdricoh_request()
309 size_t len = data->blksz; in sdricoh_request()
313 page = sg_page(data->sg); in sdricoh_request()
315 buf = kmap(page) + data->sg->offset + (len * i); in sdricoh_request()
318 data->flags & MMC_DATA_READ, buf, len); in sdricoh_request()
323 "block transfer failed\n", cmd->opcode); in sdricoh_request()
324 cmd->error = result; in sdricoh_request()
327 data->bytes_xfered += len; in sdricoh_request()
334 cmd->error = -EINVAL; in sdricoh_request()
339 mmc_request_done(mmc, mrq); in sdricoh_request()
343 static void sdricoh_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) in sdricoh_set_ios() argument
345 struct sdricoh_host *host = mmc_priv(mmc); in sdricoh_set_ios()
346 dev_dbg(host->dev, "set_ios\n"); in sdricoh_set_ios()
348 if (ios->power_mode == MMC_POWER_ON) { in sdricoh_set_ios()
351 if (ios->bus_width == MMC_BUS_WIDTH_4) { in sdricoh_set_ios()
358 } else if (ios->power_mode == MMC_POWER_UP) { in sdricoh_set_ios()
364 static int sdricoh_get_ro(struct mmc_host *mmc) in sdricoh_get_ro() argument
366 struct sdricoh_host *host = mmc_priv(mmc); in sdricoh_get_ro()
385 /* initialize the control and register it to the mmc framework */
391 struct mmc_host *mmc; in sdricoh_init_mmc() local
393 struct device *dev = &pcmcia_dev->dev; in sdricoh_init_mmc()
398 return -ENODEV; in sdricoh_init_mmc()
404 return -ENODEV; in sdricoh_init_mmc()
408 dev_dbg(dev, "no supported mmc controller found\n"); in sdricoh_init_mmc()
409 result = -ENODEV; in sdricoh_init_mmc()
413 mmc = pcmcia_dev->priv = in sdricoh_init_mmc()
414 mmc_alloc_host(sizeof(struct sdricoh_host), &pcmcia_dev->dev); in sdricoh_init_mmc()
415 if (!mmc) { in sdricoh_init_mmc()
417 result = -ENOMEM; in sdricoh_init_mmc()
420 host = mmc_priv(mmc); in sdricoh_init_mmc()
422 host->iobase = iobase; in sdricoh_init_mmc()
423 host->dev = dev; in sdricoh_init_mmc()
424 host->pci_dev = pci_dev; in sdricoh_init_mmc()
426 mmc->ops = &sdricoh_ops; in sdricoh_init_mmc()
430 mmc->f_min = 450000; in sdricoh_init_mmc()
431 mmc->f_max = 24000000; in sdricoh_init_mmc()
432 mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; in sdricoh_init_mmc()
433 mmc->caps |= MMC_CAP_4_BIT_DATA; in sdricoh_init_mmc()
435 mmc->max_seg_size = 1024 * 512; in sdricoh_init_mmc()
436 mmc->max_blk_size = 512; in sdricoh_init_mmc()
441 result = -EIO; in sdricoh_init_mmc()
445 result = mmc_add_host(mmc); in sdricoh_init_mmc()
448 dev_dbg(dev, "mmc host registered\n"); in sdricoh_init_mmc()
452 mmc_free_host(mmc); in sdricoh_init_mmc()
458 /* search for supported mmc controllers */
463 dev_info(&pcmcia_dev->dev, "Searching MMC controller for pcmcia device" in sdricoh_pcmcia_probe()
464 " %s %s ...\n", pcmcia_dev->prod_id[0], pcmcia_dev->prod_id[1]); in sdricoh_pcmcia_probe()
466 /* search pci cardbus bridge that contains the mmc controller */ in sdricoh_pcmcia_probe()
473 dev_info(&pcmcia_dev->dev, "MMC controller found\n"); in sdricoh_pcmcia_probe()
478 dev_err(&pcmcia_dev->dev, "No MMC controller was found.\n"); in sdricoh_pcmcia_probe()
479 return -ENODEV; in sdricoh_pcmcia_probe()
484 struct mmc_host *mmc = link->priv; in sdricoh_pcmcia_detach() local
486 dev_dbg(&link->dev, "detach\n"); in sdricoh_pcmcia_detach()
488 /* remove mmc host */ in sdricoh_pcmcia_detach()
489 if (mmc) { in sdricoh_pcmcia_detach()
490 struct sdricoh_host *host = mmc_priv(mmc); in sdricoh_pcmcia_detach()
491 mmc_remove_host(mmc); in sdricoh_pcmcia_detach()
492 pci_iounmap(host->pci_dev, host->iobase); in sdricoh_pcmcia_detach()
493 pci_dev_put(host->pci_dev); in sdricoh_pcmcia_detach()
494 mmc_free_host(mmc); in sdricoh_pcmcia_detach()
503 dev_dbg(&link->dev, "suspend\n"); in sdricoh_pcmcia_suspend()
509 struct mmc_host *mmc = link->priv; in sdricoh_pcmcia_resume() local
510 dev_dbg(&link->dev, "resume\n"); in sdricoh_pcmcia_resume()
511 sdricoh_reset(mmc_priv(mmc)); in sdricoh_pcmcia_resume()