Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 112485e9 authored by Benoit Cousson's avatar Benoit Cousson
Browse files

OMAP: mux: Add support for control module split in several partitions



Starting on OMAP4, the pin mux configuration is located in two
different partitions of the control module (CODE_PAD and WKUP_PAD).
The first one is inside the core power domain whereas the second
one is inside the wakeup.
- Add the capability to add any number of partition during board init
time depending of Soc partitioning.
- Add some init flags as well in order to avoid explicit Soc version
check inside the mux core code.
- Add a comment with mux0 mode on top of omap_mux/board/<partition>
if the current mux mode is not the default one.

Thanks to Tony Lindgren <tony@atomide.com> for the following improvements:
- Add omap_mux_get for getting the partition data so platform level
device code can use it.
- Fix the rx51 board code to use the new API.
- Do not store the partition for each mux entry. Look up the partition
for debugfs instead.

Thanks to Dan Murphy <dmurphy@ti.com> for testing on OMAP4 and reporting
a couple of bugs.
Thanks to Anand Gadiyar <gadiyar@ti.com> for testing on OMAP3 zoom and
bug report.

Signed-off-by: default avatarBenoit Cousson <b-cousson@ti.com>
Signed-off-by: default avatarTony Lindgren <tony@atomide.com>
Tested-by: default avatarMurphy Dan <dmurphy@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Anand Gadiyar <gadiyar@ti.com>
parent 1cbb3a9a
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -293,6 +293,8 @@ static struct omap_board_mux rx51_mmc2_off_mux[] = {
	{ .reg_offset = OMAP_MUX_TERMINATOR },
};

static struct omap_mux_partition *partition;

/*
 * Current flows to eMMC when eMMC is off and the data lines are pulled up,
 * so pull them down. N.B. we pull 8 lines because we are using 8 lines.
@@ -300,9 +302,9 @@ static struct omap_board_mux rx51_mmc2_off_mux[] = {
static void rx51_mmc2_remux(struct device *dev, int slot, int power_on)
{
	if (power_on)
		omap_mux_write_array(rx51_mmc2_on_mux);
		omap_mux_write_array(partition, rx51_mmc2_on_mux);
	else
		omap_mux_write_array(rx51_mmc2_off_mux);
		omap_mux_write_array(partition, rx51_mmc2_off_mux);
}

static struct omap2_hsmmc_info mmc[] __initdata = {
@@ -922,7 +924,11 @@ void __init rx51_peripherals_init(void)
	rx51_init_wl1251();
	spi_register_board_info(rx51_peripherals_spi_board_info,
				ARRAY_SIZE(rx51_peripherals_spi_board_info));

	partition = omap_mux_get("core");
	if (partition)
		omap2_hsmmc_init(mmc);

	platform_device_register(&rx51_charger_device);
}
+233 −104
Original line number Diff line number Diff line
/*
 * linux/arch/arm/mach-omap2/mux.c
 *
 * OMAP2 and OMAP3 pin multiplexing configurations
 * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
 *
 * Copyright (C) 2004 - 2008 Texas Instruments Inc.
 * Copyright (C) 2004 - 2010 Texas Instruments Inc.
 * Copyright (C) 2003 - 2008 Nokia Corporation
 *
 * Written by Tony Lindgren
@@ -40,60 +40,72 @@

#define OMAP_MUX_BASE_OFFSET		0x30	/* Offset from CTRL_BASE */
#define OMAP_MUX_BASE_SZ		0x5ca
#define MUXABLE_GPIO_MODE3		BIT(0)

struct omap_mux_entry {
	struct omap_mux		mux;
	struct list_head	node;
};

static unsigned long mux_phys;
static void __iomem *mux_base;
static u8 omap_mux_flags;
static LIST_HEAD(mux_partitions);
static DEFINE_MUTEX(muxmode_mutex);

u16 omap_mux_read(u16 reg)
struct omap_mux_partition *omap_mux_get(const char *name)
{
	if (cpu_is_omap24xx())
		return __raw_readb(mux_base + reg);
	struct omap_mux_partition *partition;

	list_for_each_entry(partition, &mux_partitions, node) {
		if (!strcmp(name, partition->name))
			return partition;
	}

	return NULL;
}

u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
{
	if (partition->flags & OMAP_MUX_REG_8BIT)
		return __raw_readb(partition->base + reg);
	else
		return __raw_readw(mux_base + reg);
		return __raw_readw(partition->base + reg);
}

void omap_mux_write(u16 val, u16 reg)
void omap_mux_write(struct omap_mux_partition *partition, u16 val,
			   u16 reg)
{
	if (cpu_is_omap24xx())
		__raw_writeb(val, mux_base + reg);
	if (partition->flags & OMAP_MUX_REG_8BIT)
		__raw_writeb(val, partition->base + reg);
	else
		__raw_writew(val, mux_base + reg);
		__raw_writew(val, partition->base + reg);
}

void omap_mux_write_array(struct omap_board_mux *board_mux)
void omap_mux_write_array(struct omap_mux_partition *partition,
				 struct omap_board_mux *board_mux)
{
	while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
		omap_mux_write(board_mux->value, board_mux->reg_offset);
		omap_mux_write(partition, board_mux->value,
			       board_mux->reg_offset);
		board_mux++;
	}
}

static LIST_HEAD(muxmodes);
static DEFINE_MUTEX(muxmode_mutex);

#ifdef CONFIG_OMAP_MUX

static char *omap_mux_options;

int __init omap_mux_init_gpio(int gpio, int val)
static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
				      int gpio, int val)
{
	struct omap_mux_entry *e;
	struct omap_mux *gpio_mux = NULL;
	u16 old_mode;
	u16 mux_mode;
	int found = 0;
	struct list_head *muxmodes = &partition->muxmodes;

	if (!gpio)
		return -EINVAL;

	list_for_each_entry(e, &muxmodes, node) {
	list_for_each_entry(e, muxmodes, node) {
		struct omap_mux *m = &e->mux;
		if (gpio == m->gpio) {
			gpio_mux = m;
@@ -112,24 +124,40 @@ int __init omap_mux_init_gpio(int gpio, int val)
		return -EINVAL;
	}

	old_mode = omap_mux_read(gpio_mux->reg_offset);
	old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
	mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
	if (omap_mux_flags & MUXABLE_GPIO_MODE3)
	if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
		mux_mode |= OMAP_MUX_MODE3;
	else
		mux_mode |= OMAP_MUX_MODE4;
	pr_debug("mux: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n",
		 gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
	omap_mux_write(mux_mode, gpio_mux->reg_offset);
	omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);

	return 0;
}

int __init omap_mux_init_signal(const char *muxname, int val)
int __init omap_mux_init_gpio(int gpio, int val)
{
	struct omap_mux_partition *partition;
	int ret;

	list_for_each_entry(partition, &mux_partitions, node) {
		ret = _omap_mux_init_gpio(partition, gpio, val);
		if (!ret)
			return ret;
	}

	return -ENODEV;
}

static int __init _omap_mux_init_signal(struct omap_mux_partition *partition,
					const char *muxname, int val)
{
	struct omap_mux_entry *e;
	const char *mode_name;
	int found = 0, mode0_len = 0;
	struct list_head *muxmodes = &partition->muxmodes;

	mode_name = strchr(muxname, '.');
	if (mode_name) {
@@ -139,7 +167,7 @@ int __init omap_mux_init_signal(const char *muxname, int val)
		mode_name = muxname;
	}

	list_for_each_entry(e, &muxmodes, node) {
	list_for_each_entry(e, muxmodes, node) {
		struct omap_mux *m = &e->mux;
		char *m0_entry = m->muxnames[0];
		int i;
@@ -159,12 +187,14 @@ int __init omap_mux_init_signal(const char *muxname, int val)
				u16 old_mode;
				u16 mux_mode;

				old_mode = omap_mux_read(m->reg_offset);
				old_mode = omap_mux_read(partition,
							 m->reg_offset);
				mux_mode = val | i;
				pr_debug("mux: Setting signal "
					 "%s.%s 0x%04x -> 0x%04x\n",
					 m0_entry, muxname, old_mode, mux_mode);
				omap_mux_write(mux_mode, m->reg_offset);
				omap_mux_write(partition, mux_mode,
					       m->reg_offset);
				found++;
			}
		}
@@ -184,6 +214,21 @@ int __init omap_mux_init_signal(const char *muxname, int val)
	return -ENODEV;
}

int __init omap_mux_init_signal(const char *muxname, int val)
{
	struct omap_mux_partition *partition;
	int ret;

	list_for_each_entry(partition, &mux_partitions, node) {
		ret = _omap_mux_init_signal(partition, muxname, val);
		if (!ret)
			return ret;
	}

	return -ENODEV;

}

#ifdef CONFIG_DEBUG_FS

#define OMAP_MUX_MAX_NR_FLAGS	10
@@ -248,13 +293,15 @@ static inline void omap_mux_decode(struct seq_file *s, u16 val)
	} while (i-- > 0);
}

#define OMAP_MUX_DEFNAME_LEN	16
#define OMAP_MUX_DEFNAME_LEN	32

static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
{
	struct omap_mux_partition *partition = s->private;
	struct omap_mux_entry *e;
	u8 omap_gen = omap_rev() >> 28;

	list_for_each_entry(e, &muxmodes, node) {
	list_for_each_entry(e, &partition->muxmodes, node) {
		struct omap_mux *m = &e->mux;
		char m0_def[OMAP_MUX_DEFNAME_LEN];
		char *m0_name = m->muxnames[0];
@@ -272,11 +319,16 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
			}
			m0_def[i] = toupper(m0_name[i]);
		}
		val = omap_mux_read(m->reg_offset);
		val = omap_mux_read(partition, m->reg_offset);
		mode = val & OMAP_MUX_MODE7;
		if (mode != 0)
			seq_printf(s, "/* %s */\n", m->muxnames[mode]);

		seq_printf(s, "OMAP%i_MUX(%s, ",
					cpu_is_omap34xx() ? 3 : 0, m0_def);
		/*
		 * XXX: Might be revisited to support differences accross
		 * same OMAP generation.
		 */
		seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
		omap_mux_decode(s, val);
		seq_printf(s, "),\n");
	}
@@ -286,7 +338,7 @@ static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)

static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
{
	return single_open(file, omap_mux_dbg_board_show, &inode->i_private);
	return single_open(file, omap_mux_dbg_board_show, inode->i_private);
}

static const struct file_operations omap_mux_dbg_board_fops = {
@@ -296,19 +348,43 @@ static const struct file_operations omap_mux_dbg_board_fops = {
	.release	= single_release,
};

static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
{
	struct omap_mux_partition *partition;

	list_for_each_entry(partition, &mux_partitions, node) {
		struct list_head *muxmodes = &partition->muxmodes;
		struct omap_mux_entry *e;

		list_for_each_entry(e, muxmodes, node) {
			struct omap_mux *m = &e->mux;

			if (m == mux)
				return partition;
		}
	}

	return NULL;
}

static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
{
	struct omap_mux *m = s->private;
	struct omap_mux_partition *partition;
	const char *none = "NA";
	u16 val;
	int mode;

	val = omap_mux_read(m->reg_offset);
	partition = omap_mux_get_partition(m);
	if (!partition)
		return 0;

	val = omap_mux_read(partition, m->reg_offset);
	mode = val & OMAP_MUX_MODE7;

	seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n",
	seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
			m->muxnames[0], m->muxnames[mode],
			mux_phys + m->reg_offset, m->reg_offset, val,
			partition->phys + m->reg_offset, m->reg_offset, val,
			m->balls[0] ? m->balls[0] : none,
			m->balls[1] ? m->balls[1] : none);
	seq_printf(s, "mode: ");
@@ -338,6 +414,7 @@ static ssize_t omap_mux_dbg_signal_write(struct file *file,
	struct omap_mux *m;
	unsigned long val;
	int buf_size, ret;
	struct omap_mux_partition *partition;

	if (count > OMAP_MUX_MAX_ARG_CHAR)
		return -EINVAL;
@@ -358,7 +435,11 @@ static ssize_t omap_mux_dbg_signal_write(struct file *file,
	seqf = file->private_data;
	m = seqf->private;

	omap_mux_write((u16)val, m->reg_offset);
	partition = omap_mux_get_partition(m);
	if (!partition)
		return -ENODEV;

	omap_mux_write(partition, (u16)val, m->reg_offset);
	*ppos += count;

	return count;
@@ -379,22 +460,38 @@ static const struct file_operations omap_mux_dbg_signal_fops = {

static struct dentry *mux_dbg_dir;

static void __init omap_mux_dbg_init(void)
static void __init omap_mux_dbg_create_entry(
				struct omap_mux_partition *partition,
				struct dentry *mux_dbg_dir)
{
	struct omap_mux_entry *e;

	list_for_each_entry(e, &partition->muxmodes, node) {
		struct omap_mux *m = &e->mux;

		(void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
					  m, &omap_mux_dbg_signal_fops);
	}
}

static void __init omap_mux_dbg_init(void)
{
	struct omap_mux_partition *partition;
	static struct dentry *mux_dbg_board_dir;

	mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
	if (!mux_dbg_dir)
		return;

	(void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir,
					NULL, &omap_mux_dbg_board_fops);

	list_for_each_entry(e, &muxmodes, node) {
		struct omap_mux *m = &e->mux;
	mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
	if (!mux_dbg_board_dir)
		return;

		(void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
					m, &omap_mux_dbg_signal_fops);
	list_for_each_entry(partition, &mux_partitions, node) {
		omap_mux_dbg_create_entry(partition, mux_dbg_dir);
		(void)debugfs_create_file(partition->name, S_IRUGO,
					  mux_dbg_board_dir, partition,
					  &omap_mux_dbg_board_fops);
	}
}

@@ -421,11 +518,13 @@ static void __init omap_mux_free_names(struct omap_mux *m)
/* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
static int __init omap_mux_late_init(void)
{
	struct omap_mux_entry *e, *tmp;
	struct omap_mux_partition *partition;

	list_for_each_entry_safe(e, tmp, &muxmodes, node) {
	list_for_each_entry(partition, &mux_partitions, node) {
		struct omap_mux_entry *e, *tmp;
		list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
			struct omap_mux *m = &e->mux;
		u16 mode = omap_mux_read(m->reg_offset);
			u16 mode = omap_mux_read(partition, m->reg_offset);

			if (OMAP_MODE_GPIO(mode))
				continue;
@@ -437,7 +536,7 @@ static int __init omap_mux_late_init(void)
			omap_mux_free_names(m);
			kfree(m);
#endif

		}
	}

	omap_mux_dbg_init();
@@ -592,51 +691,63 @@ free:

#endif	/* CONFIG_OMAP_MUX */

static u16 omap_mux_get_by_gpio(int gpio)
static struct omap_mux *omap_mux_get_by_gpio(
				struct omap_mux_partition *partition,
				int gpio)
{
	struct omap_mux_entry *e;
	u16 offset = OMAP_MUX_TERMINATOR;
	struct omap_mux *ret = NULL;

	list_for_each_entry(e, &muxmodes, node) {
	list_for_each_entry(e, &partition->muxmodes, node) {
		struct omap_mux *m = &e->mux;
		if (m->gpio == gpio) {
			offset = m->reg_offset;
			ret = m;
			break;
		}
	}

	return offset;
	return ret;
}

/* Needed for dynamic muxing of GPIO pins for off-idle */
u16 omap_mux_get_gpio(int gpio)
{
	u16 offset;
	struct omap_mux_partition *partition;
	struct omap_mux *m;

	offset = omap_mux_get_by_gpio(gpio);
	if (offset == OMAP_MUX_TERMINATOR) {
		pr_err("mux: Could not get gpio%i\n", gpio);
		return offset;
	list_for_each_entry(partition, &mux_partitions, node) {
		m = omap_mux_get_by_gpio(partition, gpio);
		if (m)
			return omap_mux_read(partition, m->reg_offset);
	}

	return omap_mux_read(offset);
	if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
		pr_err("mux: Could not get gpio%i\n", gpio);

	return OMAP_MUX_TERMINATOR;
}

/* Needed for dynamic muxing of GPIO pins for off-idle */
void omap_mux_set_gpio(u16 val, int gpio)
{
	u16 offset;
	struct omap_mux_partition *partition;
	struct omap_mux *m = NULL;

	offset = omap_mux_get_by_gpio(gpio);
	if (offset == OMAP_MUX_TERMINATOR) {
		pr_err("mux: Could not set gpio%i\n", gpio);
	list_for_each_entry(partition, &mux_partitions, node) {
		m = omap_mux_get_by_gpio(partition, gpio);
		if (m) {
			omap_mux_write(partition, val, m->reg_offset);
			return;
		}
	}

	omap_mux_write(val, offset);
	if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
		pr_err("mux: Could not set gpio%i\n", gpio);
}

static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
static struct omap_mux * __init omap_mux_list_add(
					struct omap_mux_partition *partition,
					struct omap_mux *src)
{
	struct omap_mux_entry *entry;
	struct omap_mux *m;
@@ -656,7 +767,7 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
#endif

	mutex_lock(&muxmode_mutex);
	list_add_tail(&entry->node, &muxmodes);
	list_add_tail(&entry->node, &partition->muxmodes);
	mutex_unlock(&muxmode_mutex);

	return m;
@@ -667,7 +778,8 @@ static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
 * the GPIO to mux offset mapping that is needed for dynamic muxing
 * of GPIO pins for off-idle.
 */
static void __init omap_mux_init_list(struct omap_mux *superset)
static void __init omap_mux_init_list(struct omap_mux_partition *partition,
				      struct omap_mux *superset)
{
	while (superset->reg_offset !=  OMAP_MUX_TERMINATOR) {
		struct omap_mux *entry;
@@ -679,13 +791,14 @@ static void __init omap_mux_init_list(struct omap_mux *superset)
		}
#else
		/* Skip pins that are not muxed as GPIO by bootloader */
		if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) {
		if (!OMAP_MODE_GPIO(omap_mux_read(partition,
				    superset->reg_offset))) {
			superset++;
			continue;
		}
#endif

		entry = omap_mux_list_add(superset);
		entry = omap_mux_list_add(partition, superset);
		if (!entry) {
			pr_err("mux: Could not add entry\n");
			return;
@@ -706,10 +819,11 @@ static void omap_mux_init_package(struct omap_mux *superset,
		omap_mux_package_init_balls(package_balls, superset);
}

static void omap_mux_init_signals(struct omap_board_mux *board_mux)
static void omap_mux_init_signals(struct omap_mux_partition *partition,
				  struct omap_board_mux *board_mux)
{
	omap_mux_set_cmdline_signals();
	omap_mux_write_array(board_mux);
	omap_mux_write_array(partition, board_mux);
}

#else
@@ -720,34 +834,49 @@ static void omap_mux_init_package(struct omap_mux *superset,
{
}

static void omap_mux_init_signals(struct omap_board_mux *board_mux)
static void omap_mux_init_signals(struct omap_mux_partition *partition,
				  struct omap_board_mux *board_mux)
{
}

#endif

int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
static u32 mux_partitions_cnt;

int __init omap_mux_init(const char *name, u32 flags,
			 u32 mux_pbase, u32 mux_size,
			 struct omap_mux *superset,
			 struct omap_mux *package_subset,
			 struct omap_board_mux *board_mux,
			 struct omap_ball *package_balls)
{
	if (mux_base)
		return -EBUSY;
	struct omap_mux_partition *partition;

	mux_phys = mux_pbase;
	mux_base = ioremap(mux_pbase, mux_size);
	if (!mux_base) {
		pr_err("mux: Could not ioremap\n");
	partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
	if (!partition)
		return -ENOMEM;

	partition->name = name;
	partition->flags = flags;
	partition->size = mux_size;
	partition->phys = mux_pbase;
	partition->base = ioremap(mux_pbase, mux_size);
	if (!partition->base) {
		pr_err("mux: Could not ioremap mux partition at 0x%08x\n",
			partition->phys);
		return -ENODEV;
	}

	if (cpu_is_omap24xx())
		omap_mux_flags = MUXABLE_GPIO_MODE3;
	INIT_LIST_HEAD(&partition->muxmodes);

	list_add_tail(&partition->node, &mux_partitions);
	mux_partitions_cnt++;
	pr_info("MUX: Add partition: #%d: %s, flags: %x\n",
		mux_partitions_cnt, partition->name, partition->flags);

	omap_mux_init_package(superset, package_subset, package_balls);
	omap_mux_init_list(superset);
	omap_mux_init_signals(board_mux);
	omap_mux_init_list(partition, superset);
	omap_mux_init_signals(partition, board_mux);

	return 0;
}
+58 −12
Original line number Diff line number Diff line
/*
 * Copyright (C) 2009 Nokia
 * Copyright (C) 2009 Texas Instruments
 * Copyright (C) 2009-2010 Texas Instruments
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
@@ -56,7 +56,7 @@

#define OMAP_MODE_GPIO(x)	(((x) & OMAP_MUX_MODE7) == OMAP_MUX_MODE4)

/* Flags for omap_mux_init */
/* Flags for omapX_mux_init */
#define OMAP_PACKAGE_MASK		0xffff
#define OMAP_PACKAGE_CBP		6		/* 515-pin 0.40 0.50 */
#define OMAP_PACKAGE_CUS		5		/* 423-pin 0.65 */
@@ -69,11 +69,44 @@
#define OMAP_MUX_NR_MODES		8		/* Available modes */
#define OMAP_MUX_NR_SIDES		2		/* Bottom & top */

/*
 * omap_mux_init flags definition:
 *
 * OMAP_MUX_REG_8BIT: Ensure that access to padconf is done in 8 bits.
 * The default value is 16 bits.
 * OMAP_MUX_GPIO_IN_MODE3: The GPIO is selected in mode3.
 * The default is mode4.
 */
#define OMAP_MUX_REG_8BIT		(1 << 0)
#define OMAP_MUX_GPIO_IN_MODE3		(1 << 1)

/**
 * struct mux_partition - contain partition related information
 * @name: name of the current partition
 * @flags: flags specific to this partition
 * @phys: physical address
 * @size: partition size
 * @base: virtual address after ioremap
 * @muxmodes: list of nodes that belong to a partition
 * @node: list node for the partitions linked list
 */
struct omap_mux_partition {
	const char		*name;
	u32			flags;
	u32			phys;
	u32			size;
	void __iomem		*base;
	struct list_head	muxmodes;
	struct list_head	node;
};

/**
 * struct omap_mux - data for omap mux register offset and it's value
 * @reg_offset:	mux register offset from the mux base
 * @gpio:	GPIO number
 * @muxnames:	available signal modes for a ball
 * @balls:	available balls on the package
 * @partition:	mux partition
 */
struct omap_mux {
	u16	reg_offset;
@@ -150,29 +183,40 @@ u16 omap_mux_get_gpio(int gpio);
 */
void omap_mux_set_gpio(u16 val, int gpio);

/**
 * omap_mux_get() - get a mux partition by name
 * @name:		Name of the mux partition
 *
 */
struct omap_mux_partition *omap_mux_get(const char *name);

/**
 * omap_mux_read() - read mux register
 * @partition:		Mux partition
 * @mux_offset:		Offset of the mux register
 *
 */
u16 omap_mux_read(u16 mux_offset);
u16 omap_mux_read(struct omap_mux_partition *p, u16 mux_offset);

/**
 * omap_mux_write() - write mux register
 * @partition:		Mux partition
 * @val:		New mux register value
 * @mux_offset:		Offset of the mux register
 *
 * This should be only needed for dynamic remuxing of non-gpio signals.
 */
void omap_mux_write(u16 val, u16 mux_offset);
void omap_mux_write(struct omap_mux_partition *p, u16 val, u16 mux_offset);

/**
 * omap_mux_write_array() - write an array of mux registers
 * @partition:		Mux partition
 * @board_mux:		Array of mux registers terminated by MAP_MUX_TERMINATOR
 *
 * This should be only needed for dynamic remuxing of non-gpio signals.
 */
void omap_mux_write_array(struct omap_board_mux *board_mux);
void omap_mux_write_array(struct omap_mux_partition *p,
			  struct omap_board_mux *board_mux);

/**
 * omap2420_mux_init() - initialize mux system with board specific set
@@ -198,8 +242,10 @@ int omap3_mux_init(struct omap_board_mux *board_mux, int flags);
/**
 * omap_mux_init - private mux init function, do not call
 */
int omap_mux_init(u32 mux_pbase, u32 mux_size,
int omap_mux_init(const char *name, u32 flags,
		  u32 mux_pbase, u32 mux_size,
		  struct omap_mux *superset,
		  struct omap_mux *package_subset,
		  struct omap_board_mux *board_mux,
		  struct omap_ball *package_balls);
+4 −3
Original line number Diff line number Diff line
@@ -681,7 +681,8 @@ int __init omap2420_mux_init(struct omap_board_mux *board_subset, int flags)
		pr_warning("mux: No ball data available for omap2420 package\n");
	}

	return omap_mux_init(OMAP2420_CONTROL_PADCONF_MUX_PBASE,
	return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
			     OMAP2420_CONTROL_PADCONF_MUX_PBASE,
			     OMAP2420_CONTROL_PADCONF_MUX_SIZE,
			     omap2420_muxmodes, NULL, board_subset,
			     package_balls);
+4 −3
Original line number Diff line number Diff line
@@ -784,7 +784,8 @@ int __init omap2430_mux_init(struct omap_board_mux *board_subset, int flags)
		pr_warning("mux: No ball data available for omap2420 package\n");
	}

	return omap_mux_init(OMAP2430_CONTROL_PADCONF_MUX_PBASE,
	return omap_mux_init("core", OMAP_MUX_REG_8BIT | OMAP_MUX_GPIO_IN_MODE3,
			     OMAP2430_CONTROL_PADCONF_MUX_PBASE,
			     OMAP2430_CONTROL_PADCONF_MUX_SIZE,
			     omap2430_muxmodes, NULL, board_subset,
			     package_balls);
Loading