📄 mmc_s3c2440.c.bak
字号:
/* * 2002 (C) Copyrigt SAMSUMNG ELECTRONICS * SW.LEE <hitchcar@sec.samsung.com> * * Low-level MMC functions for the S3CXX * * Copyright 2002 Hewlett-Packard Company * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is * preserved in its entirety in all copies and derived works. * * HEWLETT-PACKARD COMPANY MAKES NO WARRANTIES, EXPRESSED OR IMPLIED, * AS TO THE USEFULNESS OR CORRECTNESS OF THIS CODE OR ITS * FITNESS FOR ANY PARTICULAR PURPOSE. * * Many thanks to Alessandro Rubini and Jonathan Corbet! * * Author: Andrew Christian * 6 May 2002 */#include <linux/module.h>#include <linux/version.h>#include <linux/init.h>#include <linux/sched.h>#include <linux/interrupt.h>#include <linux/proc_fs.h>#include <linux/delay.h>#include <asm/irq.h> #include <asm/unaligned.h>#include <asm/arch/hardware.h>//#include <linux/mmc/mmc_ll.h>#include "mmc_ll.h"#include "mmc_samsung.h"extern struct s3c_mmc_data g_s3c_mmc_data;static __inline__ void mmc_delay(void) { mdelay(100); }/*---------------------------------------------------------------------------------*/static void s3c2440_slot_init(struct s3c_mmc_lowlevel *lowlevel){ /* External Interrupt for Card detect * connected with nCS_SD -> nCD (SO CARD SOCKET ) * PULL-UP */ // rGPGUP = 0xF800; defalt value MMC_DEBUG(2," Before rGPGCON 0x%08X \n",GPGCON); //GPGCON &= ~((0x3 << 20)); //GPGCON |= ((0x2 << 20)); /* External Interrupt #18 Enable */ GPGCON &= ~((0x3 << 16)); GPGCON |= ((0x2 << 16)); /* External Interrupt #18 Enable */ MMC_DEBUG(2," After GPGCON 0x%08X \n",GPGCON); /************************************ * SDDAT [21:14] * SDCMD [13:12] * SDCLK [11:10] ***********************************/ GPEUP = 0xf83f; // The pull up GPECON = 0xaaaaaaaa; /* * External Interrupt level - Both edge triggered */// EXTINT2 &= ~(0x7<<8); //EXTINT2 |= (0x7<<8); EXTINT2 &= ~(0x7); EXTINT2 |= (0x7);}/******* * Prototype * static int mmc_s3c_slot_is_empty (int slot) * Purpose: * Entry * Exit * 1 : slot is empty * 0 : occupied * Exceptions: *****************************************************/static int mmc_s3c2440_slot_is_empty (struct s3c_mmc_lowlevel *lowlevel){ int retval; MMC_DEBUG(2,"\n"); /* Change Port to Input mode */ MMC_DEBUG(2," INT rGPGCON 0x%08X \n",GPGCON); //GPGCON &= ~(0x3<<20); GPGCON &= ~(0x3<<16); MMC_DEBUG(2," INPUT rGPGCON 0x%08X \n",GPGCON); MMC_DEBUG(2," rGPGDAT 0x%08X \n",GPGDAT); mmc_delay(); /* I amn' sure of how long time to need to stable signal */ //if( GPGDAT & (0x1<<10)){ if( GPGDAT & (0x1<<8)){ retval = 1; } else { retval = 0; } //GPGCON |= (0x2<<20); /* Change port to EINT18 Mode */ GPGCON |= (0x2<<16); /* Change port to EINT18 Mode */ MMC_DEBUG(2," INT rGPGCON 0x%08X \n",GPGCON); return retval;}/******* * Prototype *static void mmc_s3c_fix_sd_detect( unsigned long nr ) * * Purpose: * 1. Kernel booting with SD inserted. * level interrupt setting. * 2, After kernel booting , SD inserted * Both interrupt setting * * When interrupt happens, * 1, take the time to make the signal stable * in some time interval, we have n trials * 2. if P(n)>= 90 % , the insert /eject state will be accepted. * 3. To test insert or eject we can read the GPIO * * Entry * Exit * Exceptions: *****************************************************/static void mmc_s3c_fix_sd_detect( unsigned long nr ){ MMC_DEBUG(2," INT rGPGCON 0x%08X ",GPGCON); /* Change Port to Input mode */ //GPGCON &= ~(0x3<<20); GPGCON &= ~(0x3<<16); MMC_DEBUG(2," INPUT rGPGCON 0x%08X ",GPGCON); MMC_DEBUG(2," rGPGDAT 0x%08X ",GPGDAT); //if( GPGDAT & (0x1<<10)){ /* eject */ if( GPGDAT & (0x1<<8)){ /* eject */ MMC_DEBUG(2," MMC Card eject "); g_s3c_mmc_data.insert = 0; mmc_eject(0); // g_s3c_asic_statistics.mmc_insert++; } else { if ( g_s3c_mmc_data.insert ) { MMC_DEBUG(2," MMC Card already inserted "); } else{ MMC_DEBUG(2," MMC Card insert "); g_s3c_mmc_data.insert = 1; mmc_insert(0); } // g_s3c_asic_statistics.mmc_eject++; } //GPGCON |= (0x2<<20); /* Change port to EINT18 Mode */ GPGCON |= (0x2<<16); /* Change port to EINT18 Mode */}struct s3c_mmc_lowlevel s3c2440_mmc_lowlevel = { .name = "s3c2440_mmc", //.sd_base = 0x5A000000,//VA_SD_BASE; .sdi_irq = IRQ_SDI; .detect_irq = IRQ_EINT16;//44,//IRQ_EINT18; .slot_init = s3c2440_slot_init, .slot_is_empty = mmc_s3c2440_slot_is_empty,};static int __init s3c2440_mmc_init(void){ int retval;s3c2440_mmc_lowlevel.sd_base=(volatile unsigned int*)(io_p2v(0x5a000000)); printk("\nsd base virtual:0x%08x",s3c2440_mmc_lowlevel.sd_base); retval = s3c_mmc_register_slot(&s3c2440_mmc_lowlevel); if ( retval < 0 ) printk(KERN_INFO __FUNCTION__ ": unable to register slot\n"); return retval;}void __exit s3c2440_mmc_cleanup(void){ MMC_DEBUG(0,"");// s3c_mmc_unregister_slot(&s3c2440_mmc_lowlevel);s3c_mmc_unregister_slot();}module_init(s3c2440_mmc_init);module_exit(s3c2440_mmc_cleanup);MODULE_AUTHOR("Sangwook Lee<hitchcar@sec.samsung.com");MODULE_LICENSE("GPL");MODULE_DESCRIPTION("S3C2440 SD/MMC driver ");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -