/* * linux/arch/arm/mach-omap2/mux.c * * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations * * Copyright (C) 2004 - 2010 Texas Instruments Inc. * Copyright (C) 2003 - 2008 Nokia Corporation * * Written by Tony Lindgren * * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #include #include "omap_hwmod.h" #include "soc.h" #include "control.h" #include "mux.h" #include "prm.h" #include "common.h" #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */ #define OMAP_MUX_BASE_SZ 0x5ca struct omap_mux_entry { struct omap_mux mux; struct list_head node; }; static LIST_HEAD(mux_partitions); static DEFINE_MUTEX(muxmode_mutex); struct omap_mux_partition *omap_mux_get(const char *name) { 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(partition->base + reg); } void omap_mux_write(struct omap_mux_partition *partition, u16 val, u16 reg) { if (partition->flags & OMAP_MUX_REG_8BIT) __raw_writeb(val, partition->base + reg); else __raw_writew(val, partition->base + reg); } void omap_mux_write_array(struct omap_mux_partition *partition, struct omap_board_mux *board_mux) { if (!board_mux) return; while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) { omap_mux_write(partition, board_mux->value, board_mux->reg_offset); board_mux++; } } #ifdef CONFIG_OMAP_MUX static char *omap_mux_options; 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) { struct omap_mux *m = &e->mux; if (gpio == m->gpio) { gpio_mux = m; found++; } } if (found == 0) { pr_err("%s: Could not set gpio%i\n", __func__, gpio); return -ENODEV; } if (found > 1) { pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__, found, gpio); return -EINVAL; } old_mode = omap_mux_read(partition, gpio_mux->reg_offset); mux_mode = val & ~(OMAP_MUX_NR_MODES - 1); mux_mode |= partition->gpio; pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__, gpio_mux->muxnames[0], gpio, old_mode, mux_mode); omap_mux_write(partition, mux_mode, gpio_mux->reg_offset); return 0; } 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) {