162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * linux/arch/arm/mach-omap1/board-osk.c 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Board specific init for OMAP5912 OSK 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Written by Dirk Behme <dirk.behme@de.bosch.com> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * This program is free software; you can redistribute it and/or modify it 962306a36Sopenharmony_ci * under the terms of the GNU General Public License as published by the 1062306a36Sopenharmony_ci * Free Software Foundation; either version 2 of the License, or (at your 1162306a36Sopenharmony_ci * option) any later version. 1262306a36Sopenharmony_ci * 1362306a36Sopenharmony_ci * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED 1462306a36Sopenharmony_ci * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1562306a36Sopenharmony_ci * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 1662306a36Sopenharmony_ci * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1762306a36Sopenharmony_ci * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 1862306a36Sopenharmony_ci * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 1962306a36Sopenharmony_ci * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 2062306a36Sopenharmony_ci * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2162306a36Sopenharmony_ci * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2262306a36Sopenharmony_ci * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2362306a36Sopenharmony_ci * 2462306a36Sopenharmony_ci * You should have received a copy of the GNU General Public License along 2562306a36Sopenharmony_ci * with this program; if not, write to the Free Software Foundation, Inc., 2662306a36Sopenharmony_ci * 675 Mass Ave, Cambridge, MA 02139, USA. 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci#include <linux/gpio/consumer.h> 2962306a36Sopenharmony_ci#include <linux/gpio/driver.h> 3062306a36Sopenharmony_ci#include <linux/gpio/machine.h> 3162306a36Sopenharmony_ci#include <linux/kernel.h> 3262306a36Sopenharmony_ci#include <linux/init.h> 3362306a36Sopenharmony_ci#include <linux/platform_device.h> 3462306a36Sopenharmony_ci#include <linux/interrupt.h> 3562306a36Sopenharmony_ci#include <linux/irq.h> 3662306a36Sopenharmony_ci#include <linux/i2c.h> 3762306a36Sopenharmony_ci#include <linux/leds.h> 3862306a36Sopenharmony_ci#include <linux/smc91x.h> 3962306a36Sopenharmony_ci#include <linux/omapfb.h> 4062306a36Sopenharmony_ci#include <linux/mtd/mtd.h> 4162306a36Sopenharmony_ci#include <linux/mtd/partitions.h> 4262306a36Sopenharmony_ci#include <linux/mtd/physmap.h> 4362306a36Sopenharmony_ci#include <linux/mfd/tps65010.h> 4462306a36Sopenharmony_ci#include <linux/platform_data/gpio-omap.h> 4562306a36Sopenharmony_ci#include <linux/platform_data/omap1_bl.h> 4662306a36Sopenharmony_ci#include <linux/soc/ti/omap1-io.h> 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#include <asm/mach-types.h> 4962306a36Sopenharmony_ci#include <asm/mach/arch.h> 5062306a36Sopenharmony_ci#include <asm/mach/map.h> 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#include "tc.h" 5362306a36Sopenharmony_ci#include "flash.h" 5462306a36Sopenharmony_ci#include "mux.h" 5562306a36Sopenharmony_ci#include "hardware.h" 5662306a36Sopenharmony_ci#include "usb.h" 5762306a36Sopenharmony_ci#include "common.h" 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci/* Name of the GPIO chip used by the OMAP for GPIOs 0..15 */ 6062306a36Sopenharmony_ci#define OMAP_GPIO_LABEL "gpio-0-15" 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci/* At OMAP5912 OSK the Ethernet is directly connected to CS1 */ 6362306a36Sopenharmony_ci#define OMAP_OSK_ETHR_START 0x04800300 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci/* TPS65010 has four GPIOs. nPG and LED2 can be treated like GPIOs with 6662306a36Sopenharmony_ci * alternate pin configurations for hardware-controlled blinking. 6762306a36Sopenharmony_ci */ 6862306a36Sopenharmony_ci#define OSK_TPS_GPIO_USB_PWR_EN 0 6962306a36Sopenharmony_ci#define OSK_TPS_GPIO_LED_D3 1 7062306a36Sopenharmony_ci#define OSK_TPS_GPIO_LAN_RESET 2 7162306a36Sopenharmony_ci#define OSK_TPS_GPIO_DSP_PWR_EN 3 7262306a36Sopenharmony_ci#define OSK_TPS_GPIO_LED_D9 4 7362306a36Sopenharmony_ci#define OSK_TPS_GPIO_LED_D2 5 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_cistatic struct mtd_partition osk_partitions[] = { 7662306a36Sopenharmony_ci /* bootloader (U-Boot, etc) in first sector */ 7762306a36Sopenharmony_ci { 7862306a36Sopenharmony_ci .name = "bootloader", 7962306a36Sopenharmony_ci .offset = 0, 8062306a36Sopenharmony_ci .size = SZ_128K, 8162306a36Sopenharmony_ci .mask_flags = MTD_WRITEABLE, /* force read-only */ 8262306a36Sopenharmony_ci }, 8362306a36Sopenharmony_ci /* bootloader params in the next sector */ 8462306a36Sopenharmony_ci { 8562306a36Sopenharmony_ci .name = "params", 8662306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 8762306a36Sopenharmony_ci .size = SZ_128K, 8862306a36Sopenharmony_ci .mask_flags = 0, 8962306a36Sopenharmony_ci }, { 9062306a36Sopenharmony_ci .name = "kernel", 9162306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 9262306a36Sopenharmony_ci .size = SZ_2M, 9362306a36Sopenharmony_ci .mask_flags = 0 9462306a36Sopenharmony_ci }, { 9562306a36Sopenharmony_ci .name = "filesystem", 9662306a36Sopenharmony_ci .offset = MTDPART_OFS_APPEND, 9762306a36Sopenharmony_ci .size = MTDPART_SIZ_FULL, 9862306a36Sopenharmony_ci .mask_flags = 0 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci}; 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_cistatic struct physmap_flash_data osk_flash_data = { 10362306a36Sopenharmony_ci .width = 2, 10462306a36Sopenharmony_ci .set_vpp = omap1_set_vpp, 10562306a36Sopenharmony_ci .parts = osk_partitions, 10662306a36Sopenharmony_ci .nr_parts = ARRAY_SIZE(osk_partitions), 10762306a36Sopenharmony_ci}; 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_cistatic struct resource osk_flash_resource = { 11062306a36Sopenharmony_ci /* this is on CS3, wherever it's mapped */ 11162306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_cistatic struct platform_device osk5912_flash_device = { 11562306a36Sopenharmony_ci .name = "physmap-flash", 11662306a36Sopenharmony_ci .id = 0, 11762306a36Sopenharmony_ci .dev = { 11862306a36Sopenharmony_ci .platform_data = &osk_flash_data, 11962306a36Sopenharmony_ci }, 12062306a36Sopenharmony_ci .num_resources = 1, 12162306a36Sopenharmony_ci .resource = &osk_flash_resource, 12262306a36Sopenharmony_ci}; 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_cistatic struct smc91x_platdata osk5912_smc91x_info = { 12562306a36Sopenharmony_ci .flags = SMC91X_USE_16BIT | SMC91X_NOWAIT, 12662306a36Sopenharmony_ci .leda = RPC_LED_100_10, 12762306a36Sopenharmony_ci .ledb = RPC_LED_TX_RX, 12862306a36Sopenharmony_ci}; 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_cistatic struct resource osk5912_smc91x_resources[] = { 13162306a36Sopenharmony_ci [0] = { 13262306a36Sopenharmony_ci .start = OMAP_OSK_ETHR_START, /* Physical */ 13362306a36Sopenharmony_ci .end = OMAP_OSK_ETHR_START + 0xf, 13462306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 13562306a36Sopenharmony_ci }, 13662306a36Sopenharmony_ci [1] = { 13762306a36Sopenharmony_ci .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE, 13862306a36Sopenharmony_ci }, 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic struct platform_device osk5912_smc91x_device = { 14262306a36Sopenharmony_ci .name = "smc91x", 14362306a36Sopenharmony_ci .id = -1, 14462306a36Sopenharmony_ci .dev = { 14562306a36Sopenharmony_ci .platform_data = &osk5912_smc91x_info, 14662306a36Sopenharmony_ci }, 14762306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(osk5912_smc91x_resources), 14862306a36Sopenharmony_ci .resource = osk5912_smc91x_resources, 14962306a36Sopenharmony_ci}; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_cistatic struct resource osk5912_cf_resources[] = { 15262306a36Sopenharmony_ci [0] = { 15362306a36Sopenharmony_ci .flags = IORESOURCE_IRQ, 15462306a36Sopenharmony_ci }, 15562306a36Sopenharmony_ci [1] = { 15662306a36Sopenharmony_ci .flags = IORESOURCE_MEM, 15762306a36Sopenharmony_ci }, 15862306a36Sopenharmony_ci}; 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_cistatic struct platform_device osk5912_cf_device = { 16162306a36Sopenharmony_ci .name = "omap_cf", 16262306a36Sopenharmony_ci .id = -1, 16362306a36Sopenharmony_ci .num_resources = ARRAY_SIZE(osk5912_cf_resources), 16462306a36Sopenharmony_ci .resource = osk5912_cf_resources, 16562306a36Sopenharmony_ci}; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_cistatic struct platform_device *osk5912_devices[] __initdata = { 16862306a36Sopenharmony_ci &osk5912_flash_device, 16962306a36Sopenharmony_ci &osk5912_smc91x_device, 17062306a36Sopenharmony_ci &osk5912_cf_device, 17162306a36Sopenharmony_ci}; 17262306a36Sopenharmony_ci 17362306a36Sopenharmony_cistatic const struct gpio_led tps_leds[] = { 17462306a36Sopenharmony_ci /* NOTE: D9 and D2 have hardware blink support. 17562306a36Sopenharmony_ci * Also, D9 requires non-battery power. 17662306a36Sopenharmony_ci */ 17762306a36Sopenharmony_ci { .name = "d9", .default_trigger = "disk-activity", }, 17862306a36Sopenharmony_ci { .name = "d2", }, 17962306a36Sopenharmony_ci { .name = "d3", .default_trigger = "heartbeat", }, 18062306a36Sopenharmony_ci}; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_cistatic struct gpiod_lookup_table tps_leds_gpio_table = { 18362306a36Sopenharmony_ci .dev_id = "leds-gpio", 18462306a36Sopenharmony_ci .table = { 18562306a36Sopenharmony_ci /* Use local offsets on TPS65010 */ 18662306a36Sopenharmony_ci GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D9, NULL, 0, GPIO_ACTIVE_HIGH), 18762306a36Sopenharmony_ci GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D2, NULL, 1, GPIO_ACTIVE_HIGH), 18862306a36Sopenharmony_ci GPIO_LOOKUP_IDX("tps65010", OSK_TPS_GPIO_LED_D3, NULL, 2, GPIO_ACTIVE_LOW), 18962306a36Sopenharmony_ci { } 19062306a36Sopenharmony_ci }, 19162306a36Sopenharmony_ci}; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_cistatic struct gpio_led_platform_data tps_leds_data = { 19462306a36Sopenharmony_ci .num_leds = 3, 19562306a36Sopenharmony_ci .leds = tps_leds, 19662306a36Sopenharmony_ci}; 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_cistatic struct platform_device osk5912_tps_leds = { 19962306a36Sopenharmony_ci .name = "leds-gpio", 20062306a36Sopenharmony_ci .id = 0, 20162306a36Sopenharmony_ci .dev.platform_data = &tps_leds_data, 20262306a36Sopenharmony_ci}; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci/* The board just hold these GPIOs hogged from setup to teardown */ 20562306a36Sopenharmony_cistatic struct gpio_desc *eth_reset; 20662306a36Sopenharmony_cistatic struct gpio_desc *vdd_dsp; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_cistatic int osk_tps_setup(struct i2c_client *client, struct gpio_chip *gc) 20962306a36Sopenharmony_ci{ 21062306a36Sopenharmony_ci struct gpio_desc *d; 21162306a36Sopenharmony_ci if (!IS_BUILTIN(CONFIG_TPS65010)) 21262306a36Sopenharmony_ci return -ENOSYS; 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci /* Set GPIO 1 HIGH to disable VBUS power supply; 21562306a36Sopenharmony_ci * OHCI driver powers it up/down as needed. 21662306a36Sopenharmony_ci */ 21762306a36Sopenharmony_ci d = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_USB_PWR_EN, "n_vbus_en", 21862306a36Sopenharmony_ci GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); 21962306a36Sopenharmony_ci /* Free the GPIO again as the driver will request it */ 22062306a36Sopenharmony_ci gpiochip_free_own_desc(d); 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci /* Set GPIO 2 high so LED D3 is off by default */ 22362306a36Sopenharmony_ci tps65010_set_gpio_out_value(GPIO2, HIGH); 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci /* Set GPIO 3 low to take ethernet out of reset */ 22662306a36Sopenharmony_ci eth_reset = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_LAN_RESET, "smc_reset", 22762306a36Sopenharmony_ci GPIO_ACTIVE_HIGH, GPIOD_OUT_LOW); 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci /* GPIO4 is VDD_DSP */ 23062306a36Sopenharmony_ci vdd_dsp = gpiochip_request_own_desc(gc, OSK_TPS_GPIO_DSP_PWR_EN, "dsp_power", 23162306a36Sopenharmony_ci GPIO_ACTIVE_HIGH, GPIOD_OUT_HIGH); 23262306a36Sopenharmony_ci /* REVISIT if DSP support isn't configured, power it off ... */ 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci /* Let LED1 (D9) blink; leds-gpio may override it */ 23562306a36Sopenharmony_ci tps65010_set_led(LED1, BLINK); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci /* Set LED2 off by default */ 23862306a36Sopenharmony_ci tps65010_set_led(LED2, OFF); 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci /* Enable LOW_PWR handshake */ 24162306a36Sopenharmony_ci tps65010_set_low_pwr(ON); 24262306a36Sopenharmony_ci 24362306a36Sopenharmony_ci /* Switch VLDO2 to 3.0V for AIC23 */ 24462306a36Sopenharmony_ci tps65010_config_vregs1(TPS_LDO2_ENABLE | TPS_VLDO2_3_0V 24562306a36Sopenharmony_ci | TPS_LDO1_ENABLE); 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_ci /* register these three LEDs */ 24862306a36Sopenharmony_ci osk5912_tps_leds.dev.parent = &client->dev; 24962306a36Sopenharmony_ci gpiod_add_lookup_table(&tps_leds_gpio_table); 25062306a36Sopenharmony_ci platform_device_register(&osk5912_tps_leds); 25162306a36Sopenharmony_ci 25262306a36Sopenharmony_ci return 0; 25362306a36Sopenharmony_ci} 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_cistatic void osk_tps_teardown(struct i2c_client *client, struct gpio_chip *gc) 25662306a36Sopenharmony_ci{ 25762306a36Sopenharmony_ci gpiochip_free_own_desc(eth_reset); 25862306a36Sopenharmony_ci gpiochip_free_own_desc(vdd_dsp); 25962306a36Sopenharmony_ci} 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_cistatic struct tps65010_board tps_board = { 26262306a36Sopenharmony_ci .outmask = 0x0f, 26362306a36Sopenharmony_ci .setup = osk_tps_setup, 26462306a36Sopenharmony_ci .teardown = osk_tps_teardown, 26562306a36Sopenharmony_ci}; 26662306a36Sopenharmony_ci 26762306a36Sopenharmony_cistatic struct i2c_board_info __initdata osk_i2c_board_info[] = { 26862306a36Sopenharmony_ci { 26962306a36Sopenharmony_ci /* This device will get the name "i2c-tps65010" */ 27062306a36Sopenharmony_ci I2C_BOARD_INFO("tps65010", 0x48), 27162306a36Sopenharmony_ci .dev_name = "tps65010", 27262306a36Sopenharmony_ci .platform_data = &tps_board, 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_ci }, 27562306a36Sopenharmony_ci { 27662306a36Sopenharmony_ci I2C_BOARD_INFO("tlv320aic23", 0x1B), 27762306a36Sopenharmony_ci }, 27862306a36Sopenharmony_ci /* TODO when driver support is ready: 27962306a36Sopenharmony_ci * - optionally on Mistral, ov9640 camera sensor at 0x30 28062306a36Sopenharmony_ci */ 28162306a36Sopenharmony_ci}; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_cistatic void __init osk_init_smc91x(void) 28462306a36Sopenharmony_ci{ 28562306a36Sopenharmony_ci u32 l; 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_ci /* Check EMIFS wait states to fix errors with SMC_GET_PKT_HDR */ 28862306a36Sopenharmony_ci l = omap_readl(EMIFS_CCS(1)); 28962306a36Sopenharmony_ci l |= 0x3; 29062306a36Sopenharmony_ci omap_writel(l, EMIFS_CCS(1)); 29162306a36Sopenharmony_ci} 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_cistatic void __init osk_init_cf(int seg) 29462306a36Sopenharmony_ci{ 29562306a36Sopenharmony_ci struct resource *res = &osk5912_cf_resources[1]; 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_ci omap_cfg_reg(M7_1610_GPIO62); 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci switch (seg) { 30062306a36Sopenharmony_ci /* NOTE: CS0 could be configured too ... */ 30162306a36Sopenharmony_ci case 1: 30262306a36Sopenharmony_ci res->start = OMAP_CS1_PHYS; 30362306a36Sopenharmony_ci break; 30462306a36Sopenharmony_ci case 2: 30562306a36Sopenharmony_ci res->start = OMAP_CS2_PHYS; 30662306a36Sopenharmony_ci break; 30762306a36Sopenharmony_ci case 3: 30862306a36Sopenharmony_ci res->start = omap_cs3_phys(); 30962306a36Sopenharmony_ci break; 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci res->end = res->start + SZ_8K - 1; 31362306a36Sopenharmony_ci osk5912_cf_device.dev.platform_data = (void *)(uintptr_t)seg; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci /* NOTE: better EMIFS setup might support more cards; but the 31662306a36Sopenharmony_ci * TRM only shows how to affect regular flash signals, not their 31762306a36Sopenharmony_ci * CF/PCMCIA variants... 31862306a36Sopenharmony_ci */ 31962306a36Sopenharmony_ci pr_debug("%s: cs%d, previous ccs %08x acs %08x\n", __func__, 32062306a36Sopenharmony_ci seg, omap_readl(EMIFS_CCS(seg)), omap_readl(EMIFS_ACS(seg))); 32162306a36Sopenharmony_ci omap_writel(0x0004a1b3, EMIFS_CCS(seg)); /* synch mode 4 etc */ 32262306a36Sopenharmony_ci omap_writel(0x00000000, EMIFS_ACS(seg)); /* OE hold/setup */ 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_cistatic struct gpiod_lookup_table osk_usb_gpio_table = { 32662306a36Sopenharmony_ci .dev_id = "ohci", 32762306a36Sopenharmony_ci .table = { 32862306a36Sopenharmony_ci /* Power GPIO on the I2C-attached TPS65010 */ 32962306a36Sopenharmony_ci GPIO_LOOKUP("tps65010", OSK_TPS_GPIO_USB_PWR_EN, "power", 33062306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 33162306a36Sopenharmony_ci GPIO_LOOKUP(OMAP_GPIO_LABEL, 9, "overcurrent", 33262306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 33362306a36Sopenharmony_ci { } 33462306a36Sopenharmony_ci }, 33562306a36Sopenharmony_ci}; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_cistatic struct omap_usb_config osk_usb_config __initdata = { 33862306a36Sopenharmony_ci /* has usb host connector (A) ... for development it can also 33962306a36Sopenharmony_ci * be used, with a NONSTANDARD gender-bending cable/dongle, as 34062306a36Sopenharmony_ci * a peripheral. 34162306a36Sopenharmony_ci */ 34262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_USB_OMAP) 34362306a36Sopenharmony_ci .register_dev = 1, 34462306a36Sopenharmony_ci .hmc_mode = 0, 34562306a36Sopenharmony_ci#else 34662306a36Sopenharmony_ci .register_host = 1, 34762306a36Sopenharmony_ci .hmc_mode = 16, 34862306a36Sopenharmony_ci .rwc = 1, 34962306a36Sopenharmony_ci#endif 35062306a36Sopenharmony_ci .pins[0] = 2, 35162306a36Sopenharmony_ci}; 35262306a36Sopenharmony_ci 35362306a36Sopenharmony_ci#define EMIFS_CS3_VAL (0x88013141) 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_cistatic struct gpiod_lookup_table osk_irq_gpio_table = { 35662306a36Sopenharmony_ci .dev_id = NULL, 35762306a36Sopenharmony_ci .table = { 35862306a36Sopenharmony_ci /* GPIO used for SMC91x IRQ */ 35962306a36Sopenharmony_ci GPIO_LOOKUP(OMAP_GPIO_LABEL, 0, "smc_irq", 36062306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 36162306a36Sopenharmony_ci /* GPIO used for CF IRQ */ 36262306a36Sopenharmony_ci GPIO_LOOKUP("gpio-48-63", 14, "cf_irq", 36362306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 36462306a36Sopenharmony_ci /* GPIO used by the TPS65010 chip */ 36562306a36Sopenharmony_ci GPIO_LOOKUP("mpuio", 1, "tps65010", 36662306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 36762306a36Sopenharmony_ci /* GPIOs used for serial wakeup IRQs */ 36862306a36Sopenharmony_ci GPIO_LOOKUP_IDX("gpio-32-47", 5, "wakeup", 0, 36962306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 37062306a36Sopenharmony_ci GPIO_LOOKUP_IDX("gpio-16-31", 2, "wakeup", 1, 37162306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 37262306a36Sopenharmony_ci GPIO_LOOKUP_IDX("gpio-48-63", 1, "wakeup", 2, 37362306a36Sopenharmony_ci GPIO_ACTIVE_HIGH), 37462306a36Sopenharmony_ci { } 37562306a36Sopenharmony_ci }, 37662306a36Sopenharmony_ci}; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_cistatic void __init osk_init(void) 37962306a36Sopenharmony_ci{ 38062306a36Sopenharmony_ci struct gpio_desc *d; 38162306a36Sopenharmony_ci u32 l; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci osk_init_smc91x(); 38462306a36Sopenharmony_ci osk_init_cf(2); /* CS2 */ 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci /* Workaround for wrong CS3 (NOR flash) timing 38762306a36Sopenharmony_ci * There are some U-Boot versions out there which configure 38862306a36Sopenharmony_ci * wrong CS3 memory timings. This mainly leads to CRC 38962306a36Sopenharmony_ci * or similar errors if you use NOR flash (e.g. with JFFS2) 39062306a36Sopenharmony_ci */ 39162306a36Sopenharmony_ci l = omap_readl(EMIFS_CCS(3)); 39262306a36Sopenharmony_ci if (l != EMIFS_CS3_VAL) 39362306a36Sopenharmony_ci omap_writel(EMIFS_CS3_VAL, EMIFS_CCS(3)); 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci osk_flash_resource.end = osk_flash_resource.start = omap_cs3_phys(); 39662306a36Sopenharmony_ci osk_flash_resource.end += SZ_32M - 1; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci /* 39962306a36Sopenharmony_ci * Add the GPIOs to be used as IRQs and immediately look them up 40062306a36Sopenharmony_ci * to be passed as an IRQ resource. This is ugly but should work 40162306a36Sopenharmony_ci * until the day we convert to device tree. 40262306a36Sopenharmony_ci */ 40362306a36Sopenharmony_ci gpiod_add_lookup_table(&osk_irq_gpio_table); 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci d = gpiod_get(NULL, "smc_irq", GPIOD_IN); 40662306a36Sopenharmony_ci if (IS_ERR(d)) { 40762306a36Sopenharmony_ci pr_err("Unable to get SMC IRQ GPIO descriptor\n"); 40862306a36Sopenharmony_ci } else { 40962306a36Sopenharmony_ci irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_RISING); 41062306a36Sopenharmony_ci osk5912_smc91x_resources[1] = DEFINE_RES_IRQ(gpiod_to_irq(d)); 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci d = gpiod_get(NULL, "cf_irq", GPIOD_IN); 41462306a36Sopenharmony_ci if (IS_ERR(d)) { 41562306a36Sopenharmony_ci pr_err("Unable to get CF IRQ GPIO descriptor\n"); 41662306a36Sopenharmony_ci } else { 41762306a36Sopenharmony_ci /* the CF I/O IRQ is really active-low */ 41862306a36Sopenharmony_ci irq_set_irq_type(gpiod_to_irq(d), IRQ_TYPE_EDGE_FALLING); 41962306a36Sopenharmony_ci osk5912_cf_resources[0] = DEFINE_RES_IRQ(gpiod_to_irq(d)); 42062306a36Sopenharmony_ci } 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci platform_add_devices(osk5912_devices, ARRAY_SIZE(osk5912_devices)); 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci l = omap_readl(USB_TRANSCEIVER_CTRL); 42562306a36Sopenharmony_ci l |= (3 << 1); 42662306a36Sopenharmony_ci omap_writel(l, USB_TRANSCEIVER_CTRL); 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci gpiod_add_lookup_table(&osk_usb_gpio_table); 42962306a36Sopenharmony_ci omap1_usb_init(&osk_usb_config); 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci omap_serial_init(); 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci /* irq for tps65010 chip */ 43462306a36Sopenharmony_ci /* bootloader effectively does: omap_cfg_reg(U19_1610_MPUIO1); */ 43562306a36Sopenharmony_ci d = gpiod_get(NULL, "tps65010", GPIOD_IN); 43662306a36Sopenharmony_ci if (IS_ERR(d)) 43762306a36Sopenharmony_ci pr_err("Unable to get TPS65010 IRQ GPIO descriptor\n"); 43862306a36Sopenharmony_ci else 43962306a36Sopenharmony_ci osk_i2c_board_info[0].irq = gpiod_to_irq(d); 44062306a36Sopenharmony_ci omap_register_i2c_bus(1, 400, osk_i2c_board_info, 44162306a36Sopenharmony_ci ARRAY_SIZE(osk_i2c_board_info)); 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ciMACHINE_START(OMAP_OSK, "TI-OSK") 44562306a36Sopenharmony_ci /* Maintainer: Dirk Behme <dirk.behme@de.bosch.com> */ 44662306a36Sopenharmony_ci .atag_offset = 0x100, 44762306a36Sopenharmony_ci .map_io = omap1_map_io, 44862306a36Sopenharmony_ci .init_early = omap1_init_early, 44962306a36Sopenharmony_ci .init_irq = omap1_init_irq, 45062306a36Sopenharmony_ci .init_machine = osk_init, 45162306a36Sopenharmony_ci .init_late = omap1_init_late, 45262306a36Sopenharmony_ci .init_time = omap1_timer_init, 45362306a36Sopenharmony_ci .restart = omap1_restart, 45462306a36Sopenharmony_ciMACHINE_END 455