G900 support

This commit is contained in:
Angell Fear
2010-09-03 00:59:42 +06:00
parent 464e36dc43
commit 0666031fb7
865 changed files with 20743 additions and 119167 deletions

View File

@@ -0,0 +1,702 @@
/**
*
* Hardware definitions for the Toshiba G900
*
* Most of initial work (FB, MMC, keyboard) was done by
* "El Tuba" <tuba.linux@gmail.com>
* 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 <linux/init.h>
#include <linux/kernel.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/spi/spi.h>
#include <linux/i2c.h>
#include <linux/gpio_keys.h>
#include <linux/pda_power.h>
//#include <linux/mtd/mtd.h>
//#include <linux/mtd/map.h>
//#include <linux/mtd/partitions.h>
//#include <linux/mtd/physmap.h>
#include <asm/gpio.h>
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/flash.h>
#include <mach/mfp-pxa27x.h>
#include <mach/pxa2xx-regs.h>
#include <plat/i2c.h>
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/audio.h>
#include <mach/regs-ac97.h>
#include <mach/ohci.h>
#include <linux/usb/gpio_vbus.h>
//#include <mach/g900-init.h>
#include <mach/g900-gpio.h>
#include <mach/gpio.h>
#include <mach/ssp.h>
#include <mach/pxa2xx_spi.h>
#include <linux/i2c/ak4183.h>
#include <linux/spi/libertas_spi.h>
#include <asm/setup.h>
#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 = 8000,
// .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 = 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 = 13000000,
.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