Loading arch/arm/mach-davinci/Kconfig +26 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,32 @@ config MACH_DAVINCI_EVM Configure this option to specify the whether the board used for development is a DaVinci EVM 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" 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 Loading arch/arm/mach-davinci/Makefile +3 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ # Common objects obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \ gpio.o mux.o devices.o dma.o usb.o gpio.o devices.o dma.o usb.o obj-$(CONFIG_DAVINCI_MUX) += mux.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o arch/arm/mach-davinci/devices.c +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <mach/hardware.h> #include <mach/i2c.h> #include <mach/irqs.h> #include <mach/cputype.h> #include <mach/mux.h> #define DAVINCI_I2C_BASE 0x01C21000 Loading @@ -45,6 +47,9 @@ static struct platform_device davinci_i2c_device = { void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata) { if (cpu_is_davinci_dm644x()) davinci_cfg_reg(DM644X_I2C); davinci_i2c_device.dev.platform_data = pdata; (void) platform_device_register(&davinci_i2c_device); } Loading arch/arm/mach-davinci/include/mach/mux.h +174 −46 Original line number Diff line number Diff line /* * DaVinci pin multiplexing defines * Table of the DAVINCI register configurations for the PINMUX combinations * * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> * * Based on linux/include/asm-arm/arch-omap/mux.h: * Copyright (C) 2003 - 2005 Nokia Corporation * * Written by Tony Lindgren * * 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. * * Copyright (C) 2008 Texas Instruments. */ #ifndef __ASM_ARCH_MUX_H #define __ASM_ARCH_MUX_H #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 */ #ifndef __INC_MACH_MUX_H #define __INC_MACH_MUX_H /* System module registers */ #define PINMUX0 0x00 #define PINMUX1 0x04 /* dm355 only */ #define PINMUX2 0x08 #define PINMUX3 0x0c #define PINMUX4 0x10 #define INTMUX 0x18 #define EVTMUX 0x1c struct mux_config { const char *name; const char *mux_reg_name; const unsigned char mux_reg; const unsigned char mask_offset; const unsigned char mask; const unsigned char mode; bool debug; }; enum davinci_dm644x_index { /* ATA and HDDIR functions */ DM644X_HDIREN, DM644X_ATAEN, DM644X_ATAEN_DISABLE, /* HPI functions */ DM644X_HPIEN_DISABLE, /* AEAW functions */ DM644X_AEAW, /* Memory Stick */ DM644X_MSTK, /* I2C */ DM644X_I2C, /* ASP function */ DM644X_MCBSP, /* UART1 */ DM644X_UART1, /* UART2 */ DM644X_UART2, /* PWM0 */ DM644X_PWM0, /* PWM1 */ DM644X_PWM1, /* PWM2 */ DM644X_PWM2, /* VLYNQ function */ DM644X_VLYNQEN, DM644X_VLSCREN, DM644X_VLYNQWD, /* 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, }; enum davinci_dm646x_index { /* ATA function */ DM646X_ATAEN, /* AUDIO Clock */ DM646X_AUDCK1, DM646X_AUDCK0, /* CRGEN Control */ DM646X_CRGMUX, /* VPIF Control */ DM646X_STSOMUX_DISABLE, DM646X_STSIMUX_DISABLE, DM646X_PTSOMUX_DISABLE, DM646X_PTSIMUX_DISABLE, /* TSIF Control */ DM646X_STSOMUX, DM646X_STSIMUX, DM646X_PTSOMUX_PARALLEL, DM646X_PTSIMUX_PARALLEL, DM646X_PTSOMUX_SERIAL, DM646X_PTSIMUX_SERIAL, }; enum davinci_dm355_index { /* MMC/SD 0 */ DM355_MMCSD0, /* MMC/SD 1 */ DM355_SD1_CLK, DM355_SD1_CMD, DM355_SD1_DATA3, DM355_SD1_DATA2, DM355_SD1_DATA1, DM355_SD1_DATA0, /* I2C */ DM355_I2C_SDA, DM355_I2C_SCL, /* ASP0 function */ DM355_MCBSP0_BDX, DM355_MCBSP0_X, DM355_MCBSP0_BFSX, DM355_MCBSP0_BDR, DM355_MCBSP0_R, DM355_MCBSP0_BFSR, /* SPI0 */ DM355_SPI0_SDI, DM355_SPI0_SDENA0, DM355_SPI0_SDENA1, /* IRQ muxing */ DM355_INT_EDMA_CC, DM355_INT_EDMA_TC0_ERR, DM355_INT_EDMA_TC1_ERR, /* EDMA event muxing */ DM355_EVT8_ASP1_TX, DM355_EVT9_ASP1_RX, DM355_EVT26_MMC0_RX, }; #ifdef CONFIG_DAVINCI_MUX /* setup pin muxing */ extern void davinci_mux_init(void); extern int davinci_mux_register(const struct mux_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) {} static inline int davinci_mux_register(const struct mux_config *pins, unsigned long size) { return 0; } static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; } #endif #endif /* __INC_MACH_MUX_H */ arch/arm/mach-davinci/mux.c +80 −19 Original line number Diff line number Diff line /* * DaVinci pin multiplexing configurations * Utility to set the DAVINCI MUX register from a table in mux.h * * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> * * Based on linux/arch/arm/plat-omap/mux.c: * Copyright (C) 2003 - 2005 Nokia Corporation * * Written by Tony Lindgren * * 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. * * Copyright (C) 2008 Texas Instruments. */ #include <linux/io.h> #include <linux/module.h> #include <linux/spinlock.h> #include <mach/hardware.h> #include <mach/mux.h> /* System control register offsets */ #define PINMUX0 0x00 #define PINMUX1 0x04 static const struct mux_config *mux_table; static unsigned long pin_table_sz; int __init davinci_mux_register(const struct mux_config *pins, unsigned long size) { mux_table = pins; pin_table_sz = size; static DEFINE_SPINLOCK(mux_lock); 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) { static DEFINE_SPINLOCK(mux_spin_lock); void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); u32 pinmux, muxreg = PINMUX0; unsigned long flags; const struct mux_config *cfg; unsigned int reg_orig = 0, reg = 0; unsigned int mask, warn = 0; if (!mux_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 = &mux_table[index]; if (cfg->name == NULL) { printk(KERN_ERR "No entry for the specified index\n"); return -ENODEV; } /* Update the mux register in question */ if (cfg->mask) { unsigned tmp1, tmp2; spin_lock_irqsave(&mux_spin_lock, flags); reg_orig = __raw_readl(base + 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; __raw_writel(reg, base + 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 = __raw_readl(base + muxreg); if (enable) pinmux |= (1 << mux); else pinmux &= ~(1 << mux); __raw_writel(pinmux, base + muxreg); spin_unlock(&mux_lock); return 0; } EXPORT_SYMBOL(davinci_cfg_reg); Loading
arch/arm/mach-davinci/Kconfig +26 −0 Original line number Diff line number Diff line Loading @@ -18,6 +18,32 @@ config MACH_DAVINCI_EVM Configure this option to specify the whether the board used for development is a DaVinci EVM 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" 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 Loading
arch/arm/mach-davinci/Makefile +3 −1 Original line number Diff line number Diff line Loading @@ -5,7 +5,9 @@ # Common objects obj-y := time.o irq.o clock.o serial.o io.o id.o psc.o \ gpio.o mux.o devices.o dma.o usb.o gpio.o devices.o dma.o usb.o obj-$(CONFIG_DAVINCI_MUX) += mux.o # Board specific obj-$(CONFIG_MACH_DAVINCI_EVM) += board-evm.o
arch/arm/mach-davinci/devices.c +5 −0 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ #include <mach/hardware.h> #include <mach/i2c.h> #include <mach/irqs.h> #include <mach/cputype.h> #include <mach/mux.h> #define DAVINCI_I2C_BASE 0x01C21000 Loading @@ -45,6 +47,9 @@ static struct platform_device davinci_i2c_device = { void __init davinci_init_i2c(struct davinci_i2c_platform_data *pdata) { if (cpu_is_davinci_dm644x()) davinci_cfg_reg(DM644X_I2C); davinci_i2c_device.dev.platform_data = pdata; (void) platform_device_register(&davinci_i2c_device); } Loading
arch/arm/mach-davinci/include/mach/mux.h +174 −46 Original line number Diff line number Diff line /* * DaVinci pin multiplexing defines * Table of the DAVINCI register configurations for the PINMUX combinations * * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> * * Based on linux/include/asm-arm/arch-omap/mux.h: * Copyright (C) 2003 - 2005 Nokia Corporation * * Written by Tony Lindgren * * 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. * * Copyright (C) 2008 Texas Instruments. */ #ifndef __ASM_ARCH_MUX_H #define __ASM_ARCH_MUX_H #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 */ #ifndef __INC_MACH_MUX_H #define __INC_MACH_MUX_H /* System module registers */ #define PINMUX0 0x00 #define PINMUX1 0x04 /* dm355 only */ #define PINMUX2 0x08 #define PINMUX3 0x0c #define PINMUX4 0x10 #define INTMUX 0x18 #define EVTMUX 0x1c struct mux_config { const char *name; const char *mux_reg_name; const unsigned char mux_reg; const unsigned char mask_offset; const unsigned char mask; const unsigned char mode; bool debug; }; enum davinci_dm644x_index { /* ATA and HDDIR functions */ DM644X_HDIREN, DM644X_ATAEN, DM644X_ATAEN_DISABLE, /* HPI functions */ DM644X_HPIEN_DISABLE, /* AEAW functions */ DM644X_AEAW, /* Memory Stick */ DM644X_MSTK, /* I2C */ DM644X_I2C, /* ASP function */ DM644X_MCBSP, /* UART1 */ DM644X_UART1, /* UART2 */ DM644X_UART2, /* PWM0 */ DM644X_PWM0, /* PWM1 */ DM644X_PWM1, /* PWM2 */ DM644X_PWM2, /* VLYNQ function */ DM644X_VLYNQEN, DM644X_VLSCREN, DM644X_VLYNQWD, /* 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, }; enum davinci_dm646x_index { /* ATA function */ DM646X_ATAEN, /* AUDIO Clock */ DM646X_AUDCK1, DM646X_AUDCK0, /* CRGEN Control */ DM646X_CRGMUX, /* VPIF Control */ DM646X_STSOMUX_DISABLE, DM646X_STSIMUX_DISABLE, DM646X_PTSOMUX_DISABLE, DM646X_PTSIMUX_DISABLE, /* TSIF Control */ DM646X_STSOMUX, DM646X_STSIMUX, DM646X_PTSOMUX_PARALLEL, DM646X_PTSIMUX_PARALLEL, DM646X_PTSOMUX_SERIAL, DM646X_PTSIMUX_SERIAL, }; enum davinci_dm355_index { /* MMC/SD 0 */ DM355_MMCSD0, /* MMC/SD 1 */ DM355_SD1_CLK, DM355_SD1_CMD, DM355_SD1_DATA3, DM355_SD1_DATA2, DM355_SD1_DATA1, DM355_SD1_DATA0, /* I2C */ DM355_I2C_SDA, DM355_I2C_SCL, /* ASP0 function */ DM355_MCBSP0_BDX, DM355_MCBSP0_X, DM355_MCBSP0_BFSX, DM355_MCBSP0_BDR, DM355_MCBSP0_R, DM355_MCBSP0_BFSR, /* SPI0 */ DM355_SPI0_SDI, DM355_SPI0_SDENA0, DM355_SPI0_SDENA1, /* IRQ muxing */ DM355_INT_EDMA_CC, DM355_INT_EDMA_TC0_ERR, DM355_INT_EDMA_TC1_ERR, /* EDMA event muxing */ DM355_EVT8_ASP1_TX, DM355_EVT9_ASP1_RX, DM355_EVT26_MMC0_RX, }; #ifdef CONFIG_DAVINCI_MUX /* setup pin muxing */ extern void davinci_mux_init(void); extern int davinci_mux_register(const struct mux_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) {} static inline int davinci_mux_register(const struct mux_config *pins, unsigned long size) { return 0; } static inline int davinci_cfg_reg(unsigned long reg_cfg) { return 0; } #endif #endif /* __INC_MACH_MUX_H */
arch/arm/mach-davinci/mux.c +80 −19 Original line number Diff line number Diff line /* * DaVinci pin multiplexing configurations * Utility to set the DAVINCI MUX register from a table in mux.h * * Author: Vladimir Barinov, MontaVista Software, Inc. <source@mvista.com> * * Based on linux/arch/arm/plat-omap/mux.c: * Copyright (C) 2003 - 2005 Nokia Corporation * * Written by Tony Lindgren * * 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. * * Copyright (C) 2008 Texas Instruments. */ #include <linux/io.h> #include <linux/module.h> #include <linux/spinlock.h> #include <mach/hardware.h> #include <mach/mux.h> /* System control register offsets */ #define PINMUX0 0x00 #define PINMUX1 0x04 static const struct mux_config *mux_table; static unsigned long pin_table_sz; int __init davinci_mux_register(const struct mux_config *pins, unsigned long size) { mux_table = pins; pin_table_sz = size; static DEFINE_SPINLOCK(mux_lock); 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) { static DEFINE_SPINLOCK(mux_spin_lock); void __iomem *base = IO_ADDRESS(DAVINCI_SYSTEM_MODULE_BASE); u32 pinmux, muxreg = PINMUX0; unsigned long flags; const struct mux_config *cfg; unsigned int reg_orig = 0, reg = 0; unsigned int mask, warn = 0; if (!mux_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 = &mux_table[index]; if (cfg->name == NULL) { printk(KERN_ERR "No entry for the specified index\n"); return -ENODEV; } /* Update the mux register in question */ if (cfg->mask) { unsigned tmp1, tmp2; spin_lock_irqsave(&mux_spin_lock, flags); reg_orig = __raw_readl(base + 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; __raw_writel(reg, base + 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 = __raw_readl(base + muxreg); if (enable) pinmux |= (1 << mux); else pinmux &= ~(1 << mux); __raw_writel(pinmux, base + muxreg); spin_unlock(&mux_lock); return 0; } EXPORT_SYMBOL(davinci_cfg_reg);