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