• Home
  • Raw
  • Download

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

2  *  cb710/mmc.c
4 * Copyright by Michał Mirosław, 2008-2009
14 #include "cb710-mmc.h"
21 (ARRAY_SIZE(cb710_clock_divider_log2) - 1)
28 static void cb710_mmc_select_clock_divider(struct mmc_host *mmc, int hz) in cb710_mmc_select_clock_divider() argument
30 struct cb710_slot *slot = cb710_mmc_to_slot(mmc); in cb710_mmc_select_clock_divider()
31 struct pci_dev *pdev = cb710_slot_to_chip(slot)->pdev; in cb710_mmc_select_clock_divider()
38 * indexes 1-7 work as written in the table in cb710_mmc_select_clock_divider()
39 * indexes 0,8-15 give no clock output in cb710_mmc_select_clock_divider()
67 * - it gets set later if any interrupt sources are enabled */ in __cb710_mmc_enable_irq()
72 * -> bit 15 port 0x0C seems to be global interrupt enable in __cb710_mmc_enable_irq()
90 spin_lock_irqsave(&reader->irq_lock, flags); in cb710_mmc_enable_irq()
93 spin_unlock_irqrestore(&reader->irq_lock, flags); in cb710_mmc_enable_irq()
134 return -EIO; in cb710_check_event()
157 if (!--limit) { in cb710_wait_for_event()
160 err = -ETIMEDOUT; in cb710_wait_for_event()
169 limit = 2000000 - limit; in cb710_wait_for_event()
190 if (!--limit) { in cb710_wait_while_busy()
193 err = -ETIMEDOUT; in cb710_wait_while_busy()
202 limit = 500000 - limit; in cb710_wait_while_busy()
216 ((count - 1) << 16)|(blocksize - 1)); in cb710_mmc_set_transfer_size()
224 /* without this, received data is prepended with 8-bytes of zeroes */ in cb710_mmc_fifo_hack()
238 "FIFO-read-hack: expected STATUS0 bit was %s\n", in cb710_mmc_fifo_hack()
241 "FIFO-read-hack: dwords ignored: %08X %08X - %s\n", in cb710_mmc_fifo_hack()
256 slot->iobase + CB710_MMC_DATA_PORT, dw_count); in cb710_mmc_receive_pio()
263 return !(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8)); in cb710_is_transfer_size_supported()
269 size_t len, blocks = data->blocks; in cb710_mmc_receive()
272 /* TODO: I don't know how/if the hardware handles non-16B-boundary blocks in cb710_mmc_receive()
274 if (unlikely(data->blksz & 15 && (data->blocks != 1 || data->blksz != 8))) in cb710_mmc_receive()
275 return -EINVAL; in cb710_mmc_receive()
277 sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_TO_SG); in cb710_mmc_receive()
284 while (blocks-- > 0) { in cb710_mmc_receive()
285 len = data->blksz; in cb710_mmc_receive()
291 len -= 16; in cb710_mmc_receive()
298 len - 1, CB710_MMC_C2_READ_PIO_SIZE_MASK); in cb710_mmc_receive()
313 size_t len, blocks = data->blocks; in cb710_mmc_send()
317 * non-16B-boundary blocks */ in cb710_mmc_send()
318 if (unlikely(data->blocks > 1 && data->blksz & 15)) in cb710_mmc_send()
319 return -EINVAL; in cb710_mmc_send()
321 sg_miter_start(&miter, data->sg, data->sg_len, SG_MITER_FROM_SG); in cb710_mmc_send()
326 while (blocks-- > 0) { in cb710_mmc_send()
327 len = (data->blksz + 15) >> 4; in cb710_mmc_send()
337 slot->iobase + CB710_MMC_DATA_PORT, 4); in cb710_mmc_send()
338 } while (--len); in cb710_mmc_send()
348 unsigned int flags = cmd->flags; in cb710_encode_cmd_flags()
351 /* Windows driver returned 0 for commands for which no response in cb710_encode_cmd_flags()
356 * Original driver set bit 14 for MMC/SD application in cb710_encode_cmd_flags()
357 * commands. There's no difference 'on the wire' and in cb710_encode_cmd_flags()
371 cb_flags |= cmd->opcode << CB710_MMC_CMD_CODE_SHIFT; in cb710_encode_cmd_flags()
373 if (cmd->data && (cmd->data->flags & MMC_DATA_READ)) in cb710_encode_cmd_flags()
383 * I assume that 00 here means no response is expected. in cb710_encode_cmd_flags()
402 if (cmd->flags & MMC_RSP_136) { in cb710_receive_response()
411 cmd->resp[0] = (resp[0] << 8)|(resp[1] >> 24); in cb710_receive_response()
412 cmd->resp[1] = (resp[1] << 8)|(resp[2] >> 24); in cb710_receive_response()
413 cmd->resp[2] = (resp[2] << 8)|(resp[3] >> 24); in cb710_receive_response()
414 cmd->resp[3] = (resp[3] << 8); in cb710_receive_response()
417 cmd->resp[0] = cb710_read_port_32(slot, CB710_MMC_RESPONSE0_PORT); in cb710_receive_response()
420 wanted_opcode = (cmd->flags & MMC_RSP_OPCODE) ? cmd->opcode : 0x3F; in cb710_receive_response()
422 cmd->error = -EILSEQ; in cb710_receive_response()
430 if (data->flags & MMC_DATA_READ) in cb710_mmc_transfer_data()
440 data->bytes_xfered = data->blksz * data->blocks; in cb710_mmc_transfer_data()
444 static int cb710_mmc_command(struct mmc_host *mmc, struct mmc_command *cmd) in cb710_mmc_command() argument
446 struct cb710_slot *slot = cb710_mmc_to_slot(mmc); in cb710_mmc_command()
447 struct cb710_mmc_reader *reader = mmc_priv(mmc); in cb710_mmc_command()
448 struct mmc_data *data = cmd->data; in cb710_mmc_command()
455 data->error = -EINVAL; in cb710_mmc_command()
456 return -1; in cb710_mmc_command()
458 cb710_mmc_set_transfer_size(slot, data->blocks, data->blksz); in cb710_mmc_command()
464 cb710_write_port_32(slot, CB710_MMC_CMD_PARAM_PORT, cmd->arg); in cb710_mmc_command()
469 cmd->error = cb710_wait_for_event(slot, CB710_MMC_S1_COMMAND_SENT); in cb710_mmc_command()
470 if (cmd->error) in cb710_mmc_command()
471 return -1; in cb710_mmc_command()
473 if (cmd->flags & MMC_RSP_PRESENT) { in cb710_mmc_command()
475 if (cmd->error) in cb710_mmc_command()
476 return -1; in cb710_mmc_command()
480 data->error = cb710_mmc_transfer_data(slot, data); in cb710_mmc_command()
484 static void cb710_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) in cb710_mmc_request() argument
486 struct cb710_slot *slot = cb710_mmc_to_slot(mmc); in cb710_mmc_request()
487 struct cb710_mmc_reader *reader = mmc_priv(mmc); in cb710_mmc_request()
489 WARN_ON(reader->mrq != NULL); in cb710_mmc_request()
491 reader->mrq = mrq; in cb710_mmc_request()
494 if (!cb710_mmc_command(mmc, mrq->cmd) && mrq->stop) in cb710_mmc_request()
495 cb710_mmc_command(mmc, mrq->stop); in cb710_mmc_request()
497 tasklet_schedule(&reader->finish_req_tasklet); in cb710_mmc_request()
546 * (it doesn't depend on write-to-read delay) */ in cb710_mmc_powerup()
561 static void cb710_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) in cb710_mmc_set_ios() argument
563 struct cb710_slot *slot = cb710_mmc_to_slot(mmc); in cb710_mmc_set_ios()
564 struct cb710_mmc_reader *reader = mmc_priv(mmc); in cb710_mmc_set_ios()
567 cb710_mmc_select_clock_divider(mmc, ios->clock); in cb710_mmc_set_ios()
569 if (ios->power_mode != reader->last_power_mode) in cb710_mmc_set_ios()
570 switch (ios->power_mode) { in cb710_mmc_set_ios()
575 "powerup failed (%d)- retrying\n", err); in cb710_mmc_set_ios()
581 "powerup retry failed (%d) - expect errors\n", in cb710_mmc_set_ios()
584 reader->last_power_mode = MMC_POWER_ON; in cb710_mmc_set_ios()
588 reader->last_power_mode = MMC_POWER_OFF; in cb710_mmc_set_ios()
595 cb710_mmc_enable_4bit_data(slot, ios->bus_width != MMC_BUS_WIDTH_1); in cb710_mmc_set_ios()
600 static int cb710_mmc_get_ro(struct mmc_host *mmc) in cb710_mmc_get_ro() argument
602 struct cb710_slot *slot = cb710_mmc_to_slot(mmc); in cb710_mmc_get_ro()
608 static int cb710_mmc_get_cd(struct mmc_host *mmc) in cb710_mmc_get_cd() argument
610 struct cb710_slot *slot = cb710_mmc_to_slot(mmc); in cb710_mmc_get_cd()
618 struct mmc_host *mmc = cb710_slot_to_mmc(slot); in cb710_mmc_irq_handler() local
619 struct cb710_mmc_reader *reader = mmc_priv(mmc); in cb710_mmc_irq_handler()
637 mmc_detect_change(mmc, HZ/5); in cb710_mmc_irq_handler()
640 spin_lock(&reader->irq_lock); in cb710_mmc_irq_handler()
642 spin_unlock(&reader->irq_lock); in cb710_mmc_irq_handler()
650 struct mmc_host *mmc = (void *)data; in cb710_mmc_finish_request_tasklet() local
651 struct cb710_mmc_reader *reader = mmc_priv(mmc); in cb710_mmc_finish_request_tasklet()
652 struct mmc_request *mrq = reader->mrq; in cb710_mmc_finish_request_tasklet()
654 reader->mrq = NULL; in cb710_mmc_finish_request_tasklet()
655 mmc_request_done(mmc, mrq); in cb710_mmc_finish_request_tasklet()
689 struct mmc_host *mmc; in cb710_mmc_init() local
694 mmc = mmc_alloc_host(sizeof(*reader), cb710_slot_dev(slot)); in cb710_mmc_init()
695 if (!mmc) in cb710_mmc_init()
696 return -ENOMEM; in cb710_mmc_init()
698 platform_set_drvdata(pdev, mmc); in cb710_mmc_init()
701 pci_read_config_dword(chip->pdev, 0x48, &val); in cb710_mmc_init()
706 mmc->ops = &cb710_mmc_host; in cb710_mmc_init()
707 mmc->f_max = val; in cb710_mmc_init()
708 mmc->f_min = val >> cb710_clock_divider_log2[CB710_MAX_DIVIDER_IDX]; in cb710_mmc_init()
709 mmc->ocr_avail = MMC_VDD_32_33|MMC_VDD_33_34; in cb710_mmc_init()
710 mmc->caps = MMC_CAP_4_BIT_DATA; in cb710_mmc_init()
712 reader = mmc_priv(mmc); in cb710_mmc_init()
714 tasklet_init(&reader->finish_req_tasklet, in cb710_mmc_init()
715 cb710_mmc_finish_request_tasklet, (unsigned long)mmc); in cb710_mmc_init()
716 spin_lock_init(&reader->irq_lock); in cb710_mmc_init()
722 err = mmc_add_host(mmc); in cb710_mmc_init()
727 mmc_hostname(mmc)); in cb710_mmc_init()
737 mmc_free_host(mmc); in cb710_mmc_init()
744 struct mmc_host *mmc = cb710_slot_to_mmc(slot); in cb710_mmc_exit() local
745 struct cb710_mmc_reader *reader = mmc_priv(mmc); in cb710_mmc_exit()
749 mmc_remove_host(mmc); in cb710_mmc_exit()
755 /* clear config ports - just in case */ in cb710_mmc_exit()
759 tasklet_kill(&reader->finish_req_tasklet); in cb710_mmc_exit()
761 mmc_free_host(mmc); in cb710_mmc_exit()
766 .driver.name = "cb710-mmc",
777 MODULE_AUTHOR("Michał Mirosław <mirq-linux@rere.qmqm.pl>");
778 MODULE_DESCRIPTION("ENE CB710 memory card reader driver - MMC/SD part");
780 MODULE_ALIAS("platform:cb710-mmc");