On Wed, Dec 10, 2008 at 03:35:28PM +0530, Sudhakar Rajashekhara wrote:
> Generalizes dm644x pinmux.
>
> The existing pinmux layer works only when the PINMUX register has single bit
> field to enable the secondary function. DM646x can support secondary as well
> as tertiary pin functions. This new pinmux layer is similar to the one being
> used by OMAP architecture.
>
> Checkpatch script reports a false positive error at line no.408 of this patch.
but it also reports a real positives:
ERROR: Macros with complex values should be enclosed in parenthesis
#442: FILE: arch/arm/mach-davinci/mux_cfg.c:29:
+#define MUX_REG(reg, mode_offset, mode_mask, mux_mode) \
+ .mux_reg_name = "PINMUX"#reg, \
+ .mux_reg = PINMUX##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode,
ERROR: Macros with complex values should be enclosed in parenthesis
#449: FILE: arch/arm/mach-davinci/mux_cfg.c:36:
+#define MUX_REG(reg, mode_offset, mode_mask, mux_mode) \
+ .mux_reg = PINMUX##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode,
ERROR: Macros with multiple statements should be enclosed in a do - while loop
#456: FILE: arch/arm/mach-davinci/mux_cfg.c:43:
+#define MUX_CFG(desc, mux_reg, mode_offset, mode_mask, mux_mode, dbg) \
+{ \
+ .name = desc, \
+ .debug = dbg, \
+ MUX_REG(mux_reg, mode_offset, mode_mask, mux_mode) \
+},
but most likely you want something like:
+#define MUX_REG(reg, mode_offset, mode_mask, mux_mode) \
+ { \
+ .mux_reg_name = "PINMUX"#reg, \
+ .mux_reg = PINMUX##reg, \
+ .mask_offset = mode_offset, \
+ .mask = mode_mask, \
+ .mode = mux_mode, \
+ },
> diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig
> index f82e6f4..20e55ea 100644
> --- a/arch/arm/mach-davinci/Kconfig
> +++ b/arch/arm/mach-davinci/Kconfig
> @@ -50,6 +50,31 @@ config MACH_DAVINCI_SFFSDR
> Say Y here to select the Lyrtech Small Form Factor
> Software Defined Radio (SFFSDR) board.
>
> +config DAVINCI_MUX
> + bool "DAVINCI multiplexing support"
> + depends on ARCH_DAVINCI
> + default y
> + help
> + Pin multiplexing support for DAVINCI boards. If your bootloader
> + sets the multiplexing correctly, say N. Otherwise, or if unsure,
> + say Y.
> +
> +config DAVINCI_MUX_DEBUG
> + bool "Multiplexing debug output"
> + depends on DAVINCI_MUX
> + help
> + Makes the multiplexing functions print out a lot of debug info.
> + This is useful if you want to find out the correct values of the
> + multiplexing registers.
> +
> +config DAVINCI_MUX_WARNINGS
> + bool "Warn about pins the bootloader didn't set up"
I'd say we shouldn't rely on bootloader to setup mux config, so this
would be quite useless.
> + depends on DAVINCI_MUX
> + help
> + Choose Y here to warn whenever driver initialization logic needs
> + to change the pin multiplexing setup. When there are no warnings
> + printed, it's safe to deselect DAVINCI_MUX for your product.
> +
> config DAVINCI_RESET_CLOCKS
> bool "Reset unused clocks during boot"
> depends on ARCH_DAVINCI
> diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
> index 2a339db..d2b4e24 100644
> --- a/arch/arm/mach-davinci/Makefile
> +++ b/arch/arm/mach-davinci/Makefile
> @@ -5,7 +5,7 @@
>
> # Common objects
> obj-y := time.o irq.o clock.o serial.o io.o id.o
> psc.o \
> - gpio.o mux.o devices.o usb.o dma.o common.o iram.o
> + gpio.o mux.o mux_cfg.o devices.o usb.o dma.o
> common.o iram.o
mux should only build if CONFIG_DAVINCI_MUX is true.
> # Board specific
> obj-$(CONFIG_MACH_DAVINCI_EVM) += board-dm644x-evm.o
> diff --git a/arch/arm/mach-davinci/include/mach/mux.h
> b/arch/arm/mach-davinci/include/mach/mux.h
> index 9e7cf69..317f7c7 100644
> --- a/arch/arm/mach-davinci/include/mach/mux.h
> +++ b/arch/arm/mach-davinci/include/mach/mux.h
> @@ -1,60 +1,93 @@
> /*
> - * DaVinci pin multiplexing defines
> + * Table of the DAVINCI register configurations for the PINMUX combinations
> *
> * Author: Vladimir Barinov, MontaVista Software, Inc. <[EMAIL PROTECTED]>
> *
> + * Based on linux/include/asm-arm/arch-omap/mux.h:
> + * Copyright (C) 2003 - 2005 Nokia Corporation
> + * Written by Tony Lindgren <[EMAIL PROTECTED]>
> + *
> * 2007 (c) MontaVista Software, Inc. This file is licensed under
> * the terms of the GNU General Public License version 2. This program
> * is licensed "as is" without any warranty of any kind, whether express
> * or implied.
> */
> +
why ??
> #ifndef __ASM_ARCH_MUX_H
> #define __ASM_ARCH_MUX_H
>
> -/* System control register offsets */
> -#define PINMUX0 0x00
> -#define PINMUX1 0x04
> -
> -/* System control register bits */
> -#define DAVINCI_MUX_AEAW0 0
> -#define DAVINCI_MUX_AEAW1 1
> -#define DAVINCI_MUX_AEAW2 2
> -#define DAVINCI_MUX_AEAW3 3
> -#define DAVINCI_MUX_AEAW4 4
> -#define DAVINCI_MUX_AECS4 10
> -#define DAVINCI_MUX_AECS5 11
> -#define DAVINCI_MUX_VLYNQWD0 12
> -#define DAVINCI_MUX_VLYNQWD1 13
> -#define DAVINCI_MUX_VLSCREN 14
> -#define DAVINCI_MUX_VLYNQEN 15
> -#define DAVINCI_MUX_HDIREN 16
> -#define DAVINCI_MUX_ATAEN 17
> -#define DAVINCI_MUX_RGB666 22
> -#define DAVINCI_MUX_RGB888 23
> -#define DAVINCI_MUX_LOEEN 24
> -#define DAVINCI_MUX_LFLDEN 25
> -#define DAVINCI_MUX_CWEN 26
> -#define DAVINCI_MUX_CFLDEN 27
> -#define DAVINCI_MUX_HPIEN 29
> -#define DAVINCI_MUX_1394EN 30
> -#define DAVINCI_MUX_EMACEN 31
> -
> -#define DAVINCI_MUX_LEVEL2 32
> -#define DAVINCI_MUX_UART0 (DAVINCI_MUX_LEVEL2 + 0)
> -#define DAVINCI_MUX_UART1 (DAVINCI_MUX_LEVEL2 + 1)
> -#define DAVINCI_MUX_UART2 (DAVINCI_MUX_LEVEL2 + 2)
> -#define DAVINCI_MUX_U2FLO (DAVINCI_MUX_LEVEL2 + 3)
> -#define DAVINCI_MUX_PWM0 (DAVINCI_MUX_LEVEL2 + 4)
> -#define DAVINCI_MUX_PWM1 (DAVINCI_MUX_LEVEL2 + 5)
> -#define DAVINCI_MUX_PWM2 (DAVINCI_MUX_LEVEL2 + 6)
> -#define DAVINCI_MUX_I2C (DAVINCI_MUX_LEVEL2 + 7)
> -#define DAVINCI_MUX_SPI (DAVINCI_MUX_LEVEL2 + 8)
> -#define DAVINCI_MUX_MSTK (DAVINCI_MUX_LEVEL2 + 9)
> -#define DAVINCI_MUX_ASP (DAVINCI_MUX_LEVEL2 + 10)
> -#define DAVINCI_MUX_CLK0 (DAVINCI_MUX_LEVEL2 + 16)
> -#define DAVINCI_MUX_CLK1 (DAVINCI_MUX_LEVEL2 + 17)
> -#define DAVINCI_MUX_TIMIN (DAVINCI_MUX_LEVEL2 + 18)
> -
> -extern void davinci_mux_peripheral(unsigned int mux, unsigned int enable);
> -
> -#endif /* __ASM_ARCH_MUX_H */
> +struct pin_config {
> + char *name;
> + unsigned char busy;
> + unsigned char debug;
> + const char *mux_reg_name;
> + const unsigned int mux_reg;
> + const unsigned char mask_offset;
> + const unsigned char mask;
> + const unsigned char mode;
> +};
> +
> +enum davinci_dm644x_index {
> + /* ATA and HDDIR functions */
> + DM644X_HDIREN,
> + DM644X_ATAEN,
> +
> + /* Memory Stick */
> + DM644X_MSTK,
> +
> + /* I2C */
> + DM644X_I2C,
> +
> + /* ASP function */
> + DM644X_MCBSP,
> +
> + /* PWM0 */
> + DM644X_PWM0,
> +
> + /* PWM1 */
> + DM644X_PWM1,
> +
> + /* PWM2 */
> + DM644X_PWM2,
> +
> + /* VLINQ function */
> + DM644X_VLINQEN,
> + DM644X_VLINQWD,
> +
> + /* EMAC and MDIO function */
> + DM644X_EMACEN,
> +
> + /* GPIO3V[0:16] pins */
> + DM644X_GPIO3V,
> +
> + /* GPIO pins */
> + DM644X_GPIO0,
> + DM644X_GPIO3,
> + DM644X_GPIO43_44,
> + DM644X_GPIO46_47,
> +
> + /* VPBE */
> + DM644X_RGB666,
> +
> + /* LCD */
> + DM644X_LOEEN,
> + DM644X_LFLDEN,
> +};
> +
> +#ifdef CONFIG_DAVINCI_MUX
> +/* setup pin muxing */
> +extern void davinci_mux_init(void);
> +extern int davinci_mux_register(struct pin_config *pins, unsigned long size);
> +extern int davinci_cfg_reg(unsigned long reg_cfg);
> +#else
> +/* boot loader does it all (no warnings from CONFIG_DAVINCI_MUX_WARNINGS) */
> +static inline void davinci_mux_init(void)
> +{
> + do {} while (0);
remove this line, it's as useful as
if (0)
printk(KERN_INFO "This won't execute\n");
> +}
> +static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; }
> +#endif
> +
> +extern void (*davinci_pinmux_setup)(unsigned int id);
> +
> +#endif
> diff --git a/arch/arm/mach-davinci/io.c b/arch/arm/mach-davinci/io.c
> index 299515f..c493889 100644
> --- a/arch/arm/mach-davinci/io.c
> +++ b/arch/arm/mach-davinci/io.c
> @@ -18,6 +18,7 @@
>
> #include <asm/mach/map.h>
> #include <mach/clock.h>
> +#include <mach/mux.h>
>
> extern void davinci_check_revision(void);
>
> @@ -53,5 +54,6 @@ void __init davinci_map_common_io(void)
>
> void __init davinci_init_common_hw(void)
> {
> + davinci_mux_init();
> davinci_clk_init();
> }
> diff --git a/arch/arm/mach-davinci/mux.c b/arch/arm/mach-davinci/mux.c
> index be33108..e41f6f5 100644
> --- a/arch/arm/mach-davinci/mux.c
> +++ b/arch/arm/mach-davinci/mux.c
> @@ -1,8 +1,12 @@
> /*
> - * DaVinci pin multiplexing configurations
> + * Utility to set the DAVINCI MUX register from a table in mux.h
the table should probably be chip-specific.
> *
> * Author: Vladimir Barinov, MontaVista Software, Inc. <[EMAIL PROTECTED]>
> *
> + * Based on linux/arch/arm/plat-omap/mux.c:
> + * Copyright (C) 2003 - 2005 Nokia Corporation
> + * Written by Tony Lindgren <[EMAIL PROTECTED]>
where did you get this mail ??
It's [EMAIL PROTECTED]
> + *
> * 2007 (c) MontaVista Software, Inc. This file is licensed under
> * the terms of the GNU General Public License version 2. This program
> * is licensed "as is" without any warranty of any kind, whether express
> @@ -13,27 +17,84 @@
> #include <linux/spinlock.h>
>
> #include <mach/hardware.h>
> -
> #include <mach/mux.h>
>
> -static DEFINE_SPINLOCK(mux_lock);
> +#ifdef CONFIG_DAVINCI_MUX
don't ifdef here.
> +
> +static struct pin_config *pin_table;
> +static unsigned long pin_table_sz;
> +
> +int __init davinci_mux_register(struct pin_config *pins, unsigned long size)
> +{
> + pin_table = pins;
> + pin_table_sz = size;
> +
> + return 0;
> +}
>
> -void davinci_mux_peripheral(unsigned int mux, unsigned int enable)
> +/*
> + * Sets the DAVINCI MUX register based on the table
> + */
> +int __init_or_module davinci_cfg_reg(const unsigned long index)
this cannot be called by modules, or at least shouldn't. So __init
should be safe.
> {
> - u32 pinmux, muxreg = PINMUX0;
> + static DEFINE_SPINLOCK(mux_spin_lock);
> +
> + unsigned long flags;
> + struct pin_config *cfg;
> + unsigned int reg_orig = 0, reg = 0;
> + unsigned int mask, warn = 0;
> +
> + if (!pin_table)
> + BUG();
> +
> + if (index >= pin_table_sz) {
> + printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n",
> + index, pin_table_sz);
> + dump_stack();
> + return -ENODEV;
> + }
> +
> + cfg = (struct pin_config *)&pin_table[index];
> +
> + /* Check the mux register in question */
> + if (cfg->mux_reg) {
> + unsigned tmp1, tmp2;
> +
> + spin_lock_irqsave(&mux_spin_lock, flags);
> + reg_orig = davinci_readl(cfg->mux_reg);
> +
> + mask = (cfg->mask << cfg->mask_offset);
> + tmp1 = reg_orig & mask;
> + reg = reg_orig & ~mask;
> +
> + tmp2 = (cfg->mode << cfg->mask_offset);
> + reg |= tmp2;
> +
> + if (tmp1 != tmp2)
> + warn = 1;
> +
> + davinci_writel(reg, cfg->mux_reg);
> + spin_unlock_irqrestore(&mux_spin_lock, flags);
> + }
> +
> + if (warn) {
> +#ifdef CONFIG_DAVINCI_MUX_WARNINGS
> + printk(KERN_WARNING "MUX: initialized %s\n", cfg->name);
> +#endif
> + }
>
> - if (mux >= DAVINCI_MUX_LEVEL2) {
> - muxreg = PINMUX1;
> - mux -= DAVINCI_MUX_LEVEL2;
> +#ifdef CONFIG_DAVINCI_MUX_DEBUG
> + if (cfg->debug || warn) {
> + printk(KERN_WARNING "MUX: Setting register %s\n", cfg->name);
> + printk(KERN_WARNING " %s (0x%08x) = 0x%08x -> 0x%08x\n",
> + cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg);
> }
> +#endif
>
> - spin_lock(&mux_lock);
> - pinmux = davinci_readl(DAVINCI_SYSTEM_MODULE_BASE + muxreg);
> - if (enable)
> - pinmux |= (1 << mux);
> - else
> - pinmux &= ~(1 << mux);
> - davinci_writel(pinmux, DAVINCI_SYSTEM_MODULE_BASE + muxreg);
> - spin_unlock(&mux_lock);
> + return 0;
> }
> -EXPORT_SYMBOL(davinci_mux_peripheral);
> +EXPORT_SYMBOL(davinci_cfg_reg);
> +#else
> +#define davinci_mux_init() do {} while (0)
> +#define davinci_cfg_reg(x) do {} while (0)
this should be done in the header file and should be static inline,
instead of defines.
> +#endif /* CONFIG_DAVINCI_MUX */
> diff --git a/arch/arm/mach-davinci/mux_cfg.c b/arch/arm/mach-davinci/mux_cfg.c
> new file mode 100644
> index 0000000..fc00e6b
> --- /dev/null
> +++ b/arch/arm/mach-davinci/mux_cfg.c
> @@ -0,0 +1,99 @@
> +/*
> + * DAVINCI pin multiplexing configurations
> + *
> + * Author: Vladimir Barinov, MontaVista Software, Inc. <[EMAIL PROTECTED]>
> + *
> + * Based on linux/arch/arm/mach-omap1/mux.c:
> + * Copyright (C) 2003 - 2005 Nokia Corporation
> + * Written by Tony Lindgren <[EMAIL PROTECTED]>
> + *
> + * 2007 (c) MontaVista Software, Inc. This file is licensed under
> + * the terms of the GNU General Public License version 2. This program
> + * is licensed "as is" without any warranty of any kind, whether express
> + * or implied.
> + */
> +
> +#include <linux/module.h>
> +#include <linux/init.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/cpu.h>
> +#include <mach/mux.h>
> +#include <mach/dm644x.h>
> +
> +/* System module registers */
> +#define PINMUX0 (DAVINCI_SYSTEM_MODULE_BASE + 0x00)
> +#define PINMUX1 (DAVINCI_SYSTEM_MODULE_BASE + 0x04)
> +
> +#ifdef CONFIG_DAVINCI_MUX_DEBUG
> +#define MUX_REG(reg, mode_offset, mode_mask, mux_mode) \
> + .mux_reg_name = "PINMUX"#reg, \
you should always have the name. Remove this conditional redefinition.
> + .mux_reg = PINMUX##reg, \
> + .mask_offset = mode_offset, \
> + .mask = mode_mask, \
> + .mode = mux_mode,
> +#else
> +#define MUX_REG(reg, mode_offset, mode_mask, mux_mode) \
> + .mux_reg = PINMUX##reg, \
> + .mask_offset = mode_offset, \
> + .mask = mode_mask, \
> + .mode = mux_mode,
> +#endif /* CONFIG_DAVINCI_MUX_DEBUG */
> +
> +#define MUX_CFG(desc, mux_reg, mode_offset, mode_mask, mux_mode, dbg)
> \
> +{ \
> + .name = desc, \
> + .debug = dbg, \
> + MUX_REG(mux_reg, mode_offset, mode_mask, mux_mode) \
> +},
> +
> +#ifdef CONFIG_DAVINCI_MUX
> +
> +struct pin_config __initdata_or_module davinci_dm644x_pins[] = {
> +/*
> + * description mux mode mode mux dbg
^ trailing whitespace
> + * reg offset mask mode
> + */
this comment should be above the struct.
> +[DM644X_HDIREN] = MUX_CFG("HDIREN", 0, 16, 1, 1,
> 1)
> +[DM644X_ATAEN] = MUX_CFG("ATAEN", 0, 17, 1, 1,
> 1)
> +
> +[DM644X_MSTK] = MUX_CFG("MSTK", 1, 9, 1, 0,
> 0)
> +
> +[DM644X_I2C] = MUX_CFG("I2C", 1, 7, 1, 1, 0)
> +
> +[DM644X_MCBSP] = MUX_CFG("MCBSP", 1, 10, 1, 1,
> 0)
> +
> +[DM644X_PWM0] = MUX_CFG("PWM0", 1, 4, 1, 1,
> 0)
> +
> +[DM644X_PWM1] = MUX_CFG("PWM1", 1, 5, 1, 1,
> 0)
> +
> +[DM644X_PWM2] = MUX_CFG("PWM2", 1, 6, 1, 1,
> 0)
> +
> +[DM644X_VLINQEN] = MUX_CFG("VLINQEN", 0, 15, 1, 1,
> 0)
> +[DM644X_VLINQWD] = MUX_CFG("VLINQWD", 0, 12, 3, 3,
> 0)
> +
> +[DM644X_EMACEN] = MUX_CFG("EMACEN", 0, 31, 1, 1,
> 1)
> +
> +[DM644X_GPIO3V] = MUX_CFG("GPIO3V", 0, 31, 1, 0,
> 1)
> +
> +[DM644X_GPIO0] = MUX_CFG("GPIO0", 0, 24, 1, 0,
> 1)
> +[DM644X_GPIO3] = MUX_CFG("GPIO3", 0, 25, 1, 0,
> 0)
> +[DM644X_GPIO43_44] = MUX_CFG("GPIO43_44", 1, 7, 1, 0, 0)
> +[DM644X_GPIO46_47] = MUX_CFG("GPIO46_47", 0, 22, 1, 0, 1)
> +
> +[DM644X_RGB666] = MUX_CFG("RGB666", 0, 22, 1, 1,
> 1)
> +
> +[DM644X_LOEEN] = MUX_CFG("LOEEN", 0, 24, 1, 1,
> 1)
> +[DM644X_LFLDEN] = MUX_CFG("LFLDEN", 0, 25, 1, 1,
> 0)
> +};
> +
> +void __init davinci_mux_init(void)
> +{
> + if (cpu_is_davinci_dm644x())
> + davinci_mux_register(davinci_dm644x_pins,
> + ARRAY_SIZE(davinci_dm644x_pins));
> + else
> + printk(KERN_ERR "PSC: no mux hook for this CPU\n");
you should pass the mux table as a parameter to this function.
--
balbi
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source