]> git.sur5r.net Git - u-boot/blob - arch/arm/cpu/arm926ejs/davinci/pinmux.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[u-boot] / arch / arm / cpu / arm926ejs / davinci / pinmux.c
1 /*
2  * DaVinci pinmux functions.
3  *
4  * Copyright (C) 2009 Nick Thompson, GE Fanuc Ltd, <nick.thompson@gefanuc.com>
5  * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
6  * Copyright (C) 2008 Lyrtech <www.lyrtech.com>
7  * Copyright (C) 2004 Texas Instruments.
8  *
9  * See file CREDITS for list of people who contributed to this
10  * project.
11  *
12  * This program is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU General Public License as published by
14  * the Free Software Foundation; either version 2 of the License, or
15  * (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25  */
26
27 #include <common.h>
28 #include <asm/arch/hardware.h>
29 #include <asm/io.h>
30 #include <asm/arch/davinci_misc.h>
31
32 /*
33  * Change the setting of a pin multiplexer field.
34  *
35  * Takes an array of pinmux settings similar to:
36  *
37  * struct pinmux_config uart_pins[] = {
38  *      { &davinci_syscfg_regs->pinmux[8], 2, 7 },
39  *      { &davinci_syscfg_regs->pinmux[9], 2, 0 }
40  * };
41  *
42  * Stepping through the array, each pinmux[n] register has the given value
43  * set in the pin mux field specified.
44  *
45  * The number of pins in the array must be passed (ARRAY_SIZE can provide
46  * this value conveniently).
47  *
48  * Returns 0 if all field numbers and values are in the correct range,
49  * else returns -1.
50  */
51 int davinci_configure_pin_mux(const struct pinmux_config *pins,
52                               const int n_pins)
53 {
54         int i;
55
56         /* check for invalid pinmux values */
57         for (i = 0; i < n_pins; i++) {
58                 if (pins[i].field >= PIN_MUX_NUM_FIELDS ||
59                     (pins[i].value & ~PIN_MUX_FIELD_MASK) != 0)
60                         return -1;
61         }
62
63         /* configure the pinmuxes */
64         for (i = 0; i < n_pins; i++) {
65                 const int offset = pins[i].field * PIN_MUX_FIELD_SIZE;
66                 const unsigned int value = pins[i].value << offset;
67                 const unsigned int mask = PIN_MUX_FIELD_MASK << offset;
68                 const dv_reg *mux = pins[i].mux;
69
70                 writel(value | (readl(mux) & (~mask)), mux);
71         }
72
73         return 0;
74 }
75
76 /*
77  * Configure multiple pinmux resources.
78  *
79  * Takes an pinmux_resource array of pinmux_config and pin counts:
80  *
81  * const struct pinmux_resource pinmuxes[] = {
82  *      PINMUX_ITEM(uart_pins),
83  *      PINMUX_ITEM(i2c_pins),
84  * };
85  *
86  * The number of items in the array must be passed (ARRAY_SIZE can provide
87  * this value conveniently).
88  *
89  * Each item entry is configured in the defined order. If configuration
90  * of any item fails, -1 is returned and none of the following items are
91  * configured. On success, 0 is returned.
92  */
93 int davinci_configure_pin_mux_items(const struct pinmux_resource *item,
94                                     const int n_items)
95 {
96         int i;
97
98         for (i = 0; i < n_items; i++) {
99                 if (davinci_configure_pin_mux(item[i].pins,
100                                               item[i].n_pins) != 0)
101                         return -1;
102         }
103
104         return 0;
105 }