~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/arm/mach-mxc91231/iomux.c

Version: ~ [ linux-5.15-rc5 ] ~ [ linux-5.14.11 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.72 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.152 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.210 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.250 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.286 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.288 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.18.140 ] ~ [ linux-3.16.85 ] ~ [ linux-3.14.79 ] ~ [ linux-3.12.74 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
  3  * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
  4  * Copyright (C) 2009 by Valentin Longchamp <valentin.longchamp@epfl.ch>
  5  *
  6  * This program is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU General Public License
  8  * as published by the Free Software Foundation; either version 2
  9  * of the License, or (at your option) any later version.
 10  * This program is distributed in the hope that it will be useful,
 11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 13  * GNU General Public License for more details.
 14  *
 15  * You should have received a copy of the GNU General Public License
 16  * along with this program; if not, write to the Free Software
 17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 18  * MA 02110-1301, USA.
 19  */
 20 
 21 #include <linux/module.h>
 22 #include <linux/spinlock.h>
 23 #include <linux/io.h>
 24 #include <linux/kernel.h>
 25 #include <mach/hardware.h>
 26 #include <mach/gpio.h>
 27 #include <mach/iomux-mxc91231.h>
 28 
 29 /*
 30  * IOMUX register (base) addresses
 31  */
 32 #define IOMUX_AP_BASE           MXC91231_IO_ADDRESS(MXC91231_IOMUX_AP_BASE_ADDR)
 33 #define IOMUX_COM_BASE          MXC91231_IO_ADDRESS(MXC91231_IOMUX_COM_BASE_ADDR)
 34 #define IOMUXSW_AP_MUX_CTL      (IOMUX_AP_BASE + 0x000)
 35 #define IOMUXSW_SP_MUX_CTL      (IOMUX_COM_BASE + 0x000)
 36 #define IOMUXSW_PAD_CTL         (IOMUX_COM_BASE + 0x200)
 37 
 38 #define IOMUXINT_OBS1           (IOMUX_AP_BASE + 0x600)
 39 #define IOMUXINT_OBS2           (IOMUX_AP_BASE + 0x004)
 40 
 41 static DEFINE_SPINLOCK(gpio_mux_lock);
 42 
 43 #define NB_PORTS                        ((PIN_MAX + 32) / 32)
 44 #define PIN_GLOBAL_NUM(pin) \
 45         (((pin & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT)*PIN_AP_MAX + \
 46          ((pin & MUX_REG_MASK) >> MUX_REG_SHIFT)*4 +            \
 47          ((pin & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT))
 48 
 49 unsigned long mxc_pin_alloc_map[NB_PORTS * 32 / BITS_PER_LONG];
 50 /*
 51  * set the mode for a IOMUX pin.
 52  */
 53 int mxc_iomux_mode(const unsigned int pin_mode)
 54 {
 55         u32 side, field, l, mode, ret = 0;
 56         void __iomem *reg;
 57 
 58         side = (pin_mode & MUX_SIDE_MASK) >> MUX_SIDE_SHIFT;
 59         switch (side) {
 60         case MUX_SIDE_AP:
 61                 reg = IOMUXSW_AP_MUX_CTL;
 62                 break;
 63         case MUX_SIDE_SP:
 64                 reg = IOMUXSW_SP_MUX_CTL;
 65                 break;
 66         default:
 67                 return -EINVAL;
 68         }
 69         reg += ((pin_mode & MUX_REG_MASK) >> MUX_REG_SHIFT) * 4;
 70         field = (pin_mode & MUX_FIELD_MASK) >> MUX_FIELD_SHIFT;
 71         mode = (pin_mode & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
 72 
 73         spin_lock(&gpio_mux_lock);
 74 
 75         l = __raw_readl(reg);
 76         l &= ~(0xff << (field * 8));
 77         l |= mode << (field * 8);
 78         __raw_writel(l, reg);
 79 
 80         spin_unlock(&gpio_mux_lock);
 81 
 82         return ret;
 83 }
 84 EXPORT_SYMBOL(mxc_iomux_mode);
 85 
 86 /*
 87  * This function configures the pad value for a IOMUX pin.
 88  */
 89 void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
 90 {
 91         u32 padgrp, field, l;
 92         void __iomem *reg;
 93 
 94         padgrp = (pin & MUX_PADGRP_MASK) >> MUX_PADGRP_SHIFT;
 95         reg = IOMUXSW_PAD_CTL + (pin + 2) / 3 * 4;
 96         field = (pin + 2) % 3;
 97 
 98         pr_debug("%s: reg offset = 0x%x, field = %d\n",
 99                         __func__, (pin + 2) / 3, field);
100 
101         spin_lock(&gpio_mux_lock);
102 
103         l = __raw_readl(reg);
104         l &= ~(0x1ff << (field * 10));
105         l |= config << (field * 10);
106         __raw_writel(l, reg);
107 
108         spin_unlock(&gpio_mux_lock);
109 }
110 EXPORT_SYMBOL(mxc_iomux_set_pad);
111 
112 /*
113  * allocs a single pin:
114  *      - reserves the pin so that it is not claimed by another driver
115  *      - setups the iomux according to the configuration
116  */
117 int mxc_iomux_alloc_pin(const unsigned int pin_mode, const char *label)
118 {
119         unsigned pad = PIN_GLOBAL_NUM(pin_mode);
120         if (pad >= (PIN_MAX + 1)) {
121                 printk(KERN_ERR "mxc_iomux: Attempt to request nonexistant pin %u for \"%s\"\n",
122                         pad, label ? label : "?");
123                 return -EINVAL;
124         }
125 
126         if (test_and_set_bit(pad, mxc_pin_alloc_map)) {
127                 printk(KERN_ERR "mxc_iomux: pin %u already used. Allocation for \"%s\" failed\n",
128                         pad, label ? label : "?");
129                 return -EBUSY;
130         }
131         mxc_iomux_mode(pin_mode);
132 
133         return 0;
134 }
135 EXPORT_SYMBOL(mxc_iomux_alloc_pin);
136 
137 int mxc_iomux_setup_multiple_pins(unsigned int *pin_list, unsigned count,
138                 const char *label)
139 {
140         unsigned int *p = pin_list;
141         int i;
142         int ret = -EINVAL;
143 
144         for (i = 0; i < count; i++) {
145                 ret = mxc_iomux_alloc_pin(*p, label);
146                 if (ret)
147                         goto setup_error;
148                 p++;
149         }
150         return 0;
151 
152 setup_error:
153         mxc_iomux_release_multiple_pins(pin_list, i);
154         return ret;
155 }
156 EXPORT_SYMBOL(mxc_iomux_setup_multiple_pins);
157 
158 void mxc_iomux_release_pin(const unsigned int pin_mode)
159 {
160         unsigned pad = PIN_GLOBAL_NUM(pin_mode);
161 
162         if (pad < (PIN_MAX + 1))
163                 clear_bit(pad, mxc_pin_alloc_map);
164 }
165 EXPORT_SYMBOL(mxc_iomux_release_pin);
166 
167 void mxc_iomux_release_multiple_pins(unsigned int *pin_list, int count)
168 {
169         unsigned int *p = pin_list;
170         int i;
171 
172         for (i = 0; i < count; i++) {
173                 mxc_iomux_release_pin(*p);
174                 p++;
175         }
176 }
177 EXPORT_SYMBOL(mxc_iomux_release_multiple_pins);
178 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp