Skip to content

Commit

Permalink
pinctrl: add a driver for the U300 pinmux
Browse files Browse the repository at this point in the history
This adds a driver for the U300 pinmux portions of the system
controller "SYSCON". It also serves as an example of how to use
the pinmux subsystem. This driver also houses the platform data
for the only supported platform.

This deletes the old U300 driver in arch/arm/mach-u300 and
replace it with a driver using the new subsystem.

The new driver is considerably fatter than the old one, but it
also registers all 467 pins of the system and adds the power
and EMIF pin groups and corresponding functions. The idea
is to use this driver as a a reference for other
implementation so it needs to be as complete and verbose
as possible.

Reviewed-by: Barry Song <21cnbao@gmail.com>
[Fixup for changed function names and semantics in the v10 patch]
Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
  • Loading branch information
Linus Walleij authored and Linus Walleij committed Oct 13, 2011
1 parent 2744e8a commit 98da352
Show file tree
Hide file tree
Showing 11 changed files with 1,228 additions and 581 deletions.
2 changes: 2 additions & 0 deletions arch/arm/mach-u300/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ comment "ST-Ericsson Mobile Platform Products"

config MACH_U300
bool "U300"
select PINCTRL
select PINMUX_U300

comment "ST-Ericsson U300/U330/U335/U365 Feature Selections"

Expand Down
2 changes: 1 addition & 1 deletion arch/arm/mach-u300/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Makefile for the linux kernel, U300 machine.
#

obj-y := core.o clock.o timer.o padmux.o
obj-y := core.o clock.o timer.o
obj-m :=
obj-n :=
obj- :=
Expand Down
84 changes: 82 additions & 2 deletions arch/arm/mach-u300/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#include <linux/err.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h>

#include <asm/types.h>
#include <asm/setup.h>
Expand Down Expand Up @@ -1535,6 +1537,14 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS,
};

static struct resource pinmux_resources[] = {
{
.start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
},
};

static struct platform_device wdog_device = {
.name = "coh901327_wdog",
.id = -1,
Expand Down Expand Up @@ -1630,6 +1640,72 @@ static struct platform_device dma_device = {
},
};

static struct platform_device pinmux_device = {
.name = "pinmux-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinmux_resources),
.resource = pinmux_resources,
};

/* Pinmux settings */
static struct pinmux_map u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */
PINMUX_MAP_PRIMARY_SYS_HOG("POWER", "power"),
PINMUX_MAP_PRIMARY_SYS_HOG("EMIF0", "emif0"),
PINMUX_MAP_PRIMARY_SYS_HOG("EMIF1", "emif1"),
/* per-device maps for MMC/SD, SPI and UART */
PINMUX_MAP_PRIMARY("MMCSD", "mmc0", "mmci"),
PINMUX_MAP_PRIMARY("SPI", "spi0", "pl022"),
PINMUX_MAP_PRIMARY("UART0", "uart0", "uart0"),
};

struct u300_mux_hog {
const char *name;
struct device *dev;
struct pinmux *pmx;
};

static struct u300_mux_hog u300_mux_hogs[] = {
{
.name = "uart0",
.dev = &uart0_device.dev,
},
{
.name = "spi0",
.dev = &pl022_device.dev,
},
{
.name = "mmc0",
.dev = &mmcsd_device.dev,
},
};

static int __init u300_pinmux_fetch(void)
{
int i;

for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
struct pinmux *pmx;
int ret;

pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
if (IS_ERR(pmx)) {
pr_err("u300: could not get pinmux hog %s\n",
u300_mux_hogs[i].name);
continue;
}
ret = pinmux_enable(pmx);
if (ret) {
pr_err("u300: could enable pinmux hog %s\n",
u300_mux_hogs[i].name);
continue;
}
u300_mux_hogs[i].pmx = pmx;
}
return 0;
}
subsys_initcall(u300_pinmux_fetch);

/*
* Notice that AMBA devices are initialized before platform devices.
*
Expand All @@ -1643,10 +1719,10 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device,
&nand_device,
&wdog_device,
&ave_device
&ave_device,
&pinmux_device,
};


/*
* Interrupts: the U300 platforms have two pl190 ARM PrimeCells connected
* together so some interrupts are connected to the first one and some
Expand Down Expand Up @@ -1828,6 +1904,10 @@ void __init u300_init_devices(void)

u300_assign_physmem();

/* Initialize pinmuxing */
pinmux_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map));

/* Register subdevices on the I2C buses */
u300_i2c_register_board_devices();

Expand Down
136 changes: 0 additions & 136 deletions arch/arm/mach-u300/include/mach/syscon.h
Original file line number Diff line number Diff line change
Expand Up @@ -234,91 +234,6 @@
#define U300_SYSCON_ECCR_EMIF_1_RET_OUT_CLK_EN_N_DISABLE (0x0004)
#define U300_SYSCON_ECCR_EMIF_MEMCLK_RET_EN_N_DISABLE (0x0002)
#define U300_SYSCON_ECCR_EMIF_SDRCLK_RET_EN_N_DISABLE (0x0001)
/* PAD MUX Control register 1 (LOW) 16bit (R/W) */
#define U300_SYSCON_PMC1LR (0x007C)
#define U300_SYSCON_PMC1LR_MASK (0xFFFF)
#define U300_SYSCON_PMC1LR_CDI_MASK (0xC000)
#define U300_SYSCON_PMC1LR_CDI_CDI (0x0000)
#define U300_SYSCON_PMC1LR_CDI_EMIF (0x4000)
#ifdef CONFIG_MACH_U300_BS335
#define U300_SYSCON_PMC1LR_CDI_CDI2 (0x8000)
#define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO (0xC000)
#elif CONFIG_MACH_U300_BS365
#define U300_SYSCON_PMC1LR_CDI_GPIO (0x8000)
#define U300_SYSCON_PMC1LR_CDI_WCDMA (0xC000)
#endif
#define U300_SYSCON_PMC1LR_PDI_MASK (0x3000)
#define U300_SYSCON_PMC1LR_PDI_PDI (0x0000)
#define U300_SYSCON_PMC1LR_PDI_EGG (0x1000)
#define U300_SYSCON_PMC1LR_PDI_WCDMA (0x3000)
#define U300_SYSCON_PMC1LR_MMCSD_MASK (0x0C00)
#define U300_SYSCON_PMC1LR_MMCSD_MMCSD (0x0000)
#define U300_SYSCON_PMC1LR_MMCSD_MSPRO (0x0400)
#define U300_SYSCON_PMC1LR_MMCSD_DSP (0x0800)
#define U300_SYSCON_PMC1LR_MMCSD_WCDMA (0x0C00)
#define U300_SYSCON_PMC1LR_ETM_MASK (0x0300)
#define U300_SYSCON_PMC1LR_ETM_ACC (0x0000)
#define U300_SYSCON_PMC1LR_ETM_APP (0x0100)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK (0x00C0)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF (0x0040)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM (0x0080)
#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB (0x00C0)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK (0x0030)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF (0x0010)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM (0x0020)
#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI (0x0030)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK (0x000C)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF (0x0004)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM (0x0008)
#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI (0x000C)
#define U300_SYSCON_PMC1LR_EMIF_1_MASK (0x0003)
#define U300_SYSCON_PMC1LR_EMIF_1_STATIC (0x0000)
#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 (0x0001)
#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 (0x0002)
#define U300_SYSCON_PMC1LR_EMIF_1 (0x0003)
/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */
#define U300_SYSCON_PMC1HR (0x007E)
#define U300_SYSCON_PMC1HR_MASK (0xFFFF)
#define U300_SYSCON_PMC1HR_MISC_2_MASK (0xC000)
#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_MISC_2_MSPRO (0x4000)
#define U300_SYSCON_PMC1HR_MISC_2_DSP (0x8000)
#define U300_SYSCON_PMC1HR_MISC_2_AAIF (0xC000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK (0x3000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF (0x1000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP (0x2000)
#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF (0x3000)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK (0x0C00)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC (0x0400)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP (0x0800)
#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF (0x0C00)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK (0x0300)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI (0x0100)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF (0x0300)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK (0x00C0)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI (0x0040)
#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF (0x00C0)
#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK (0x0030)
#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI (0x0010)
#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP (0x0020)
#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF (0x0030)
#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK (0x000C)
#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 (0x0004)
#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS (0x0008)
#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF (0x000C)
#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK (0x0003)
#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 (0x0001)
#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF (0x0003)
/* Step one for killing the applications system 16bit (-/W) */
#define U300_SYSCON_KA1R (0x0080)
#define U300_SYSCON_KA1R_MASK (0xFFFF)
Expand Down Expand Up @@ -357,57 +272,6 @@
#define U300_SYSCON_PUCR_EMIF_1_16BIT_PU_ENABLE (0x0080)
#define U300_SYSCON_PUCR_EMIF_1_8BIT_PU_ENABLE (0x0040)
#define U300_SYSCON_PUCR_KEY_IN_PU_EN_MASK (0x003F)
/* Padmux 2 control */
#define U300_SYSCON_PMC2R (0x100)
#define U300_SYSCON_PMC2R_APP_MISC_0_MASK (0x00C0)
#define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM (0x0040)
#define U300_SYSCON_PMC2R_APP_MISC_0_MMC (0x0080)
#define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 (0x00C0)
#define U300_SYSCON_PMC2R_APP_MISC_1_MASK (0x0300)
#define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM (0x0100)
#define U300_SYSCON_PMC2R_APP_MISC_1_MMC (0x0200)
#define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 (0x0300)
#define U300_SYSCON_PMC2R_APP_MISC_2_MASK (0x0C00)
#define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM (0x0400)
#define U300_SYSCON_PMC2R_APP_MISC_2_MMC (0x0800)
#define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 (0x0C00)
#define U300_SYSCON_PMC2R_APP_MISC_3_MASK (0x3000)
#define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM (0x1000)
#define U300_SYSCON_PMC2R_APP_MISC_3_MMC (0x2000)
#define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 (0x3000)
#define U300_SYSCON_PMC2R_APP_MISC_4_MASK (0xC000)
#define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO (0x0000)
#define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM (0x4000)
#define U300_SYSCON_PMC2R_APP_MISC_4_MMC (0x8000)
#define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO (0xC000)
/* TODO: More SYSCON registers missing */
#define U300_SYSCON_PMC3R (0x10c)
#define U300_SYSCON_PMC3R_APP_MISC_11_MASK (0xc000)
#define U300_SYSCON_PMC3R_APP_MISC_11_SPI (0x4000)
#define U300_SYSCON_PMC3R_APP_MISC_10_MASK (0x3000)
#define U300_SYSCON_PMC3R_APP_MISC_10_SPI (0x1000)
/* TODO: Missing other configs */
#define U300_SYSCON_PMC4R (0x168)
#define U300_SYSCON_PMC4R_APP_MISC_12_MASK (0x0003)
#define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_13_MASK (0x000C)
#define U300_SYSCON_PMC4R_APP_MISC_13_CDI (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA (0x0004)
#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 (0x0008)
#define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO (0x000C)
#define U300_SYSCON_PMC4R_APP_MISC_14_MASK (0x0030)
#define U300_SYSCON_PMC4R_APP_MISC_14_CDI (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_14_SMIA (0x0010)
#define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 (0x0020)
#define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO (0x0030)
#define U300_SYSCON_PMC4R_APP_MISC_16_MASK (0x0300)
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 (0x0000)
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS (0x0100)
#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N (0x0200)
/* SYS_0_CLK_CONTROL first clock control 16bit (R/W) */
#define U300_SYSCON_S0CCR (0x120)
#define U300_SYSCON_S0CCR_FIELD_MASK (0x43FF)
Expand Down
16 changes: 0 additions & 16 deletions arch/arm/mach-u300/mmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
#include <mach/dma_channels.h>

#include "mmc.h"
#include "padmux.h"

static struct mmci_platform_data mmc0_plat_data = {
/*
Expand All @@ -45,24 +44,9 @@ static struct mmci_platform_data mmc0_plat_data = {
int __devinit mmc_init(struct amba_device *adev)
{
struct device *mmcsd_device = &adev->dev;
struct pmx *pmx;
int ret = 0;

mmcsd_device->platform_data = &mmc0_plat_data;

/*
* Setup padmuxing for MMC. Since this must always be
* compiled into the kernel, pmx is never released.
*/
pmx = pmx_get(mmcsd_device, U300_APP_PMX_MMC_SETTING);

if (IS_ERR(pmx))
pr_warning("Could not get padmux handle\n");
else {
ret = pmx_activate(mmcsd_device, pmx);
if (IS_ERR_VALUE(ret))
pr_warning("Could not activate padmuxing\n");
}

return ret;
}
Loading

0 comments on commit 98da352

Please sign in to comment.