 de291cdb60
			
		
	
	
		de291cdb60
		
	
	
	
	
		
			
			* Add dummy driver to allow independent testing of mmcblk. * Always build the mmc driver to prevent breakage. * Allow to specify the mmc driver to be used at load time. Change-Id: I4e14b912fb8f3612e252864b53733968b23ac023
		
			
				
	
	
		
			150 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			150 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| #define SUBPARTITION_PER_PARTITION 4	/* 4 sub partitions per partition */
 | |
| #define PARTITONS_PER_DISK 4	/* 4 partitions per disk */
 | |
| #define MINOR_PER_DISK  1	/* one additional minor to point to */
 | |
| 
 | |
| /**
 | |
|  * We can have multiple MMC host controller present on the hardware. The MINIX
 | |
|  * approach to handle this is to run a driver for each instance. Every driver
 | |
|  * will therefore be stated with an "instance" id and the rest of the code here
 | |
|  * will assume a single host controller to be present.
 | |
|  *
 | |
|  * The SD specification allows multiple cards to be attached to a single host
 | |
|  * controller using the same lines. I recommend reading SD Specifications Part 1
 | |
|  * Physical layer Simplified Specification chapter 3 about SD Memory Card system
 | |
|  * concepts if you want to get a better understanding of this.
 | |
|  *
 | |
|  * In practice an MMC host will usually have a single slot attached to it and that
 | |
|  * Slot may or may not contain a card. On sudden card removal we might want to
 | |
|  * keep track of the last inserted card and we might therefore at later stage
 | |
|  * add an additional "last_card" attribute to the card.
 | |
|  *
 | |
|  * The following diagram shows the structure that will be used to modulate the
 | |
|  * hardware written in umlwiki  syntax.
 | |
|  *
 | |
|  * [/host/
 | |
|  *   +instance:int] 1 --- 0..4 [ /slot/
 | |
|  *                                +card_detect:func ] 1 --- 0..1 [ /card/ ]
 | |
|  *                                 `
 | |
|  */
 | |
| 
 | |
| #define MAX_SD_SLOTS 4
 | |
| 
 | |
| struct mmc_host;
 | |
| 
 | |
| //TODO Add more modes like INACTIVE STATE and such
 | |
| #define SD_MODE_UNINITIALIZED 0
 | |
| #define SD_MODE_CARD_IDENTIFICATION 1
 | |
| #define SD_MODE_DATA_TRANSFER_MODE 2
 | |
| 
 | |
| struct sd_card_regs
 | |
| {
 | |
| 	uint32_t cid[4];	/* Card Identification */
 | |
| 	uint32_t rca;		/* Relative card address */
 | |
| 	uint32_t dsr;		/* Driver stage register */
 | |
| 	uint32_t csd[4];	/* Card specific data */
 | |
| 	uint32_t scr[2];	/* SD configuration */
 | |
| 	uint32_t ocr;		/* Operation conditions */
 | |
| 	uint32_t ssr[5];	/* SD Status */
 | |
| 	uint32_t csr;		/* Card status */
 | |
| };
 | |
| 
 | |
| /* struct representing an mmc command */
 | |
| struct mmc_command
 | |
| {
 | |
| 	uint32_t cmd;
 | |
| 	uint32_t args;
 | |
| 	uint32_t resp_type;
 | |
| 
 | |
| #define  RESP_LEN_48_CHK_BUSY (3<<0)
 | |
| #define  RESP_LEN_48		  (2<<0)
 | |
| #define  RESP_LEN_136		  (1<<0)
 | |
| #define  NO_RESPONSE		  (0<<0)
 | |
| 
 | |
| 	uint32_t resp[4];
 | |
| 	unsigned char *data;
 | |
| 	uint32_t data_len;
 | |
| };
 | |
| 
 | |
| /* structure representing an SD card */
 | |
| struct sd_card
 | |
| {
 | |
| 	/* pointer back to the SD slot for convenience */
 | |
| 	struct sd_slot *slot;
 | |
| 
 | |
| 	struct sd_card_regs regs;
 | |
| 
 | |
| 	/* some helpers (data comming from the csd) */
 | |
| 	uint32_t blk_size;
 | |
| 	uint32_t blk_count;
 | |
| 
 | |
| 	/* drive state: deaf, initialized, dead */
 | |
| 	unsigned state;
 | |
| 
 | |
| 	/* MINIX/block driver related things */
 | |
| 	int open_ct;		/* in-use count */
 | |
| 
 | |
| 	/* 1 disks + 4 partitions and 16 possible sub partitions */
 | |
| 	struct device part[MINOR_PER_DISK + PARTITONS_PER_DISK];
 | |
| 	struct device subpart[PARTITONS_PER_DISK * SUBPARTITION_PER_PARTITION];
 | |
| };
 | |
| 
 | |
| /* structure representing an SD slot */
 | |
| struct sd_slot
 | |
| {
 | |
| 	/* pointer back to the host for convenience */
 | |
| 	struct mmc_host *host;
 | |
| 
 | |
| 	unsigned state;
 | |
| 	struct sd_card card;
 | |
| };
 | |
| 
 | |
| /* structure for the host controller */
 | |
| struct mmc_host
 | |
| {
 | |
| 	/* MMC host configuration */
 | |
| 	int (*host_set_instance) (struct mmc_host * host, int instance);
 | |
| 	/* MMC host configuration */
 | |
| 	int (*host_init) (struct mmc_host * host);
 | |
| 	/* Set log level */
 | |
| 	void (*set_log_level) (int level);
 | |
| 	/* Host controller reset */
 | |
| 	int (*host_reset) (struct mmc_host * host);
 | |
| 	/* Card detection (binary yes/no) */
 | |
| 	int (*card_detect) (struct sd_slot * slot);
 | |
| 	/* Perform card detection e.g. card type */
 | |
| 	struct sd_card *(*card_initialize) (struct sd_slot * slot);
 | |
| 	/* Release the card */
 | |
| 	int (*card_release) (struct sd_card * card);
 | |
| 
 | |
| 	/* read count blocks into existing buf */
 | |
| 	int (*read) (struct sd_card * card,
 | |
| 	    uint32_t blknr, uint32_t count, unsigned char *buf);
 | |
| 
 | |
| 	/* write count blocks */
 | |
| 	int (*write) (struct sd_card * card,
 | |
| 	    uint32_t blknr, uint32_t count, unsigned char *buf);
 | |
| 
 | |
| 	/* up to 4 slots with 4 SD cards */
 | |
| 	struct sd_slot slot[MAX_SD_SLOTS];
 | |
| };
 | |
| 
 | |
| #if 0
 | |
| /* Command execution */
 | |
| int (*send_cmd) (struct sd_card * card, struct mmc_command *);
 | |
| 
 | |
| /* struct representing an mmc command */
 | |
| struct mmc_command
 | |
| {
 | |
| 	uint32_t cmd;
 | |
| 	uint32_t args;
 | |
| 	uint32_t resp[4];
 | |
| 	unsigned char *data;
 | |
| 	uint32_t data_len;
 | |
| };
 | |
| #endif
 | |
| 
 | |
| /* Hack done for driver registration */
 | |
| void host_initialize_host_structure_mmchs(struct mmc_host *host);
 | |
| void host_initialize_host_structure_dummy(struct mmc_host *host);
 |