/* * 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; } } }
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); }
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); }
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); }
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); }
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); }
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(); }
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); }