예제 #1
0
/*
 * Set the IOS
 */
static void at91rm9200_mci_set_ios(struct mmc_host* mmc, struct mmc_ios* ios)
{
	int clkdiv;
	struct at91mci_host *host = mmc_priv(mmc);

	DBG("Clock %uHz, busmode %u, powermode %u, Vdd %u\n",
		ios->clock, ios->bus_mode, ios->power_mode, ios->vdd);

	if (ios->clock == 0) {
		/* Disable the MCI controller */
		controller->MCI_CR = AT91C_MCI_MCIDIS;
		clkdiv = 0;
 		controller->MCI_SDCR &= ~0x80;
	}
	else {
		/* Enable the MCI controller */
		controller->MCI_CR = AT91C_MCI_MCIEN;

                /* figure out a clock divisor for MCCK */

                /* TODO: refactor all this math, to be sure that the
                   resulting mcck is truly less than or equal to
                   ios->clock */
                DBG("ios->clock = %d\n", ios->clock);
                DBG("at91_master_clock = %ld\n", at91_master_clock);

		clkdiv = ((at91_master_clock / ios->clock) / 2) - 1;

                DBG("unadjusted clkdiv = %d\n", clkdiv);

 		/* TODO: this band-aid prevents us from getting the
                   wrong divisor; we shouldn't need it, but the maths
                   above and below are still flawed in some way that
                   needs to be investigated */
                if (clkdiv <= 0) clkdiv = 1;
                while ((at91_master_clock / (2 * (clkdiv + 1))) > ios->clock)
                  clkdiv++;

                DBG("clkdiv = %d mcck = %ld\n", clkdiv,
                    at91_master_clock / (2 * (clkdiv + 1)));
	}

	/* Set the clock divider */
	controller->MCI_MR = (controller->MCI_MR & ~0x000000FF) | clkdiv;

	/* maybe switch power to the card */
	if (host && host->board->vcc_pin) {
		switch (ios->power_mode) {
		case MMC_POWER_OFF:
			at91_set_gpio_direction(host->board->vcc_pin, 0, 0);
			break;
		case MMC_POWER_UP:
		case MMC_POWER_ON:
			at91_set_gpio_direction(host->board->vcc_pin, 0, 1);
			break;
		}
	}
}
예제 #2
0
void __init at91_add_device_udc(struct at91_udc_data *data)
{
	if (!data)
		return;

	if (data->vbus_pin) {
		at91_set_gpio_direction(data->vbus_pin, 1, 0);
		at91_set_deglitch(data->vbus_pin, 1);
	}
	if (data->pullup_pin)
		at91_set_gpio_direction(data->pullup_pin, 0, 0);

	udc_data = *data;
	platform_device_register(&at91rm9200_udc_device);
}
예제 #3
0
void __init at91_add_device_cf(struct at91_cf_data *data)
{
	if (!data)
		return;

	/* input/irq */
	if (data->irq_pin) {
		at91_set_gpio_direction(data->irq_pin, 1, 1);
		at91_set_deglitch(data->irq_pin, 1);
	}
	at91_set_gpio_direction(data->det_pin, 1, 1);
	at91_set_deglitch(data->det_pin, 1);

	/* outputs, initially off */
	if (data->vcc_pin)
		at91_set_gpio_direction(data->vcc_pin, 0, 0);
	at91_set_gpio_direction(data->rst_pin, 0, 0);

	cf_data = *data;
	platform_device_register(&at91rm9200_cf_device);
}
예제 #4
0
static void __init csb437tl_board_init(void)
{
        /* activate the LED */
        at91_set_gpio_direction(LED, 0, 1);

#if (CONFIG_MACH_CSB437TL_REV == 4)
        /* power up vcc5 */
        at91_set_gpio_direction(AT91_PIN_PB0, 0, 1);
#endif

        /* power up USBH ports */
        /* TODO: let USBH controller manage USB power */
#if (CONFIG_MACH_CSB437TL_REV == 2)
        /* the P2 uses active-low USBHVCC switches */
        at91_set_gpio_direction(USBHVCC0, 0, 0);
        at91_set_gpio_direction(USBHVCC1, 0, 0);
#else
        at91_set_gpio_direction(USBHVCC0, 0, 1);
        at91_set_gpio_direction(USBHVCC1, 0, 1);
#endif
        
#if defined(CONFIG_FB)
        {
          struct clk *plla, *pck0;
          
          plla = clk_get(NULL, "plla");
          pck0 = clk_get(NULL, "pck0");
          if (plla && pck0) {
            clk_set_rate(plla, 48000000);
            clk_set_parent(pck0, plla);
            clk_set_rate(pck0, 24000000);
            at91_set_A_periph(AT91_PIN_PB27, 0);
          }
        }
#endif

	/* Ethernet */
	at91_add_device_eth(&csb437tl_eth_data);
	/* USB Host */
	at91_add_device_usbh();
	/* USB Device */
	at91_add_device_udc(&csb437tl_udc_data);
	/* Compact Flash */
	at91_set_gpio_direction(AT91_PIN_PB22, 1, 1);	/* IOIS16 */
	at91_add_device_cf(&csb437tl_cf_data);
	/* MMC */
	at91_add_device_mmc(&csb437tl_mmc_data);

#if defined(CONFIG_FB_VOYAGER_GX)
       platform_device_register(&at91_panel_dev);
#endif
       platform_device_register(&sm501_8051_dev);
       platform_device_register(&ac97_dev);

}
예제 #5
0
void __init at91_add_device_mmc(struct at91_mmc_data *data)
{
	/* input/irq */
	if (data->det_pin) {
		at91_set_gpio_direction(data->det_pin, 1, 1);
		at91_set_deglitch(data->det_pin, 1);
	}
	if (data->wp_pin)
		at91_set_gpio_direction(data->wp_pin, 1, 1);

	/* CLK */
	at91_set_A_periph(AT91_PIN_PA27, 0);

	if (data->is_b) {
		/* CMD */
		at91_set_B_periph(AT91_PIN_PA8, 0);

		/* DAT0, maybe DAT1..DAT3 */
		at91_set_B_periph(AT91_PIN_PA9, 0);
		if (data->wire4) {
			at91_set_B_periph(AT91_PIN_PA10, 0);
			at91_set_B_periph(AT91_PIN_PA11, 0);
			at91_set_B_periph(AT91_PIN_PA12, 0);
		}
	} else {
		/* CMD */
		at91_set_A_periph(AT91_PIN_PA28, 0);

		/* DAT0, maybe DAT1..DAT3 */
		at91_set_A_periph(AT91_PIN_PA29, 0);
		if (data->wire4) {
			at91_set_B_periph(AT91_PIN_PB3, 0);
			at91_set_B_periph(AT91_PIN_PB4, 0);
			at91_set_B_periph(AT91_PIN_PB5, 0);
		}
	}

	mmc_data = *data;
	platform_device_register(&at91rm9200_mmc_device);
}
예제 #6
0
static void __init csb337_board_init(void)
{
	/* Ethernet */
	at91_add_device_eth(&csb337_eth_data);
	/* USB Host */
	at91_add_device_usbh();
	/* USB Device */
	at91_add_device_udc(&csb337_udc_data);
	/* Compact Flash */
	at91_set_gpio_direction(AT91_PIN_PB22, 1, 1);	/* IOIS16 */
	at91_add_device_cf(&csb337_cf_data);
	/* MMC */
	at91_add_device_mmc(&csb337_mmc_data);
}
예제 #7
0
static void __init ek_board_init(void)
{
	/* Ethernet */
	at91_add_device_eth(&ek_eth_data);
	/* USB Host */
	at91_add_device_usbh();
	/* USB Device */
	at91_add_device_udc(&ek_udc_data);
	/* MMC */
	at91_set_gpio_direction(AT91_PIN_PB22, 0, 1);	/* this MMC card slot can optionally use SPI signaling (CS3). default: MMC */
	at91_add_device_mmc(&ek_mmc_data);
	/* VGA */
	ek_add_device_video();
}
예제 #8
0
void __init at91_add_device_eth(struct at91_eth_data *data)
{
	if (!data)
		return;

	if (data->phy_irq_pin) {
		at91_set_gpio_direction(data->phy_irq_pin, 1, 0);
		at91_set_deglitch(data->phy_irq_pin, 1);
	}

	if (data->is_rmii)
		AT91_CfgPIO_EMAC_RMII();
	else
		AT91_CfgPIO_EMAC_MII();

	eth_data = *data;
	platform_device_register(&at91rm9200_eth_device);
}