00001
00043 #include <bitops.h>
00044 #include <byteorder.h>
00045 #include <debug.h>
00046 #include <errno.h>
00047 #include <stdbool.h>
00048 #include <string.h>
00049 #include <util.h>
00050 #include <sdmmc/sdmmc.h>
00051 #include "protocol.h"
00052
00053 void sdmmc_slot_submit_req(struct sdmmc_slot *slot, struct sdmmc_request *req)
00054 {
00055 req->slot = slot;
00056 slot->host->submit_req(slot->host, req);
00057 }
00058
00059 uint32_t sdmmc_slot_set_voltage(struct sdmmc_slot *slot, uint32_t ocr)
00060 {
00061 unsigned int bit;
00062
00063
00064
00065
00066
00067 if (ocr & 0x7F) {
00068 dbg_verbose("sdmmc: card claims to support voltages "
00069 "below the defined range. These will "
00070 "be ignored.\n");
00071 ocr &= ~0x7F;
00072 }
00073
00074 if (ocr & SDMMC_OCR_LOW_VOLTAGE) {
00075 dbg_verbose("sdmmc: SD card claims to support the "
00076 "incompletely defined 'low voltage range'. "
00077 "This will be ignored.\n");
00078 ocr &= ~SDMMC_OCR_LOW_VOLTAGE;
00079 }
00080
00081
00082 ocr &= slot->host->ocr_avail;
00083
00084 bit = ffs(ocr);
00085 if (bit) {
00086 bit--;
00087 ocr &= 3 << bit;
00088 slot->host->set_voltage(slot->host, bit);
00089 } else {
00090 ocr = 0;
00091 }
00092
00093 return ocr;
00094 }
00095
00096 void sdmmc_slot_power_up(struct sdmmc_slot *slot)
00097 {
00098 slot->bus_width = 1;
00099 clear_bit(SDMMC_SLOT_HIGH_SPEED, &slot->flags);
00100 sdmmc_slot_set_f_max(slot, 0);
00101 slot->host->power_up(slot->host, slot);
00102 }
00103
00104 void sdmmc_slot_power_down(struct sdmmc_slot *slot)
00105 {
00106 sdmmc_slot_set_f_max(slot, 0);
00107 slot->host->power_down(slot->host, slot);
00108 sdmmc_slot_set_f_max(slot, -1);
00109 }
00110
00111 void sdmmc_slot_set_f_max(struct sdmmc_slot *slot, int32_t f_max)
00112 {
00113 struct sdmmc_host *host = slot->host;
00114
00115 if (f_max > 0 && f_max < host->f_min)
00116 f_max = host->f_min;
00117 slot->f_max = f_max;
00118
00119 sdmmc_slot_update(slot);
00120 }
00121
00122 void sdmmc_slot_set_bus_width(struct sdmmc_slot *slot, unsigned int bits)
00123 {
00124 slot->bus_width = bits;
00125 sdmmc_slot_update(slot);
00126 }
00127
00128 void sdmmc_slot_notify_card_detect(struct sdmmc_slot *slot, int cd_value)
00129 {
00130 if (cd_value)
00131 set_bit(SDMMC_SLOT_CARD_DETECT, &slot->flags);
00132 else
00133 clear_bit(SDMMC_SLOT_CARD_DETECT, &slot->flags);
00134
00135 if (slot->notify_card_detect)
00136 slot->notify_card_detect(slot->context);
00137 }
00138
00139 void sdmmc_slot_init(struct sdmmc_slot *slot, struct sdmmc_host *host,
00140 int slot_id)
00141 {
00142 slot->host = host;
00143 slot->id = slot_id;
00144 slot->flags = 0;
00145 slot->f_max = -1;
00146 slot->notify_card_detect = NULL;
00147 }
00148