Ejemplo n.º 1
0
/*
 * Get write-protect tab state by reading GPIO pin
 */
static int pollux_sdi_get_ro(struct mmc_host *mmc)
{
	struct pollux_sdi_host *host = mmc_priv(mmc);
	
	//host->readonly = WRITE_ENABLED; // just fix
	host->readonly =  pollux_gpio_getpin(host->wppin); // low면 write protected, high면 write enable ==> low active
	
	gprintk("Read only state: %d (1 if write protected)\n", host->readonly);
	return (host->readonly);
}
Ejemplo n.º 2
0
static irqreturn_t pollux_sdi_irq_cd(int irq, void *dev_id)
{
	struct pollux_sdi_host *host = (struct pollux_sdi_host *)dev_id;
	int new_cd_state;

	disable_irq(irq);

	new_cd_state = pollux_gpio_getpin(host->cdpin); // low/high인지 읽어냄
	aprintk("host->cd_state = %s, New card state: %d\n", (host->cd_state)?"Inserted":"Removed", new_cd_state);
	
	if( host->cd_state == SD_REMOVED && new_cd_state == 0) // removed/low ==> inserted
	{
		aprintk("CD IRQ insert =====================> change to rising\n");
		host->cd_state = SD_INSERTED;		
		set_irq_type(irq, IRQT_RISING);	/* Current GPIO value is low: wait for raising high */
		schedule_work(&host->card_detect_work);
	}
    else if( host->cd_state == SD_INSERTED && new_cd_state == 1) // inserted/high ==> removed
	{
		aprintk("CD IRQ eject  =====================> change to falling\n");
    	host->cd_state = SD_REMOVED;
    	set_irq_type(irq, IRQT_FALLING);	/* Current GPIO value is hight: wait for raising low */
		schedule_work(&host->card_detect_work);
    }
    else
    {
    	aprintk("CD IRQ - Unexpected state\n");
    	if( new_cd_state == 1 ) // high 상태이면
    		set_irq_type( irq, IRQT_FALLING); // falling으로 바꾼다.
    	else
    		set_irq_type( irq, IRQT_RISING);
    }

	enable_irq(irq);
	
	return IRQ_HANDLED;	
}
Ejemplo n.º 3
0
static int usb_connection_status(void)
{
	return pollux_gpio_getpin(GPIO_USB_DETECT);
}
Ejemplo n.º 4
0
int pollux_sdi_probe1(void)
{
	struct mmc_host 	*mmc;
	struct pollux_sdi_host 	*host;
	int ret = 0;
	struct resource *res;


	/* 
	 * Allocate memory space for host specific data structure 
	 */
	dprintk("sdi: 1\n");
	mmc = mmc_alloc_host(sizeof(struct pollux_sdi_host), &pbdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto probe_out;
	}
	
	printk(KERN_INFO "======================mmc: %p, private: %p, sizeof(private) = %d\n", mmc, &(mmc->private), sizeof(mmc->private) );


	/*
	 * Set host specific pointer to allocated space
	 */
	dprintk("sdi: 2\n");
	host = mmc_priv(mmc);
	
	printk(KERN_INFO "==================host: %p\n", host);


	/* 
	 * Initialize host specific data
	 */
	dprintk("sdi: 3\n");
	/* Set value of mmc structure */
	mmc->ops			= &pollux_sdi_ops;
	mmc->f_min			=   400000;
	mmc->f_max			= 33000000;
	mmc->caps			= MMC_CAP_4_BIT_DATA;	
		/*
		 * Set the maximum segment size.  Since we aren't doing DMA
		 * we are only limited by the data length register.
		 */
	mmc->max_seg_size	= 64 * 512;
	mmc->max_phys_segs	= 1;
	mmc->max_blk_size   = 2048;
	mmc->max_blk_count  = 64;
	mmc->ocr_avail = MMC_VDD_32_33;

	spin_lock_init( &host->complete_lock );

	/* 
	 * Set host specific structure 
	 */
	host->mmc				= mmc;
	host->dma				= 0;
	host->size				= 0;
	host->irq_cd			= 0;
	host->cd_state			= 0;
	host->clock				= 0;
	host->cd_state			= SD_INSERTED;
	host->readonly			= 0;
	host->bus_width 		= 0;
	
#if 0	
	aprintk("pdev.id = %d\n", pdev->id);
	host->channel           = 0; // sdmmc channel 0로 일단 세팅 
#else
	aprintk("pdev.id = %d\n", pbdev->id);
	host->channel           = pbdev->id; // sdmmc channel 0로 일단 세팅 
#endif	
	
	if( host->channel == 0 )
		strcpy(host->hname, POLLUX_SDI0_NAME);
	else
		strcpy(host->hname, POLLUX_SDI1_NAME);
	
	res = platform_get_resource(pbdev, IORESOURCE_MEM, 0); // MEM resource #0, Virtual memory of sdmmc base address
	if( res == 0 )
	{
		printk("POLLUX_SDI: error......get memory base resources\n");
		ret = -EINVAL;
		goto probe_out;
	}
	host->baseaddr = (u32)res->start;
	

	res = platform_get_resource(pbdev, IORESOURCE_IO, 0); // IO resource #0, card detection gpio number
	if( res == 0 )
	{
		printk("POLLUX_SDI: error......get resources 2\n");
		ret = -EINVAL;
		goto probe_out;
	}
	gprintk("cd gpio = %d\n", res->start );
	host->cdpin = (int)res->start;
	
	
	res = platform_get_resource(pbdev, IORESOURCE_IO, 1); // IO resource #1, write protection gpio number
	if( res == 0 )
	{
		printk("POLLUX_SDI: error......get resources 3\n");
		ret = -EINVAL;
		goto probe_out;
	}
	gprintk("wp gpio = %d\n", res->start );
	host->wppin = (int)res->start;


	/*
	 * Get SD/MMC controller IRQ
	 */
	dprintk("sdi: 5 \n");	
	host->irq = platform_get_irq(pbdev, 0);
	if (host->irq == 0) 
	{
		printk(KERN_INFO "failed to get interrupt resouce.\n");
		ret = -EINVAL;
		goto probe_out;
	}
	
	/*
	 * Initialize GPIO prototype.
	 * GPIO pin is used for card detection and write protection state detection 
	 */
	host->irq_cd = platform_get_irq(pbdev, 1);
	aprintk("SDI___________________IRQ_CD = %d\n", host->irq_cd );
	if( host->irq_cd == 0 ) 
	{
		printk(KERN_INFO "failed to get card detection interrupt resource.\n");
		ret = -EINVAL;
		goto probe_out;
	}


	/*
	 * Initialize SD controller prototype  from sdmmc.cpp of wince bsp
	 */
	
	MES_SDHC_Initialize(); //mes_sdhc.c 의 해당 레지스터 block 초기화 루틴, 두번 호출이 안되도록 세팅이 되어 있음.
	
#if 1	
	/*
	 * Initialize MP2530F SDI
	 */
	ret = sdmmc_init(host);
	if(ret != 0)
	{
		ret = -EINVAL;
		goto probe_out;
	}
#endif	

//return 0; // ghcstop for debugging



	/*
	 * Register handler for host interupt
	 */
	dprintk("sdi: 6 - SD IRQ number is %d\n", host->irq);
	if(request_irq(host->irq, pollux_sdi_irq, 0, POLLUX_SDI0_NAME, host)) 
	{
		printk(KERN_INFO "failed to request sdi interrupt.\n");
		ret = -ENOENT;
		goto probe_out;
	}


	/*
	 * Read current card state 
	 */

	host->readonly =  pollux_gpio_getpin(host->wppin); // low면 write protected, high면 write enable ==> low active
	host->cd_state = !pollux_gpio_getpin(host->cdpin); // low면 Inserted, high면 ejected. ==> 그러므로 !로 뒤집음
	
	
	gprintk("host->readonly = %d, host->cd_state = %d, pollux_get_gpio_func(host->cdpin) = %d\n", host->readonly, host->cd_state, pollux_get_gpio_func(host->cdpin) );

	/*
	 * Register interrupt handler for card detection 
	 */
	INIT_WORK(&host->card_detect_work, pollux_sdi_card_detect);
#if 1
	if( host->cd_state ) // inserted
		set_irq_type(host->irq_cd, IRQT_RISING);
	else
		set_irq_type( host->irq_cd, IRQT_FALLING);
		
		
	//if(request_irq(host->irq_cd, pollux_sdi_irq_cd, 0, POLLUX_SDI0_NAME, host)) 
	if(request_irq(host->irq_cd, pollux_sdi_irq_cd, 0, host->hname, host)) 
	{
		printk(KERN_WARNING "failed to request card detect interrupt.\n" );
		ret = -ENOENT;
		goto probe_free_irq;
	}
#endif


	/*
	 * Register MP2530F host driver
	 */
	dprintk("sdi: 8\n");
	if((ret = mmc_add_host(mmc)))
	{
		printk(KERN_INFO "failed to add mmc host.\n");
		goto free_resource;
	}

	platform_set_drvdata(pbdev, mmc);

	printk(KERN_INFO "initialization done.\n");
	
	
	//mmc_detect_change(host->mmc, 100); // number of jiffies to wait before queueing	

	return ret;

free_resource:
    free_irq(host->irq_cd, host);	/* unregister card detection interrupt handler */

probe_free_irq:
 	free_irq(host->irq, host);	/* unregister host controller interrupt handler */

probe_out:
	return ret;
}
Ejemplo n.º 5
0
static void mmc_rescan(struct work_struct *work)
{
	struct mmc_host *host =
		container_of(work, struct mmc_host, detect.work);
	u32 ocr;
	int err;

	if(fo_k){
		fo_k = 0;
		return;		
	}	 
	
	printk(" mmc_rescan... \n");
	mmc_bus_get(host);

	if (host->bus_ops == NULL) {
		/*
		 * Only we can add a new handler, so it's safe to
		 * release the lock here.
		 */
		if(pollux_gpio_getpin(SDI_CD_IO)) {
			printk("  mmc_rescan 1===> no card \n");
			mmc_bus_put(host);
			return;
		}
		mmc_bus_put(host);
		mmc_claim_host(host);
		mmc_power_up(host);
		if(pollux_gpio_getpin(SDI_CD_IO)) {
			printk("  mmc_rescan 2===> no card \n");
			mmc_power_off(host);
			mmc_release_host(host);
			return;
		}
		
		mmc_go_idle(host);
		mmc_send_if_cond(host, host->ocr_avail);

		err = mmc_send_app_op_cond(host, 0, &ocr);
		if (err == MMC_ERR_NONE) {
			if (mmc_attach_sd(host, ocr)){
				printk("mmc_attach_sd_error .... \n");
				mmc_power_off(host);
				fo_k = 1;
			}						
		} else {
			/*
			 * If we fail to detect any SD cards then try
			 * searching for MMC cards.
			 */
			if(pollux_gpio_getpin(SDI_CD_IO)) {
				printk("  mmc_rescan 4===> no card \n");
				mmc_power_off(host);
				mmc_release_host(host);
				return;
			}
			
			err = mmc_send_op_cond(host, 0, &ocr);
			if (err == MMC_ERR_NONE) {
				if (mmc_attach_mmc(host, ocr))
					mmc_power_off(host);
			} else {
				mmc_power_off(host);
				mmc_release_host(host);
			}
		}
	} else {
		if (host->bus_ops->detect && !host->bus_dead)
			host->bus_ops->detect(host);

		mmc_bus_put(host);
	}
}