Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 137218
b: refs/heads/master
c: b722263
h: refs/heads/master
v: v3
  • Loading branch information
Valentin Longchamp authored and Sascha Hauer committed Mar 13, 2009
1 parent b81f1d5 commit 0dd830c
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 12 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: 41a1d91e7e7b08a13d78e03e67dcd7634f2d5cca
refs/heads/master: b7222631c3d0fd26e6d85dd78b1d0aa10dc64929
88 changes: 84 additions & 4 deletions trunk/arch/arm/mach-mx3/iomux.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
* 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
Expand All @@ -21,6 +22,7 @@
#include <linux/spinlock.h>
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/kernel.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
#include <mach/iomux-mx3.h>
Expand All @@ -38,6 +40,8 @@
static DEFINE_SPINLOCK(gpio_mux_lock);

#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)

unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
/*
* set the mode for a IOMUX pin.
*/
Expand All @@ -50,9 +54,6 @@ int mxc_iomux_mode(unsigned int pin_mode)
field = pin_mode & 0x3;
mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;

pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n",
__func__, (pin_mode & IOMUX_REG_MASK), field, mode);

spin_lock(&gpio_mux_lock);

l = __raw_readl(reg);
Expand Down Expand Up @@ -92,6 +93,86 @@ void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
}
EXPORT_SYMBOL(mxc_iomux_set_pad);

/*
* setups a single pin:
* - reserves the pin so that it is not claimed by another driver
* - setups the iomux according to the configuration
* - if the pin is configured as a GPIO, we claim it through kernel gpiolib
*/
int mxc_iomux_setup_pin(const unsigned int pin, const char *label)
{
unsigned pad = pin & IOMUX_PADNUM_MASK;
unsigned gpio;

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 -EINVAL;
}
mxc_iomux_mode(pin);

/* if we have a gpio, we can allocate it */
gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
if (gpio < (GPIO_PORT_MAX + 1) * 32)
if (gpio_request(gpio, label))
return -EINVAL;

return 0;
}
EXPORT_SYMBOL(mxc_iomux_setup_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++) {
if (mxc_iomux_setup_pin(*p, label))
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)
{
unsigned pad = pin & IOMUX_PADNUM_MASK;
unsigned gpio;

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

gpio = (pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT;
if (gpio < (GPIO_PORT_MAX + 1) * 32)
gpio_free(gpio);
}
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);

/*
* This function enables/disables the general purpose function for a particular
* signal.
Expand All @@ -111,4 +192,3 @@ void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
spin_unlock(&gpio_mux_lock);
}
EXPORT_SYMBOL(mxc_iomux_set_gpr);

45 changes: 38 additions & 7 deletions trunk/arch/arm/plat-mxc/include/mach/iomux-mx3.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ enum iomux_gp_func {
MUX_EXTDMAREQ2_MBX_SEL = 1 << 15,
MUX_TAMPER_DETECT_EN = 1 << 16,
MUX_PGP_USB_4WIRE = 1 << 17,
MUX_PGB_USB_COMMON = 1 << 18,
MUX_PGP_USB_COMMON = 1 << 18,
MUX_SDHC_MEMSTICK1 = 1 << 19,
MUX_SDHC_MEMSTICK2 = 1 << 20,
MUX_PGP_SPLL_BYP = 1 << 21,
Expand All @@ -109,21 +109,44 @@ enum iomux_gp_func {
};

/*
* This function enables/disables the general purpose function for a particular
* signal.
* setups a single pin:
* - reserves the pin so that it is not claimed by another driver
* - setups the iomux according to the configuration
* - if the pin is configured as a GPIO, we claim it throug kernel gpiolib
*/
int mxc_iomux_setup_pin(const unsigned int pin, const char *label);
/*
* setups mutliple pins
* convenient way to call the above function with tables
*/
void iomux_config_gpr(enum iomux_gp_func , bool);
int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
const char *label);

/*
* set the mode for a IOMUX pin.
* releases a single pin:
* - make it available for a future use by another driver
* - frees the GPIO if the pin was configured as GPIO
* - DOES NOT reconfigure the IOMUX in its reset state
*/
int mxc_iomux_mode(unsigned int);
void mxc_iomux_release_pin(const unsigned int pin);
/*
* releases multiple pins
* convenvient way to call the above function with tables
*/
void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count);

/*
* This function enables/disables the general purpose function for a particular
* signal.
*/
void mxc_iomux_set_gpr(enum iomux_gp_func, bool);
void mxc_iomux_set_gpr(enum iomux_gp_func, bool en);

/*
* This function only configures the iomux hardware.
* It is called by the setup functions and should not be called directly anymore.
* It is here visible for backward compatibility
*/
int mxc_iomux_mode(unsigned int pin_mode);

#define IOMUX_PADNUM_MASK 0x1ff
#define IOMUX_GPIONUM_SHIFT 9
Expand All @@ -143,6 +166,11 @@ void mxc_iomux_set_gpr(enum iomux_gp_func, bool);
(((iomux_pin & IOMUX_GPIONUM_MASK) >> IOMUX_GPIONUM_SHIFT) + \
MXC_GPIO_IRQ_START)

/*
* The number of gpio devices among the pads
*/
#define GPIO_PORT_MAX 3

/*
* This enumeration is constructed based on the Section
* "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
Expand Down Expand Up @@ -480,6 +508,9 @@ enum iomux_pins {
MX31_PIN_CAPTURE = IOMUX_PIN( 7, 327),
};

#define PIN_MAX 327
#define NB_PORTS 12 /* NB_PINS/32, we chose 32 pins per "PORT" */

/*
* Convenience values for use with mxc_iomux_mode()
*
Expand Down

0 comments on commit 0dd830c

Please sign in to comment.