sdhci.h 13.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
/* linux/arch/arm/plat-s3c/include/plat/sdhci.h
 *
 * Copyright 2008 Openmoko, Inc.
 * Copyright 2008 Simtec Electronics
 *	http://armlinux.simtec.co.uk/
 *	Ben Dooks <ben@simtec.co.uk>
 *
 * S3C Platform - SDHCI (HSMMC) platform data definitions
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
*/

#ifndef __PLAT_S3C_SDHCI_H
#define __PLAT_S3C_SDHCI_H __FILE__

struct platform_device;
struct mmc_host;
struct mmc_card;
struct mmc_ios;

23 24 25 26 27 28 29 30
enum cd_types {
	S3C_SDHCI_CD_INTERNAL,	/* use mmc internal CD line */
	S3C_SDHCI_CD_EXTERNAL,	/* use external callback */
	S3C_SDHCI_CD_GPIO,	/* use external gpio pin for CD line */
	S3C_SDHCI_CD_NONE,	/* no CD line, use polling to detect card */
	S3C_SDHCI_CD_PERMANENT,	/* no CD line, card permanently wired to host */
};

31 32 33 34 35
enum clk_types {
	S3C_SDHCI_CLK_DIV_INTERNAL,	/* use mmc internal clock divider */
	S3C_SDHCI_CLK_DIV_EXTERNAL,	/* use external clock divider */
};

36 37 38 39
/**
 * struct s3c_sdhci_platdata() - Platform device data for Samsung SDHCI
 * @max_width: The maximum number of data bits supported.
 * @host_caps: Standard MMC host capabilities bit field.
40
 * @cd_type: Type of Card Detection method (see cd_types enum above)
41
 * @clk_type: Type of clock divider method (see clk_types enum above)
42 43 44 45 46 47 48 49 50 51 52 53
 * @ext_cd_init: Initialize external card detect subsystem. Called on
 *		 sdhci-s3c driver probe when cd_type == S3C_SDHCI_CD_EXTERNAL.
 *		 notify_func argument is a callback to the sdhci-s3c driver
 *		 that triggers the card detection event. Callback arguments:
 *		 dev is pointer to platform device of the host controller,
 *		 state is new state of the card (0 - removed, 1 - inserted).
 * @ext_cd_cleanup: Cleanup external card detect subsystem. Called on
 *		 sdhci-s3c driver remove when cd_type == S3C_SDHCI_CD_EXTERNAL.
 *		 notify_func argument is the same callback as for ext_cd_init.
 * @ext_cd_gpio: gpio pin used for external CD line, valid only if
 *		 cd_type == S3C_SDHCI_CD_GPIO
 * @ext_cd_gpio_invert: invert values for external CD gpio line
54 55 56 57 58 59 60 61 62 63 64 65 66
 * @cfg_gpio: Configure the GPIO for a specific card bit-width
 * @cfg_card: Configure the interface for a specific card and speed. This
 *            is necessary the controllers and/or GPIO blocks require the
 *	      changing of driver-strength and other controls dependant on
 *	      the card and speed of operation.
 *
 * Initialisation data specific to either the machine or the platform
 * for the device driver to use or call-back when configuring gpio or
 * card speed information.
*/
struct s3c_sdhci_platdata {
	unsigned int	max_width;
	unsigned int	host_caps;
67
	enum cd_types	cd_type;
68
	enum clk_types	clk_type;
69 70 71

	char		**clocks;	/* set of clock sources */

72 73 74 75 76 77 78
	int		ext_cd_gpio;
	bool		ext_cd_gpio_invert;
	int	(*ext_cd_init)(void (*notify_func)(struct platform_device *,
						   int state));
	int	(*ext_cd_cleanup)(void (*notify_func)(struct platform_device *,
						      int state));

79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
	void	(*cfg_gpio)(struct platform_device *dev, int width);
	void	(*cfg_card)(struct platform_device *dev,
			    void __iomem *regbase,
			    struct mmc_ios *ios,
			    struct mmc_card *card);
};

/**
 * s3c_sdhci0_set_platdata - Set platform data for S3C SDHCI device.
 * @pd: Platform data to register to device.
 *
 * Register the given platform data for use withe S3C SDHCI device.
 * The call will copy the platform data, so the board definitions can
 * make the structure itself __initdata.
 */
extern void s3c_sdhci0_set_platdata(struct s3c_sdhci_platdata *pd);
95
extern void s3c_sdhci1_set_platdata(struct s3c_sdhci_platdata *pd);
96
extern void s3c_sdhci2_set_platdata(struct s3c_sdhci_platdata *pd);
97
extern void s3c_sdhci3_set_platdata(struct s3c_sdhci_platdata *pd);
98 99 100 101 102

/* Default platform data, exported so that per-cpu initialisation can
 * set the correct one when there are more than one cpu type selected.
*/

103 104
extern struct s3c_sdhci_platdata s3c_hsmmc0_def_platdata;
extern struct s3c_sdhci_platdata s3c_hsmmc1_def_platdata;
105
extern struct s3c_sdhci_platdata s3c_hsmmc2_def_platdata;
106
extern struct s3c_sdhci_platdata s3c_hsmmc3_def_platdata;
107 108 109

/* Helper function availablity */

110 111
extern void s3c2416_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s3c2416_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
112 113
extern void s3c64xx_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s3c64xx_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
114 115 116
extern void s5pc100_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pc100_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pc100_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
117
extern void s3c64xx_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
118 119 120
extern void s5pv210_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pv210_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
121
extern void s5pv210_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
H
Hyuk Lee 已提交
122 123 124 125
extern void s5pv310_setup_sdhci0_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci1_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci2_cfg_gpio(struct platform_device *, int w);
extern void s5pv310_setup_sdhci3_cfg_gpio(struct platform_device *, int w);
126

127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
/* S3C2416 SDHCI setup */

#ifdef CONFIG_S3C2416_SETUP_SDHCI
extern char *s3c2416_hsmmc_clksrcs[4];

extern void s3c2416_setup_sdhci_cfg_card(struct platform_device *dev,
					   void __iomem *r,
					   struct mmc_ios *ios,
					   struct mmc_card *card);

static inline void s3c2416_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
	s3c_hsmmc0_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
	s3c_hsmmc0_def_platdata.cfg_gpio = s3c2416_setup_sdhci0_cfg_gpio;
	s3c_hsmmc0_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
#endif /* CONFIG_S3C_DEV_HSMMC */
}

static inline void s3c2416_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
	s3c_hsmmc1_def_platdata.clocks = s3c2416_hsmmc_clksrcs;
	s3c_hsmmc1_def_platdata.cfg_gpio = s3c2416_setup_sdhci1_cfg_gpio;
	s3c_hsmmc1_def_platdata.cfg_card = s3c2416_setup_sdhci_cfg_card;
#endif /* CONFIG_S3C_DEV_HSMMC1 */
}

#else
static inline void s3c2416_default_sdhci0(void) { }
static inline void s3c2416_default_sdhci1(void) { }

#endif /* CONFIG_S3C2416_SETUP_SDHCI */
160
/* S3C64XX SDHCI setup */
161

162 163
#ifdef CONFIG_S3C64XX_SETUP_SDHCI
extern char *s3c64xx_hsmmc_clksrcs[4];
164 165 166 167 168 169 170 171

extern void s3c6400_setup_sdhci_cfg_card(struct platform_device *dev,
					 void __iomem *r,
					 struct mmc_ios *ios,
					 struct mmc_card *card);

static inline void s3c6400_default_sdhci0(void)
{
172
#ifdef CONFIG_S3C_DEV_HSMMC
173
	s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
174 175
	s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
	s3c_hsmmc0_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
176
#endif
177 178 179 180
}

static inline void s3c6400_default_sdhci1(void)
{
181
#ifdef CONFIG_S3C_DEV_HSMMC1
182
	s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
183 184
	s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
	s3c_hsmmc1_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
185
#endif
186 187
}

188 189
static inline void s3c6400_default_sdhci2(void)
{
190
#ifdef CONFIG_S3C_DEV_HSMMC2
191
	s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
192 193
	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
	s3c_hsmmc2_def_platdata.cfg_card = s3c6400_setup_sdhci_cfg_card;
194
#endif
195
}
196

197 198 199 200
extern void s3c6410_setup_sdhci_cfg_card(struct platform_device *dev,
					 void __iomem *r,
					 struct mmc_ios *ios,
					 struct mmc_card *card);
201 202 203

static inline void s3c6410_default_sdhci0(void)
{
204
#ifdef CONFIG_S3C_DEV_HSMMC
205
	s3c_hsmmc0_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
206
	s3c_hsmmc0_def_platdata.cfg_gpio = s3c64xx_setup_sdhci0_cfg_gpio;
207
	s3c_hsmmc0_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
208
#endif
209
}
210 211 212

static inline void s3c6410_default_sdhci1(void)
{
213
#ifdef CONFIG_S3C_DEV_HSMMC1
214
	s3c_hsmmc1_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
215
	s3c_hsmmc1_def_platdata.cfg_gpio = s3c64xx_setup_sdhci1_cfg_gpio;
216
	s3c_hsmmc1_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
217
#endif
218
}
B
Ben Dooks 已提交
219

220 221
static inline void s3c6410_default_sdhci2(void)
{
222
#ifdef CONFIG_S3C_DEV_HSMMC2
223
	s3c_hsmmc2_def_platdata.clocks = s3c64xx_hsmmc_clksrcs;
224
	s3c_hsmmc2_def_platdata.cfg_gpio = s3c64xx_setup_sdhci2_cfg_gpio;
225
	s3c_hsmmc2_def_platdata.cfg_card = s3c6410_setup_sdhci_cfg_card;
226
#endif
227 228
}

229 230
#else
static inline void s3c6410_default_sdhci0(void) { }
231
static inline void s3c6410_default_sdhci1(void) { }
232
static inline void s3c6410_default_sdhci2(void) { }
233 234
static inline void s3c6400_default_sdhci0(void) { }
static inline void s3c6400_default_sdhci1(void) { }
235
static inline void s3c6400_default_sdhci2(void) { }
236 237

#endif /* CONFIG_S3C64XX_SETUP_SDHCI */
238

239 240 241 242 243 244 245 246 247 248 249 250
/* S5PC100 SDHCI setup */

#ifdef CONFIG_S5PC100_SETUP_SDHCI
extern char *s5pc100_hsmmc_clksrcs[4];

extern void s5pc100_setup_sdhci0_cfg_card(struct platform_device *dev,
					   void __iomem *r,
					   struct mmc_ios *ios,
					   struct mmc_card *card);

static inline void s5pc100_default_sdhci0(void)
{
251
#ifdef CONFIG_S3C_DEV_HSMMC
252 253 254
	s3c_hsmmc0_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
	s3c_hsmmc0_def_platdata.cfg_gpio = s5pc100_setup_sdhci0_cfg_gpio;
	s3c_hsmmc0_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
255
#endif
256 257 258 259
}

static inline void s5pc100_default_sdhci1(void)
{
260
#ifdef CONFIG_S3C_DEV_HSMMC1
261 262 263
	s3c_hsmmc1_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
	s3c_hsmmc1_def_platdata.cfg_gpio = s5pc100_setup_sdhci1_cfg_gpio;
	s3c_hsmmc1_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
264
#endif
265 266 267 268
}

static inline void s5pc100_default_sdhci2(void)
{
269
#ifdef CONFIG_S3C_DEV_HSMMC2
270 271 272
	s3c_hsmmc2_def_platdata.clocks = s5pc100_hsmmc_clksrcs;
	s3c_hsmmc2_def_platdata.cfg_gpio = s5pc100_setup_sdhci2_cfg_gpio;
	s3c_hsmmc2_def_platdata.cfg_card = s5pc100_setup_sdhci0_cfg_card;
273
#endif
274 275 276 277 278 279
}

#else
static inline void s5pc100_default_sdhci0(void) { }
static inline void s5pc100_default_sdhci1(void) { }
static inline void s5pc100_default_sdhci2(void) { }
280

281 282
#endif /* CONFIG_S5PC100_SETUP_SDHCI */

283
/* S5PV210 SDHCI setup */
284 285 286 287 288 289 290 291 292 293 294

#ifdef CONFIG_S5PV210_SETUP_SDHCI
extern char *s5pv210_hsmmc_clksrcs[4];

extern void s5pv210_setup_sdhci_cfg_card(struct platform_device *dev,
					   void __iomem *r,
					   struct mmc_ios *ios,
					   struct mmc_card *card);

static inline void s5pv210_default_sdhci0(void)
{
295
#ifdef CONFIG_S3C_DEV_HSMMC
296 297 298
	s3c_hsmmc0_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
	s3c_hsmmc0_def_platdata.cfg_gpio = s5pv210_setup_sdhci0_cfg_gpio;
	s3c_hsmmc0_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
299
#endif
300 301 302 303
}

static inline void s5pv210_default_sdhci1(void)
{
304
#ifdef CONFIG_S3C_DEV_HSMMC1
305 306 307
	s3c_hsmmc1_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
	s3c_hsmmc1_def_platdata.cfg_gpio = s5pv210_setup_sdhci1_cfg_gpio;
	s3c_hsmmc1_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
308
#endif
309 310 311 312
}

static inline void s5pv210_default_sdhci2(void)
{
313
#ifdef CONFIG_S3C_DEV_HSMMC2
314 315 316
	s3c_hsmmc2_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
	s3c_hsmmc2_def_platdata.cfg_gpio = s5pv210_setup_sdhci2_cfg_gpio;
	s3c_hsmmc2_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
317
#endif
318 319
}

320 321
static inline void s5pv210_default_sdhci3(void)
{
322
#ifdef CONFIG_S3C_DEV_HSMMC3
323 324 325
	s3c_hsmmc3_def_platdata.clocks = s5pv210_hsmmc_clksrcs;
	s3c_hsmmc3_def_platdata.cfg_gpio = s5pv210_setup_sdhci3_cfg_gpio;
	s3c_hsmmc3_def_platdata.cfg_card = s5pv210_setup_sdhci_cfg_card;
326
#endif
327 328
}

329 330 331 332
#else
static inline void s5pv210_default_sdhci0(void) { }
static inline void s5pv210_default_sdhci1(void) { }
static inline void s5pv210_default_sdhci2(void) { }
333
static inline void s5pv210_default_sdhci3(void) { }
334

335
#endif /* CONFIG_S5PV210_SETUP_SDHCI */
336

H
Hyuk Lee 已提交
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389
/* S5PV310 SDHCI setup */
#ifdef CONFIG_S5PV310_SETUP_SDHCI
extern char *s5pv310_hsmmc_clksrcs[4];

extern void s5pv310_setup_sdhci_cfg_card(struct platform_device *dev,
					   void __iomem *r,
					   struct mmc_ios *ios,
					   struct mmc_card *card);

static inline void s5pv310_default_sdhci0(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC
	s3c_hsmmc0_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
	s3c_hsmmc0_def_platdata.cfg_gpio = s5pv310_setup_sdhci0_cfg_gpio;
	s3c_hsmmc0_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}

static inline void s5pv310_default_sdhci1(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC1
	s3c_hsmmc1_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
	s3c_hsmmc1_def_platdata.cfg_gpio = s5pv310_setup_sdhci1_cfg_gpio;
	s3c_hsmmc1_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}

static inline void s5pv310_default_sdhci2(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC2
	s3c_hsmmc2_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
	s3c_hsmmc2_def_platdata.cfg_gpio = s5pv310_setup_sdhci2_cfg_gpio;
	s3c_hsmmc2_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}

static inline void s5pv310_default_sdhci3(void)
{
#ifdef CONFIG_S3C_DEV_HSMMC3
	s3c_hsmmc3_def_platdata.clocks = s5pv310_hsmmc_clksrcs;
	s3c_hsmmc3_def_platdata.cfg_gpio = s5pv310_setup_sdhci3_cfg_gpio;
	s3c_hsmmc3_def_platdata.cfg_card = s5pv310_setup_sdhci_cfg_card;
#endif
}

#else
static inline void s5pv310_default_sdhci0(void) { }
static inline void s5pv310_default_sdhci1(void) { }
static inline void s5pv310_default_sdhci2(void) { }
static inline void s5pv310_default_sdhci3(void) { }

#endif /* CONFIG_S5PV310_SETUP_SDHCI */

390
#endif /* __PLAT_S3C_SDHCI_H */