/** * * Hardware definitions for the Toshiba G900 * * Most of initial work (FB, MMC, keyboard) was done by * "El Tuba" * and * LeStat (Eugene Nikitin). * * Use consistent with the GNU GPL is permitted, * provided that this copyright notice is * preserved in its entirety in all copies and derived works. * Based on Asus P535 Android port. */ #include #include #include #include #include #include #include #include #include #include #include #include //#include //#include //#include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include "../generic.h" #include "../devices.h" #define G900_CFG_IN(pin, af) \ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK)) |\ (MFP_PIN(pin) | MFP_##af | MFP_DIR_IN)) #define G900_CFG_OUT(pin, af, state) \ ((MFP_CFG_DEFAULT & ~(MFP_AF_MASK | MFP_DIR_MASK | MFP_LPM_STATE_MASK)) |\ (MFP_PIN(pin) | MFP_##af | MFP_DIR_OUT | MFP_LPM_##state)) /* Devices */ #define G900_PARENT_DEV(var, strname, tparent, pdata) \ static struct platform_device var = { \ .name = strname, \ .id = -1, \ .dev = { \ .platform_data = pdata, \ .parent = tparent, \ }, \ }; #define G900_SIMPLE_DEV(var, strname, pdata) \ G900_PARENT_DEV(var, strname, NULL, pdata) static unsigned long g900_pin_config[] __initdata = { /* MMC */ GPIO32_MMC_CLK, GPIO92_MMC_DAT_0, GPIO109_MMC_DAT_1, GPIO110_MMC_DAT_2, GPIO111_MMC_DAT_3, GPIO112_MMC_CMD, /* Sound */ GPIO28_AC97_BITCLK, GPIO29_AC97_SDATA_IN_0, GPIO30_AC97_SDATA_OUT, GPIO31_AC97_SYNC, GPIO89_AC97_SYSCLK, GPIO113_AC97_nRESET, /* USB Host Port & otg */ G900_CFG_IN(GPIO40_nUSB_DETECT, AF0), GPIO41_USB_P2_7, G900_CFG_OUT(GPIO75_USB_ENABLE, AF0, DRIVE_LOW), G900_CFG_OUT(GPIO93_USB_ENABLE, AF0, DRIVE_LOW), /* d+ = USBC_P(B 22) d- = USBC_N(C 20) */ /* Synchronous Serial Port 2 (FinderPrint sensor)*/ GPIO87_SSP2_TXD, GPIO11_SSP2_RXD, GPIO19_SSP2_SCLK, GPIO88_SSP2_SFRM, GPIO96_GPIO, /* FinderPrint IRQ*/ /* Synchronous Serial Port 3 (WI-FI)*/ GPIO38_SSP3_TXD, GPIO82_SSP3_RXD, //GPIO34_GPIO, /* SSP3 clock is used as GPIO for Libertas pin-strap */ GPIO34_SSP3_SCLK, GPIO14_GPIO, /* wlan IRQ */ GPIO24_GPIO, /* WLAN reset */ GPIO77_GPIO, /* WLAN power */ GPIO39_GPIO, /* WLAN cs */ /* BTUART */ GPIO42_BTUART_RXD, GPIO43_BTUART_TXD, GPIO44_BTUART_CTS, GPIO45_BTUART_RTS, /* Leds G900_CFG_OUT(GPIO16_LED_nVibra, AF0, DRIVE_HIGH), // or should be GPIO16_PWM0_OUT ? G900_CFG_OUT(GPIO37_LED_nFlash, AF0, DRIVE_HIGH), // it can't be GPIO37_USB_P2_8 ? G900_CFG_OUT(GPIO85_LED_nKeyboard, AF0, DRIVE_HIGH), G900_CFG_OUT(GPIO86_LED_nKeypad, AF0, DRIVE_HIGH), */ /* Lcd backlight */ GPIO17_PWM1_OUT, /* I2C */ GPIO117_I2C_SCL, GPIO118_I2C_SDA, /* TS */ G900_CFG_IN(GPIO_TS_IRQ, AF0), /* HZ */ GPIO33_nCS_5, GPIO80_nCS_4, GPIO78_nCS_2, /* Variable Latency I/O Ready Pin */ /* An external variable-latency I/O (VLIO) device asserts RDY when it is ready to transfer data. */ GPIO18_RDY, /* PC Card Write Enable */ /* Enables writes to PC Card memory and PC Card attribute space. Also serves as the write enable signal for variable-latency I/O. */ GPIO49_nPWE, /* DMA Request 0 */ /* DMA request from an external companion chip. */ GPIO20_DREQ_0, G900_CFG_IN(0, AF0), /* testing */ /* GPIO15_nPCE_1 // GF in FE GPIO50_nPIOR // mb GPIO48_nPOE // mb GPIO57_nIOIS16 // mb 1 = Data bus is 16 bits wide GPIO79_PSKTSEL //mb GPIO46_STUART_RXD, // STD_UART receive data GPIO47_STUART_TXD, // STD_UART transmit data */ }; /***********************************************/ /****** TouchScreen for AK4183 Device ********/ /***********************************************/ static int ts_get_pendown_state(void) { //printk(KERN_INFO "\t >>> %s <<< \n", __FUNCTION__); return !gpio_get_value(GPIO_TS_IRQ); } static int ts_init(void) { if (gpio_request(GPIO_TS_IRQ, "AK4183 pendown") < 0) { printk(KERN_ERR "AK4183 TS: can't get AK4183 pen down GPIO\n"); } return 0; } struct ak4183_platform_data ak4183_info = { .model = 4183, .get_pendown_state = ts_get_pendown_state, .init_platform_hw = ts_init, .x_plate_ohms = 248, .y_plate_ohms = 516, // .clear_penirq = true, }; static struct i2c_board_info __initdata g900_i2c_board_info[] = { { I2C_BOARD_INFO("ak4183", 0x48), .type = "ak4183", .platform_data = &ak4183_info, .irq = gpio_to_irq(GPIO_TS_IRQ), }, }; /***********************************************/ /****************** I2C *******************/ /***********************************************/ struct i2c_pxa_platform_data i2c_pdata = { .fast_mode = 1, }; static void __init g900_i2c_init(void) { pxa_set_i2c_info(&i2c_pdata); i2c_register_board_info(0, ARRAY_AND_SIZE(g900_i2c_board_info)); } /***********************************************/ /****************** SD & MMC card **************/ /***********************************************/ static struct pxamci_platform_data g900_mci_platform_data = { .ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34, .gpio_card_ro = -1, .gpio_power = GPIO_G900_SD_POWER, .gpio_card_detect = GPIO_G900_SD_DETECT, }; static void __init g900_mmc_init(void) { pxa_set_mci_info(&g900_mci_platform_data); } /***********************************************/ /****************** USB bus pxa **************/ /***********************************************/ /****************************************************************************** * USB host ******************************************************************************/ /* // stass static struct pxaohci_platform_data g900_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW | POWER_SENSE_LOW, // .flags = ENABLE_PORT_ALL | POWER_CONTROL_LOW | POWER_SENSE_LOW, }; */ /* // angell static struct pxaohci_platform_data g900_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, //.init = g900_ohci_init, .power_on_delay = 11, .flags = ENABLE_PORT1 | POWER_CONTROL_LOW | OC_MODE_PERPORT , .power_budget = 100, }; */ static struct pxaohci_platform_data g900_ohci_platform_data = { .port_mode = PMM_PERPORT_MODE, .flags = ENABLE_PORT1 | ENABLE_PORT2 | POWER_CONTROL_LOW | POWER_SENSE_LOW, //.flags = ENABLE_PORT2 | OC_MODE_PERPORT |POWER_CONTROL_LOW , .power_on_delay = 0x08, .power_budget = 501, }; /* UHCHR : 0x00000084 = 00000000 00000000 00000000 10000100 UHCRHDA : 0x04000b02 = 00000100 00000000 00001011 00000010 uhcrhda : 0x04001102 = 00000100 00000000 00001011 00000010 [ 494.474134] uhchr: 0x00000084 [ 494.484948] uhcrhda: 0x04000902 [ 494.495882] pxa27x_setup_hc write [ 494.506884] uhchr: 0x00000084 [ 494.518029] uhcrhda: 0x04000902 [ 494.529259] pxa27x_ohci_select_pmm read(mode = 3) [ 494.540759] uhcrhda: 0x04000902 [ 494.552272] uhcrhdb: 0x00000000 [ 494.563518] pxa27x_ohci_select_pmm write [ 494.574646] uhcrhda: 0x04000b02 [ */ /****************************************************************************** * USB Gadget (UDC) ******************************************************************************/ static struct pxa2xx_udc_mach_info g900_udc_info __initdata = { // .udc_is_connected = is_usb_connected, .gpio_vbus = GPIO40_nUSB_DETECT, // .gpio_vbus = GPIO41_USB_P2_7, // .gpio_pullup = GPIO93_USB_ENABLE, .gpio_pullup = GPIO75_USB_ENABLE, // .udc_command = g900_udc_command, }; struct gpio_vbus_mach_info gpio_vbus_data = { .gpio_vbus = GPIO40_nUSB_DETECT, .gpio_vbus_inverted = 1, .gpio_pullup = -1, }; static void __init usb_init(void) { printk(KERN_INFO "pxa_set_ohci_info\n"); pxa_set_ohci_info(&g900_ohci_platform_data); printk(KERN_INFO "pxa_set_udc_info\n"); pxa_set_udc_info(&g900_udc_info); } /***********************************************/ /****************** SPI Device *****************/ /***********************************************/ static struct pxa2xx_spi_master pxa_ssp_master_1_info = { .num_chipselect = 1, }; static struct pxa2xx_spi_master pxa_ssp_master_2_info = { .num_chipselect = 1, .enable_dma = 1, // .clock_enable = CKEN_SSP3, }; static struct pxa2xx_spi_chip gspi8385_info = { .rx_threshold = 1, .tx_threshold = 1, .timeout = 1000, .gpio_cs = G900_WIFI_CS, }; static unsigned long g900_libertas_pin_config[] = { // SSP3 // GPIO34_SSP3_SCLK, // GPIO39_GPIO, /// wifi_cs /// GPIO38_SSP3_TXD, GPIO82_SSP3_RXD, }; static int g900_libertas_setup(struct spi_device *spi) { int err = 0 ; err = gpio_request(G900_WIFI_STRAP, "WLAN STRAP"); //if (err) return err; err = gpio_request(G900_WIFI_RESET, "WLAN RST"); //if (err) goto err_free_strap; err = gpio_direction_output(G900_WIFI_STRAP, 0); err = gpio_direction_output(G900_WIFI_RESET, 0); //if (err) goto err_free_strap; msleep(300); err = gpio_direction_output(G900_WIFI_STRAP, 1); //if (err) goto err_free_strap; msleep(100); pxa2xx_mfp_config(ARRAY_AND_SIZE(g900_libertas_pin_config)); gpio_set_value(G900_WIFI_RESET, 1); msleep(100); spi->bits_per_word = 16; spi_setup(spi); return 0; /*err_free_strap: gpio_free(G900_WIFI_STRAP); */ return err; } static int g900_libertas_teardown(struct spi_device *spi) { gpio_set_value(G900_WIFI_RESET, 0); gpio_set_value(G900_WIFI_STRAP, 0); gpio_free(G900_WIFI_RESET); gpio_free(G900_WIFI_STRAP); return 0; } struct libertas_spi_platform_data g900_libertas_pdata = { .use_dummy_writes = 1, .setup = g900_libertas_setup, .teardown = g900_libertas_teardown, }; static struct spi_board_info g900_spi_devices[] __initdata = { { .modalias = "libertas_spi", .max_speed_hz = 12000000, /*MAX 13000000*/ .bus_num = 3, .irq = gpio_to_irq(G900_WIFI_IRQ), .chip_select = 0, .platform_data = &g900_libertas_pdata, .controller_data = &gspi8385_info, }, { .modalias = "finderprint_sensor", .max_speed_hz = 8000000, .bus_num = 2, .irq = gpio_to_irq(FP_IRQ), .chip_select = 0, //.platform_data = &, //.controller_data = &, }, }; static void __init spi_init(void) { pxa2xx_set_spi_info(2, &pxa_ssp_master_1_info); /* finderprint */ pxa2xx_set_spi_info(3, &pxa_ssp_master_2_info); /* wifi*/ spi_register_board_info(g900_spi_devices, ARRAY_SIZE(g900_spi_devices)); } /* DEBUG */ static void __init debuging(void) { } /** * reset_bluetooth() reset the bluecore to ensure consistent state **/ /* static int g900_reset_bluetooth(void) { int err; err = gpio_request(G900_BT_RESET, "G900_BT_RESET"); if (err) { printk(KERN_ERR "Could not get gpio for bluetooth reset \n"); return err; } err = gpio_request(G900_BT_POWER, "G900_BT_POWER"); if (err) { printk(KERN_ERR "Could not get gpio for bluetooth power \n"); return err; } gpio_direction_output(G900_BT_POWER, 1); mdelay(5); // now reset it - 5 msec minimum gpio_set_value(G900_BT_RESET, 0); mdelay(10); gpio_direction_input(G900_BT_RESET); gpio_free(G900_BT_RESET); gpio_free(G900_BT_POWER); printk(KERN_INFO "Bluetooth: reset done\n"); return 0; } static int wifi_power(void) { int err; err = gpio_request(G900_WIFI_RESET, "G900_WIFI_RESET"); if (err) { printk(KERN_ERR "Could not get gpio for WIFI power \n"); return err; } gpio_direction_output(G900_WIFI_RESET, 1); mdelay(200); gpio_free(G900_WIFI_RESET); printk("WIFI power set on"); return 0; } */ /***********************************************/ /****************** Device *********************/ /***********************************************/ static struct platform_device g900_ts = { .name = "g900-ts", }; static struct platform_device g900_keyboard = { .name = "g900-keyboard", }; static struct platform_device g900_button = { .name = "g900-button", }; static struct platform_device g900_sound = { .name = "g900-wm9714", .id = -1, .dev = { .platform_data = NULL, .parent = NULL, }, }; static struct platform_device pxa2xx_pcm = { .name = "pxa2xx-pcm", .id = -1, .dev = { .platform_data = NULL, .parent = NULL, }, }; #if 0 static struct platform_device wm9713_codec = { .name = "wm9713-codec", .id = -1, .dev = { .platform_data = NULL, .parent = &pxa2xx_ac97.dev, }, }; #endif static struct platform_device *g900_devices[] __initdata = { &g900_keyboard, &g900_button, &g900_ts, &pxa2xx_pcm, &g900_sound, }; static void __init g900_map_io(void) { pxa_map_io(); } static void __init g900_init_irq(void) { pxa27x_init_irq(); } static void fix_msc(void) { /* * Localbus setup: * CS0: ; * CS1: ; * CS5: gsm. */ MSC0 = 0x7ff09888; MSC1 = 0x000089c4; MSC2 = 0x5ff95ff9; MDREFR = 0x2013a01e; } static void __init g900_init(void) { /* disable primary codec interrupt to prevent WM9714 constantly * interrupting the CPU and preventing the boot process to complete */ GCR |= GCR_ACLINK_OFF; fix_msc(); pxa2xx_mfp_config(ARRAY_AND_SIZE(g900_pin_config)); g900_mmc_init(); pxa_set_btuart_info(NULL); pxa_set_ac97_info(NULL); g900_i2c_init(); spi_init(); usb_init(); debuging(); platform_add_devices(ARRAY_AND_SIZE(g900_devices)); // reset bluetooth //g900_reset_bluetooth(); //wifi_power(); } #if 0 void __init g900_fixup(struct machine_desc *desc, struct tag *tags, char **cmdline, struct meminfo *mi) { //sharpsl_save_param(); mi->nr_banks=2; mi->bank[0].start = 0xa0000000; mi->bank[0].node = 0; mi->bank[0].size = (64*1024*1024); mi->bank[1].start = 0xb0000000; mi->bank[1].node = 1; mi->bank[1].size = (64*1024*1024); } #endif MACHINE_START(G900, "Toshiba G900") .phys_io = 0x40000000, .io_pg_offst = (io_p2v(0x40000000) >> 18) & 0xfffc, .boot_params = 0xa0000100, // .fixup = g900_fixup, .map_io = g900_map_io, .init_irq = g900_init_irq, .timer = &pxa_timer, .init_machine = g900_init, MACHINE_END