288 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * Private header for the mmc subsystem4 *5 * Copyright (C) 2016 Linaro Ltd6 *7 * Author: Ulf Hansson <ulf.hansson@linaro.org>8 */9 10#ifndef _MMC_CORE_CARD_H11#define _MMC_CORE_CARD_H12 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 */46struct 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 /* Manufacturing date */57 unsigned short year;58 unsigned char month;59 60 /* SDIO-specific fields. You can use SDIO_ANY_ID here of course */61 u16 cis_vendor, cis_device;62 63 /* for MMC cards */64 unsigned int ext_csd_rev;65 66 /* Match against functions declared in device tree */67 const char *of_compatible;68 69 void (*vendor_fixup)(struct mmc_card *card, int data);70 int data;71};72 73#define CID_MANFID_ANY (-1u)74#define CID_OEMID_ANY ((unsigned short) -1)75#define CID_YEAR_ANY ((unsigned short) -1)76#define CID_MONTH_ANY ((unsigned char) -1)77#define CID_NAME_ANY (NULL)78 79#define EXT_CSD_REV_ANY (-1u)80 81#define CID_MANFID_SANDISK 0x282#define CID_MANFID_SANDISK_SD 0x383#define CID_MANFID_ATP 0x984#define CID_MANFID_TOSHIBA 0x1185#define CID_MANFID_MICRON 0x1386#define CID_MANFID_SAMSUNG 0x1587#define CID_MANFID_APACER 0x2788#define CID_MANFID_KINGSTON 0x7089#define CID_MANFID_HYNIX 0x9090#define CID_MANFID_KINGSTON_SD 0x9F91#define CID_MANFID_NUMONYX 0xFE92 93#define END_FIXUP { NULL }94 95#define _FIXUP_EXT(_name, _manfid, _oemid, _year, _month, \96 _rev_start, _rev_end, \97 _cis_vendor, _cis_device, \98 _fixup, _data, _ext_csd_rev) \99 { \100 .name = (_name), \101 .manfid = (_manfid), \102 .oemid = (_oemid), \103 .year = (_year), \104 .month = (_month), \105 .rev_start = (_rev_start), \106 .rev_end = (_rev_end), \107 .cis_vendor = (_cis_vendor), \108 .cis_device = (_cis_device), \109 .vendor_fixup = (_fixup), \110 .data = (_data), \111 .ext_csd_rev = (_ext_csd_rev), \112 }113 114#define MMC_FIXUP_REV(_name, _manfid, _oemid, _rev_start, _rev_end, \115 _fixup, _data, _ext_csd_rev) \116 _FIXUP_EXT(_name, _manfid, _oemid, CID_YEAR_ANY, CID_MONTH_ANY, \117 _rev_start, _rev_end, \118 SDIO_ANY_ID, SDIO_ANY_ID, \119 _fixup, _data, _ext_csd_rev) \120 121#define MMC_FIXUP(_name, _manfid, _oemid, _fixup, _data) \122 MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \123 EXT_CSD_REV_ANY)124 125#define MMC_FIXUP_EXT_CSD_REV(_name, _manfid, _oemid, _fixup, _data, \126 _ext_csd_rev) \127 MMC_FIXUP_REV(_name, _manfid, _oemid, 0, -1ull, _fixup, _data, \128 _ext_csd_rev)129 130#define SDIO_FIXUP(_vendor, _device, _fixup, _data) \131 _FIXUP_EXT(CID_NAME_ANY, CID_MANFID_ANY, CID_OEMID_ANY, \132 CID_YEAR_ANY, CID_MONTH_ANY, \133 0, -1ull, \134 _vendor, _device, \135 _fixup, _data, EXT_CSD_REV_ANY) \136 137#define SDIO_FIXUP_COMPATIBLE(_compatible, _fixup, _data) \138 { \139 .name = CID_NAME_ANY, \140 .manfid = CID_MANFID_ANY, \141 .oemid = CID_OEMID_ANY, \142 .rev_start = 0, \143 .rev_end = -1ull, \144 .cis_vendor = SDIO_ANY_ID, \145 .cis_device = SDIO_ANY_ID, \146 .vendor_fixup = (_fixup), \147 .data = (_data), \148 .ext_csd_rev = EXT_CSD_REV_ANY, \149 .of_compatible = _compatible, \150 }151 152#define cid_rev(hwrev, fwrev, year, month) \153 (((u64) hwrev) << 40 | \154 ((u64) fwrev) << 32 | \155 ((u64) year) << 16 | \156 ((u64) month))157 158#define cid_rev_card(card) \159 cid_rev(card->cid.hwrev, \160 card->cid.fwrev, \161 card->cid.year, \162 card->cid.month)163 164/*165 * Unconditionally quirk add/remove.166 */167static inline void __maybe_unused add_quirk(struct mmc_card *card, int data)168{169 card->quirks |= data;170}171 172static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data)173{174 card->quirks &= ~data;175}176 177static inline void __maybe_unused add_limit_rate_quirk(struct mmc_card *card,178 int data)179{180 card->quirk_max_rate = data;181}182 183static inline void __maybe_unused wl1251_quirk(struct mmc_card *card,184 int data)185{186 /*187 * We have TI wl1251 attached to this mmc. Pass this188 * information to the SDIO core because it can't be189 * probed by normal methods.190 */191 192 dev_info(card->host->parent, "found wl1251\n");193 card->quirks |= MMC_QUIRK_NONSTD_SDIO;194 card->cccr.wide_bus = 1;195 card->cis.vendor = 0x104c;196 card->cis.device = 0x9066;197 card->cis.blksize = 512;198 card->cis.max_dtr = 24000000;199}200 201/*202 * Quirk add/remove for MMC products.203 */204static inline void __maybe_unused add_quirk_mmc(struct mmc_card *card, int data)205{206 if (mmc_card_mmc(card))207 card->quirks |= data;208}209 210static inline void __maybe_unused remove_quirk_mmc(struct mmc_card *card,211 int data)212{213 if (mmc_card_mmc(card))214 card->quirks &= ~data;215}216 217/*218 * Quirk add/remove for SD products.219 */220static inline void __maybe_unused add_quirk_sd(struct mmc_card *card, int data)221{222 if (mmc_card_sd(card))223 card->quirks |= data;224}225 226static inline void __maybe_unused remove_quirk_sd(struct mmc_card *card,227 int data)228{229 if (mmc_card_sd(card))230 card->quirks &= ~data;231}232 233static inline int mmc_card_lenient_fn0(const struct mmc_card *c)234{235 return c->quirks & MMC_QUIRK_LENIENT_FN0;236}237 238static inline int mmc_blksz_for_byte_mode(const struct mmc_card *c)239{240 return c->quirks & MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;241}242 243static inline int mmc_card_disable_cd(const struct mmc_card *c)244{245 return c->quirks & MMC_QUIRK_DISABLE_CD;246}247 248static inline int mmc_card_nonstd_func_interface(const struct mmc_card *c)249{250 return c->quirks & MMC_QUIRK_NONSTD_FUNC_IF;251}252 253static inline int mmc_card_broken_byte_mode_512(const struct mmc_card *c)254{255 return c->quirks & MMC_QUIRK_BROKEN_BYTE_MODE_512;256}257 258static inline int mmc_card_long_read_time(const struct mmc_card *c)259{260 return c->quirks & MMC_QUIRK_LONG_READ_TIME;261}262 263static inline int mmc_card_broken_irq_polling(const struct mmc_card *c)264{265 return c->quirks & MMC_QUIRK_BROKEN_IRQ_POLLING;266}267 268static inline int mmc_card_broken_hpi(const struct mmc_card *c)269{270 return c->quirks & MMC_QUIRK_BROKEN_HPI;271}272 273static inline int mmc_card_broken_sd_discard(const struct mmc_card *c)274{275 return c->quirks & MMC_QUIRK_BROKEN_SD_DISCARD;276}277 278static inline int mmc_card_broken_sd_cache(const struct mmc_card *c)279{280 return c->quirks & MMC_QUIRK_BROKEN_SD_CACHE;281}282 283static inline int mmc_card_broken_cache_flush(const struct mmc_card *c)284{285 return c->quirks & MMC_QUIRK_BROKEN_CACHE_FLUSH;286}287#endif288