2 * arch/arm/plat-spear/include/plat/padmux.c
4 * SPEAr platform specific gpio pads muxing source file
6 * Copyright (C) 2009 ST Microelectronics
7 * Viresh Kumar<viresh.kumar@st.com>
9 * This file is licensed under the terms of the GNU General Public
10 * License version 2. This program is licensed "as is" without any
11 * warranty of any kind, whether express or implied.
14 #include <linux/err.h>
16 #include <linux/slab.h>
17 #include <plat/padmux.h>
20 * struct pmx: pmx definition structure
22 * base: base address of configuration registers
23 * mode_reg: mode configurations
24 * mux_reg: muxing configurations
25 * active_mode: pointer to current active mode
29 struct pmx_reg mode_reg
;
30 struct pmx_reg mux_reg
;
31 struct pmx_mode
*active_mode
;
34 static struct pmx
*pmx
;
37 * pmx_mode_set - Enables an multiplexing mode
38 * @mode - pointer to pmx mode
40 * It will set mode of operation in hardware.
41 * Returns -ve on Err otherwise 0
43 static int pmx_mode_set(struct pmx_mode
*mode
)
50 pmx
->active_mode
= mode
;
52 val
= readl(pmx
->base
+ pmx
->mode_reg
.offset
);
53 val
&= ~pmx
->mode_reg
.mask
;
54 val
|= mode
->mask
& pmx
->mode_reg
.mask
;
55 writel(val
, pmx
->base
+ pmx
->mode_reg
.offset
);
61 * pmx_devs_enable - Enables list of devices
62 * @devs - pointer to pmx device array
63 * @count - number of devices to enable
65 * It will enable pads for all required peripherals once and only once.
66 * If peripheral is not supported by current mode then request is rejected.
67 * Conflicts between peripherals are not handled and peripherals will be
68 * enabled in the order they are present in pmx_dev array.
69 * In case of conflicts last peripheral enabled will be present.
70 * Returns -ve on Err otherwise 0
72 static int pmx_devs_enable(struct pmx_dev
**devs
, u8 count
)
79 val
= readl(pmx
->base
+ pmx
->mux_reg
.offset
);
80 for (i
= 0; i
< count
; i
++) {
83 if (!devs
[i
]->name
|| !devs
[i
]->modes
) {
84 printk(KERN_ERR
"padmux: dev name or modes is null\n");
87 /* check if peripheral exists in active mode */
88 if (pmx
->active_mode
) {
90 for (j
= 0; j
< devs
[i
]->mode_count
; j
++) {
91 if (devs
[i
]->modes
[j
].ids
&
92 pmx
->active_mode
->id
) {
98 printk(KERN_ERR
"%s device not available in %s"\
99 "mode\n", devs
[i
]->name
,
100 pmx
->active_mode
->name
);
105 /* enable peripheral */
106 mask
= devs
[i
]->modes
[j
].mask
& pmx
->mux_reg
.mask
;
107 if (devs
[i
]->enb_on_reset
)
112 devs
[i
]->is_active
= true;
114 writel(val
, pmx
->base
+ pmx
->mux_reg
.offset
);
117 /* this will ensure that multiplexing can't be changed now */
118 pmx
= (struct pmx
*)-1;
124 * pmx_register - registers a platform requesting pad mux feature
125 * @driver - pointer to driver structure containing driver specific parameters
127 * Also this must be called only once. This will allocate memory for pmx
128 * structure, will call pmx_mode_set, will call pmx_devs_enable.
129 * Returns -ve on Err otherwise 0
131 int pmx_register(struct pmx_driver
*driver
)
137 if (!driver
->base
|| !driver
->devs
)
140 pmx
= kzalloc(sizeof(*pmx
), GFP_KERNEL
);
144 pmx
->base
= (u32
)driver
->base
;
145 pmx
->mode_reg
.offset
= driver
->mode_reg
.offset
;
146 pmx
->mode_reg
.mask
= driver
->mode_reg
.mask
;
147 pmx
->mux_reg
.offset
= driver
->mux_reg
.offset
;
148 pmx
->mux_reg
.mask
= driver
->mux_reg
.mask
;
150 /* choose mode to enable */
152 ret
= pmx_mode_set(driver
->mode
);
156 ret
= pmx_devs_enable(driver
->devs
, driver
->devs_count
);