コード例 #1
0
ファイル: mach-athena.c プロジェクト: andyliu/ak98_kernel
static void __init athena_evt_machine_init(void)
{
	pm_power_off = athena_power_off;
	ak98_arch_reset = athena_reset;

	ak98_nand_device.dev.platform_data = &athena_evt_nand_info;
	i2c_register_board_info(0, ak98_ts_devices, ARRAY_SIZE(ak98_ts_devices));
	i2c_register_board_info(0, ak98_sensor_devices, ARRAY_SIZE(ak98_sensor_devices));
	i2c_register_board_info(0, ak98_aw9523_ext, ARRAY_SIZE(ak98_aw9523_ext));
	ak_sensor_device.dev.platform_data = &sensor_info;
   
	ak98adc_ts_device.dev.platform_data = &ak98adc_ts_info; 
  	// set battery platform_data
	ak98_battery_power.dev.platform_data = &ak98_bat_info;
	ak98pwm_backlight_device.dev.platform_data = &ak98pwm_backlight_data;
  
	spidev_info.max_speed_hz = ak98_get_asic_clk()/2;	   
	//spi_register_board_info(&spidev_info, 1);
	spi_register_board_info(&ar7643_info, 1);
	ak98_spi1_device.dev.platform_data = &ak98_spi1_info;
	/* register platform devices */
	platform_add_devices(athena_evt_platform_devices,
		ARRAY_SIZE(athena_evt_platform_devices));

	/* Initialize L2 buffer */
	ak98_l2_init();

}
コード例 #2
0
static int ak98sdio_cpufreq_transition(struct notifier_block *nb,
				     unsigned long val, void *data)
{
	struct ak98_mci_host *host;
	struct mmc_host *mmc;
	unsigned long newclk;
	unsigned long flags;
	struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
	host = container_of(nb, struct ak98_mci_host, freq_transition);
	
	PKCLK("%s\n",__func__);	
	PKCLK("%s(): in_interrupt()=%ld\n", __func__, in_interrupt());
	PKCLK("ak98_get_asic_clk = %ld\n",ak98_get_asic_clk());	
	PKCLK("freqs->new_cpufreq.asic_clk = %d\n",
		  freqs->new_cpufreq.asic_clk);	
		  
	mmc = host->mmc;
	newclk = freqs->new_cpufreq.asic_clk;
	if ((val == CPUFREQ_PRECHANGE && newclk > host->asic_clkrate) 
		|| (val == CPUFREQ_POSTCHANGE && newclk < host->asic_clkrate)) 
	{

		if (mmc->ios.power_mode != MMC_POWER_OFF &&
			mmc->ios.clock != 0)
		{		
			PKCLK("%s(): preempt_count()=%d\n",
				__func__, preempt_count());
				
			down(&host->freq_lock);
			
			spin_lock_irqsave(&mmc->lock, flags);
		
			host->asic_clkrate = newclk;
			PKCLK("AK98MCICLOCK1 = %d\n",readl(host->base + AK98MCICLOCK));	
			ak98sdio_set_clk(host, &mmc->ios);
			PKCLK("AK98MCICLOCK2 = %d\n",readl(host->base + AK98MCICLOCK));	
			
			spin_unlock_irqrestore(&mmc->lock, flags);

			up(&host->freq_lock);
		}		

	}

	return NOTIFY_DONE;
}
コード例 #3
0
static int __devinit ak98_sdio_probe(struct platform_device *pdev)
{
	struct ak98_mci_platform_data *plat = pdev->dev.platform_data;
	struct ak98_mci_host *host;
	struct mmc_host *mmc;
	struct resource *res;
	int irq;
	int ret;

	/* must have platform data */
	if (!plat) {
		ret = -EINVAL;
		goto out;
	}

	PK("%s\n", __func__);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	irq = platform_get_irq(pdev, 0);

	PK("res: %x, %u", res->start, resource_size(res));
	res = request_mem_region(res->start, resource_size(res), DRIVER_NAME);
	if (!res) {
		ret = -EBUSY;
		goto out;
	}
	PK("res: %x, %u\n", res->start, resource_size(res));

	mmc = mmc_alloc_host(sizeof(struct ak98_mci_host), &pdev->dev);
	if (!mmc) {
		ret = -ENOMEM;
		goto out;
	}

	host = mmc_priv(mmc);
	host->mmc = mmc;

	host->gpio_wp = -ENOSYS;
	host->gpio_cd = -ENOSYS;

    ak98_sdio_reset();
    host->clk = clk_get(&pdev->dev, "sdio_clk");
    if (IS_ERR(host->clk)) {
        ret = PTR_ERR(host->clk);
        host->clk = NULL;
        goto host_free;
    }      

	ret = clk_enable(host->clk);
	if (ret)
		goto clk_free;

	host->plat = plat;
	host->asic_clkrate = ak98_get_asic_clk();
	

	host->base = ioremap(res->start, resource_size(res));
	if (!host->base) {
		ret = -ENOMEM;
		goto clk_disable;
	} 
    PK("asic_clkrate: %luhz,host->base=0x%x\n", host->asic_clkrate,host->base);
	mmc->ops = &ak98_mci_ops;
	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
	mmc->caps = MMC_CAP_4_BIT_DATA;
#if 0
	mmc->caps |= MMC_CAP_SD_HIGHSPEED | MMC_CAP_MMC_HIGHSPEED;
#endif 
	mmc->caps |= MMC_CAP_SDIO_IRQ;

//	mmc->caps |= MMC_CAP_NEEDS_POLL;
	mmc->f_min = host->asic_clkrate / (255+1 + 255+1);
	mmc->f_max = host->asic_clkrate / (0+1 + 0+1);
	mmc->f_max = mmc->f_max < fmax ? mmc->f_max : fmax;

	/*
	 * We can do SGIO
	 */
	mmc->max_hw_segs = 16;
	mmc->max_phys_segs = NR_SG;

	/*
	 * Since we only have a 16-bit data length register, we must
	 * ensure that we don't exceed 2^16-1 bytes in a single request.
	 */
	mmc->max_req_size = 65535;

	/*
	 * Set the maximum segment size.  Since we aren't doing DMA
	 * (yet) we are only limited by the data length register.
	 */
	mmc->max_seg_size = mmc->max_req_size;

#if 0
	/*
	 * Block size can be up to 2048 bytes, but must be a power of two.
	 */
	mmc->max_blk_size = 2048;
#else
	/* as l2 fifo limit to 512 bytes */
	mmc->max_blk_size = 512;
#endif

	/*
	 * No limit on the number of blocks transferred.
	 */
	mmc->max_blk_count = mmc->max_req_size;

	spin_lock_init(&host->lock);
	
    ak98_group_config(ePIN_AS_SDIO); 
	writel(MCI_ENABLE|MCI_FAIL_TRIGGER, host->base + AK98MCICLOCK);	
    PK("%s: MCICLOCK: 0x%08x\n", __func__, readl(host->base + AK98MCICLOCK));
    
	writel(0, host->base + AK98MCIMASK);
	
	PK("request irq %i\n", irq);
	ret = request_irq(irq, ak98_sdio_irq, IRQF_DISABLED, DRIVER_NAME " (cmd)", host);
	if (ret)
		goto unmap;
		
	host->irq_mci = irq;
	if(plat->gpio_cd >= 0)
	{
    	host->gpio_cd = plat->gpio_cd;	
    	ak98_gpio_cfgpin(host->gpio_cd, AK98_GPIO_DIR_INPUT);
    	ak98_gpio_pulldown(host->gpio_cd,AK98_PULLDOWN_DISABLE);
        ak98_gpio_pullup(host->gpio_cd, AK98_PULLUP_ENABLE);  
        
        setup_timer(&host->detect_timer, ak98_sdio_detect_change,
                    (unsigned long)host);
                    
        irq = ak98_gpio_to_irq(host->gpio_cd);    
        ret = request_irq(irq, ak98_sdio_card_detect_irq,
                  IRQF_DISABLED,
                  DRIVER_NAME " cd", host);
        printk("request gpio irq ret = %d, irq=%d", ret, irq);
        if (ret)
            goto irq_free;
        host->irq_cd = irq;
        host->irq_cd_type = IRQ_TYPE_LEVEL_LOW; 
    }
    
    if(plat->gpio_wp >= 0)
    {
        host->gpio_wp = plat->gpio_wp;	
    	ak98_gpio_cfgpin(host->gpio_wp, AK98_GPIO_DIR_INPUT);
    	ak98_gpio_pullup(host->gpio_wp, AK98_PULLUP_ENABLE);
    	ak98_gpio_pulldown(host->gpio_wp,AK98_PULLDOWN_DISABLE);
    }
	
	platform_set_drvdata(pdev, mmc);

	ret = ak98sdio_cpufreq_register(host);
	if (ret) {
		goto irq_free;
	}

	ret = mmc_add_host(mmc);
	if (ret) {
		goto cpufreq_free;
	}

	PK(KERN_INFO "%s: ak98MCI at 0x%016llx irq %d\n",
		mmc_hostname(mmc), (unsigned long long)res->start,
		host->irq_mci);

	return 0;

 cpufreq_free:
	 PK("ERR cpufreq_free\n");
	 ak98sdio_cpufreq_deregister(host);

 irq_free:
	PK("ERR irq_free\n");
	free_irq(host->irq_mci, host);
 unmap:
	PK("ERR unmap\n");
	iounmap(host->base);
 clk_disable:
	PK("ERR clk_disable\n");
	clk_disable(host->clk);
 clk_free:
	PK("ERR clk_free\n");
	clk_put(host->clk);
 host_free:
	PK("ERR host_free\n");
	mmc_free_host(mmc);
 out:
	PK("ERR out\n");
	return ret;
}