Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 160883
b: refs/heads/master
c: 94da274
h: refs/heads/master
i:
  160881: f898517
  160879: dab2a12
v: v3
  • Loading branch information
Dmitriy Taychenachev authored and Sascha Hauer committed Aug 14, 2009
1 parent e095de6 commit 62b6f6d
Show file tree
Hide file tree
Showing 5 changed files with 470 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: fd6ac7bb9d671d36fd7536c68fde977d197756ab
refs/heads/master: 94da274b4982f5b36b55bde0c76d3ef8233bceda
2 changes: 1 addition & 1 deletion trunk/arch/arm/mach-mxc91231/Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
obj-y := mm.o clock.o devices.o system.o
obj-y := mm.o clock.o devices.o system.o iomux.o
obj-$(CONFIG_MACH_MAGX_ZN5) += magx-zn5.o
177 changes: 177 additions & 0 deletions trunk/arch/arm/mach-mxc91231/iomux.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
/*
* Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
* Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/

#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
#include <mach/iomux-mxc91231.h>

/*
* IOMUX register (base) addresses
*/
#define IOMUX_AP_BASE MXC91231_IO_ADDRESS(MXC91231_IOMUX_AP_BASE_ADDR)
#define IOMUX_COM_BASE MXC91231_IO_ADDRESS(MXC91231_IOMUX_COM_BASE_ADDR)
#define IOMUXSW_AP_MUX_CTL (IOMUX_AP_BASE + 0x000)
#define IOMUXSW_SP_MUX_CTL (IOMUX_COM_BASE + 0x000)
#define IOMUXSW_PAD_CTL (IOMUX_COM_BASE + 0x200)

#define IOMUXINT_OBS1 (IOMUX_AP_BASE + 0x600)
#define IOMUXINT_OBS2 (IOMUX_AP_BASE + 0x004)

static DEFINE_SPINLOCK(gpio_mux_lock);

#define NB_PORTS ((PIN_MAX + 32) / 32)
#define PIN_GLOBAL_NUM(pin) \
(((pin & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT)*PIN_AP_MAX + \
((pin & MUX_REG_MASK) >> MUX_REG_SHIFT)*4 + \
((pin & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT))

unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
/*
* set the mode for a IOMUX pin.
*/
int mxc_iomux_mode(const unsigned int pin_mode)
{
u32 side, field, l, mode, ret = 0;
void __iomem *reg;

side = (pin_mode & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT;
switch (side) {
case MUX_SIDE_AP:
reg = IOMUXSW_AP_MUX_CTL;
break;
case MUX_SIDE_SP:
reg = IOMUXSW_SP_MUX_CTL;
break;
default:
return -EINVAL;
}
reg += ((pin_mode & MUX_REG_MASK) >> MUX_REG_SHIFT) * 4;
field = (pin_mode & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT;
mode = (pin_mode & MUX_MODE_MASK) >> MUX_MODE_SHIFT;

spin_lock(&gpio_mux_lock);

l = __raw_readl(reg);
l &= ~(0xff << (field * 8));
l |= mode << (field * 8);
__raw_writel(l, reg);

spin_unlock(&gpio_mux_lock);

return ret;
}
EXPORT_SYMBOL(mxc_iomux_mode);

/*
* This function configures the pad value for a IOMUX pin.
*/
void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
{
u32 padgrp, field, l;
void __iomem *reg;

padgrp = (pin & MUX_PADGRP_MASK) >> MUX_PADGRP_SHIFT;
reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
field = (pin + 2) % 3;

pr_debug("%s: reg offset = 0x%x, field = %d\n",
__func__, (pin + 2) / 3, field);

spin_lock(&gpio_mux_lock);

l = __raw_readl(reg);
l &= ~(0x1ff << (field * 10));
l |= config << (field * 10);
__raw_writel(l, reg);

spin_unlock(&gpio_mux_lock);
}
EXPORT_SYMBOL(mxc_iomux_set_pad);

/*
* allocs a single pin:
* - reserves the pin so that it is not claimed by another driver
* - setups the iomux according to the configuration
*/
int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label)
{
unsigned pad = PIN_GLOBAL_NUM(pin_mode);
if (pad >= (PIN_MAX + 1)) {
printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
pad, label ? label : "?");
return -EINVAL;
}

if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
pad, label ? label : "?");
return -EBUSY;
}
mxc_iomux_mode(pin_mode);

return 0;
}
EXPORT_SYMBOL(mxc_iomux_alloc_pin);

int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
const char *label)
{
unsigned int *p = pin_list;
int i;
int ret = -EINVAL;

for (i = 0; i < count; i++) {
ret = mxc_iomux_alloc_pin(*p, label);
if (ret)
goto setup_error;
p++;
}
return 0;

setup_error:
mxc_iomux_release_multiple_pins(pin_list, i);
return ret;
}
EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);

void mxc_iomux_release_pin(const unsigned int pin_mode)
{
unsigned pad = PIN_GLOBAL_NUM(pin_mode);

if (pad < (PIN_MAX + 1))
clear_bit(pad, mxc_pin_alloc_map);
}
EXPORT_SYMBOL(mxc_iomux_release_pin);

void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
{
unsigned int *p = pin_list;
int i;

for (i = 0; i < count; i++) {
mxc_iomux_release_pin(*p);
p++;
}
}
EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
4 changes: 4 additions & 0 deletions trunk/arch/arm/mach-mxc91231/magx-zn5.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <mach/common.h>
#include <mach/hardware.h>
#include <mach/iomux-mxc91231.h>
#include <mach/mmc.h>
#include <mach/imx-uart.h>

Expand All @@ -29,6 +30,9 @@ static void __init zn5_init(void)
{
pm_power_off = mxc91231_power_off;

mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_DAT_VP__RXD2, "uart2-rx");
mxc_iomux_alloc_pin(MXC91231_PIN_SP_USB_SE0_VM__TXD2, "uart2-tx");

mxc_register_device(&mxc_uart_device1, &uart_pdata);
mxc_register_device(&mxc_uart_device0, &uart_pdata);

Expand Down
Loading

0 comments on commit 62b6f6d

Please sign in to comment.