Merge branch 'tegra/devel' into next/devel
This commit is contained in:
commit
1075329202
|
@ -0,0 +1,5 @@
|
|||
NVIDIA Tegra 2 pinmux controller
|
||||
|
||||
Required properties:
|
||||
- compatible : "nvidia,tegra20-pinmux"
|
||||
|
32
arch/arm/boot/dts/tegra-ventana.dts
Normal file
32
arch/arm/boot/dts/tegra-ventana.dts
Normal file
|
@ -0,0 +1,32 @@
|
|||
/dts-v1/;
|
||||
|
||||
/memreserve/ 0x1c000000 0x04000000;
|
||||
/include/ "tegra20.dtsi"
|
||||
|
||||
/ {
|
||||
model = "NVIDIA Tegra2 Ventana evaluation board";
|
||||
compatible = "nvidia,ventana", "nvidia,tegra20";
|
||||
|
||||
chosen {
|
||||
bootargs = "vmalloc=192M video=tegrafb console=ttyS0,115200n8 root=/dev/ram rdinit=/sbin/init";
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = < 0x00000000 0x40000000 >;
|
||||
};
|
||||
|
||||
serial@70006300 {
|
||||
clock-frequency = < 216000000 >;
|
||||
};
|
||||
|
||||
sdhci@c8000400 {
|
||||
cd-gpios = <&gpio 69 0>; /* gpio PI5 */
|
||||
wp-gpios = <&gpio 57 0>; /* gpio PH1 */
|
||||
power-gpios = <&gpio 155 0>; /* gpio PT3 */
|
||||
};
|
||||
|
||||
sdhci@c8000600 {
|
||||
power-gpios = <&gpio 70 0>; /* gpio PI6 */
|
||||
support-8bit;
|
||||
};
|
||||
};
|
|
@ -77,6 +77,14 @@
|
|||
gpio-controller;
|
||||
};
|
||||
|
||||
pinmux: pinmux@70000000 {
|
||||
compatible = "nvidia,tegra20-pinmux";
|
||||
reg = < 0x70000014 0x10 /* Tri-state registers */
|
||||
0x70000080 0x20 /* Mux registers */
|
||||
0x700000a0 0x14 /* Pull-up/down registers */
|
||||
0x70000868 0xa8 >; /* Pad control registers */
|
||||
};
|
||||
|
||||
serial@70006000 {
|
||||
compatible = "nvidia,tegra20-uart";
|
||||
reg = <0x70006000 0x40>;
|
||||
|
|
|
@ -25,6 +25,7 @@ CONFIG_MACH_KAEN=y
|
|||
CONFIG_MACH_PAZ00=y
|
||||
CONFIG_MACH_TRIMSLICE=y
|
||||
CONFIG_MACH_WARIO=y
|
||||
CONFIG_MACH_VENTANA=y
|
||||
CONFIG_TEGRA_DEBUG_UARTD=y
|
||||
CONFIG_ARM_ERRATA_742230=y
|
||||
CONFIG_NO_HZ=y
|
||||
|
@ -38,7 +39,6 @@ CONFIG_HIGHMEM=y
|
|||
CONFIG_ZBOOT_ROM_TEXT=0x0
|
||||
CONFIG_ZBOOT_ROM_BSS=0x0
|
||||
CONFIG_VFP=y
|
||||
CONFIG_PM=y
|
||||
CONFIG_NET=y
|
||||
CONFIG_PACKET=y
|
||||
CONFIG_UNIX=y
|
||||
|
@ -65,6 +65,7 @@ CONFIG_IPV6_TUNNEL=y
|
|||
CONFIG_IPV6_MULTIPLE_TABLES=y
|
||||
# CONFIG_WIRELESS is not set
|
||||
# CONFIG_FIRMWARE_IN_KERNEL is not set
|
||||
CONFIG_PROC_DEVICETREE=y
|
||||
CONFIG_BLK_DEV_LOOP=y
|
||||
CONFIG_MISC_DEVICES=y
|
||||
CONFIG_AD525X_DPOT=y
|
||||
|
@ -72,34 +73,61 @@ CONFIG_AD525X_DPOT_I2C=y
|
|||
CONFIG_ICS932S401=y
|
||||
CONFIG_APDS9802ALS=y
|
||||
CONFIG_ISL29003=y
|
||||
CONFIG_SCSI=y
|
||||
CONFIG_BLK_DEV_SD=y
|
||||
# CONFIG_SCSI_LOWLEVEL is not set
|
||||
CONFIG_NETDEVICES=y
|
||||
CONFIG_DUMMY=y
|
||||
CONFIG_NET_ETHERNET=y
|
||||
CONFIG_R8169=y
|
||||
# CONFIG_NETDEV_10000 is not set
|
||||
# CONFIG_WLAN is not set
|
||||
CONFIG_USB_PEGASUS=y
|
||||
CONFIG_USB_USBNET=y
|
||||
CONFIG_USB_NET_SMSC75XX=y
|
||||
CONFIG_USB_NET_SMSC95XX=y
|
||||
# CONFIG_INPUT is not set
|
||||
# CONFIG_SERIO is not set
|
||||
# CONFIG_VT is not set
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
# CONFIG_DEVKMEM is not set
|
||||
CONFIG_SERIAL_8250=y
|
||||
CONFIG_SERIAL_8250_CONSOLE=y
|
||||
# CONFIG_LEGACY_PTYS is not set
|
||||
CONFIG_SERIAL_OF_PLATFORM=y
|
||||
# CONFIG_HW_RANDOM is not set
|
||||
CONFIG_I2C=y
|
||||
# CONFIG_I2C_COMPAT is not set
|
||||
# CONFIG_I2C_HELPER_AUTO is not set
|
||||
CONFIG_I2C_TEGRA=y
|
||||
CONFIG_SPI=y
|
||||
CONFIG_SPI_TEGRA=y
|
||||
CONFIG_SENSORS_LM90=y
|
||||
CONFIG_MFD_TPS6586X=y
|
||||
CONFIG_REGULATOR=y
|
||||
CONFIG_REGULATOR_TPS6586X=y
|
||||
# CONFIG_USB_SUPPORT is not set
|
||||
CONFIG_SOUND=y
|
||||
CONFIG_SND=y
|
||||
# CONFIG_SND_SUPPORT_OLD_API is not set
|
||||
# CONFIG_SND_DRIVERS is not set
|
||||
# CONFIG_SND_PCI is not set
|
||||
# CONFIG_SND_ARM is not set
|
||||
# CONFIG_SND_SPI is not set
|
||||
# CONFIG_SND_USB is not set
|
||||
CONFIG_SND_SOC=y
|
||||
CONFIG_SND_SOC_TEGRA=y
|
||||
CONFIG_SND_SOC_TEGRA_WM8903=y
|
||||
CONFIG_SND_SOC_TEGRA_TRIMSLICE=y
|
||||
CONFIG_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_TEGRA=y
|
||||
CONFIG_USB_STORAGE=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_SDHCI=y
|
||||
CONFIG_MMC_SDHCI_PLTFM=y
|
||||
CONFIG_MMC_SDHCI_TEGRA=y
|
||||
CONFIG_RTC_CLASS=y
|
||||
CONFIG_RTC_DRV_TEGRA=y
|
||||
CONFIG_STAGING=y
|
||||
# CONFIG_STAGING_EXCLUDE_BUILD is not set
|
||||
CONFIG_IIO=y
|
||||
CONFIG_SENSORS_ISL29018=y
|
||||
CONFIG_SENSORS_AK8975=y
|
||||
|
@ -123,18 +151,15 @@ CONFIG_NLS_ISO8859_1=y
|
|||
CONFIG_PRINTK_TIME=y
|
||||
CONFIG_MAGIC_SYSRQ=y
|
||||
CONFIG_DEBUG_FS=y
|
||||
CONFIG_DEBUG_KERNEL=y
|
||||
CONFIG_DETECT_HUNG_TASK=y
|
||||
CONFIG_SCHEDSTATS=y
|
||||
CONFIG_TIMER_STATS=y
|
||||
CONFIG_DEBUG_SLAB=y
|
||||
# CONFIG_DEBUG_PREEMPT is not set
|
||||
CONFIG_DEBUG_MUTEXES=y
|
||||
CONFIG_DEBUG_SPINLOCK_SLEEP=y
|
||||
CONFIG_DEBUG_INFO=y
|
||||
CONFIG_DEBUG_VM=y
|
||||
CONFIG_DEBUG_SG=y
|
||||
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
|
||||
CONFIG_DEBUG_LL=y
|
||||
CONFIG_EARLY_PRINTK=y
|
||||
CONFIG_CRYPTO_ECB=y
|
||||
|
|
|
@ -69,6 +69,12 @@ config MACH_WARIO
|
|||
help
|
||||
Support for the Wario version of Seaboard
|
||||
|
||||
config MACH_VENTANA
|
||||
bool "Ventana board"
|
||||
select MACH_TEGRA_DT
|
||||
help
|
||||
Support for the nVidia Ventana development platform
|
||||
|
||||
choice
|
||||
prompt "Low-level debug console UART"
|
||||
default TEGRA_DEBUG_UART_NONE
|
||||
|
|
|
@ -31,6 +31,7 @@ obj-${CONFIG_MACH_SEABOARD} += board-seaboard-pinmux.o
|
|||
|
||||
obj-${CONFIG_MACH_TEGRA_DT} += board-dt.o
|
||||
obj-${CONFIG_MACH_TEGRA_DT} += board-harmony-pinmux.o
|
||||
obj-${CONFIG_MACH_TEGRA_DT} += board-seaboard-pinmux.o
|
||||
|
||||
obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice.o
|
||||
obj-${CONFIG_MACH_TRIMSLICE} += board-trimslice-pinmux.o
|
||||
|
|
|
@ -4,3 +4,4 @@ initrd_phys-$(CONFIG_ARCH_TEGRA_2x_SOC) := 0x00800000
|
|||
|
||||
dtb-$(CONFIG_MACH_HARMONY) += tegra-harmony.dtb
|
||||
dtb-$(CONFIG_MACH_SEABOARD) += tegra-seaboard.dtb
|
||||
dtb-$(CONFIG_MACH_VENTANA) += tegra-ventana.dtb
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
|
||||
void harmony_pinmux_init(void);
|
||||
void seaboard_pinmux_init(void);
|
||||
|
||||
void ventana_pinmux_init(void);
|
||||
|
||||
struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
|
||||
OF_DEV_AUXDATA("nvidia,tegra20-sdhci", TEGRA_SDMMC1_BASE, "sdhci-tegra.0", NULL),
|
||||
|
@ -80,9 +80,19 @@ static struct of_device_id tegra_dt_gic_match[] __initdata = {
|
|||
{}
|
||||
};
|
||||
|
||||
static struct {
|
||||
char *machine;
|
||||
void (*init)(void);
|
||||
} pinmux_configs[] = {
|
||||
{ "nvidia,harmony", harmony_pinmux_init },
|
||||
{ "nvidia,seaboard", seaboard_pinmux_init },
|
||||
{ "nvidia,ventana", ventana_pinmux_init },
|
||||
};
|
||||
|
||||
static void __init tegra_dt_init(void)
|
||||
{
|
||||
struct device_node *node;
|
||||
int i;
|
||||
|
||||
node = of_find_matching_node_by_address(NULL, tegra_dt_gic_match,
|
||||
TEGRA_ARM_INT_DIST_BASE);
|
||||
|
@ -91,10 +101,15 @@ static void __init tegra_dt_init(void)
|
|||
|
||||
tegra_clk_init_from_table(tegra_dt_clk_init_table);
|
||||
|
||||
if (of_machine_is_compatible("nvidia,harmony"))
|
||||
harmony_pinmux_init();
|
||||
else if (of_machine_is_compatible("nvidia,seaboard"))
|
||||
seaboard_pinmux_init();
|
||||
for (i = 0; i < ARRAY_SIZE(pinmux_configs); i++) {
|
||||
if (of_machine_is_compatible(pinmux_configs[i].machine)) {
|
||||
pinmux_configs[i].init();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
WARN(i == ARRAY_SIZE(pinmux_configs),
|
||||
"Unknown platform! Pinmuxing not initialized\n");
|
||||
|
||||
/*
|
||||
* Finished with the static registrations now; fill in the missing
|
||||
|
@ -106,6 +121,7 @@ static void __init tegra_dt_init(void)
|
|||
static const char * tegra_dt_board_compat[] = {
|
||||
"nvidia,harmony",
|
||||
"nvidia,seaboard",
|
||||
"nvidia,ventana",
|
||||
NULL
|
||||
};
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gpio-names.h"
|
||||
#include "board-harmony.h"
|
||||
#include "devices.h"
|
||||
|
||||
static struct tegra_pingroup_config harmony_pinmux[] = {
|
||||
{TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
|
@ -140,6 +141,11 @@ static struct tegra_pingroup_config harmony_pinmux[] = {
|
|||
{TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
};
|
||||
|
||||
static struct platform_device *pinmux_devices[] = {
|
||||
&tegra_gpio_device,
|
||||
&tegra_pinmux_device,
|
||||
};
|
||||
|
||||
static struct tegra_gpio_table gpio_table[] = {
|
||||
{ .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
|
||||
{ .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
|
||||
|
@ -155,6 +161,8 @@ static struct tegra_gpio_table gpio_table[] = {
|
|||
|
||||
void harmony_pinmux_init(void)
|
||||
{
|
||||
platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
|
||||
|
||||
tegra_pinmux_config_table(harmony_pinmux, ARRAY_SIZE(harmony_pinmux));
|
||||
|
||||
tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
|
||||
|
|
|
@ -18,10 +18,11 @@
|
|||
#include <linux/i2c.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/gpio.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/mfd/tps6586x.h>
|
||||
|
||||
#include <mach/iomap.h>
|
||||
#include <mach/irqs.h>
|
||||
|
||||
#include "board-harmony.h"
|
||||
|
@ -113,6 +114,16 @@ static struct i2c_board_info __initdata harmony_regulators[] = {
|
|||
|
||||
int __init harmony_regulator_init(void)
|
||||
{
|
||||
void __iomem *pmc = IO_ADDRESS(TEGRA_PMC_BASE);
|
||||
u32 pmc_ctrl;
|
||||
|
||||
/*
|
||||
* Configure the power management controller to trigger PMU
|
||||
* interrupts when low
|
||||
*/
|
||||
pmc_ctrl = readl(pmc + PMC_CTRL);
|
||||
writel(pmc_ctrl | PMC_CTRL_INTR_LOW, pmc + PMC_CTRL);
|
||||
|
||||
i2c_register_board_info(3, harmony_regulators, 1);
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "gpio-names.h"
|
||||
#include "board-paz00.h"
|
||||
#include "devices.h"
|
||||
|
||||
static struct tegra_pingroup_config paz00_pinmux[] = {
|
||||
{TEGRA_PINGROUP_ATA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
|
@ -140,6 +141,11 @@ static struct tegra_pingroup_config paz00_pinmux[] = {
|
|||
{TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
};
|
||||
|
||||
static struct platform_device *pinmux_devices[] = {
|
||||
&tegra_gpio_device,
|
||||
&tegra_pinmux_device,
|
||||
};
|
||||
|
||||
static struct tegra_gpio_table gpio_table[] = {
|
||||
{ .gpio = TEGRA_GPIO_SD1_CD, .enable = true },
|
||||
{ .gpio = TEGRA_GPIO_SD1_WP, .enable = true },
|
||||
|
@ -149,6 +155,8 @@ static struct tegra_gpio_table gpio_table[] = {
|
|||
|
||||
void paz00_pinmux_init(void)
|
||||
{
|
||||
platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
|
||||
|
||||
tegra_pinmux_config_table(paz00_pinmux, ARRAY_SIZE(paz00_pinmux));
|
||||
|
||||
tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/*
|
||||
* Copyright (C) 2010 NVIDIA Corporation
|
||||
* Copyright (C) 2010,2011 NVIDIA Corporation
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
|
@ -21,6 +22,7 @@
|
|||
|
||||
#include "gpio-names.h"
|
||||
#include "board-seaboard.h"
|
||||
#include "devices.h"
|
||||
|
||||
#define DEFAULT_DRIVE(_name) \
|
||||
{ \
|
||||
|
@ -157,10 +159,33 @@ static __initdata struct tegra_pingroup_config seaboard_pinmux[] = {
|
|||
{TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
};
|
||||
|
||||
static __initdata struct tegra_pingroup_config ventana_pinmux[] = {
|
||||
{TEGRA_PINGROUP_DAP3, TEGRA_MUX_DAP3, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
{TEGRA_PINGROUP_DDC, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_DTA, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_DTB, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_DTC, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_DTD, TEGRA_MUX_VI, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_GMD, TEGRA_MUX_SFLASH, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
{TEGRA_PINGROUP_LPW0, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_LPW2, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_LSC1, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_LSCK, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
{TEGRA_PINGROUP_LSDA, TEGRA_MUX_RSVD4, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
{TEGRA_PINGROUP_PTA, TEGRA_MUX_RSVD2, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_SLXC, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_SLXK, TEGRA_MUX_SDIO3, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
{TEGRA_PINGROUP_SPIA, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
{TEGRA_PINGROUP_SPIC, TEGRA_MUX_GMI, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
{TEGRA_PINGROUP_SPIG, TEGRA_MUX_SPI2_ALT, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
};
|
||||
|
||||
static struct platform_device *pinmux_devices[] = {
|
||||
&tegra_gpio_device,
|
||||
&tegra_pinmux_device,
|
||||
};
|
||||
|
||||
|
||||
static struct tegra_gpio_table gpio_table[] = {
|
||||
static struct tegra_gpio_table common_gpio_table[] = {
|
||||
{ .gpio = TEGRA_GPIO_SD2_CD, .enable = true },
|
||||
{ .gpio = TEGRA_GPIO_SD2_WP, .enable = true },
|
||||
{ .gpio = TEGRA_GPIO_SD2_POWER, .enable = true },
|
||||
|
@ -169,12 +194,46 @@ static struct tegra_gpio_table gpio_table[] = {
|
|||
{ .gpio = TEGRA_GPIO_ISL29018_IRQ, .enable = true },
|
||||
};
|
||||
|
||||
void __init seaboard_pinmux_init(void)
|
||||
static void __init update_pinmux(struct tegra_pingroup_config *newtbl, int size)
|
||||
{
|
||||
int i, j;
|
||||
struct tegra_pingroup_config *new_pingroup, *base_pingroup;
|
||||
|
||||
/* Update base seaboard pinmux table with secondary board
|
||||
* specific pinmux table table.
|
||||
*/
|
||||
for (i = 0; i < size; i++) {
|
||||
new_pingroup = &newtbl[i];
|
||||
for (j = 0; j < ARRAY_SIZE(seaboard_pinmux); j++) {
|
||||
base_pingroup = &seaboard_pinmux[j];
|
||||
if (new_pingroup->pingroup == base_pingroup->pingroup) {
|
||||
*base_pingroup = *new_pingroup;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void __init seaboard_common_pinmux_init(void)
|
||||
{
|
||||
platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
|
||||
|
||||
tegra_pinmux_config_table(seaboard_pinmux, ARRAY_SIZE(seaboard_pinmux));
|
||||
|
||||
tegra_drive_pinmux_config_table(seaboard_drive_pinmux,
|
||||
ARRAY_SIZE(seaboard_drive_pinmux));
|
||||
|
||||
tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
|
||||
tegra_gpio_config(common_gpio_table, ARRAY_SIZE(common_gpio_table));
|
||||
}
|
||||
|
||||
void __init seaboard_pinmux_init(void)
|
||||
{
|
||||
seaboard_common_pinmux_init();
|
||||
}
|
||||
|
||||
void __init ventana_pinmux_init(void)
|
||||
{
|
||||
update_pinmux(ventana_pinmux, ARRAY_SIZE(ventana_pinmux));
|
||||
seaboard_common_pinmux_init();
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "gpio-names.h"
|
||||
#include "board-trimslice.h"
|
||||
#include "devices.h"
|
||||
|
||||
static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
|
||||
{TEGRA_PINGROUP_ATA, TEGRA_MUX_IDE, TEGRA_PUPD_NORMAL, TEGRA_TRI_TRISTATE},
|
||||
|
@ -142,6 +143,11 @@ static __initdata struct tegra_pingroup_config trimslice_pinmux[] = {
|
|||
{TEGRA_PINGROUP_XM2D, TEGRA_MUX_NONE, TEGRA_PUPD_NORMAL, TEGRA_TRI_NORMAL},
|
||||
};
|
||||
|
||||
static struct platform_device *pinmux_devices[] = {
|
||||
&tegra_gpio_device,
|
||||
&tegra_pinmux_device,
|
||||
};
|
||||
|
||||
static struct tegra_gpio_table gpio_table[] = {
|
||||
{ .gpio = TRIMSLICE_GPIO_SD4_CD, .enable = true }, /* mmc4 cd */
|
||||
{ .gpio = TRIMSLICE_GPIO_SD4_WP, .enable = true }, /* mmc4 wp */
|
||||
|
@ -152,6 +158,7 @@ static struct tegra_gpio_table gpio_table[] = {
|
|||
|
||||
void __init trimslice_pinmux_init(void)
|
||||
{
|
||||
platform_add_devices(pinmux_devices, ARRAY_SIZE(pinmux_devices));
|
||||
tegra_pinmux_config_table(trimslice_pinmux, ARRAY_SIZE(trimslice_pinmux));
|
||||
tegra_gpio_config(gpio_table, ARRAY_SIZE(gpio_table));
|
||||
}
|
||||
|
|
|
@ -31,6 +31,90 @@
|
|||
#include <mach/usb_phy.h>
|
||||
#include "gpio-names.h"
|
||||
|
||||
static struct resource gpio_resource[] = {
|
||||
[0] = {
|
||||
.start = TEGRA_GPIO_BASE,
|
||||
.end = TEGRA_GPIO_BASE + TEGRA_GPIO_SIZE-1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
.start = INT_GPIO1,
|
||||
.end = INT_GPIO1,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[2] = {
|
||||
.start = INT_GPIO2,
|
||||
.end = INT_GPIO2,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[3] = {
|
||||
.start = INT_GPIO3,
|
||||
.end = INT_GPIO3,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[4] = {
|
||||
.start = INT_GPIO4,
|
||||
.end = INT_GPIO4,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[5] = {
|
||||
.start = INT_GPIO5,
|
||||
.end = INT_GPIO5,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[6] = {
|
||||
.start = INT_GPIO6,
|
||||
.end = INT_GPIO6,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
[7] = {
|
||||
.start = INT_GPIO7,
|
||||
.end = INT_GPIO7,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device tegra_gpio_device = {
|
||||
.name = "tegra-gpio",
|
||||
.id = -1,
|
||||
.resource = gpio_resource,
|
||||
.num_resources = ARRAY_SIZE(gpio_resource),
|
||||
};
|
||||
|
||||
static struct resource pinmux_resource[] = {
|
||||
[0] = {
|
||||
/* Tri-state registers */
|
||||
.start = TEGRA_APB_MISC_BASE + 0x14,
|
||||
.end = TEGRA_APB_MISC_BASE + 0x20 + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[1] = {
|
||||
/* Mux registers */
|
||||
.start = TEGRA_APB_MISC_BASE + 0x80,
|
||||
.end = TEGRA_APB_MISC_BASE + 0x9c + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[2] = {
|
||||
/* Pull-up/down registers */
|
||||
.start = TEGRA_APB_MISC_BASE + 0xa0,
|
||||
.end = TEGRA_APB_MISC_BASE + 0xb0 + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
[3] = {
|
||||
/* Pad control registers */
|
||||
.start = TEGRA_APB_MISC_BASE + 0x868,
|
||||
.end = TEGRA_APB_MISC_BASE + 0x90c + 3,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
};
|
||||
|
||||
struct platform_device tegra_pinmux_device = {
|
||||
.name = "tegra-pinmux",
|
||||
.id = -1,
|
||||
.resource = pinmux_resource,
|
||||
.num_resources = ARRAY_SIZE(pinmux_resource),
|
||||
};
|
||||
|
||||
static struct resource i2c_resource1[] = {
|
||||
[0] = {
|
||||
.start = INT_I2C,
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
extern struct platform_device tegra_gpio_device;
|
||||
extern struct platform_device tegra_pinmux_device;
|
||||
extern struct platform_device tegra_sdhci_device1;
|
||||
extern struct platform_device tegra_sdhci_device2;
|
||||
extern struct platform_device tegra_sdhci_device3;
|
||||
|
|
|
@ -199,6 +199,7 @@ struct tegra_drive_pingroup_config {
|
|||
|
||||
struct tegra_drive_pingroup_desc {
|
||||
const char *name;
|
||||
s16 reg_bank;
|
||||
s16 reg;
|
||||
};
|
||||
|
||||
|
@ -207,6 +208,9 @@ struct tegra_pingroup_desc {
|
|||
int funcs[4];
|
||||
int func_safe;
|
||||
int vddio;
|
||||
s16 tri_bank; /* Register bank the tri_reg exists within */
|
||||
s16 mux_bank; /* Register bank the mux_reg exists within */
|
||||
s16 pupd_bank; /* Register bank the pupd_reg exists within */
|
||||
s16 tri_reg; /* offset into the TRISTATE_REG_* register bank */
|
||||
s16 mux_reg; /* offset into the PIN_MUX_CTL_* register bank */
|
||||
s16 pupd_reg; /* offset into the PULL_UPDOWN_REG_* register bank */
|
||||
|
|
|
@ -31,10 +31,16 @@
|
|||
#include <mach/pinmux.h>
|
||||
#include <mach/suspend.h>
|
||||
|
||||
#define TRISTATE_REG_A 0x14
|
||||
#define PIN_MUX_CTL_REG_A 0x80
|
||||
#define PULLUPDOWN_REG_A 0xa0
|
||||
#define PINGROUP_REG_A 0x868
|
||||
|
||||
#define DRIVE_PINGROUP(pg_name, r) \
|
||||
[TEGRA_DRIVE_PINGROUP_ ## pg_name] = { \
|
||||
.name = #pg_name, \
|
||||
.reg = r \
|
||||
.reg_bank = 3, \
|
||||
.reg = ((r) - PINGROUP_REG_A) \
|
||||
}
|
||||
|
||||
const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE_PINGROUP] = {
|
||||
|
@ -90,11 +96,14 @@ const struct tegra_drive_pingroup_desc tegra_soc_drive_pingroups[TEGRA_MAX_DRIVE
|
|||
TEGRA_MUX_ ## f3, \
|
||||
}, \
|
||||
.func_safe = TEGRA_MUX_ ## f_safe, \
|
||||
.tri_reg = tri_r, \
|
||||
.tri_bank = 0, \
|
||||
.tri_reg = ((tri_r) - TRISTATE_REG_A), \
|
||||
.tri_bit = tri_b, \
|
||||
.mux_reg = mux_r, \
|
||||
.mux_bank = 1, \
|
||||
.mux_reg = ((mux_r) - PIN_MUX_CTL_REG_A), \
|
||||
.mux_bit = mux_b, \
|
||||
.pupd_reg = pupd_r, \
|
||||
.pupd_bank = 2, \
|
||||
.pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \
|
||||
.pupd_bit = pupd_b, \
|
||||
}
|
||||
|
||||
|
@ -217,62 +226,3 @@ const struct tegra_pingroup_desc tegra_soc_pingroups[TEGRA_MAX_PINGROUP] = {
|
|||
PINGROUP(XM2C, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 30),
|
||||
PINGROUP(XM2D, DDR, RSVD, RSVD, RSVD, RSVD, RSVD, -1, -1, -1, -1, 0xA8, 28),
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#define TRISTATE_REG_A 0x14
|
||||
#define TRISTATE_REG_NUM 4
|
||||
#define PIN_MUX_CTL_REG_A 0x80
|
||||
#define PIN_MUX_CTL_REG_NUM 8
|
||||
#define PULLUPDOWN_REG_A 0xa0
|
||||
#define PULLUPDOWN_REG_NUM 5
|
||||
|
||||
static u32 pinmux_reg[TRISTATE_REG_NUM + PIN_MUX_CTL_REG_NUM +
|
||||
PULLUPDOWN_REG_NUM +
|
||||
ARRAY_SIZE(tegra_soc_drive_pingroups)];
|
||||
|
||||
static inline unsigned long pg_readl(unsigned long offset)
|
||||
{
|
||||
return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
|
||||
}
|
||||
|
||||
static inline void pg_writel(unsigned long value, unsigned long offset)
|
||||
{
|
||||
writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
|
||||
}
|
||||
|
||||
void tegra_pinmux_suspend(void)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 *ctx = pinmux_reg;
|
||||
|
||||
for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
|
||||
*ctx++ = pg_readl(PIN_MUX_CTL_REG_A + i*4);
|
||||
|
||||
for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
|
||||
*ctx++ = pg_readl(PULLUPDOWN_REG_A + i*4);
|
||||
|
||||
for (i = 0; i < TRISTATE_REG_NUM; i++)
|
||||
*ctx++ = pg_readl(TRISTATE_REG_A + i*4);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
|
||||
*ctx++ = pg_readl(tegra_soc_drive_pingroups[i].reg);
|
||||
}
|
||||
|
||||
void tegra_pinmux_resume(void)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 *ctx = pinmux_reg;
|
||||
|
||||
for (i = 0; i < PIN_MUX_CTL_REG_NUM; i++)
|
||||
pg_writel(*ctx++, PIN_MUX_CTL_REG_A + i*4);
|
||||
|
||||
for (i = 0; i < PULLUPDOWN_REG_NUM; i++)
|
||||
pg_writel(*ctx++, PULLUPDOWN_REG_A + i*4);
|
||||
|
||||
for (i = 0; i < TRISTATE_REG_NUM; i++)
|
||||
pg_writel(*ctx++, TRISTATE_REG_A + i*4);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_soc_drive_pingroups); i++)
|
||||
pg_writel(*ctx++, tegra_soc_drive_pingroups[i].reg);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/errno.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include <mach/iomap.h>
|
||||
#include <mach/pinmux.h>
|
||||
|
@ -169,15 +170,17 @@ static const char *pupd_name(unsigned long val)
|
|||
}
|
||||
}
|
||||
|
||||
static int nbanks;
|
||||
static void __iomem **regs;
|
||||
|
||||
static inline unsigned long pg_readl(unsigned long offset)
|
||||
static inline u32 pg_readl(u32 bank, u32 reg)
|
||||
{
|
||||
return readl(IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
|
||||
return readl(regs[bank] + reg);
|
||||
}
|
||||
|
||||
static inline void pg_writel(unsigned long value, unsigned long offset)
|
||||
static inline void pg_writel(u32 val, u32 bank, u32 reg)
|
||||
{
|
||||
writel(value, IO_TO_VIRT(TEGRA_APB_MISC_BASE + offset));
|
||||
writel(val, regs[bank] + reg);
|
||||
}
|
||||
|
||||
static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
|
||||
|
@ -217,10 +220,10 @@ static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(pingroups[pg].mux_reg);
|
||||
reg = pg_readl(pingroups[pg].mux_bank, pingroups[pg].mux_reg);
|
||||
reg &= ~(0x3 << pingroups[pg].mux_bit);
|
||||
reg |= mux << pingroups[pg].mux_bit;
|
||||
pg_writel(reg, pingroups[pg].mux_reg);
|
||||
pg_writel(reg, pingroups[pg].mux_bank, pingroups[pg].mux_reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -241,11 +244,11 @@ int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(pingroups[pg].tri_reg);
|
||||
reg = pg_readl(pingroups[pg].tri_bank, pingroups[pg].tri_reg);
|
||||
reg &= ~(0x1 << pingroups[pg].tri_bit);
|
||||
if (tristate)
|
||||
reg |= 1 << pingroups[pg].tri_bit;
|
||||
pg_writel(reg, pingroups[pg].tri_reg);
|
||||
pg_writel(reg, pingroups[pg].tri_bank, pingroups[pg].tri_reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -272,10 +275,10 @@ int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(pingroups[pg].pupd_reg);
|
||||
reg = pg_readl(pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
|
||||
reg &= ~(0x3 << pingroups[pg].pupd_bit);
|
||||
reg |= pupd << pingroups[pg].pupd_bit;
|
||||
pg_writel(reg, pingroups[pg].pupd_reg);
|
||||
pg_writel(reg, pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -362,12 +365,12 @@ static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
if (hsm == TEGRA_HSM_ENABLE)
|
||||
reg |= (1 << 2);
|
||||
else
|
||||
reg &= ~(1 << 2);
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -387,12 +390,12 @@ static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
if (schmitt == TEGRA_SCHMITT_ENABLE)
|
||||
reg |= (1 << 3);
|
||||
else
|
||||
reg &= ~(1 << 3);
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -412,10 +415,10 @@ static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
reg &= ~(0x3 << 4);
|
||||
reg |= drive << 4;
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -435,10 +438,10 @@ static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
reg &= ~(0x1f << 12);
|
||||
reg |= pull_down << 12;
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -458,10 +461,10 @@ static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
reg &= ~(0x1f << 12);
|
||||
reg |= pull_up << 12;
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -481,10 +484,10 @@ static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
reg &= ~(0x3 << 28);
|
||||
reg |= slew_rising << 28;
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -504,10 +507,10 @@ static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
|
|||
|
||||
spin_lock_irqsave(&mux_lock, flags);
|
||||
|
||||
reg = pg_readl(drive_pingroups[pg].reg);
|
||||
reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
reg &= ~(0x3 << 30);
|
||||
reg |= slew_falling << 30;
|
||||
pg_writel(reg, drive_pingroups[pg].reg);
|
||||
pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
|
||||
|
||||
spin_unlock_irqrestore(&mux_lock, flags);
|
||||
|
||||
|
@ -665,6 +668,99 @@ void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *co
|
|||
}
|
||||
}
|
||||
|
||||
static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
int i;
|
||||
int config_bad = 0;
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
|
||||
if (!res)
|
||||
break;
|
||||
}
|
||||
nbanks = i;
|
||||
|
||||
for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
|
||||
if (pingroups[i].tri_bank >= nbanks) {
|
||||
dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i);
|
||||
config_bad = 1;
|
||||
}
|
||||
|
||||
if (pingroups[i].mux_bank >= nbanks) {
|
||||
dev_err(&pdev->dev, "pingroup %d: bad mux_bank\n", i);
|
||||
config_bad = 1;
|
||||
}
|
||||
|
||||
if (pingroups[i].pupd_bank >= nbanks) {
|
||||
dev_err(&pdev->dev, "pingroup %d: bad pupd_bank\n", i);
|
||||
config_bad = 1;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
|
||||
if (drive_pingroups[i].reg_bank >= nbanks) {
|
||||
dev_err(&pdev->dev,
|
||||
"drive pingroup %d: bad reg_bank\n", i);
|
||||
config_bad = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (config_bad)
|
||||
return -ENODEV;
|
||||
|
||||
regs = devm_kzalloc(&pdev->dev, nbanks * sizeof(*regs), GFP_KERNEL);
|
||||
if (!regs) {
|
||||
dev_err(&pdev->dev, "Can't alloc regs pointer\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < nbanks; i++) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Missing MEM resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res),
|
||||
dev_name(&pdev->dev))) {
|
||||
dev_err(&pdev->dev,
|
||||
"Couldn't request MEM resource %d\n", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regs[i] = devm_ioremap(&pdev->dev, res->start,
|
||||
resource_size(res));
|
||||
if (!regs) {
|
||||
dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i);
|
||||
return -ENODEV;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
|
||||
{ .compatible = "nvidia,tegra20-pinmux", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver tegra_pinmux_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-pinmux",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = tegra_pinmux_of_match,
|
||||
},
|
||||
.probe = tegra_pinmux_probe,
|
||||
};
|
||||
|
||||
static int __init tegra_pinmux_init(void)
|
||||
{
|
||||
return platform_driver_register(&tegra_pinmux_driver);
|
||||
}
|
||||
postcore_initcall(tegra_pinmux_init);
|
||||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
|
||||
#include <linux/debugfs.h>
|
||||
|
@ -684,6 +780,7 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
|
|||
int len;
|
||||
|
||||
for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
|
||||
unsigned long reg;
|
||||
unsigned long tri;
|
||||
unsigned long mux;
|
||||
unsigned long pupd;
|
||||
|
@ -696,8 +793,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
|
|||
seq_printf(s, "TEGRA_MUX_NONE");
|
||||
len = strlen("NONE");
|
||||
} else {
|
||||
mux = (pg_readl(pingroups[i].mux_reg) >>
|
||||
pingroups[i].mux_bit) & 0x3;
|
||||
reg = pg_readl(pingroups[i].mux_bank,
|
||||
pingroups[i].mux_reg);
|
||||
mux = (reg >> pingroups[i].mux_bit) & 0x3;
|
||||
if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
|
||||
seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
|
||||
len = 5;
|
||||
|
@ -713,8 +811,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
|
|||
seq_printf(s, "TEGRA_PUPD_NORMAL");
|
||||
len = strlen("NORMAL");
|
||||
} else {
|
||||
pupd = (pg_readl(pingroups[i].pupd_reg) >>
|
||||
pingroups[i].pupd_bit) & 0x3;
|
||||
reg = pg_readl(pingroups[i].pupd_bank,
|
||||
pingroups[i].pupd_reg);
|
||||
pupd = (reg >> pingroups[i].pupd_bit) & 0x3;
|
||||
seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
|
||||
len = strlen(pupd_name(pupd));
|
||||
}
|
||||
|
@ -723,8 +822,9 @@ static int dbg_pinmux_show(struct seq_file *s, void *unused)
|
|||
if (pingroups[i].tri_reg < 0) {
|
||||
seq_printf(s, "TEGRA_TRI_NORMAL");
|
||||
} else {
|
||||
tri = (pg_readl(pingroups[i].tri_reg) >>
|
||||
pingroups[i].tri_bit) & 0x1;
|
||||
reg = pg_readl(pingroups[i].tri_bank,
|
||||
pingroups[i].tri_reg);
|
||||
tri = (reg >> pingroups[i].tri_bit) & 0x1;
|
||||
|
||||
seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
|
||||
}
|
||||
|
@ -759,7 +859,8 @@ static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
|
|||
dbg_pad_field(s, 7 - len);
|
||||
|
||||
|
||||
reg = pg_readl(drive_pingroups[i].reg);
|
||||
reg = pg_readl(drive_pingroups[i].reg_bank,
|
||||
drive_pingroups[i].reg);
|
||||
if (HSM_EN(reg)) {
|
||||
seq_printf(s, "TEGRA_HSM_ENABLE");
|
||||
len = 16;
|
||||
|
|
|
@ -20,10 +20,11 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <asm/mach/irq.h>
|
||||
|
||||
|
@ -34,9 +35,7 @@
|
|||
#define GPIO_PORT(x) (((x) >> 3) & 0x3)
|
||||
#define GPIO_BIT(x) ((x) & 0x7)
|
||||
|
||||
#define GPIO_REG(x) (IO_TO_VIRT(TEGRA_GPIO_BASE) + \
|
||||
GPIO_BANK(x) * 0x80 + \
|
||||
GPIO_PORT(x) * 4)
|
||||
#define GPIO_REG(x) (GPIO_BANK(x) * 0x80 + GPIO_PORT(x) * 4)
|
||||
|
||||
#define GPIO_CNF(x) (GPIO_REG(x) + 0x00)
|
||||
#define GPIO_OE(x) (GPIO_REG(x) + 0x10)
|
||||
|
@ -75,15 +74,18 @@ struct tegra_gpio_bank {
|
|||
};
|
||||
|
||||
|
||||
static struct tegra_gpio_bank tegra_gpio_banks[] = {
|
||||
{.bank = 0, .irq = INT_GPIO1},
|
||||
{.bank = 1, .irq = INT_GPIO2},
|
||||
{.bank = 2, .irq = INT_GPIO3},
|
||||
{.bank = 3, .irq = INT_GPIO4},
|
||||
{.bank = 4, .irq = INT_GPIO5},
|
||||
{.bank = 5, .irq = INT_GPIO6},
|
||||
{.bank = 6, .irq = INT_GPIO7},
|
||||
};
|
||||
static void __iomem *regs;
|
||||
static struct tegra_gpio_bank tegra_gpio_banks[7];
|
||||
|
||||
static inline void tegra_gpio_writel(u32 val, u32 reg)
|
||||
{
|
||||
__raw_writel(val, regs + reg);
|
||||
}
|
||||
|
||||
static inline u32 tegra_gpio_readl(u32 reg)
|
||||
{
|
||||
return __raw_readl(regs + reg);
|
||||
}
|
||||
|
||||
static int tegra_gpio_compose(int bank, int port, int bit)
|
||||
{
|
||||
|
@ -97,7 +99,7 @@ static void tegra_gpio_mask_write(u32 reg, int gpio, int value)
|
|||
val = 0x100 << GPIO_BIT(gpio);
|
||||
if (value)
|
||||
val |= 1 << GPIO_BIT(gpio);
|
||||
__raw_writel(val, reg);
|
||||
tegra_gpio_writel(val, reg);
|
||||
}
|
||||
|
||||
void tegra_gpio_enable(int gpio)
|
||||
|
@ -117,7 +119,7 @@ static void tegra_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
|
|||
|
||||
static int tegra_gpio_get(struct gpio_chip *chip, unsigned offset)
|
||||
{
|
||||
return (__raw_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
|
||||
return (tegra_gpio_readl(GPIO_IN(offset)) >> GPIO_BIT(offset)) & 0x1;
|
||||
}
|
||||
|
||||
static int tegra_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
|
||||
|
@ -150,7 +152,7 @@ static void tegra_gpio_irq_ack(struct irq_data *d)
|
|||
{
|
||||
int gpio = d->irq - INT_GPIO_BASE;
|
||||
|
||||
__raw_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
|
||||
tegra_gpio_writel(1 << GPIO_BIT(gpio), GPIO_INT_CLR(gpio));
|
||||
}
|
||||
|
||||
static void tegra_gpio_irq_mask(struct irq_data *d)
|
||||
|
@ -203,10 +205,10 @@ static int tegra_gpio_irq_set_type(struct irq_data *d, unsigned int type)
|
|||
|
||||
spin_lock_irqsave(&bank->lvl_lock[port], flags);
|
||||
|
||||
val = __raw_readl(GPIO_INT_LVL(gpio));
|
||||
val = tegra_gpio_readl(GPIO_INT_LVL(gpio));
|
||||
val &= ~(GPIO_INT_LVL_MASK << GPIO_BIT(gpio));
|
||||
val |= lvl_type << GPIO_BIT(gpio);
|
||||
__raw_writel(val, GPIO_INT_LVL(gpio));
|
||||
tegra_gpio_writel(val, GPIO_INT_LVL(gpio));
|
||||
|
||||
spin_unlock_irqrestore(&bank->lvl_lock[port], flags);
|
||||
|
||||
|
@ -232,12 +234,12 @@ static void tegra_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
|
|||
|
||||
for (port = 0; port < 4; port++) {
|
||||
int gpio = tegra_gpio_compose(bank->bank, port, 0);
|
||||
unsigned long sta = __raw_readl(GPIO_INT_STA(gpio)) &
|
||||
__raw_readl(GPIO_INT_ENB(gpio));
|
||||
u32 lvl = __raw_readl(GPIO_INT_LVL(gpio));
|
||||
unsigned long sta = tegra_gpio_readl(GPIO_INT_STA(gpio)) &
|
||||
tegra_gpio_readl(GPIO_INT_ENB(gpio));
|
||||
u32 lvl = tegra_gpio_readl(GPIO_INT_LVL(gpio));
|
||||
|
||||
for_each_set_bit(pin, &sta, 8) {
|
||||
__raw_writel(1 << pin, GPIO_INT_CLR(gpio));
|
||||
tegra_gpio_writel(1 << pin, GPIO_INT_CLR(gpio));
|
||||
|
||||
/* if gpio is edge triggered, clear condition
|
||||
* before executing the hander so that we don't
|
||||
|
@ -271,11 +273,11 @@ void tegra_gpio_resume(void)
|
|||
|
||||
for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
|
||||
unsigned int gpio = (b<<5) | (p<<3);
|
||||
__raw_writel(bank->cnf[p], GPIO_CNF(gpio));
|
||||
__raw_writel(bank->out[p], GPIO_OUT(gpio));
|
||||
__raw_writel(bank->oe[p], GPIO_OE(gpio));
|
||||
__raw_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
|
||||
__raw_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
|
||||
tegra_gpio_writel(bank->cnf[p], GPIO_CNF(gpio));
|
||||
tegra_gpio_writel(bank->out[p], GPIO_OUT(gpio));
|
||||
tegra_gpio_writel(bank->oe[p], GPIO_OE(gpio));
|
||||
tegra_gpio_writel(bank->int_lvl[p], GPIO_INT_LVL(gpio));
|
||||
tegra_gpio_writel(bank->int_enb[p], GPIO_INT_ENB(gpio));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -294,11 +296,11 @@ void tegra_gpio_suspend(void)
|
|||
|
||||
for (p = 0; p < ARRAY_SIZE(bank->oe); p++) {
|
||||
unsigned int gpio = (b<<5) | (p<<3);
|
||||
bank->cnf[p] = __raw_readl(GPIO_CNF(gpio));
|
||||
bank->out[p] = __raw_readl(GPIO_OUT(gpio));
|
||||
bank->oe[p] = __raw_readl(GPIO_OE(gpio));
|
||||
bank->int_enb[p] = __raw_readl(GPIO_INT_ENB(gpio));
|
||||
bank->int_lvl[p] = __raw_readl(GPIO_INT_LVL(gpio));
|
||||
bank->cnf[p] = tegra_gpio_readl(GPIO_CNF(gpio));
|
||||
bank->out[p] = tegra_gpio_readl(GPIO_OUT(gpio));
|
||||
bank->oe[p] = tegra_gpio_readl(GPIO_OE(gpio));
|
||||
bank->int_enb[p] = tegra_gpio_readl(GPIO_INT_ENB(gpio));
|
||||
bank->int_lvl[p] = tegra_gpio_readl(GPIO_INT_LVL(gpio));
|
||||
}
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
|
@ -328,27 +330,54 @@ static struct irq_chip tegra_gpio_irq_chip = {
|
|||
*/
|
||||
static struct lock_class_key gpio_lock_class;
|
||||
|
||||
static int __init tegra_gpio_init(void)
|
||||
static int __devinit tegra_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct resource *res;
|
||||
struct tegra_gpio_bank *bank;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(tegra_gpio_banks); i++) {
|
||||
res = platform_get_resource(pdev, IORESOURCE_IRQ, i);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Missing IRQ resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
bank = &tegra_gpio_banks[i];
|
||||
bank->bank = i;
|
||||
bank->irq = res->start;
|
||||
}
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res) {
|
||||
dev_err(&pdev->dev, "Missing MEM resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (!devm_request_mem_region(&pdev->dev, res->start,
|
||||
resource_size(res),
|
||||
dev_name(&pdev->dev))) {
|
||||
dev_err(&pdev->dev, "Couldn't request MEM resource\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
regs = devm_ioremap(&pdev->dev, res->start, resource_size(res));
|
||||
if (!regs) {
|
||||
dev_err(&pdev->dev, "Couldn't ioremap regs\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
for (i = 0; i < 7; i++) {
|
||||
for (j = 0; j < 4; j++) {
|
||||
int gpio = tegra_gpio_compose(i, j, 0);
|
||||
__raw_writel(0x00, GPIO_INT_ENB(gpio));
|
||||
tegra_gpio_writel(0x00, GPIO_INT_ENB(gpio));
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF_GPIO
|
||||
/*
|
||||
* This isn't ideal, but it gets things hooked up until this
|
||||
* driver is converted into a platform_device
|
||||
*/
|
||||
tegra_gpio_chip.of_node = of_find_compatible_node(NULL, NULL,
|
||||
"nvidia,tegra20-gpio");
|
||||
#endif /* CONFIG_OF_GPIO */
|
||||
tegra_gpio_chip.of_node = pdev->dev.of_node;
|
||||
#endif
|
||||
|
||||
gpiochip_add(&tegra_gpio_chip);
|
||||
|
||||
|
@ -375,6 +404,24 @@ static int __init tegra_gpio_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id tegra_gpio_of_match[] __devinitdata = {
|
||||
{ .compatible = "nvidia,tegra20-gpio", },
|
||||
{ },
|
||||
};
|
||||
|
||||
static struct platform_driver tegra_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "tegra-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = tegra_gpio_of_match,
|
||||
},
|
||||
.probe = tegra_gpio_probe,
|
||||
};
|
||||
|
||||
static int __init tegra_gpio_init(void)
|
||||
{
|
||||
return platform_driver_register(&tegra_gpio_driver);
|
||||
}
|
||||
postcore_initcall(tegra_gpio_init);
|
||||
|
||||
void __init tegra_gpio_config(struct tegra_gpio_table *table, int num)
|
||||
|
@ -407,13 +454,13 @@ static int dbg_gpio_show(struct seq_file *s, void *unused)
|
|||
seq_printf(s,
|
||||
"%d:%d %02x %02x %02x %02x %02x %02x %06x\n",
|
||||
i, j,
|
||||
__raw_readl(GPIO_CNF(gpio)),
|
||||
__raw_readl(GPIO_OE(gpio)),
|
||||
__raw_readl(GPIO_OUT(gpio)),
|
||||
__raw_readl(GPIO_IN(gpio)),
|
||||
__raw_readl(GPIO_INT_STA(gpio)),
|
||||
__raw_readl(GPIO_INT_ENB(gpio)),
|
||||
__raw_readl(GPIO_INT_LVL(gpio)));
|
||||
tegra_gpio_readl(GPIO_CNF(gpio)),
|
||||
tegra_gpio_readl(GPIO_OE(gpio)),
|
||||
tegra_gpio_readl(GPIO_OUT(gpio)),
|
||||
tegra_gpio_readl(GPIO_IN(gpio)),
|
||||
tegra_gpio_readl(GPIO_INT_STA(gpio)),
|
||||
tegra_gpio_readl(GPIO_INT_ENB(gpio)),
|
||||
tegra_gpio_readl(GPIO_INT_LVL(gpio)));
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue