mirror of
https://github.com/adulau/aha.git
synced 2025-01-03 22:53:18 +00:00
Merge branch 'omap3-boards' into for-next
This commit is contained in:
commit
4c50d22a0c
14 changed files with 3842 additions and 203 deletions
1528
arch/arm/configs/omap3_evm_defconfig
Normal file
1528
arch/arm/configs/omap3_evm_defconfig
Normal file
File diff suppressed because it is too large
Load diff
1211
arch/arm/configs/omap_zoom2_defconfig
Normal file
1211
arch/arm/configs/omap_zoom2_defconfig
Normal file
File diff suppressed because it is too large
Load diff
|
@ -56,6 +56,10 @@ config MACH_OVERO
|
||||||
bool "Gumstix Overo board"
|
bool "Gumstix Overo board"
|
||||||
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
||||||
|
|
||||||
|
config MACH_OMAP3EVM
|
||||||
|
bool "OMAP 3530 EVM board"
|
||||||
|
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
||||||
|
|
||||||
config MACH_OMAP3_PANDORA
|
config MACH_OMAP3_PANDORA
|
||||||
bool "OMAP3 Pandora"
|
bool "OMAP3 Pandora"
|
||||||
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
||||||
|
@ -67,3 +71,7 @@ config MACH_OMAP_3430SDP
|
||||||
config MACH_NOKIA_RX51
|
config MACH_NOKIA_RX51
|
||||||
bool "Nokia RX-51 board"
|
bool "Nokia RX-51 board"
|
||||||
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
||||||
|
|
||||||
|
config MACH_OMAP_ZOOM2
|
||||||
|
bool "OMAP3 Zoom2 board"
|
||||||
|
depends on ARCH_OMAP3 && ARCH_OMAP34XX
|
||||||
|
|
|
@ -47,6 +47,8 @@ obj-$(CONFIG_MACH_OMAP_LDP) += board-ldp.o \
|
||||||
mmc-twl4030.o
|
mmc-twl4030.o
|
||||||
obj-$(CONFIG_MACH_OVERO) += board-overo.o \
|
obj-$(CONFIG_MACH_OVERO) += board-overo.o \
|
||||||
mmc-twl4030.o
|
mmc-twl4030.o
|
||||||
|
obj-$(CONFIG_MACH_OMAP3EVM) += board-omap3evm.o \
|
||||||
|
mmc-twl4030.o
|
||||||
obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
|
obj-$(CONFIG_MACH_OMAP3_PANDORA) += board-omap3pandora.o \
|
||||||
mmc-twl4030.o
|
mmc-twl4030.o
|
||||||
obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
|
obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
|
||||||
|
@ -55,7 +57,9 @@ obj-$(CONFIG_MACH_OMAP_3430SDP) += board-3430sdp.o \
|
||||||
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
|
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o \
|
||||||
board-rx51-peripherals.o \
|
board-rx51-peripherals.o \
|
||||||
mmc-twl4030.o
|
mmc-twl4030.o
|
||||||
|
obj-$(CONFIG_MACH_OMAP_ZOOM2) += board-zoom2.o \
|
||||||
|
mmc-twl4030.o \
|
||||||
|
board-zoom-debugboard.o
|
||||||
# Platform specific device init code
|
# Platform specific device init code
|
||||||
obj-y += usb-musb.o
|
obj-y += usb-musb.o
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
#include <linux/mtd/nand.h>
|
#include <linux/mtd/nand.h>
|
||||||
|
|
||||||
|
#include <linux/regulator/machine.h>
|
||||||
#include <linux/i2c/twl4030.h>
|
#include <linux/i2c/twl4030.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
|
@ -120,6 +121,23 @@ static struct twl4030_hsmmc_info mmc[] = {
|
||||||
{} /* Terminator */
|
{} /* Terminator */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct platform_device omap3_beagle_lcd_device = {
|
||||||
|
.name = "omap3beagle_lcd",
|
||||||
|
.id = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
|
||||||
|
.ctrl_name = "internal",
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply beagle_vmmc1_supply = {
|
||||||
|
.supply = "vmmc",
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply beagle_vsim_supply = {
|
||||||
|
.supply = "vmmc_aux",
|
||||||
|
};
|
||||||
|
|
||||||
static struct gpio_led gpio_leds[];
|
static struct gpio_led gpio_leds[];
|
||||||
|
|
||||||
static int beagle_twl_gpio_setup(struct device *dev,
|
static int beagle_twl_gpio_setup(struct device *dev,
|
||||||
|
@ -130,6 +148,10 @@ static int beagle_twl_gpio_setup(struct device *dev,
|
||||||
mmc[0].gpio_cd = gpio + 0;
|
mmc[0].gpio_cd = gpio + 0;
|
||||||
twl4030_mmc_init(mmc);
|
twl4030_mmc_init(mmc);
|
||||||
|
|
||||||
|
/* link regulators to MMC adapters */
|
||||||
|
beagle_vmmc1_supply.dev = mmc[0].dev;
|
||||||
|
beagle_vsim_supply.dev = mmc[0].dev;
|
||||||
|
|
||||||
/* REVISIT: need ehci-omap hooks for external VBUS
|
/* REVISIT: need ehci-omap hooks for external VBUS
|
||||||
* power switch and overcurrent detect
|
* power switch and overcurrent detect
|
||||||
*/
|
*/
|
||||||
|
@ -158,12 +180,85 @@ static struct twl4030_gpio_platform_data beagle_gpio_data = {
|
||||||
.setup = beagle_twl_gpio_setup,
|
.setup = beagle_twl_gpio_setup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply beagle_vdac_supply = {
|
||||||
|
.supply = "vdac",
|
||||||
|
.dev = &omap3_beagle_lcd_device.dev,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply beagle_vdvi_supply = {
|
||||||
|
.supply = "vdvi",
|
||||||
|
.dev = &omap3_beagle_lcd_device.dev,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
|
||||||
|
static struct regulator_init_data beagle_vmmc1 = {
|
||||||
|
.constraints = {
|
||||||
|
.min_uV = 1850000,
|
||||||
|
.max_uV = 3150000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
||||||
|
| REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &beagle_vmmc1_supply,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* VSIM for MMC1 pins DAT4..DAT7 (2 mA, plus card == max 50 mA) */
|
||||||
|
static struct regulator_init_data beagle_vsim = {
|
||||||
|
.constraints = {
|
||||||
|
.min_uV = 1800000,
|
||||||
|
.max_uV = 3000000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
||||||
|
| REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &beagle_vsim_supply,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* VDAC for DSS driving S-Video (8 mA unloaded, max 65 mA) */
|
||||||
|
static struct regulator_init_data beagle_vdac = {
|
||||||
|
.constraints = {
|
||||||
|
.min_uV = 1800000,
|
||||||
|
.max_uV = 1800000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &beagle_vdac_supply,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* VPLL2 for digital video outputs */
|
||||||
|
static struct regulator_init_data beagle_vpll2 = {
|
||||||
|
.constraints = {
|
||||||
|
.name = "VDVI",
|
||||||
|
.min_uV = 1800000,
|
||||||
|
.max_uV = 1800000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &beagle_vdvi_supply,
|
||||||
|
};
|
||||||
|
|
||||||
static struct twl4030_platform_data beagle_twldata = {
|
static struct twl4030_platform_data beagle_twldata = {
|
||||||
.irq_base = TWL4030_IRQ_BASE,
|
.irq_base = TWL4030_IRQ_BASE,
|
||||||
.irq_end = TWL4030_IRQ_END,
|
.irq_end = TWL4030_IRQ_END,
|
||||||
|
|
||||||
/* platform_data for children goes here */
|
/* platform_data for children goes here */
|
||||||
.gpio = &beagle_gpio_data,
|
.gpio = &beagle_gpio_data,
|
||||||
|
.vmmc1 = &beagle_vmmc1,
|
||||||
|
.vsim = &beagle_vsim,
|
||||||
|
.vdac = &beagle_vdac,
|
||||||
|
.vpll2 = &beagle_vpll2,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
|
static struct i2c_board_info __initdata beagle_i2c_boardinfo[] = {
|
||||||
|
@ -195,15 +290,6 @@ static void __init omap3_beagle_init_irq(void)
|
||||||
omap_gpio_init();
|
omap_gpio_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_device omap3_beagle_lcd_device = {
|
|
||||||
.name = "omap3beagle_lcd",
|
|
||||||
.id = -1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct omap_lcd_config omap3_beagle_lcd_config __initdata = {
|
|
||||||
.ctrl_name = "internal",
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct gpio_led gpio_leds[] = {
|
static struct gpio_led gpio_leds[] = {
|
||||||
{
|
{
|
||||||
.name = "beagleboard::usr0",
|
.name = "beagleboard::usr0",
|
||||||
|
|
329
arch/arm/mach-omap2/board-omap3evm.c
Normal file
329
arch/arm/mach-omap2/board-omap3evm.c
Normal file
|
@ -0,0 +1,329 @@
|
||||||
|
/*
|
||||||
|
* linux/arch/arm/mach-omap2/board-omap3evm.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2008 Texas Instruments
|
||||||
|
*
|
||||||
|
* Modified from mach-omap2/board-3430sdp.c
|
||||||
|
*
|
||||||
|
* Initial code: Syed Mohammed Khasim
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/clk.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
|
||||||
|
#include <linux/spi/spi.h>
|
||||||
|
#include <linux/spi/ads7846.h>
|
||||||
|
#include <linux/i2c/twl4030.h>
|
||||||
|
|
||||||
|
#include <mach/hardware.h>
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
#include <asm/mach/map.h>
|
||||||
|
|
||||||
|
#include <mach/board.h>
|
||||||
|
#include <mach/mux.h>
|
||||||
|
#include <mach/usb.h>
|
||||||
|
#include <mach/common.h>
|
||||||
|
#include <mach/mcspi.h>
|
||||||
|
#include <mach/keypad.h>
|
||||||
|
|
||||||
|
#include "sdram-micron-mt46h32m32lf-6.h"
|
||||||
|
#include "mmc-twl4030.h"
|
||||||
|
|
||||||
|
#define OMAP3_EVM_TS_GPIO 175
|
||||||
|
|
||||||
|
#define OMAP3EVM_ETHR_START 0x2c000000
|
||||||
|
#define OMAP3EVM_ETHR_SIZE 1024
|
||||||
|
#define OMAP3EVM_ETHR_GPIO_IRQ 176
|
||||||
|
#define OMAP3EVM_SMC911X_CS 5
|
||||||
|
|
||||||
|
static struct resource omap3evm_smc911x_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = OMAP3EVM_ETHR_START,
|
||||||
|
.end = (OMAP3EVM_ETHR_START + OMAP3EVM_ETHR_SIZE - 1),
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.start = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
|
||||||
|
.end = OMAP_GPIO_IRQ(OMAP3EVM_ETHR_GPIO_IRQ),
|
||||||
|
.flags = IORESOURCE_IRQ,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device omap3evm_smc911x_device = {
|
||||||
|
.name = "smc911x",
|
||||||
|
.id = -1,
|
||||||
|
.num_resources = ARRAY_SIZE(omap3evm_smc911x_resources),
|
||||||
|
.resource = &omap3evm_smc911x_resources[0],
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void __init omap3evm_init_smc911x(void)
|
||||||
|
{
|
||||||
|
int eth_cs;
|
||||||
|
struct clk *l3ck;
|
||||||
|
unsigned int rate;
|
||||||
|
|
||||||
|
eth_cs = OMAP3EVM_SMC911X_CS;
|
||||||
|
|
||||||
|
l3ck = clk_get(NULL, "l3_ck");
|
||||||
|
if (IS_ERR(l3ck))
|
||||||
|
rate = 100000000;
|
||||||
|
else
|
||||||
|
rate = clk_get_rate(l3ck);
|
||||||
|
|
||||||
|
if (gpio_request(OMAP3EVM_ETHR_GPIO_IRQ, "SMC911x irq") < 0) {
|
||||||
|
printk(KERN_ERR "Failed to request GPIO%d for smc911x IRQ\n",
|
||||||
|
OMAP3EVM_ETHR_GPIO_IRQ);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
gpio_direction_input(OMAP3EVM_ETHR_GPIO_IRQ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct omap_uart_config omap3_evm_uart_config __initdata = {
|
||||||
|
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_hsmmc_info mmc[] = {
|
||||||
|
{
|
||||||
|
.mmc = 1,
|
||||||
|
.wires = 4,
|
||||||
|
.gpio_cd = -EINVAL,
|
||||||
|
.gpio_wp = 63,
|
||||||
|
},
|
||||||
|
{} /* Terminator */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpio_led gpio_leds[] = {
|
||||||
|
{
|
||||||
|
.name = "omap3evm::ledb",
|
||||||
|
/* normally not visible (board underside) */
|
||||||
|
.default_trigger = "default-on",
|
||||||
|
.gpio = -EINVAL, /* gets replaced */
|
||||||
|
.active_low = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpio_led_platform_data gpio_led_info = {
|
||||||
|
.leds = gpio_leds,
|
||||||
|
.num_leds = ARRAY_SIZE(gpio_leds),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device leds_gpio = {
|
||||||
|
.name = "leds-gpio",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &gpio_led_info,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int omap3evm_twl_gpio_setup(struct device *dev,
|
||||||
|
unsigned gpio, unsigned ngpio)
|
||||||
|
{
|
||||||
|
/* gpio + 0 is "mmc0_cd" (input/IRQ) */
|
||||||
|
omap_cfg_reg(L8_34XX_GPIO63);
|
||||||
|
mmc[0].gpio_cd = gpio + 0;
|
||||||
|
twl4030_mmc_init(mmc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Most GPIOs are for USB OTG. Some are mostly sent to
|
||||||
|
* the P2 connector; notably LEDA for the LCD backlight.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */
|
||||||
|
gpio_leds[2].gpio = gpio + TWL4030_GPIO_MAX + 1;
|
||||||
|
|
||||||
|
platform_device_register(&leds_gpio);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct twl4030_gpio_platform_data omap3evm_gpio_data = {
|
||||||
|
.gpio_base = OMAP_MAX_GPIO_LINES,
|
||||||
|
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
||||||
|
.irq_end = TWL4030_GPIO_IRQ_END,
|
||||||
|
.use_leds = true,
|
||||||
|
.setup = omap3evm_twl_gpio_setup,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_usb_data omap3evm_usb_data = {
|
||||||
|
.usb_mode = T2_USB_MODE_ULPI,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int omap3evm_keymap[] = {
|
||||||
|
KEY(0, 0, KEY_LEFT),
|
||||||
|
KEY(0, 1, KEY_RIGHT),
|
||||||
|
KEY(0, 2, KEY_A),
|
||||||
|
KEY(0, 3, KEY_B),
|
||||||
|
KEY(1, 0, KEY_DOWN),
|
||||||
|
KEY(1, 1, KEY_UP),
|
||||||
|
KEY(1, 2, KEY_E),
|
||||||
|
KEY(1, 3, KEY_F),
|
||||||
|
KEY(2, 0, KEY_ENTER),
|
||||||
|
KEY(2, 1, KEY_I),
|
||||||
|
KEY(2, 2, KEY_J),
|
||||||
|
KEY(2, 3, KEY_K),
|
||||||
|
KEY(3, 0, KEY_M),
|
||||||
|
KEY(3, 1, KEY_N),
|
||||||
|
KEY(3, 2, KEY_O),
|
||||||
|
KEY(3, 3, KEY_P)
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_keypad_data omap3evm_kp_data = {
|
||||||
|
.rows = 4,
|
||||||
|
.cols = 4,
|
||||||
|
.keymap = omap3evm_keymap,
|
||||||
|
.keymapsize = ARRAY_SIZE(omap3evm_keymap),
|
||||||
|
.rep = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_madc_platform_data omap3evm_madc_data = {
|
||||||
|
.irq_line = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_platform_data omap3evm_twldata = {
|
||||||
|
.irq_base = TWL4030_IRQ_BASE,
|
||||||
|
.irq_end = TWL4030_IRQ_END,
|
||||||
|
|
||||||
|
/* platform_data for children goes here */
|
||||||
|
.keypad = &omap3evm_kp_data,
|
||||||
|
.madc = &omap3evm_madc_data,
|
||||||
|
.usb = &omap3evm_usb_data,
|
||||||
|
.gpio = &omap3evm_gpio_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata omap3evm_i2c_boardinfo[] = {
|
||||||
|
{
|
||||||
|
I2C_BOARD_INFO("twl4030", 0x48),
|
||||||
|
.flags = I2C_CLIENT_WAKE,
|
||||||
|
.irq = INT_34XX_SYS_NIRQ,
|
||||||
|
.platform_data = &omap3evm_twldata,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init omap3_evm_i2c_init(void)
|
||||||
|
{
|
||||||
|
omap_register_i2c_bus(1, 2600, omap3evm_i2c_boardinfo,
|
||||||
|
ARRAY_SIZE(omap3evm_i2c_boardinfo));
|
||||||
|
omap_register_i2c_bus(2, 400, NULL, 0);
|
||||||
|
omap_register_i2c_bus(3, 400, NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_device omap3_evm_lcd_device = {
|
||||||
|
.name = "omap3evm_lcd",
|
||||||
|
.id = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
|
||||||
|
.ctrl_name = "internal",
|
||||||
|
};
|
||||||
|
|
||||||
|
static void ads7846_dev_init(void)
|
||||||
|
{
|
||||||
|
if (gpio_request(OMAP3_EVM_TS_GPIO, "ADS7846 pendown") < 0)
|
||||||
|
printk(KERN_ERR "can't get ads7846 pen down GPIO\n");
|
||||||
|
|
||||||
|
gpio_direction_input(OMAP3_EVM_TS_GPIO);
|
||||||
|
|
||||||
|
omap_set_gpio_debounce(OMAP3_EVM_TS_GPIO, 1);
|
||||||
|
omap_set_gpio_debounce_time(OMAP3_EVM_TS_GPIO, 0xa);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ads7846_get_pendown_state(void)
|
||||||
|
{
|
||||||
|
return !gpio_get_value(OMAP3_EVM_TS_GPIO);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ads7846_platform_data ads7846_config = {
|
||||||
|
.x_max = 0x0fff,
|
||||||
|
.y_max = 0x0fff,
|
||||||
|
.x_plate_ohms = 180,
|
||||||
|
.pressure_max = 255,
|
||||||
|
.debounce_max = 10,
|
||||||
|
.debounce_tol = 3,
|
||||||
|
.debounce_rep = 1,
|
||||||
|
.get_pendown_state = ads7846_get_pendown_state,
|
||||||
|
.keep_vref_on = 1,
|
||||||
|
.settle_delay_usecs = 150,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct omap2_mcspi_device_config ads7846_mcspi_config = {
|
||||||
|
.turbo_mode = 0,
|
||||||
|
.single_channel = 1, /* 0: slave, 1: master */
|
||||||
|
};
|
||||||
|
|
||||||
|
struct spi_board_info omap3evm_spi_board_info[] = {
|
||||||
|
[0] = {
|
||||||
|
.modalias = "ads7846",
|
||||||
|
.bus_num = 1,
|
||||||
|
.chip_select = 0,
|
||||||
|
.max_speed_hz = 1500000,
|
||||||
|
.controller_data = &ads7846_mcspi_config,
|
||||||
|
.irq = OMAP_GPIO_IRQ(OMAP3_EVM_TS_GPIO),
|
||||||
|
.platform_data = &ads7846_config,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init omap3_evm_init_irq(void)
|
||||||
|
{
|
||||||
|
omap2_init_common_hw(mt46h32m32lf6_sdrc_params);
|
||||||
|
omap_init_irq();
|
||||||
|
omap_gpio_init();
|
||||||
|
omap3evm_init_smc911x();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
|
||||||
|
{ OMAP_TAG_UART, &omap3_evm_uart_config },
|
||||||
|
{ OMAP_TAG_LCD, &omap3_evm_lcd_config },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device *omap3_evm_devices[] __initdata = {
|
||||||
|
&omap3_evm_lcd_device,
|
||||||
|
&omap3evm_smc911x_device,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init omap3_evm_init(void)
|
||||||
|
{
|
||||||
|
omap3_evm_i2c_init();
|
||||||
|
|
||||||
|
platform_add_devices(omap3_evm_devices, ARRAY_SIZE(omap3_evm_devices));
|
||||||
|
omap_board_config = omap3_evm_config;
|
||||||
|
omap_board_config_size = ARRAY_SIZE(omap3_evm_config);
|
||||||
|
|
||||||
|
spi_register_board_info(omap3evm_spi_board_info,
|
||||||
|
ARRAY_SIZE(omap3evm_spi_board_info));
|
||||||
|
|
||||||
|
omap_serial_init();
|
||||||
|
usb_musb_init();
|
||||||
|
ads7846_dev_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init omap3_evm_map_io(void)
|
||||||
|
{
|
||||||
|
omap2_set_globals_343x();
|
||||||
|
omap2_map_common_io();
|
||||||
|
}
|
||||||
|
|
||||||
|
MACHINE_START(OMAP3EVM, "OMAP3 EVM")
|
||||||
|
/* Maintainer: Syed Mohammed Khasim - Texas Instruments */
|
||||||
|
.phys_io = 0x48000000,
|
||||||
|
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||||
|
.boot_params = 0x80000100,
|
||||||
|
.map_io = omap3_evm_map_io,
|
||||||
|
.init_irq = omap3_evm_init_irq,
|
||||||
|
.init_machine = omap3_evm_init,
|
||||||
|
.timer = &omap_timer,
|
||||||
|
MACHINE_END
|
|
@ -23,7 +23,11 @@
|
||||||
|
|
||||||
#include <linux/spi/spi.h>
|
#include <linux/spi/spi.h>
|
||||||
#include <linux/spi/ads7846.h>
|
#include <linux/spi/ads7846.h>
|
||||||
|
#include <linux/regulator/machine.h>
|
||||||
#include <linux/i2c/twl4030.h>
|
#include <linux/i2c/twl4030.h>
|
||||||
|
#include <linux/leds.h>
|
||||||
|
#include <linux/input.h>
|
||||||
|
#include <linux/gpio_keys.h>
|
||||||
|
|
||||||
#include <asm/mach-types.h>
|
#include <asm/mach-types.h>
|
||||||
#include <asm/mach/arch.h>
|
#include <asm/mach/arch.h>
|
||||||
|
@ -35,12 +39,154 @@
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/mcspi.h>
|
#include <mach/mcspi.h>
|
||||||
#include <mach/usb.h>
|
#include <mach/usb.h>
|
||||||
|
#include <mach/keypad.h>
|
||||||
|
|
||||||
#include "sdram-micron-mt46h32m32lf-6.h"
|
#include "sdram-micron-mt46h32m32lf-6.h"
|
||||||
#include "mmc-twl4030.h"
|
#include "mmc-twl4030.h"
|
||||||
|
|
||||||
#define OMAP3_PANDORA_TS_GPIO 94
|
#define OMAP3_PANDORA_TS_GPIO 94
|
||||||
|
|
||||||
|
/* hardware debounce: (value + 1) * 31us */
|
||||||
|
#define GPIO_DEBOUNCE_TIME 127
|
||||||
|
|
||||||
|
static struct gpio_led pandora_gpio_leds[] = {
|
||||||
|
{
|
||||||
|
.name = "pandora::sd1",
|
||||||
|
.default_trigger = "mmc0",
|
||||||
|
.gpio = 128,
|
||||||
|
}, {
|
||||||
|
.name = "pandora::sd2",
|
||||||
|
.default_trigger = "mmc1",
|
||||||
|
.gpio = 129,
|
||||||
|
}, {
|
||||||
|
.name = "pandora::bluetooth",
|
||||||
|
.gpio = 158,
|
||||||
|
}, {
|
||||||
|
.name = "pandora::wifi",
|
||||||
|
.gpio = 159,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpio_led_platform_data pandora_gpio_led_data = {
|
||||||
|
.leds = pandora_gpio_leds,
|
||||||
|
.num_leds = ARRAY_SIZE(pandora_gpio_leds),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device pandora_leds_gpio = {
|
||||||
|
.name = "leds-gpio",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &pandora_gpio_led_data,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define GPIO_BUTTON(gpio_num, ev_type, ev_code, act_low, descr) \
|
||||||
|
{ \
|
||||||
|
.gpio = gpio_num, \
|
||||||
|
.type = ev_type, \
|
||||||
|
.code = ev_code, \
|
||||||
|
.active_low = act_low, \
|
||||||
|
.desc = "btn " descr, \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GPIO_BUTTON_LOW(gpio_num, event_code, description) \
|
||||||
|
GPIO_BUTTON(gpio_num, EV_KEY, event_code, 1, description)
|
||||||
|
|
||||||
|
static struct gpio_keys_button pandora_gpio_keys[] = {
|
||||||
|
GPIO_BUTTON_LOW(110, KEY_UP, "up"),
|
||||||
|
GPIO_BUTTON_LOW(103, KEY_DOWN, "down"),
|
||||||
|
GPIO_BUTTON_LOW(96, KEY_LEFT, "left"),
|
||||||
|
GPIO_BUTTON_LOW(98, KEY_RIGHT, "right"),
|
||||||
|
GPIO_BUTTON_LOW(111, BTN_A, "a"),
|
||||||
|
GPIO_BUTTON_LOW(106, BTN_B, "b"),
|
||||||
|
GPIO_BUTTON_LOW(109, BTN_X, "x"),
|
||||||
|
GPIO_BUTTON_LOW(101, BTN_Y, "y"),
|
||||||
|
GPIO_BUTTON_LOW(102, BTN_TL, "l"),
|
||||||
|
GPIO_BUTTON_LOW(97, BTN_TL2, "l2"),
|
||||||
|
GPIO_BUTTON_LOW(105, BTN_TR, "r"),
|
||||||
|
GPIO_BUTTON_LOW(107, BTN_TR2, "r2"),
|
||||||
|
GPIO_BUTTON_LOW(104, KEY_LEFTCTRL, "ctrl"),
|
||||||
|
GPIO_BUTTON_LOW(99, KEY_MENU, "menu"),
|
||||||
|
GPIO_BUTTON_LOW(176, KEY_COFFEE, "hold"),
|
||||||
|
GPIO_BUTTON(100, EV_KEY, KEY_LEFTALT, 0, "alt"),
|
||||||
|
GPIO_BUTTON(108, EV_SW, SW_LID, 1, "lid"),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct gpio_keys_platform_data pandora_gpio_key_info = {
|
||||||
|
.buttons = pandora_gpio_keys,
|
||||||
|
.nbuttons = ARRAY_SIZE(pandora_gpio_keys),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device pandora_keys_gpio = {
|
||||||
|
.name = "gpio-keys",
|
||||||
|
.id = -1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &pandora_gpio_key_info,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init pandora_keys_gpio_init(void)
|
||||||
|
{
|
||||||
|
/* set debounce time for GPIO banks 4 and 6 */
|
||||||
|
omap_set_gpio_debounce_time(32 * 3, GPIO_DEBOUNCE_TIME);
|
||||||
|
omap_set_gpio_debounce_time(32 * 5, GPIO_DEBOUNCE_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pandora_keypad_map[] = {
|
||||||
|
/* col, row, code */
|
||||||
|
KEY(0, 0, KEY_9),
|
||||||
|
KEY(0, 1, KEY_0),
|
||||||
|
KEY(0, 2, KEY_BACKSPACE),
|
||||||
|
KEY(0, 3, KEY_O),
|
||||||
|
KEY(0, 4, KEY_P),
|
||||||
|
KEY(0, 5, KEY_K),
|
||||||
|
KEY(0, 6, KEY_L),
|
||||||
|
KEY(0, 7, KEY_ENTER),
|
||||||
|
KEY(1, 0, KEY_8),
|
||||||
|
KEY(1, 1, KEY_7),
|
||||||
|
KEY(1, 2, KEY_6),
|
||||||
|
KEY(1, 3, KEY_5),
|
||||||
|
KEY(1, 4, KEY_4),
|
||||||
|
KEY(1, 5, KEY_3),
|
||||||
|
KEY(1, 6, KEY_2),
|
||||||
|
KEY(1, 7, KEY_1),
|
||||||
|
KEY(2, 0, KEY_I),
|
||||||
|
KEY(2, 1, KEY_U),
|
||||||
|
KEY(2, 2, KEY_Y),
|
||||||
|
KEY(2, 3, KEY_T),
|
||||||
|
KEY(2, 4, KEY_R),
|
||||||
|
KEY(2, 5, KEY_E),
|
||||||
|
KEY(2, 6, KEY_W),
|
||||||
|
KEY(2, 7, KEY_Q),
|
||||||
|
KEY(3, 0, KEY_J),
|
||||||
|
KEY(3, 1, KEY_H),
|
||||||
|
KEY(3, 2, KEY_G),
|
||||||
|
KEY(3, 3, KEY_F),
|
||||||
|
KEY(3, 4, KEY_D),
|
||||||
|
KEY(3, 5, KEY_S),
|
||||||
|
KEY(3, 6, KEY_A),
|
||||||
|
KEY(3, 7, KEY_LEFTSHIFT),
|
||||||
|
KEY(4, 0, KEY_N),
|
||||||
|
KEY(4, 1, KEY_B),
|
||||||
|
KEY(4, 2, KEY_V),
|
||||||
|
KEY(4, 3, KEY_C),
|
||||||
|
KEY(4, 4, KEY_X),
|
||||||
|
KEY(4, 5, KEY_Z),
|
||||||
|
KEY(4, 6, KEY_DOT),
|
||||||
|
KEY(4, 7, KEY_COMMA),
|
||||||
|
KEY(5, 0, KEY_M),
|
||||||
|
KEY(5, 1, KEY_SPACE),
|
||||||
|
KEY(5, 2, KEY_FN),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_keypad_data pandora_kp_data = {
|
||||||
|
.rows = 8,
|
||||||
|
.cols = 6,
|
||||||
|
.keymap = pandora_keypad_map,
|
||||||
|
.keymapsize = ARRAY_SIZE(pandora_keypad_map),
|
||||||
|
.rep = 1,
|
||||||
|
};
|
||||||
|
|
||||||
static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
|
static struct twl4030_hsmmc_info omap3pandora_mmc[] = {
|
||||||
{
|
{
|
||||||
.mmc = 1,
|
.mmc = 1,
|
||||||
|
@ -70,6 +216,14 @@ static struct omap_uart_config omap3pandora_uart_config __initdata = {
|
||||||
.enabled_uarts = (1 << 2), /* UART3 */
|
.enabled_uarts = (1 << 2), /* UART3 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply pandora_vmmc1_supply = {
|
||||||
|
.supply = "vmmc",
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply pandora_vmmc2_supply = {
|
||||||
|
.supply = "vmmc",
|
||||||
|
};
|
||||||
|
|
||||||
static int omap3pandora_twl_gpio_setup(struct device *dev,
|
static int omap3pandora_twl_gpio_setup(struct device *dev,
|
||||||
unsigned gpio, unsigned ngpio)
|
unsigned gpio, unsigned ngpio)
|
||||||
{
|
{
|
||||||
|
@ -78,6 +232,10 @@ static int omap3pandora_twl_gpio_setup(struct device *dev,
|
||||||
omap3pandora_mmc[1].gpio_cd = gpio + 1;
|
omap3pandora_mmc[1].gpio_cd = gpio + 1;
|
||||||
twl4030_mmc_init(omap3pandora_mmc);
|
twl4030_mmc_init(omap3pandora_mmc);
|
||||||
|
|
||||||
|
/* link regulators to MMC adapters */
|
||||||
|
pandora_vmmc1_supply.dev = omap3pandora_mmc[0].dev;
|
||||||
|
pandora_vmmc2_supply.dev = omap3pandora_mmc[1].dev;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +246,36 @@ static struct twl4030_gpio_platform_data omap3pandora_gpio_data = {
|
||||||
.setup = omap3pandora_twl_gpio_setup,
|
.setup = omap3pandora_twl_gpio_setup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
|
||||||
|
static struct regulator_init_data pandora_vmmc1 = {
|
||||||
|
.constraints = {
|
||||||
|
.min_uV = 1850000,
|
||||||
|
.max_uV = 3150000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
||||||
|
| REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &pandora_vmmc1_supply,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* VMMC2 for MMC2 pins CMD, CLK, DAT0..DAT3 (max 100 mA) */
|
||||||
|
static struct regulator_init_data pandora_vmmc2 = {
|
||||||
|
.constraints = {
|
||||||
|
.min_uV = 1850000,
|
||||||
|
.max_uV = 3150000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
||||||
|
| REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &pandora_vmmc2_supply,
|
||||||
|
};
|
||||||
|
|
||||||
static struct twl4030_usb_data omap3pandora_usb_data = {
|
static struct twl4030_usb_data omap3pandora_usb_data = {
|
||||||
.usb_mode = T2_USB_MODE_ULPI,
|
.usb_mode = T2_USB_MODE_ULPI,
|
||||||
};
|
};
|
||||||
|
@ -97,6 +285,9 @@ static struct twl4030_platform_data omap3pandora_twldata = {
|
||||||
.irq_end = TWL4030_IRQ_END,
|
.irq_end = TWL4030_IRQ_END,
|
||||||
.gpio = &omap3pandora_gpio_data,
|
.gpio = &omap3pandora_gpio_data,
|
||||||
.usb = &omap3pandora_usb_data,
|
.usb = &omap3pandora_usb_data,
|
||||||
|
.vmmc1 = &pandora_vmmc1,
|
||||||
|
.vmmc2 = &pandora_vmmc2,
|
||||||
|
.keypad = &pandora_kp_data,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
|
static struct i2c_board_info __initdata omap3pandora_i2c_boardinfo[] = {
|
||||||
|
@ -189,6 +380,8 @@ static struct omap_board_config_kernel omap3pandora_config[] __initdata = {
|
||||||
|
|
||||||
static struct platform_device *omap3pandora_devices[] __initdata = {
|
static struct platform_device *omap3pandora_devices[] __initdata = {
|
||||||
&omap3pandora_lcd_device,
|
&omap3pandora_lcd_device,
|
||||||
|
&pandora_leds_gpio,
|
||||||
|
&pandora_keys_gpio,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __init omap3pandora_init(void)
|
static void __init omap3pandora_init(void)
|
||||||
|
@ -202,6 +395,7 @@ static void __init omap3pandora_init(void)
|
||||||
spi_register_board_info(omap3pandora_spi_board_info,
|
spi_register_board_info(omap3pandora_spi_board_info,
|
||||||
ARRAY_SIZE(omap3pandora_spi_board_info));
|
ARRAY_SIZE(omap3pandora_spi_board_info));
|
||||||
omap3pandora_ads7846_init();
|
omap3pandora_ads7846_init();
|
||||||
|
pandora_keys_gpio_init();
|
||||||
usb_musb_init();
|
usb_musb_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/i2c/twl4030.h>
|
#include <linux/i2c/twl4030.h>
|
||||||
|
#include <linux/regulator/machine.h>
|
||||||
|
|
||||||
#include <linux/mtd/mtd.h>
|
#include <linux/mtd/mtd.h>
|
||||||
#include <linux/mtd/nand.h>
|
#include <linux/mtd/nand.h>
|
||||||
|
@ -272,21 +273,76 @@ static struct omap_uart_config overo_uart_config __initdata = {
|
||||||
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct twl4030_hsmmc_info mmc[] = {
|
||||||
|
{
|
||||||
|
.mmc = 1,
|
||||||
|
.wires = 4,
|
||||||
|
.gpio_cd = -EINVAL,
|
||||||
|
.gpio_wp = -EINVAL,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.mmc = 2,
|
||||||
|
.wires = 4,
|
||||||
|
.gpio_cd = -EINVAL,
|
||||||
|
.gpio_wp = -EINVAL,
|
||||||
|
.transceiver = true,
|
||||||
|
.ocr_mask = 0x00100000, /* 3.3V */
|
||||||
|
},
|
||||||
|
{} /* Terminator */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_consumer_supply overo_vmmc1_supply = {
|
||||||
|
.supply = "vmmc",
|
||||||
|
};
|
||||||
|
|
||||||
|
static int overo_twl_gpio_setup(struct device *dev,
|
||||||
|
unsigned gpio, unsigned ngpio)
|
||||||
|
{
|
||||||
|
twl4030_mmc_init(mmc);
|
||||||
|
|
||||||
|
overo_vmmc1_supply.dev = mmc[0].dev;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct twl4030_gpio_platform_data overo_gpio_data = {
|
static struct twl4030_gpio_platform_data overo_gpio_data = {
|
||||||
.gpio_base = OMAP_MAX_GPIO_LINES,
|
.gpio_base = OMAP_MAX_GPIO_LINES,
|
||||||
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
||||||
.irq_end = TWL4030_GPIO_IRQ_END,
|
.irq_end = TWL4030_GPIO_IRQ_END,
|
||||||
|
.setup = overo_twl_gpio_setup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct twl4030_usb_data overo_usb_data = {
|
||||||
|
.usb_mode = T2_USB_MODE_ULPI,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct regulator_init_data overo_vmmc1 = {
|
||||||
|
.constraints = {
|
||||||
|
.min_uV = 1850000,
|
||||||
|
.max_uV = 3150000,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
||||||
|
| REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &overo_vmmc1_supply,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* mmc2 (WLAN) and Bluetooth don't use twl4030 regulators */
|
||||||
|
|
||||||
static struct twl4030_platform_data overo_twldata = {
|
static struct twl4030_platform_data overo_twldata = {
|
||||||
.irq_base = TWL4030_IRQ_BASE,
|
.irq_base = TWL4030_IRQ_BASE,
|
||||||
.irq_end = TWL4030_IRQ_END,
|
.irq_end = TWL4030_IRQ_END,
|
||||||
.gpio = &overo_gpio_data,
|
.gpio = &overo_gpio_data,
|
||||||
|
.usb = &overo_usb_data,
|
||||||
|
.vmmc1 = &overo_vmmc1,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
|
static struct i2c_board_info __initdata overo_i2c_boardinfo[] = {
|
||||||
{
|
{
|
||||||
I2C_BOARD_INFO("twl4030", 0x48),
|
I2C_BOARD_INFO("tps65950", 0x48),
|
||||||
.flags = I2C_CLIENT_WAKE,
|
.flags = I2C_CLIENT_WAKE,
|
||||||
.irq = INT_34XX_SYS_NIRQ,
|
.irq = INT_34XX_SYS_NIRQ,
|
||||||
.platform_data = &overo_twldata,
|
.platform_data = &overo_twldata,
|
||||||
|
@ -327,23 +383,6 @@ static struct platform_device *overo_devices[] __initdata = {
|
||||||
&overo_lcd_device,
|
&overo_lcd_device,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct twl4030_hsmmc_info mmc[] __initdata = {
|
|
||||||
{
|
|
||||||
.mmc = 1,
|
|
||||||
.wires = 4,
|
|
||||||
.gpio_cd = -EINVAL,
|
|
||||||
.gpio_wp = -EINVAL,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
.mmc = 2,
|
|
||||||
.wires = 4,
|
|
||||||
.gpio_cd = -EINVAL,
|
|
||||||
.gpio_wp = -EINVAL,
|
|
||||||
.transceiver = true,
|
|
||||||
},
|
|
||||||
{} /* Terminator */
|
|
||||||
};
|
|
||||||
|
|
||||||
static void __init overo_init(void)
|
static void __init overo_init(void)
|
||||||
{
|
{
|
||||||
overo_i2c_init();
|
overo_i2c_init();
|
||||||
|
@ -351,7 +390,6 @@ static void __init overo_init(void)
|
||||||
omap_board_config = overo_config;
|
omap_board_config = overo_config;
|
||||||
omap_board_config_size = ARRAY_SIZE(overo_config);
|
omap_board_config_size = ARRAY_SIZE(overo_config);
|
||||||
omap_serial_init();
|
omap_serial_init();
|
||||||
twl4030_mmc_init(mmc);
|
|
||||||
overo_flash_init();
|
overo_flash_init();
|
||||||
usb_musb_init();
|
usb_musb_init();
|
||||||
overo_ads7846_init();
|
overo_ads7846_init();
|
||||||
|
|
|
@ -32,6 +32,9 @@
|
||||||
|
|
||||||
#include "mmc-twl4030.h"
|
#include "mmc-twl4030.h"
|
||||||
|
|
||||||
|
#define SYSTEM_REV_B_USES_VAUX3 0x1699
|
||||||
|
#define SYSTEM_REV_S_USES_VAUX3 0x8
|
||||||
|
|
||||||
static int rx51_keymap[] = {
|
static int rx51_keymap[] = {
|
||||||
KEY(0, 0, KEY_Q),
|
KEY(0, 0, KEY_Q),
|
||||||
KEY(0, 1, KEY_W),
|
KEY(0, 1, KEY_W),
|
||||||
|
@ -147,7 +150,7 @@ static struct regulator_init_data rx51_vaux2 = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* VAUX3 - adds more power to VIO_18 rail */
|
/* VAUX3 - adds more power to VIO_18 rail */
|
||||||
static struct regulator_init_data rx51_vaux3 = {
|
static struct regulator_init_data rx51_vaux3_cam = {
|
||||||
.constraints = {
|
.constraints = {
|
||||||
.name = "VCAM_DIG_18",
|
.name = "VCAM_DIG_18",
|
||||||
.min_uV = 1800000,
|
.min_uV = 1800000,
|
||||||
|
@ -160,6 +163,22 @@ static struct regulator_init_data rx51_vaux3 = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct regulator_init_data rx51_vaux3_mmc = {
|
||||||
|
.constraints = {
|
||||||
|
.name = "VMMC2_30",
|
||||||
|
.min_uV = 2800000,
|
||||||
|
.max_uV = 3000000,
|
||||||
|
.apply_uV = true,
|
||||||
|
.valid_modes_mask = REGULATOR_MODE_NORMAL
|
||||||
|
| REGULATOR_MODE_STANDBY,
|
||||||
|
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
|
||||||
|
| REGULATOR_CHANGE_MODE
|
||||||
|
| REGULATOR_CHANGE_STATUS,
|
||||||
|
},
|
||||||
|
.num_consumer_supplies = 1,
|
||||||
|
.consumer_supplies = &rx51_vmmc2_supply,
|
||||||
|
};
|
||||||
|
|
||||||
static struct regulator_init_data rx51_vaux4 = {
|
static struct regulator_init_data rx51_vaux4 = {
|
||||||
.constraints = {
|
.constraints = {
|
||||||
.name = "VCAM_ANA_28",
|
.name = "VCAM_ANA_28",
|
||||||
|
@ -270,10 +289,8 @@ static struct twl4030_platform_data rx51_twldata = {
|
||||||
|
|
||||||
.vaux1 = &rx51_vaux1,
|
.vaux1 = &rx51_vaux1,
|
||||||
.vaux2 = &rx51_vaux2,
|
.vaux2 = &rx51_vaux2,
|
||||||
.vaux3 = &rx51_vaux3,
|
|
||||||
.vaux4 = &rx51_vaux4,
|
.vaux4 = &rx51_vaux4,
|
||||||
.vmmc1 = &rx51_vmmc1,
|
.vmmc1 = &rx51_vmmc1,
|
||||||
.vmmc2 = &rx51_vmmc2,
|
|
||||||
.vsim = &rx51_vsim,
|
.vsim = &rx51_vsim,
|
||||||
.vdac = &rx51_vdac,
|
.vdac = &rx51_vdac,
|
||||||
};
|
};
|
||||||
|
@ -289,6 +306,13 @@ static struct i2c_board_info __initdata rx51_peripherals_i2c_board_info_1[] = {
|
||||||
|
|
||||||
static int __init rx51_i2c_init(void)
|
static int __init rx51_i2c_init(void)
|
||||||
{
|
{
|
||||||
|
if ((system_rev >= SYSTEM_REV_S_USES_VAUX3 && system_rev < 0x100) ||
|
||||||
|
system_rev >= SYSTEM_REV_B_USES_VAUX3)
|
||||||
|
rx51_twldata.vaux3 = &rx51_vaux3_mmc;
|
||||||
|
else {
|
||||||
|
rx51_twldata.vaux3 = &rx51_vaux3_cam;
|
||||||
|
rx51_twldata.vmmc2 = &rx51_vmmc2;
|
||||||
|
}
|
||||||
omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
|
omap_register_i2c_bus(1, 2600, rx51_peripherals_i2c_board_info_1,
|
||||||
ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
|
ARRAY_SIZE(rx51_peripherals_i2c_board_info_1));
|
||||||
omap_register_i2c_bus(2, 100, NULL, 0);
|
omap_register_i2c_bus(2, 100, NULL, 0);
|
||||||
|
|
160
arch/arm/mach-omap2/board-zoom-debugboard.c
Normal file
160
arch/arm/mach-omap2/board-zoom-debugboard.c
Normal file
|
@ -0,0 +1,160 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 Texas Instruments Inc.
|
||||||
|
* Mikkel Christensen <mlc@ti.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/serial_8250.h>
|
||||||
|
#include <linux/smsc911x.h>
|
||||||
|
|
||||||
|
#include <mach/gpmc.h>
|
||||||
|
|
||||||
|
#define ZOOM2_SMSC911X_CS 7
|
||||||
|
#define ZOOM2_SMSC911X_GPIO 158
|
||||||
|
#define ZOOM2_QUADUART_CS 3
|
||||||
|
#define ZOOM2_QUADUART_GPIO 102
|
||||||
|
#define QUART_CLK 1843200
|
||||||
|
#define DEBUG_BASE 0x08000000
|
||||||
|
#define ZOOM2_ETHR_START DEBUG_BASE
|
||||||
|
|
||||||
|
static struct resource zoom2_smsc911x_resources[] = {
|
||||||
|
[0] = {
|
||||||
|
.start = ZOOM2_ETHR_START,
|
||||||
|
.end = ZOOM2_ETHR_START + SZ_4K,
|
||||||
|
.flags = IORESOURCE_MEM,
|
||||||
|
},
|
||||||
|
[1] = {
|
||||||
|
.flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct smsc911x_platform_config zoom2_smsc911x_config = {
|
||||||
|
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
|
||||||
|
.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
|
||||||
|
.flags = SMSC911X_USE_32BIT,
|
||||||
|
.phy_interface = PHY_INTERFACE_MODE_MII,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device zoom2_smsc911x_device = {
|
||||||
|
.name = "smsc911x",
|
||||||
|
.id = -1,
|
||||||
|
.num_resources = ARRAY_SIZE(zoom2_smsc911x_resources),
|
||||||
|
.resource = zoom2_smsc911x_resources,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = &zoom2_smsc911x_config,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void __init zoom2_init_smsc911x(void)
|
||||||
|
{
|
||||||
|
int eth_cs;
|
||||||
|
unsigned long cs_mem_base;
|
||||||
|
int eth_gpio = 0;
|
||||||
|
|
||||||
|
eth_cs = ZOOM2_SMSC911X_CS;
|
||||||
|
|
||||||
|
if (gpmc_cs_request(eth_cs, SZ_16M, &cs_mem_base) < 0) {
|
||||||
|
printk(KERN_ERR "Failed to request GPMC mem for smsc911x\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
zoom2_smsc911x_resources[0].start = cs_mem_base + 0x0;
|
||||||
|
zoom2_smsc911x_resources[0].end = cs_mem_base + 0xff;
|
||||||
|
|
||||||
|
eth_gpio = ZOOM2_SMSC911X_GPIO;
|
||||||
|
|
||||||
|
zoom2_smsc911x_resources[1].start = OMAP_GPIO_IRQ(eth_gpio);
|
||||||
|
|
||||||
|
if (gpio_request(eth_gpio, "smsc911x irq") < 0) {
|
||||||
|
printk(KERN_ERR "Failed to request GPIO%d for smsc911x IRQ\n",
|
||||||
|
eth_gpio);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpio_direction_input(eth_gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct plat_serial8250_port serial_platform_data[] = {
|
||||||
|
{
|
||||||
|
.mapbase = 0x10000000,
|
||||||
|
.irq = OMAP_GPIO_IRQ(102),
|
||||||
|
.flags = UPF_BOOT_AUTOCONF|UPF_IOREMAP|UPF_SHARE_IRQ,
|
||||||
|
.iotype = UPIO_MEM,
|
||||||
|
.regshift = 1,
|
||||||
|
.uartclk = QUART_CLK,
|
||||||
|
}, {
|
||||||
|
.flags = 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct platform_device zoom2_debugboard_serial_device = {
|
||||||
|
.name = "serial8250",
|
||||||
|
.id = PLAT8250_DEV_PLATFORM1,
|
||||||
|
.dev = {
|
||||||
|
.platform_data = serial_platform_data,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline void __init zoom2_init_quaduart(void)
|
||||||
|
{
|
||||||
|
int quart_cs;
|
||||||
|
unsigned long cs_mem_base;
|
||||||
|
int quart_gpio = 0;
|
||||||
|
|
||||||
|
quart_cs = ZOOM2_QUADUART_CS;
|
||||||
|
|
||||||
|
if (gpmc_cs_request(quart_cs, SZ_1M, &cs_mem_base) < 0) {
|
||||||
|
printk(KERN_ERR "Failed to request GPMC mem"
|
||||||
|
"for Quad UART(TL16CP754C)\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
quart_gpio = ZOOM2_QUADUART_GPIO;
|
||||||
|
|
||||||
|
if (gpio_request(quart_gpio, "TL16CP754C GPIO") < 0) {
|
||||||
|
printk(KERN_ERR "Failed to request GPIO%d for TL16CP754C\n",
|
||||||
|
quart_gpio);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
gpio_direction_input(quart_gpio);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int omap_zoom2_debugboard_detect(void)
|
||||||
|
{
|
||||||
|
int debug_board_detect = 0;
|
||||||
|
|
||||||
|
debug_board_detect = ZOOM2_SMSC911X_GPIO;
|
||||||
|
|
||||||
|
if (gpio_request(debug_board_detect, "Zoom2 debug board detect") < 0) {
|
||||||
|
printk(KERN_ERR "Failed to request GPIO%d for Zoom2 debug"
|
||||||
|
"board detect\n", debug_board_detect);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
gpio_direction_input(debug_board_detect);
|
||||||
|
|
||||||
|
if (!gpio_get_value(debug_board_detect)) {
|
||||||
|
gpio_free(debug_board_detect);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_device *zoom2_devices[] __initdata = {
|
||||||
|
&zoom2_smsc911x_device,
|
||||||
|
&zoom2_debugboard_serial_device,
|
||||||
|
};
|
||||||
|
|
||||||
|
int __init omap_zoom2_debugboard_init(void)
|
||||||
|
{
|
||||||
|
if (!omap_zoom2_debugboard_detect())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
zoom2_init_smsc911x();
|
||||||
|
zoom2_init_quaduart();
|
||||||
|
return platform_add_devices(zoom2_devices, ARRAY_SIZE(zoom2_devices));
|
||||||
|
}
|
110
arch/arm/mach-omap2/board-zoom2.c
Normal file
110
arch/arm/mach-omap2/board-zoom2.c
Normal file
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2009 Texas Instruments Inc.
|
||||||
|
* Mikkel Christensen <mlc@ti.com>
|
||||||
|
*
|
||||||
|
* Modified from mach-omap2/board-ldp.c
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/gpio.h>
|
||||||
|
#include <linux/i2c/twl4030.h>
|
||||||
|
|
||||||
|
#include <asm/mach-types.h>
|
||||||
|
#include <asm/mach/arch.h>
|
||||||
|
|
||||||
|
#include <mach/common.h>
|
||||||
|
#include <mach/usb.h>
|
||||||
|
|
||||||
|
#include "mmc-twl4030.h"
|
||||||
|
|
||||||
|
static void __init omap_zoom2_init_irq(void)
|
||||||
|
{
|
||||||
|
omap2_init_common_hw(NULL);
|
||||||
|
omap_init_irq();
|
||||||
|
omap_gpio_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct omap_uart_config zoom2_uart_config __initdata = {
|
||||||
|
.enabled_uarts = ((1 << 0) | (1 << 1) | (1 << 2)),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct omap_board_config_kernel zoom2_config[] __initdata = {
|
||||||
|
{ OMAP_TAG_UART, &zoom2_uart_config },
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_gpio_platform_data zoom2_gpio_data = {
|
||||||
|
.gpio_base = OMAP_MAX_GPIO_LINES,
|
||||||
|
.irq_base = TWL4030_GPIO_IRQ_BASE,
|
||||||
|
.irq_end = TWL4030_GPIO_IRQ_END,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct twl4030_platform_data zoom2_twldata = {
|
||||||
|
.irq_base = TWL4030_IRQ_BASE,
|
||||||
|
.irq_end = TWL4030_IRQ_END,
|
||||||
|
|
||||||
|
/* platform_data for children goes here */
|
||||||
|
.gpio = &zoom2_gpio_data,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct i2c_board_info __initdata zoom2_i2c_boardinfo[] = {
|
||||||
|
{
|
||||||
|
I2C_BOARD_INFO("twl4030", 0x48),
|
||||||
|
.flags = I2C_CLIENT_WAKE,
|
||||||
|
.irq = INT_34XX_SYS_NIRQ,
|
||||||
|
.platform_data = &zoom2_twldata,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init omap_i2c_init(void)
|
||||||
|
{
|
||||||
|
omap_register_i2c_bus(1, 2600, zoom2_i2c_boardinfo,
|
||||||
|
ARRAY_SIZE(zoom2_i2c_boardinfo));
|
||||||
|
omap_register_i2c_bus(2, 400, NULL, 0);
|
||||||
|
omap_register_i2c_bus(3, 400, NULL, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct twl4030_hsmmc_info mmc[] __initdata = {
|
||||||
|
{
|
||||||
|
.mmc = 1,
|
||||||
|
.wires = 4,
|
||||||
|
.gpio_cd = -EINVAL,
|
||||||
|
.gpio_wp = -EINVAL,
|
||||||
|
},
|
||||||
|
{} /* Terminator */
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int __init omap_zoom2_debugboard_init(void);
|
||||||
|
|
||||||
|
static void __init omap_zoom2_init(void)
|
||||||
|
{
|
||||||
|
omap_i2c_init();
|
||||||
|
omap_board_config = zoom2_config;
|
||||||
|
omap_board_config_size = ARRAY_SIZE(zoom2_config);
|
||||||
|
omap_serial_init();
|
||||||
|
omap_zoom2_debugboard_init();
|
||||||
|
twl4030_mmc_init(mmc);
|
||||||
|
usb_musb_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init omap_zoom2_map_io(void)
|
||||||
|
{
|
||||||
|
omap2_set_globals_343x();
|
||||||
|
omap2_map_common_io();
|
||||||
|
}
|
||||||
|
|
||||||
|
MACHINE_START(OMAP_ZOOM2, "OMAP Zoom2 board")
|
||||||
|
.phys_io = 0x48000000,
|
||||||
|
.io_pg_offst = ((0xd8000000) >> 18) & 0xfffc,
|
||||||
|
.boot_params = 0x80000100,
|
||||||
|
.map_io = omap_zoom2_map_io,
|
||||||
|
.init_irq = omap_zoom2_init_irq,
|
||||||
|
.init_machine = omap_zoom2_init,
|
||||||
|
.timer = &omap_timer,
|
||||||
|
MACHINE_END
|
|
@ -16,8 +16,8 @@
|
||||||
#include <linux/interrupt.h>
|
#include <linux/interrupt.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/gpio.h>
|
#include <linux/gpio.h>
|
||||||
#include <linux/i2c/twl4030.h>
|
#include <linux/mmc/host.h>
|
||||||
#include <linux/regulator/machine.h>
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#include <mach/hardware.h>
|
#include <mach/hardware.h>
|
||||||
#include <mach/control.h>
|
#include <mach/control.h>
|
||||||
|
@ -26,32 +26,10 @@
|
||||||
|
|
||||||
#include "mmc-twl4030.h"
|
#include "mmc-twl4030.h"
|
||||||
|
|
||||||
#if defined(CONFIG_TWL4030_CORE) && \
|
|
||||||
|
#if defined(CONFIG_REGULATOR) && \
|
||||||
(defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
|
(defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
|
||||||
|
|
||||||
#define LDO_CLR 0x00
|
|
||||||
#define VSEL_S2_CLR 0x40
|
|
||||||
|
|
||||||
#define VMMC1_DEV_GRP 0x27
|
|
||||||
#define VMMC1_CLR 0x00
|
|
||||||
#define VMMC1_315V 0x03
|
|
||||||
#define VMMC1_300V 0x02
|
|
||||||
#define VMMC1_285V 0x01
|
|
||||||
#define VMMC1_185V 0x00
|
|
||||||
#define VMMC1_DEDICATED 0x2A
|
|
||||||
|
|
||||||
#define VMMC2_DEV_GRP 0x2B
|
|
||||||
#define VMMC2_CLR 0x40
|
|
||||||
#define VMMC2_315V 0x0c
|
|
||||||
#define VMMC2_300V 0x0b
|
|
||||||
#define VMMC2_285V 0x0a
|
|
||||||
#define VMMC2_280V 0x09
|
|
||||||
#define VMMC2_260V 0x08
|
|
||||||
#define VMMC2_185V 0x06
|
|
||||||
#define VMMC2_DEDICATED 0x2E
|
|
||||||
|
|
||||||
#define VMMC_DEV_GRP_P1 0x20
|
|
||||||
|
|
||||||
static u16 control_pbias_offset;
|
static u16 control_pbias_offset;
|
||||||
static u16 control_devconf1_offset;
|
static u16 control_devconf1_offset;
|
||||||
|
|
||||||
|
@ -59,19 +37,16 @@ static u16 control_devconf1_offset;
|
||||||
|
|
||||||
static struct twl_mmc_controller {
|
static struct twl_mmc_controller {
|
||||||
struct omap_mmc_platform_data *mmc;
|
struct omap_mmc_platform_data *mmc;
|
||||||
u8 twl_vmmc_dev_grp;
|
/* Vcc == configured supply
|
||||||
u8 twl_mmc_dedicated;
|
* Vcc_alt == optional
|
||||||
char name[HSMMC_NAME_LEN + 1];
|
* - MMC1, supply for DAT4..DAT7
|
||||||
} hsmmc[OMAP34XX_NR_MMC] = {
|
* - MMC2/MMC2, external level shifter voltage supply, for
|
||||||
{
|
* chip (SDIO, eMMC, etc) or transceiver (MMC2 only)
|
||||||
.twl_vmmc_dev_grp = VMMC1_DEV_GRP,
|
*/
|
||||||
.twl_mmc_dedicated = VMMC1_DEDICATED,
|
struct regulator *vcc;
|
||||||
},
|
struct regulator *vcc_aux;
|
||||||
{
|
char name[HSMMC_NAME_LEN + 1];
|
||||||
.twl_vmmc_dev_grp = VMMC2_DEV_GRP,
|
} hsmmc[OMAP34XX_NR_MMC];
|
||||||
.twl_mmc_dedicated = VMMC2_DEDICATED,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
static int twl_mmc_card_detect(int irq)
|
static int twl_mmc_card_detect(int irq)
|
||||||
{
|
{
|
||||||
|
@ -117,16 +92,60 @@ static int twl_mmc_late_init(struct device *dev)
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
|
/* MMC/SD/SDIO doesn't require a card detect switch */
|
||||||
if (ret)
|
if (gpio_is_valid(mmc->slots[0].switch_pin)) {
|
||||||
goto done;
|
ret = gpio_request(mmc->slots[0].switch_pin, "mmc_cd");
|
||||||
ret = gpio_direction_input(mmc->slots[0].switch_pin);
|
if (ret)
|
||||||
if (ret)
|
goto done;
|
||||||
goto err;
|
ret = gpio_direction_input(mmc->slots[0].switch_pin);
|
||||||
|
if (ret)
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* require at least main regulator */
|
||||||
for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
|
for (i = 0; i < ARRAY_SIZE(hsmmc); i++) {
|
||||||
if (hsmmc[i].name == mmc->slots[0].name) {
|
if (hsmmc[i].name == mmc->slots[0].name) {
|
||||||
|
struct regulator *reg;
|
||||||
|
|
||||||
hsmmc[i].mmc = mmc;
|
hsmmc[i].mmc = mmc;
|
||||||
|
|
||||||
|
reg = regulator_get(dev, "vmmc");
|
||||||
|
if (IS_ERR(reg)) {
|
||||||
|
dev_dbg(dev, "vmmc regulator missing\n");
|
||||||
|
/* HACK: until fixed.c regulator is usable,
|
||||||
|
* we don't require a main regulator
|
||||||
|
* for MMC2 or MMC3
|
||||||
|
*/
|
||||||
|
if (i != 0)
|
||||||
|
break;
|
||||||
|
ret = PTR_ERR(reg);
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
hsmmc[i].vcc = reg;
|
||||||
|
mmc->slots[0].ocr_mask = mmc_regulator_get_ocrmask(reg);
|
||||||
|
|
||||||
|
/* allow an aux regulator */
|
||||||
|
reg = regulator_get(dev, "vmmc_aux");
|
||||||
|
hsmmc[i].vcc_aux = IS_ERR(reg) ? NULL : reg;
|
||||||
|
|
||||||
|
/* UGLY HACK: workaround regulator framework bugs.
|
||||||
|
* When the bootloader leaves a supply active, it's
|
||||||
|
* initialized with zero usecount ... and we can't
|
||||||
|
* disable it without first enabling it. Until the
|
||||||
|
* framework is fixed, we need a workaround like this
|
||||||
|
* (which is safe for MMC, but not in general).
|
||||||
|
*/
|
||||||
|
if (regulator_is_enabled(hsmmc[i].vcc) > 0) {
|
||||||
|
regulator_enable(hsmmc[i].vcc);
|
||||||
|
regulator_disable(hsmmc[i].vcc);
|
||||||
|
}
|
||||||
|
if (hsmmc[i].vcc_aux) {
|
||||||
|
if (regulator_is_enabled(reg) > 0) {
|
||||||
|
regulator_enable(reg);
|
||||||
|
regulator_disable(reg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,96 +192,6 @@ static int twl_mmc_resume(struct device *dev, int slot)
|
||||||
#define twl_mmc_resume NULL
|
#define twl_mmc_resume NULL
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Sets the MMC voltage in twl4030
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define MMC1_OCR (MMC_VDD_165_195 \
|
|
||||||
|MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
|
|
||||||
#define MMC2_OCR (MMC_VDD_165_195 \
|
|
||||||
|MMC_VDD_25_26|MMC_VDD_26_27|MMC_VDD_27_28 \
|
|
||||||
|MMC_VDD_28_29|MMC_VDD_29_30|MMC_VDD_30_31|MMC_VDD_31_32)
|
|
||||||
|
|
||||||
static int twl_mmc_set_voltage(struct twl_mmc_controller *c, int vdd)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
u8 vmmc = 0, dev_grp_val;
|
|
||||||
|
|
||||||
if (!vdd)
|
|
||||||
goto doit;
|
|
||||||
|
|
||||||
if (c->twl_vmmc_dev_grp == VMMC1_DEV_GRP) {
|
|
||||||
/* VMMC1: max 220 mA. And for 8-bit mode,
|
|
||||||
* VSIM: max 50 mA
|
|
||||||
*/
|
|
||||||
switch (1 << vdd) {
|
|
||||||
case MMC_VDD_165_195:
|
|
||||||
vmmc = VMMC1_185V;
|
|
||||||
/* and VSIM_180V */
|
|
||||||
break;
|
|
||||||
case MMC_VDD_28_29:
|
|
||||||
vmmc = VMMC1_285V;
|
|
||||||
/* and VSIM_280V */
|
|
||||||
break;
|
|
||||||
case MMC_VDD_29_30:
|
|
||||||
case MMC_VDD_30_31:
|
|
||||||
vmmc = VMMC1_300V;
|
|
||||||
/* and VSIM_300V */
|
|
||||||
break;
|
|
||||||
case MMC_VDD_31_32:
|
|
||||||
vmmc = VMMC1_315V;
|
|
||||||
/* error if VSIM needed */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
} else if (c->twl_vmmc_dev_grp == VMMC2_DEV_GRP) {
|
|
||||||
/* VMMC2: max 100 mA */
|
|
||||||
switch (1 << vdd) {
|
|
||||||
case MMC_VDD_165_195:
|
|
||||||
vmmc = VMMC2_185V;
|
|
||||||
break;
|
|
||||||
case MMC_VDD_25_26:
|
|
||||||
case MMC_VDD_26_27:
|
|
||||||
vmmc = VMMC2_260V;
|
|
||||||
break;
|
|
||||||
case MMC_VDD_27_28:
|
|
||||||
vmmc = VMMC2_280V;
|
|
||||||
break;
|
|
||||||
case MMC_VDD_28_29:
|
|
||||||
vmmc = VMMC2_285V;
|
|
||||||
break;
|
|
||||||
case MMC_VDD_29_30:
|
|
||||||
case MMC_VDD_30_31:
|
|
||||||
vmmc = VMMC2_300V;
|
|
||||||
break;
|
|
||||||
case MMC_VDD_31_32:
|
|
||||||
vmmc = VMMC2_315V;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
doit:
|
|
||||||
if (vdd)
|
|
||||||
dev_grp_val = VMMC_DEV_GRP_P1; /* Power up */
|
|
||||||
else
|
|
||||||
dev_grp_val = LDO_CLR; /* Power down */
|
|
||||||
|
|
||||||
ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
|
|
||||||
dev_grp_val, c->twl_vmmc_dev_grp);
|
|
||||||
if (ret || !vdd)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
|
|
||||||
vmmc, c->twl_mmc_dedicated);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
|
static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
|
||||||
int vdd)
|
int vdd)
|
||||||
{
|
{
|
||||||
|
@ -273,11 +202,13 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
|
* Assume we power both OMAP VMMC1 (for CMD, CLK, DAT0..3) and the
|
||||||
* card using the same TWL VMMC1 supply (hsmmc[0]); OMAP has both
|
* card with Vcc regulator (from twl4030 or whatever). OMAP has both
|
||||||
* 1.8V and 3.0V modes, controlled by the PBIAS register.
|
* 1.8V and 3.0V modes, controlled by the PBIAS register.
|
||||||
*
|
*
|
||||||
* In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
|
* In 8-bit modes, OMAP VMMC1A (for DAT4..7) needs a supply, which
|
||||||
* is most naturally TWL VSIM; those pins also use PBIAS.
|
* is most naturally TWL VSIM; those pins also use PBIAS.
|
||||||
|
*
|
||||||
|
* FIXME handle VMMC1A as needed ...
|
||||||
*/
|
*/
|
||||||
if (power_on) {
|
if (power_on) {
|
||||||
if (cpu_is_omap2430()) {
|
if (cpu_is_omap2430()) {
|
||||||
|
@ -300,7 +231,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
|
||||||
reg &= ~OMAP2_PBIASLITEPWRDNZ0;
|
reg &= ~OMAP2_PBIASLITEPWRDNZ0;
|
||||||
omap_ctrl_writel(reg, control_pbias_offset);
|
omap_ctrl_writel(reg, control_pbias_offset);
|
||||||
|
|
||||||
ret = twl_mmc_set_voltage(c, vdd);
|
ret = mmc_regulator_set_ocr(c->vcc, vdd);
|
||||||
|
|
||||||
/* 100ms delay required for PBIAS configuration */
|
/* 100ms delay required for PBIAS configuration */
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
@ -316,7 +247,7 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
|
||||||
reg &= ~OMAP2_PBIASLITEPWRDNZ0;
|
reg &= ~OMAP2_PBIASLITEPWRDNZ0;
|
||||||
omap_ctrl_writel(reg, control_pbias_offset);
|
omap_ctrl_writel(reg, control_pbias_offset);
|
||||||
|
|
||||||
ret = twl_mmc_set_voltage(c, 0);
|
ret = mmc_regulator_set_ocr(c->vcc, 0);
|
||||||
|
|
||||||
/* 100ms delay required for PBIAS configuration */
|
/* 100ms delay required for PBIAS configuration */
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
@ -329,19 +260,33 @@ static int twl_mmc1_set_power(struct device *dev, int slot, int power_on,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vdd)
|
static int twl_mmc23_set_power(struct device *dev, int slot, int power_on, int vdd)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
struct twl_mmc_controller *c = &hsmmc[1];
|
struct twl_mmc_controller *c = &hsmmc[1];
|
||||||
struct omap_mmc_platform_data *mmc = dev->platform_data;
|
struct omap_mmc_platform_data *mmc = dev->platform_data;
|
||||||
|
|
||||||
|
/* If we don't see a Vcc regulator, assume it's a fixed
|
||||||
|
* voltage always-on regulator.
|
||||||
|
*/
|
||||||
|
if (!c->vcc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Assume TWL VMMC2 (hsmmc[1]) is used only to power the card ... OMAP
|
* Assume Vcc regulator is used only to power the card ... OMAP
|
||||||
* VDDS is used to power the pins, optionally with a transceiver to
|
* VDDS is used to power the pins, optionally with a transceiver to
|
||||||
* support cards using voltages other than VDDS (1.8V nominal). When a
|
* support cards using voltages other than VDDS (1.8V nominal). When a
|
||||||
* transceiver is used, DAT3..7 are muxed as transceiver control pins.
|
* transceiver is used, DAT3..7 are muxed as transceiver control pins.
|
||||||
|
*
|
||||||
|
* In some cases this regulator won't support enable/disable;
|
||||||
|
* e.g. it's a fixed rail for a WLAN chip.
|
||||||
|
*
|
||||||
|
* In other cases vcc_aux switches interface power. Example, for
|
||||||
|
* eMMC cards it represents VccQ. Sometimes transceivers or SDIO
|
||||||
|
* chips/cards need an interface voltage rail too.
|
||||||
*/
|
*/
|
||||||
if (power_on) {
|
if (power_on) {
|
||||||
|
/* only MMC2 supports a CLKIN */
|
||||||
if (mmc->slots[0].internal_clock) {
|
if (mmc->slots[0].internal_clock) {
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
@ -349,24 +294,23 @@ static int twl_mmc2_set_power(struct device *dev, int slot, int power_on, int vd
|
||||||
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
|
reg |= OMAP2_MMCSDIO2ADPCLKISEL;
|
||||||
omap_ctrl_writel(reg, control_devconf1_offset);
|
omap_ctrl_writel(reg, control_devconf1_offset);
|
||||||
}
|
}
|
||||||
ret = twl_mmc_set_voltage(c, vdd);
|
ret = mmc_regulator_set_ocr(c->vcc, vdd);
|
||||||
|
/* enable interface voltage rail, if needed */
|
||||||
|
if (ret == 0 && c->vcc_aux) {
|
||||||
|
ret = regulator_enable(c->vcc_aux);
|
||||||
|
if (ret < 0)
|
||||||
|
ret = mmc_regulator_set_ocr(c->vcc, 0);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
ret = twl_mmc_set_voltage(c, 0);
|
if (c->vcc_aux && (ret = regulator_is_enabled(c->vcc_aux)) > 0)
|
||||||
|
ret = regulator_disable(c->vcc_aux);
|
||||||
|
if (ret == 0)
|
||||||
|
ret = mmc_regulator_set_ocr(c->vcc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int twl_mmc3_set_power(struct device *dev, int slot, int power_on,
|
|
||||||
int vdd)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Assume MMC3 has self-powered device connected, for example on-board
|
|
||||||
* chip with external power source.
|
|
||||||
*/
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
|
static struct omap_mmc_platform_data *hsmmc_data[OMAP34XX_NR_MMC] __initdata;
|
||||||
|
|
||||||
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
||||||
|
@ -412,10 +356,10 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
||||||
mmc->slots[0].wires = c->wires;
|
mmc->slots[0].wires = c->wires;
|
||||||
mmc->slots[0].internal_clock = !c->ext_clock;
|
mmc->slots[0].internal_clock = !c->ext_clock;
|
||||||
mmc->dma_mask = 0xffffffff;
|
mmc->dma_mask = 0xffffffff;
|
||||||
|
mmc->init = twl_mmc_late_init;
|
||||||
|
|
||||||
/* note: twl4030 card detect GPIOs normally switch VMMCx ... */
|
/* note: twl4030 card detect GPIOs can disable VMMCx ... */
|
||||||
if (gpio_is_valid(c->gpio_cd)) {
|
if (gpio_is_valid(c->gpio_cd)) {
|
||||||
mmc->init = twl_mmc_late_init;
|
|
||||||
mmc->cleanup = twl_mmc_cleanup;
|
mmc->cleanup = twl_mmc_cleanup;
|
||||||
mmc->suspend = twl_mmc_suspend;
|
mmc->suspend = twl_mmc_suspend;
|
||||||
mmc->resume = twl_mmc_resume;
|
mmc->resume = twl_mmc_resume;
|
||||||
|
@ -439,26 +383,28 @@ void __init twl4030_mmc_init(struct twl4030_hsmmc_info *controllers)
|
||||||
} else
|
} else
|
||||||
mmc->slots[0].gpio_wp = -EINVAL;
|
mmc->slots[0].gpio_wp = -EINVAL;
|
||||||
|
|
||||||
/* NOTE: we assume OMAP's MMC1 and MMC2 use
|
/* NOTE: MMC slots should have a Vcc regulator set up.
|
||||||
* the TWL4030's VMMC1 and VMMC2, respectively;
|
* This may be from a TWL4030-family chip, another
|
||||||
* and that MMC3 device has it's own power source.
|
* controllable regulator, or a fixed supply.
|
||||||
|
*
|
||||||
|
* temporary HACK: ocr_mask instead of fixed supply
|
||||||
*/
|
*/
|
||||||
|
mmc->slots[0].ocr_mask = c->ocr_mask;
|
||||||
|
|
||||||
switch (c->mmc) {
|
switch (c->mmc) {
|
||||||
case 1:
|
case 1:
|
||||||
|
/* on-chip level shifting via PBIAS0/PBIAS1 */
|
||||||
mmc->slots[0].set_power = twl_mmc1_set_power;
|
mmc->slots[0].set_power = twl_mmc1_set_power;
|
||||||
mmc->slots[0].ocr_mask = MMC1_OCR;
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
mmc->slots[0].set_power = twl_mmc2_set_power;
|
if (c->ext_clock)
|
||||||
if (c->transceiver)
|
c->transceiver = 1;
|
||||||
mmc->slots[0].ocr_mask = MMC2_OCR;
|
if (c->transceiver && c->wires > 4)
|
||||||
else
|
c->wires = 4;
|
||||||
mmc->slots[0].ocr_mask = MMC_VDD_165_195;
|
/* FALLTHROUGH */
|
||||||
break;
|
|
||||||
case 3:
|
case 3:
|
||||||
mmc->slots[0].set_power = twl_mmc3_set_power;
|
/* off-chip level shifting, or none */
|
||||||
mmc->slots[0].ocr_mask = MMC_VDD_165_195;
|
mmc->slots[0].set_power = twl_mmc23_set_power;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("MMC%d configuration not supported!\n", c->mmc);
|
pr_err("MMC%d configuration not supported!\n", c->mmc);
|
||||||
|
|
|
@ -16,9 +16,10 @@ struct twl4030_hsmmc_info {
|
||||||
int gpio_wp; /* or -EINVAL */
|
int gpio_wp; /* or -EINVAL */
|
||||||
char *name; /* or NULL for default */
|
char *name; /* or NULL for default */
|
||||||
struct device *dev; /* returned: pointer to mmc adapter */
|
struct device *dev; /* returned: pointer to mmc adapter */
|
||||||
|
int ocr_mask; /* temporary HACK */
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(CONFIG_TWL4030_CORE) && \
|
#if defined(CONFIG_REGULATOR) && \
|
||||||
(defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
|
(defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
|
||||||
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
|
defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE))
|
||||||
|
|
||||||
|
|
|
@ -1073,7 +1073,6 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
|
||||||
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
|
mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
|
||||||
mmc->max_seg_size = mmc->max_req_size;
|
mmc->max_seg_size = mmc->max_req_size;
|
||||||
|
|
||||||
mmc->ocr_avail = mmc_slot(host).ocr_mask;
|
|
||||||
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
|
mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
|
||||||
|
|
||||||
if (pdata->slots[host->slot_id].wires >= 8)
|
if (pdata->slots[host->slot_id].wires >= 8)
|
||||||
|
@ -1110,13 +1109,14 @@ static int __init omap_mmc_probe(struct platform_device *pdev)
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize power supplies, gpios, etc */
|
||||||
if (pdata->init != NULL) {
|
if (pdata->init != NULL) {
|
||||||
if (pdata->init(&pdev->dev) != 0) {
|
if (pdata->init(&pdev->dev) != 0) {
|
||||||
dev_dbg(mmc_dev(host->mmc),
|
dev_dbg(mmc_dev(host->mmc), "late init error\n");
|
||||||
"Unable to configure MMC IRQs\n");
|
|
||||||
goto err_irq_cd_init;
|
goto err_irq_cd_init;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
mmc->ocr_avail = mmc_slot(host).ocr_mask;
|
||||||
|
|
||||||
/* Request IRQ for card detect */
|
/* Request IRQ for card detect */
|
||||||
if ((mmc_slot(host).card_detect_irq)) {
|
if ((mmc_slot(host).card_detect_irq)) {
|
||||||
|
|
Loading…
Reference in a new issue