Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0-only */ 2 : : /* 3 : : * Private header for the mmc subsystem 4 : : * 5 : : * Copyright (C) 2016 Linaro Ltd 6 : : * 7 : : * Author: Ulf Hansson <ulf.hansson@linaro.org> 8 : : */ 9 : : 10 : : #ifndef _MMC_CORE_CARD_H 11 : : #define _MMC_CORE_CARD_H 12 : : 13 : : #include <linux/mmc/card.h> 14 : : 15 : : #define mmc_card_name(c) ((c)->cid.prod_name) 16 : : #define mmc_card_id(c) (dev_name(&(c)->dev)) 17 : : #define mmc_dev_to_card(d) container_of(d, struct mmc_card, dev) 18 : : 19 : : /* Card states */ 20 : : #define MMC_STATE_PRESENT (1<<0) /* present in sysfs */ 21 : : #define MMC_STATE_READONLY (1<<1) /* card is read-only */ 22 : : #define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing */ 23 : : #define MMC_CARD_SDXC (1<<3) /* card is SDXC */ 24 : : #define MMC_CARD_REMOVED (1<<4) /* card has been removed */ 25 : : #define MMC_STATE_SUSPENDED (1<<5) /* card is suspended */ 26 : : 27 : : #define mmc_card_present(c) ((c)->state & MMC_STATE_PRESENT) 28 : : #define mmc_card_readonly(c) ((c)->state & MMC_STATE_READONLY) 29 : : #define mmc_card_blockaddr(c) ((c)->state & MMC_STATE_BLOCKADDR) 30 : : #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) 31 : : #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) 32 : : #define mmc_card_suspended(c) ((c)->state & MMC_STATE_SUSPENDED) 33 : : 34 : : #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) 35 : : #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) 36 : : #define mmc_card_set_blockaddr(c) ((c)->state |= MMC_STATE_BLOCKADDR) 37 : : #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) 38 : : #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) 39 : : #define mmc_card_set_suspended(c) ((c)->state |= MMC_STATE_SUSPENDED) 40 : : #define mmc_card_clr_suspended(c) ((c)->state &= ~MMC_STATE_SUSPENDED) 41 : : 42 : : /* 43 : : * The world is not perfect and supplies us with broken mmc/sdio devices. 44 : : * For at least some of these bugs we need a work-around. 45 : : */ 46 : : struct mmc_fixup { 47 : : /* CID-specific fields. */ 48 : : const char *name; 49 : : 50 : : /* Valid revision range */ 51 : : u64 rev_start, rev_end; 52 : : 53 : : unsigned int manfid; 54 : : unsigned short oemid; 55 : : 56 : : /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */ 57 : : u16 cis_vendor, cis_device; 58 : : 59 : : /* for MMC cards */ 60 : : unsigned int ext_csd_rev; 61 : : 62 : : void (*vendor_fixup)(struct mmc_card *card, int data); 63 : : int data; 64 : : }; 65 : : 66 : : #define CID_MANFID_ANY (-1u) 67 : : #define CID_OEMID_ANY ((unsigned short) -1) 68 : : #define CID_NAME_ANY (NULL) 69 : : 70 : : #define EXT_CSD_REV_ANY (-1u) 71 : : 72 : : #define CID_MANFID_SANDISK 0x2 73 : : #define CID_MANFID_ATP 0x9 74 : : #define CID_MANFID_TOSHIBA 0x11 75 : : #define CID_MANFID_MICRON 0x13 76 : : #define CID_MANFID_SAMSUNG 0x15 77 : : #define CID_MANFID_APACER 0x27 78 : : #define CID_MANFID_KINGSTON 0x70 79 : : #define CID_MANFID_HYNIX 0x90 80 : : #define CID_MANFID_NUMONYX 0xFE 81 : : 82 : : #define END_FIXUP { NULL } 83 : : 84 : : #define _FIXUP_EXT(_name, _manfid, _oemid, _rev_start, _rev_end, \ 85 : : _cis_vendor, _cis_device, \ 86 : : _fixup, _data, _ext_csd_rev) \ 87 : : { \ 88 : : .name = (_name), \ 89 : : .manfid = (_manfid), \ 90 : : .oemid = (_oemid), \ 91 : : .rev_start = (_rev_start), \ 92 : : .rev_end = (_rev_end), \ 93 : : .cis_vendor = (_cis_vendor), \ 94 : : .cis_device = (_cis_device), \ 95 : : .vendor_fixup = (_fixup), \ 96 : : .data = (_data), \ 97 : : .ext_csd_rev = (_ext_csd_rev), \ 98 : : } 99 : : 100 : : #define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \ 101 : : _fixup, _data, _ext_csd_rev) \ 102 : : _FIXUP_EXT(_name, _manfid, \ 103 : : _oemid, _rev_start, _rev_end, \ 104 : : SDIO_ANY_ID, SDIO_ANY_ID, \ 105 : : _fixup, _data, _ext_csd_rev) \ 106 : : 107 : : #define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \ 108 : : MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ 109 : : EXT_CSD_REV_ANY) 110 : : 111 : : #define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \ 112 : : _ext_csd_rev) \ 113 : : MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \ 114 : : _ext_csd_rev) 115 : : 116 : : #define SDIO_FIXUP(_vendor, _device, _fixup, _data) \ 117 : : _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, \ 118 : : CID_OEMID_ANY, 0, -1ull, \ 119 : : _vendor, _device, \ 120 : : _fixup, _data, EXT_CSD_REV_ANY) \ 121 : : 122 : : #define cid_rev(hwrev, fwrev, year, month) \ 123 : : (((u64) hwrev) << 40 | \ 124 : : ((u64) fwrev) << 32 | \ 125 : : ((u64) year) << 16 | \ 126 : : ((u64) month)) 127 : : 128 : : #define cid_rev_card(card) \ 129 : : cid_rev(card->cid.hwrev, \ 130 : : card->cid.fwrev, \ 131 : : card->cid.year, \ 132 : : card->cid.month) 133 : : 134 : : /* 135 : : * Unconditionally quirk add/remove. 136 : : */ 137 : 0 : static inline void __maybe_unused add_quirk(struct mmc_card *card, int data) 138 : : { 139 : 0 : card->quirks |= data; 140 : 0 : } 141 : : 142 : : static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) 143 : : { 144 : : card->quirks &= ~data; 145 : : } 146 : : 147 : 0 : static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card, 148 : : int data) 149 : : { 150 : 0 : card->quirk_max_rate = data; 151 : 0 : } 152 : : 153 : : /* 154 : : * Quirk add/remove for MMC products. 155 : : */ 156 : 0 : static inline void __maybe_unused add_quirk_mmc(struct mmc_card *card, int data) 157 : : { 158 : 0 : if (mmc_card_mmc(card)) 159 : 0 : card->quirks |= data; 160 : 0 : } 161 : : 162 : : static inline void __maybe_unused remove_quirk_mmc(struct mmc_card *card, 163 : : int data) 164 : : { 165 : : if (mmc_card_mmc(card)) 166 : : card->quirks &= ~data; 167 : : } 168 : : 169 : : /* 170 : : * Quirk add/remove for SD products. 171 : : */ 172 : 0 : static inline void __maybe_unused add_quirk_sd(struct mmc_card *card, int data) 173 : : { 174 : 0 : if (mmc_card_sd(card)) 175 : 0 : card->quirks |= data; 176 : 0 : } 177 : : 178 : : static inline void __maybe_unused remove_quirk_sd(struct mmc_card *card, 179 : : int data) 180 : : { 181 : : if (mmc_card_sd(card)) 182 : : card->quirks &= ~data; 183 : : } 184 : : 185 : : static inline int mmc_card_lenient_fn0(const struct mmc_card *c) 186 : : { 187 : 0 : return c->quirks & MMC_QUIRK_LENIENT_FN0; 188 : : } 189 : : 190 : : static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c) 191 : : { 192 : 0 : return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 193 : : } 194 : : 195 : : static inline int mmc_card_disable_cd(const struct mmc_card *c) 196 : : { 197 : 0 : return c->quirks & MMC_QUIRK_DISABLE_CD; 198 : : } 199 : : 200 : : static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c) 201 : : { 202 : 0 : return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF; 203 : : } 204 : : 205 : : static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c) 206 : : { 207 : 0 : return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512; 208 : : } 209 : : 210 : : static inline int mmc_card_long_read_time(const struct mmc_card *c) 211 : : { 212 : 3 : return c->quirks & MMC_QUIRK_LONG_READ_TIME; 213 : : } 214 : : 215 : : static inline int mmc_card_broken_irq_polling(const struct mmc_card *c) 216 : : { 217 : 0 : return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING; 218 : : } 219 : : 220 : : static inline int mmc_card_broken_hpi(const struct mmc_card *c) 221 : : { 222 : 0 : return c->quirks & MMC_QUIRK_BROKEN_HPI; 223 : : } 224 : : 225 : : #endif