Commit latest Qisda version and Bookeen's modification

This commit is contained in:
mlt
2010-04-23 11:27:04 +00:00
committed by Godzil
parent 2c907884d1
commit f2fd2aec61
75 changed files with 182708 additions and 51781 deletions

View File

@@ -18,6 +18,13 @@ config MMC_DEBUG
This is an option for use by developers; most people should
say N here. This enables MMC core and driver debugging.
config SD_SW_DEBOUNCE
bool "Use SD_SW_DEBOUNC detect method"
default n
help
This is an option for enable the added sd-card detection
method with "software debounce time" feature
if MMC
source "drivers/mmc/core/Kconfig"

View File

@@ -430,7 +430,10 @@ static struct mmc_blk_data *mmc_blk_alloc(struct mmc_card *card)
struct mmc_blk_data *md;
int devidx, ret;
devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS);
/* Qisda, howard hsu, 2010/01/21, fix start slot for SD card { */
//devidx = find_first_zero_bit(dev_use, MMC_NUM_MINORS);
devidx = find_next_zero_bit(dev_use, MMC_NUM_MINORS, card->host->first_devidx);
/* } Qisda, howard hsu, 2010/01/21, fix start slot for SD card */
if (devidx >= MMC_NUM_MINORS)
return ERR_PTR(-ENOSPC);
__set_bit(devidx, dev_use);

View File

@@ -120,8 +120,8 @@ config MMC_TIFM_SD
config MMC_SPI
tristate "MMC/SD over SPI (EXPERIMENTAL)"
depends on MMC && SPI_MASTER && !HIGHMEM && EXPERIMENTAL
select CRC7
select CRC_ITU_T
#select CRC7
#select CRC_ITU_T
help
Some systems accss MMC/SD cards using a SPI controller instead of
using a "native" MMC/SD controller. This has a disadvantage of

View File

@@ -55,6 +55,10 @@
#include <asm/arch/hsmmc.h>
/*Qisda , wenny cheng , 20091224 , board id info {*/
#include <../include/asm-arm/plat-s3c24xx/common-smdk.h>
/*Qisda , wenny cheng , 20091224 , board id info }*/
/*Trevor add for debug*/
/*#define CONFIG_S3CMMC_DEBUG*/
@@ -79,6 +83,11 @@ struct s3c_hsmmc_host *global_host[3];
#endif
static void s3c_hsmmc_tasklet_finish (unsigned long param);
/*Qisda , wenny cheng , 20091224 , board id info {*/
extern int board_id;
/*Qisda , wenny cheng , 20091224 , board id info }*/
static int inResume = 0; //howard, 2009/12/22, fix resume card-detect
/*Qisda,2009/7/28,Leo SJ Yang {*/
/*Fix: Must plug-in twice ,SD is reconginzed by system*/
/* GEORGE 20090608 update for module on board.*/
@@ -86,6 +95,106 @@ static int card_detect = 0;
static int card_detect2 = 2;
/* GEORGE 20090608 update for module on board.*/
/*}Qisda,2009/7/28,Leo SJ Yang*/
/* Qisda , howard hsu, 2010/01/16 , op_mode-delay key event {*/
//extern void op_mode_delay_message_to_ap();
/* } Qisda , howard hsu, 2010/01/16 , op_mode-delay key event */
/* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
// disable it first, wait integration test
#ifdef CONFIG_SD_SW_DEBOUNCE
static int SDCardStatus = 16;
#define SD_INSERTED 0
#define SD_REMOVED 2
#define CHECK_MSEC 50
#define INSERT_MSEC 800
#define REMOVE_MSEC 800
static struct timer_list sd_detect_timer;
static void sdcard_debounce_timer(unsigned long data);
static int ReadSDCardStatus()
{
int SDStatus= 0;
#if defined(CONFIG_CPU_S3C2450) || defined(CONFIG_CPU_S3C2416)
SDStatus = readl(S3C2410_GPFDAT);
SDStatus &= SD_REMOVED; /* GPF1 */
#elif defined(CONFIG_CPU_S3C6410)
SDStatus = readl(S3C_GPNDAT);
SDStatus &= 0x2000; /* GPN13 */
#endif
return SDStatus;
}
static void sdcard_debounce_timer(unsigned long data)
{
static unsigned int StayCount = 0;
static unsigned int MaxCount = 2*INSERT_MSEC/CHECK_MSEC;
static unsigned int MidCount = INSERT_MSEC/CHECK_MSEC;
static unsigned int MinCount = INSERT_MSEC/CHECK_MSEC/2;
static int LastSDCardStatus = 0xF;
int RawStatus = ReadSDCardStatus();
/* stay count in case of resume in progress */
if (inResume == 1)
{
mod_timer(&sd_detect_timer ,jiffies+msecs_to_jiffies(CHECK_MSEC));
return;
}
if ( SDCardStatus == RawStatus )
{
StayCount++;
if (StayCount >= MaxCount)
{
StayCount = 0;
LastSDCardStatus = SDCardStatus;
del_timer(&sd_detect_timer);
}
else if (StayCount == MidCount)
{
struct s3c_hsmmc_host *s3c_host = global_host[0];
struct mmc_host *host = s3c_host->mmc;
if (SDCardStatus == LastSDCardStatus )
{
//StayCount = 0;
//LastSDCardStatus = 0xF;
}
mmc_detect_change(host, 1);
mod_timer(&sd_detect_timer, jiffies+msecs_to_jiffies(CHECK_MSEC));
}
else if ( StayCount==MinCount )
{
/* call detect twice for SD_INSERTED case */
//if (SDCardStatus == LastSDCardStatus )
if (SDCardStatus == SD_INSERTED )
{
struct s3c_hsmmc_host *s3c_host = global_host[0];
struct mmc_host *host = s3c_host->mmc;
mmc_detect_change(host, 1);
}
mod_timer(&sd_detect_timer, jiffies+msecs_to_jiffies(CHECK_MSEC));
}
else
{
mod_timer(&sd_detect_timer, jiffies+msecs_to_jiffies(CHECK_MSEC));
}
}
else
{
SDCardStatus = RawStatus;
if (SDCardStatus==SD_INSERTED) {
MaxCount = 2*INSERT_MSEC/CHECK_MSEC;
MidCount = INSERT_MSEC/CHECK_MSEC;
}
else {
MaxCount = 2*REMOVE_MSEC/CHECK_MSEC;
MidCount = REMOVE_MSEC/CHECK_MSEC;
}
StayCount = 0;
mod_timer(&sd_detect_timer ,jiffies+msecs_to_jiffies(CHECK_MSEC));
}
}
#endif /* CONFIG_SD_SW_DEBOUNCE */
/* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
/*****************************************************************************\
* *
* Low level functions *
@@ -123,8 +232,34 @@ static int s3c_hsmmc_power_switch(int channel, int arg)
if(arg){
if(channel == 0){
//Power on
#ifdef CONFIG_QISDA_QD090B00
/*Qisda , wenny cheng , 20091224 , board id info {*/
//if((readl(S3C2416_GPKDAT) & (0x3<<3))){
if(board_id!=QD090B00_S02){
s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD14, 1);
}
else{
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
s3c2410_gpio_setpin(S3C2410_GPG2, 1);
}
/*Qisda , wenny cheng , 20091224 , board id info }*/
#endif
#ifdef CONFIG_QISDA_QD060B00
#ifdef CONFIG_QISDA_BK060B00
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH4, 1);
#else
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
s3c2410_gpio_setpin(S3C2410_GPG2, 1);
#endif
#endif
//Signal
s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2450_GPE5_SD0_CLK);
s3c2410_gpio_cfgpin(S3C2410_GPE6, S3C2450_GPE6_SD0_CMD);
@@ -145,8 +280,32 @@ static int s3c_hsmmc_power_switch(int channel, int arg)
else{
if(channel == 0){
//Power off
#ifdef CONFIG_QISDA_QD090B00
/*Qisda , wenny cheng , 20091224 , board id info {*/
//if((readl(S3C2416_GPKDAT) & (0x3<<3))){
if(board_id!=QD090B00_S02){
s3c2410_gpio_cfgpin(S3C2410_GPD14, S3C2410_GPD14_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD14, 0);
}
else{
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
s3c2410_gpio_setpin(S3C2410_GPG2, 0);
}
/*Qisda , wenny cheng , 20091224 , board id info }*/
#endif
#ifdef CONFIG_QISDA_QD060B00
#ifdef CONFIG_QISDA_BK060B00
s3c2410_gpio_cfgpin(S3C2410_GPH4, S3C2410_GPH4_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH4, 0);
#else
s3c2410_gpio_cfgpin(S3C2410_GPG2, S3C2410_GPG2_OUTP);
s3c2410_gpio_setpin(S3C2410_GPG2, 0);
#endif
#endif
//Signal
s3c2410_gpio_cfgpin(S3C2410_GPE5, S3C2410_GPE5_INP);
s3c2410_gpio_pullup(S3C2410_GPE5, 1);
@@ -274,7 +433,18 @@ static void s3c_hsmmc_tasklet_card (ulong param)
spin_unlock_irqrestore(&host->lock, iflags);
/* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
#ifdef CONFIG_SD_SW_DEBOUNCE
int exist = timer_pending(&sd_detect_timer);
if (exist == 0)
{
sd_detect_timer.expires = jiffies+msecs_to_jiffies(CHECK_MSEC);
add_timer(&sd_detect_timer);
}
#else
mmc_detect_change(host->mmc, msecs_to_jiffies(500));
#endif /* CONFIG_SD_SW_DEBOUNCE */
/* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
}
static void s3c_hsmmc_activate_led(struct s3c_hsmmc_host *host)
@@ -933,6 +1103,10 @@ out:
return result;
}
#include <linux/cyio.h>
int Cyio_PushEvent(char eventId, char unique);
static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
{
struct s3c_hsmmc_host *host = dev_id;
@@ -948,23 +1122,41 @@ static irqreturn_t s3c_hsmmc_irq_cd (int irq, void *dev_id)
//printk("\ns3c_hsmmc_irq_cd, ext_CD_int: %d, card_detect: %d, card_detect2: %d\n", ext_CD_int, card_detect, card_detect2);
if(ext_CD_int && card_detect) {
printk("s3c-hsmmc channel-0(EXT): card removed.\n");
set_irq_type(host->irq_cd, IRQT_FALLING);
/*Qisda Qube for sd card detect20091124*/
//set_irq_type(host->irq_cd, IRQT_FALLING);
set_irq_type(host->irq_cd, IRQT_LOW);
/*Qisda Qube for sd card detect20091124*/
card_detect = 0;
//Qisda, Asaku Chen, 2009/11/03, SD power off
s3c_hsmmc_power_switch(0, 0);
card_detect2 = 2;
/* Send CyIO event */
Cyio_PushEvent(CYEVENT_SD_OUT, 1);
}
else if(!ext_CD_int && !card_detect) {
printk("s3c-hsmmc channel-0(EXT): card inserted.\n");
set_irq_type(host->irq_cd, IRQT_RISING);
card_detect = 1;
/*Qisda Qube for sd card detect20091124*/
//set_irq_type(host->irq_cd, IRQT_RISING);
set_irq_type(host->irq_cd, IRQT_HIGH);
/*Qisda Qube for sd card detect20091124*/
//Qisda, Asaku Chen, 2009/11/03, SD power on
s3c_hsmmc_power_switch(0, 1);
if (inResume!=1)//howard, 2009/12/22, fix resume card-detect
{
card_detect = 1;
s3c_hsmmc_power_switch(0, 1);
}
if(card_detect2 == 3){
printk("resume host first\n");
s3c_hsmmc_ios_init(host);
mmc_resume_host(host->mmc);
card_detect2 = 2;
}
/* Send CyIO event */
Cyio_PushEvent(CYEVENT_SD_IN, 1);
}
//Qisda, Asaku Chen, 2009/11/03 {
@@ -1244,9 +1436,105 @@ static int s3c_wifi_open(struct inode *inode, struct file *file)
#define S3C_READ_GPIO_VALUE 4
#define S3C_SET_GPIO_ADDR 5
#define S3C_WRITE_GPIO_VALUE 6
#define S3C_READ_HW_VERSION 7
#define S3C_TCON_ERASE 10
#define S3C_TCON_ID 11
#define S3C_TCON_READ 12
#define S3C_TCON_BYTE_COUNT 13
#define S3C_TCON_WRITE 14
#define MMC_DEVICE_POWER_STATE 20
#define S3C_BT_POWER_ON 1
#define S3C_BT_POWER_OFF 2
static unsigned char s3c_tcon_read_byte(void)
{
/*
Unsigned char Get data () //Receive a byte from Serial flash
{
unsigned char k, temdata =0, i;
for ( k = 0; k++; k< 8)
{
if ( SO == 1 )
{
i = (0x80 >> k);
temdata = (temdata || i);
}
SCLK = 1;
SCLK = 0;
}
return (temdata);
}
*/
unsigned char k, temdata =0, i=0;
u32 read_pin;
for(k=0; k<8; k++){
read_pin = (readl(S3C2410_GPEDAT) & (1<<11));
//printk(" [%d]: 0x%X 0x%X\n", k, read_pin, readl(S3C2410_GPEDAT));
if(read_pin){
i = (0x80 >> k);
temdata = (temdata | i);
}
s3c2410_gpio_setpin(S3C2410_GPE13, 1);
udelay(2);
s3c2410_gpio_setpin(S3C2410_GPE13, 0);
udelay(2);
}
//printk("s3c_tcon_read_byte: 0x%2X\n", temdata);
return (temdata);
}
static void s3c_tcon_write_byte(char w_data)
{
/*
Send data (unsigned char indata) // Send 1 byte data to Serial flash
{
unsigned char k;
for ( k = 0; k++; k< 8)
{
if( (indata & 0x80) == 0x80)
SI = 1;
else
SI = 0;
SCLK = 1;
SCLK = 0;
indata = (indata << 1);
}
}
*/
unsigned char k;
//printk("s3c_tcon_write_byte: 0x%2X\n", w_data);
for(k=0; k<8; k++){
if((w_data & 0x80))
s3c2410_gpio_setpin(S3C2410_GPE12, 1);
else
s3c2410_gpio_setpin(S3C2410_GPE12, 0);
s3c2410_gpio_setpin(S3C2410_GPE13, 1);
udelay(2);
s3c2410_gpio_setpin(S3C2410_GPE13, 0);
udelay(2);
w_data = (w_data << 1);
}
}
@@ -1255,10 +1543,128 @@ static int s3c_wifi_ioctl(struct inode *inode, struct file *file, unsigned int c
{
static char s3c_power_off = 0;
static unsigned int gpio_addr = 0;
static unsigned int tcon_byte_count;
static unsigned int tcon_address;
unsigned char tcon_buffer[128];
unsigned char r_data;
int ret, i;
u32 read_pin;
switch(cmd){
#ifdef CONFIG_QISDA_BK060B00
case S3C_WIFI_POWER_ON:
printk("BCM4329-WIFI_BT_POWER_ON\n");
//TCON Flash disable, and select WiFi
s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH6, 0);
//bcm4329 module power on control
//GPK7, WIFI PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<7)), S3C2416_GPKDAT);
//GPK6, PA 1.8V
writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
//GPK5, PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
//GPK9 (green light), pull high
writel(((readl(S3C2416_GPKCON) & ~(1<<19)) | (1<<18)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<9)), S3C2416_GPKDAT);
//WIFI_BT_EN (GPD11) pull high
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD11, 0);
//writel(((readl(S3C2416_GPGCON) & ~(1<<9)) | (1<<8)), S3C2416_GPGCON);
//writel((readl(S3C2416_GPGDAT) & ~(1<<4)), S3C2416_GPGDAT);
mdelay(1);
s3c2410_gpio_setpin(S3C2410_GPD11, 1);
//writel((readl(S3C2416_GPGDAT) | (1<<4)), S3C2416_GPGDAT);
mdelay(20);
//EXT_N_WIFI_RST (GPD8) pull high
s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD8, 0);
//writel(((readl(S3C2416_GPDCON) & ~(1<<17)) | (1<<16)), S3C2416_GPDCON);
//writel((readl(S3C2416_GPDDAT) & ~(1<<8)), S3C2416_GPDDAT);
mdelay(1);
s3c2410_gpio_setpin(S3C2410_GPD8, 1);
//writel((readl(S3C2416_GPDDAT) | (1<<8)), S3C2416_GPDDAT);
mdelay(20);
//EXT_N_BT_RST (GPA2) pull high
s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
s3c2410_gpio_setpin(S3C2410_GPA2, 0);
mdelay(1);
s3c2410_gpio_setpin(S3C2410_GPA2, 1);
mdelay(20);
//UART1 CTS1 (GPH10) set
s3c2410_gpio_cfgpin(S3C2410_GPH10, S3C2410_GPH10_CLKOUT1);
//writel(((readl(S3C2416_GPHCON) | (1<<21)) & ~ (1<<20)), S3C2416_GPHCON);
//writel(((readl(S3C2416_GPHUDP) & ~ (1<<21)) & ~ (1<<20)), S3C2416_GPHUDP);
//writel((readl(S3C2416_GPHDAT) & ~(1<<10)), S3C2416_GPHDAT);
mdelay(1);
//UART1 RTS1 (GPH11) set
s3c2410_gpio_cfgpin(S3C2410_GPH11, S3C2410_GPH11_nRTS);
//writel(((readl(S3C2416_GPHCON) | (1<<23)) & ~(1<<22)), S3C2416_GPHCON);
//writel((readl(S3C2416_GPHDAT) & ~(1<<11)), S3C2416_GPHDAT);
//writel(((readl(S3C2416_GPHUDP) & ~ (1<<23)) & ~ (1<<22)), S3C2416_GPHUDP);
mdelay(1);
break;
case S3C_WIFI_POWER_OFF:
printk("BCM4329-WIFI_POWER_OFF\n");
//TCON Flash disable, and select WiFi
s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH6, 0);
//bcm4329 module power off control
//EXT_N_WIFI_RST (GPD8) pull down
s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD8, 0);
//WIFI_BT_EN (GPD11) pull down
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD11, 0);
//EXT_N_BT_RST (GPA2) pull down
s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
s3c2410_gpio_setpin(S3C2410_GPA2, 0);
mdelay(20);
//GPK9 (green light), pull down
writel(((readl(S3C2416_GPKCON) & ~(1<<19)) | (1<<18)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<9)), S3C2416_GPKDAT);
//GPK7, WIFI PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<7)), S3C2416_GPKDAT);
//GPK6, PA 1.8V
writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
//GPK5, PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
break;
#else
case S3C_WIFI_POWER_ON:
printk("WIFI_POWER_ON\n");
//TCON Flash disable, and select WiFi
s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH6, 0);
//GPL13, SPI_CS
s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_SS0);
//SPI DI
@@ -1288,6 +1694,11 @@ static int s3c_wifi_ioctl(struct inode *inode, struct file *file, unsigned int c
case S3C_WIFI_POWER_OFF:
printk("WIFI_POWER_OFF\n");
//TCON Flash disable, and select WiFi
s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH6, 0);
//GPK5, PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
@@ -1315,7 +1726,7 @@ static int s3c_wifi_ioctl(struct inode *inode, struct file *file, unsigned int c
break;
#endif
case S3C_READ_TILT_STATUS:
if( ((readl(S3C2410_GPDDAT) & (0x3<<10)) >> 10) == 2){
return 270;
@@ -1366,6 +1777,191 @@ static int s3c_wifi_ioctl(struct inode *inode, struct file *file, unsigned int c
break;
case S3C_READ_HW_VERSION:
//printk("S3C_READ_HW_VERSION\n");
read_pin = readl(S3C2416_GPKDAT) & 0x1E;
//printk(" read_pin: 0x%x\n", read_pin);
ret = 0;
if((read_pin & (1<<4)))
ret = ret + 0x1000;
if((read_pin & (1<<3)))
ret = ret + 0x0100;
if((read_pin & (1<<2)))
ret = ret + 0x0010;
if((read_pin & (1<<1)))
ret = ret + 0x0001;
printk("Board ID: 0x%04x\n", ret);
return ret;
break;
case S3C_TCON_ERASE:
printk("S3C_TCON_ERASE\n");
//WiFi off
//GPK5, PA 3.3V off
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
//GPK6, PA 1.8V
writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
//GPD8, RESET
s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD8, 0);
//GPH6, TCON_FLASH enable, and select TCON flash
s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_OUTP);
s3c2410_gpio_setpin(S3C2410_GPH6, 1);
mdelay(200);
//Set GPIO for TCON update
//Chip Select
s3c2410_gpio_cfgpin(S3C2410_GPL13, S3C2410_GPL13_OUTP);
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
//GPE11 SPIMISO0
s3c2410_gpio_cfgpin(S3C2410_GPE11, S3C2410_GPE11_INP);
s3c2410_gpio_pullup(S3C2410_GPE11, 0);
//GPE12 SPIMOSI0
s3c2410_gpio_cfgpin(S3C2410_GPE12, S3C2410_GPE12_OUTP);
s3c2410_gpio_setpin(S3C2410_GPE12, 1);
//GPE13 SPI CLK
s3c2410_gpio_cfgpin(S3C2410_GPE13, S3C2410_GPE13_OUTP);
s3c2410_gpio_setpin(S3C2410_GPE13, 0);
msleep(50);
//Erase TCON Flash
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x06); //Setting Write Enable Latch bit
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
udelay(50);
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x60); //Write Chip Erase command
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
msleep(500);
do{
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x05); //Write Read Status command
r_data = s3c_tcon_read_byte();
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
//printk("r_data: 0x%02x\n", r_data);
msleep(500);
}while(r_data & 0x01);
tcon_byte_count = 0;
tcon_address = 0;
break;
case S3C_TCON_ID:
printk("S3C_TCON_ID: ");
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x9F);
r_data = s3c_tcon_read_byte();
printk("0x%02X ", r_data);
r_data = s3c_tcon_read_byte();
printk("0x%02X ", r_data);
r_data = s3c_tcon_read_byte();
printk("0x%02X\n", r_data);
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
break;
case S3C_TCON_READ:
printk("S3C_TCON_READ\n");
printk("\n\ns3c_tcon_read_content 1\n");
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x03);
s3c_tcon_write_byte(0x00);
s3c_tcon_write_byte(0x00);
s3c_tcon_write_byte(0x00);
for(i=0; i<300; i++){
printk("0x%02x\n", s3c_tcon_read_byte());
}
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
msleep(50);
printk("\n\ns3c_tcon_read_content 2\n");
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x03);
s3c_tcon_write_byte(0x02);
s3c_tcon_write_byte(0x0F);
s3c_tcon_write_byte(0xA0);
for(i=0; i<40; i++){
printk("0x%02x\n", s3c_tcon_read_byte());
}
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
break;
case S3C_TCON_BYTE_COUNT:
tcon_byte_count = arg;
//printk("S3C_TCON_BYTE_COUNT: %d\n", tcon_byte_count);
break;
case S3C_TCON_WRITE:
//printk("+ S3C_TCON_WRITE: %d\n ", tcon_address);
copy_from_user(tcon_buffer, arg, tcon_byte_count);
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(20);
s3c_tcon_write_byte(0x06); //Setting Write Enable Latch bit
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
udelay(20);
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(20);
//printk("0x%x 0x%x 0x%x\n", (tcon_address & 0xFF0000) >> 16, (tcon_address & 0xFF00) >> 8, (tcon_address & 0xFF));
s3c_tcon_write_byte(0x02); //Write Page Program command
s3c_tcon_write_byte( (tcon_address & 0xFF0000) >> 16 );
s3c_tcon_write_byte( (tcon_address & 0xFF00) >> 8 );
s3c_tcon_write_byte( (tcon_address & 0xFF) );
for(i=0; i<tcon_byte_count; i++){
//printk("0x%02X ", tcon_buffer[i]);
s3c_tcon_write_byte(tcon_buffer[i]);
}
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
udelay(400);
do{
s3c2410_gpio_setpin(S3C2410_GPL13, 0);
udelay(50);
s3c_tcon_write_byte(0x05); //Write Read Status command
r_data = s3c_tcon_read_byte();
s3c2410_gpio_setpin(S3C2410_GPL13, 1);
//printk("r_data: 0x%02x\n", r_data);
udelay(100);
}while(r_data & 0x01);
tcon_address = tcon_address + tcon_byte_count;
//printk("\n- S3C_TCON_WRITE: %d\n\n", tcon_address);
break;
default:
printk("no this command\n");
@@ -1373,12 +1969,140 @@ static int s3c_wifi_ioctl(struct inode *inode, struct file *file, unsigned int c
return 0;
}
#ifdef CONFIG_QISDA_BK060B00
static int s3c_bt_open(struct inode *inode, struct file *file);
static int s3c_bt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);
/* File operations struct for character device */
static const struct file_operations s3c_bt_fops = {
.owner = THIS_MODULE,
.ioctl = s3c_bt_ioctl,
.open = s3c_bt_open,
.release = NULL
};
//Qisda, Ralph Chang, 2010/02/09, for bt power }
//Qisda, Ralph Chang, 2010/02/09, for bt power {
static int s3c_bt_open(struct inode *inode, struct file *file)
{
return 0;
}
static int s3c_bt_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{
switch(cmd){
case S3C_BT_POWER_ON:
printk("BCM4329-BT_POWER_ON\n");
//bcm4329 module power on control
//GPK7, WIFI PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<7)), S3C2416_GPKDAT);
//GPK6, PA 1.8V
writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<6)), S3C2416_GPKDAT);
//GPK5, PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) | (1<<5)), S3C2416_GPKDAT);
mdelay(1);
//GPL8 (blue light), pull high
//printk ("\n GPL8 (blue light), pull high\n");
//writel(((readl(S3C2416_GPLCON) & ~(1<<17)) | (1<<16)), S3C2416_GPLCON);
//writel((readl(S3C2416_GPLDAT) | (1<<8)), S3C2416_GPLDAT);
//writel(((readl(S3C2416_GPLUDP) | (1<<17)) & ~(1<<16)), S3C2416_GPLUDP); //pull up enable
//s3c2410_gpio_cfgpin(S3C2410_GPL8, S3C2410_GPL8_OUTP);
//s3c2410_gpio_setpin(S3C2410_GPL8, 1);
//s3c2410_gpio_pullup(S3C2410_GPL8, 1);
//WIFI_BT_EN (GPD11) pull high
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD11, 0);
//writel(((readl(S3C2416_GPGCON) & ~(1<<9)) | (1<<8)), S3C2416_GPGCON);
//writel((readl(S3C2416_GPGDAT) & ~(1<<4)), S3C2416_GPGDAT);
mdelay(1);
s3c2410_gpio_setpin(S3C2410_GPD11, 1);
//writel((readl(S3C2416_GPGDAT) | (1<<4)), S3C2416_GPGDAT);
mdelay(20);
/*
printk("EXT_N_WIFI_RST (GPD8) set high\n");
//s3c2410_gpio_cfgpin(S3C2410_GPD8, S3C2410_GPD8_OUTP);
//s3c2410_gpio_setpin(S3C2410_GPD8, 0);
writel(((readl(S3C2416_GPDCON) & ~(1<<17)) | (1<<16)), S3C2416_GPDCON);
writel((readl(S3C2416_GPDDAT) & ~(1<<8)), S3C2416_GPDDAT);
mdelay(1);
//s3c2410_gpio_setpin(S3C2410_GPD8, 1);
writel((readl(S3C2416_GPDDAT) | (1<<8)), S3C2416_GPDDAT);
mdelay(20);
*/
//EXT_N_BT_RST (GPA2) pull high
s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
s3c2410_gpio_setpin(S3C2410_GPA2, 0);
mdelay(1);
s3c2410_gpio_setpin(S3C2410_GPA2, 1);
mdelay(20);
//UART1 CTS1 (GPH10) set
s3c2410_gpio_cfgpin(S3C2410_GPH10, S3C2410_GPH10_CLKOUT1);
//writel(((readl(S3C2416_GPHCON) | (1<<21)) & ~ (1<<20)), S3C2416_GPHCON);
//writel(((readl(S3C2416_GPHUDP) & ~ (1<<21)) & ~ (1<<20)), S3C2416_GPHUDP);
//writel((readl(S3C2416_GPHDAT) & ~(1<<10)), S3C2416_GPHDAT);
mdelay(1);
//"UART1 RTS1 (GPH11) set
s3c2410_gpio_cfgpin(S3C2410_GPH11, S3C2410_GPH11_nRTS);
//writel(((readl(S3C2416_GPHCON) | (1<<23)) & ~(1<<22)), S3C2416_GPHCON);
//writel((readl(S3C2416_GPHDAT) & ~(1<<11)), S3C2416_GPHDAT);
//writel(((readl(S3C2416_GPHUDP) & ~ (1<<23)) & ~ (1<<22)), S3C2416_GPHUDP);
mdelay(1);
break;
case S3C_BT_POWER_OFF:
printk("BCM4329-BT_POWER_OFF\n");
//bcm4329 module power off control
//EXT_N_BT_RST (GPA2) pull down
s3c2410_gpio_cfgpin(S3C2410_GPA2, S3C2410_GPA2_OUT);
s3c2410_gpio_setpin(S3C2410_GPA2, 0);
mdelay(20);
//WIFI_BT_EN (GPD11) pull down
s3c2410_gpio_cfgpin(S3C2410_GPD11, S3C2410_GPD11_OUTP);
s3c2410_gpio_setpin(S3C2410_GPD11, 0);
//GPL8 (blue light), pull down
//writel(((readl(S3C2416_GPLCON) & ~(1<<17)) | (1<<16)), S3C2416_GPLCON);
//writel((readl(S3C2416_GPLDAT) & ~(1<<8)), S3C2416_GPLDAT);
//s3c2410_gpio_cfgpin(S3C2410_GPL8, S3C2410_GPL8_OUTP);
//s3c2410_gpio_setpin(S3C2410_GPL8, 0);
//GPK7, WIFI PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<15)) | (1<<14)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<7)), S3C2416_GPKDAT);
//GPK6, PA 1.8V
writel(((readl(S3C2416_GPKCON) & ~(1<<13)) | (1<<12)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<6)), S3C2416_GPKDAT);
//GPK5, PA 3.3V
writel(((readl(S3C2416_GPKCON) & ~(1<<11)) | (1<<10)), S3C2416_GPKCON);
writel((readl(S3C2416_GPKDAT) & ~(1<<5)), S3C2416_GPKDAT);
break;
default:
printk("no this command\n");
}
return 0;
}
#endif
/* File operations struct for character device */
static const struct file_operations s3c_wifi_fops = {
@@ -1426,6 +2150,17 @@ static int s3c_hsmmc_probe (struct platform_device *pdev)
}
//Qisda, Asaku Chen, 2009/08/20, for wifi power }
#ifdef CONFIG_QISDA_BK060B00
//Qisda, Ralph Chang, 2010/02/09, for bt power {
if(plat_data->hwport==1){
if (register_chrdev (S3C_BT_MAJOR, "s3c_bt_cmd", &s3c_bt_fops)) {
printk("unable to get major S3C_BT_MAJOR\n");
}
}
//Qisda, Asaku Chen, 2009/08/20, for wifi power }
#endif
host = mmc_priv(mmc);
host->mmc = mmc;
@@ -1465,7 +2200,25 @@ static int s3c_hsmmc_probe (struct platform_device *pdev)
DBG("s3c_hsmmc_cfg(plat_data): enabled(%d) hwport(%d)\n", plat_data->enabled, plat_data->hwport);
/* To detect a card inserted on channel 0, an external interrupt is used. */
/* Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card { */
#ifdef CONFIG_SD_SW_DEBOUNCE
if( plat_data->hwport == 0)
{
init_timer(&sd_detect_timer);
sd_detect_timer.function=sdcard_debounce_timer;
}
#endif /* CONFIG_SD_SW_DEBOUNCE */
/* } Qisda, howard hsu, 2010/01/21, SW_DEBOUNCE for sd card */
/* Qisda, howard hsu, 2010/01/21, fix start slot for SD card { */
if( plat_data->hwport == 0)
{
mmc->first_devidx = 1;
}
else
{
mmc->first_devidx = 0;
}
/* } Qisda, howard hsu, 2010/01/21, fix start slot for SD card */
if ((plat_data->enabled == 1) && (plat_data->hwport == 0)) {
host->irq_cd = platform_get_irq(pdev, 1);
if (host->irq_cd == 0) {
@@ -1514,7 +2267,8 @@ static int s3c_hsmmc_probe (struct platform_device *pdev)
/* you must make sure that our hsmmc block can support
* up to 52MHz. by scsuh
*/
mmc->f_max = 100 * MHZ;
//mmc->f_max = 100 * MHZ;
mmc->f_max = 25 * MHZ;
mmc->caps = plat_data->host_caps;
DBG("mmc->caps: %08lx\n", mmc->caps);
printk(KERN_INFO "mmc->caps: %08lx\n", mmc->caps);
@@ -1708,7 +2462,13 @@ static int s3c_hsmmc_suspend(struct platform_device *pdev, pm_message_t state)
//mmc suspend GPIO config
s3c_hsmmc_power_switch(s3c_host->plat_data->hwport, 0);
/* Qisda, Howard, 2009/12/22, fix resume card-detect { */
if(s3c_host->plat_data->hwport==0)
{
inResume = 1;
card_detect2 = 2;
}
/* } Qisda, Howard, 2009/12/22, fix resume card-detect */
return 0;
}
@@ -1733,19 +2493,41 @@ static int s3c_hsmmc_resume(struct platform_device *pdev)
//PWREN_SD
if(s3c_host->plat_data->hwport==0){
read_pin = readl(S3C2410_GPFDAT) & (1<<1);
if(read_pin){
//printk("\nno card\n");
if(read_pin && !card_detect){
printk("\nNO CARD\n");
s3c_hsmmc_power_switch(0, 0);
set_irq_type(s3c_host->irq_cd, IRQT_FALLING);
/* Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger { */
//set_irq_type(s3c_host->irq_cd, IRQT_FALLING);
set_irq_type(s3c_host->irq_cd, IRQT_LOW);
/* } Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger */
card_detect2 = 3;
}
else{
//printk("\ncard in\n");
if(read_pin){
printk("no card\n");
/* Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger { */
//set_irq_type(s3c_host->irq_cd, IRQT_FALLING);
set_irq_type(s3c_host->irq_cd, IRQT_LOW);
/* } Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger */
card_detect = 0;
//s3c_hsmmc_power_switch(0, 0);
}
else{
printk("card in\n");
/* Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger { */
//set_irq_type(s3c_host->irq_cd, IRQT_RISING);
set_irq_type(s3c_host->irq_cd, IRQT_HIGH);
/* } Qisda, Howard Hsu, 2009/12/17, card detect by level-trigger */
card_detect = 1;
//s3c_hsmmc_power_switch(0, 1);
}
card_detect2 = 2;
s3c_hsmmc_power_switch(0, 1);
set_irq_type(s3c_host->irq_cd, IRQT_RISING);
s3c_hsmmc_ios_init(s3c_host);
mmc_resume_host(host);
mmc_resume_host(host);
}
card_detect2 = 2; //Qisda, Asaku Chen, 2009/11/03 {
inResume = 0; //howard, 2009/12/22, fix resume card-detect
}
else if(s3c_host->plat_data->hwport==1){
s3c_hsmmc_power_switch(1, 1);
@@ -1813,6 +2595,12 @@ static void __exit s3c_hsmmc_drv_exit(void)
platform_driver_unregister(&s3c_hsmmc_driver);
}
void s3c_moviNAND_power_off(void)
{
struct s3c_hsmmc_host *host = global_host[1];
printk("s3c_moviNAND_power_off");
s3c_hsmmc_writeb(S3C_HSMMC_POWER_OFF, S3C_HSMMC_PWRCON);
}
module_init(s3c_hsmmc_drv_init);
module_exit(s3c_hsmmc_drv_exit);