2 * arch/arm/mach-orion5x/mpp.c
4 * MPP functions for Marvell Orion 5x SoCs
6 * This file is licensed under the terms of the GNU General Public
7 * License version 2. This program is licensed "as is" without any
8 * warranty of any kind, whether express or implied.
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/mbus.h>
16 #include <mach/hardware.h>
20 static int is_5181l(void)
25 orion5x_pcie_id(&dev
, &rev
);
27 return !!(dev
== MV88F5181_DEV_ID
&& rev
>= MV88F5181L_REV_A0
);
30 static int is_5182(void)
35 orion5x_pcie_id(&dev
, &rev
);
37 return !!(dev
== MV88F5182_DEV_ID
);
40 static int is_5281(void)
45 orion5x_pcie_id(&dev
, &rev
);
47 return !!(dev
== MV88F5281_DEV_ID
);
50 static int __init
determine_type_encoding(int mpp
, enum orion5x_mpp_type type
)
57 if (mpp
>= 1 && mpp
<= 15)
59 if (mpp
>= 16 && mpp
<= 19) {
62 if (type
== MPP_UNUSED
)
67 case MPP_PCIE_RST_OUTn
:
73 if (mpp
>= 0 && mpp
<= 7)
83 if (mpp
>= 8 && mpp
<= 19)
88 if (is_5182() || is_5281()) {
89 if (mpp
>= 4 && mpp
<= 7)
91 if (mpp
>= 12 && mpp
<= 17)
97 if (is_5181l() && mpp
>= 6 && mpp
<= 7)
103 if (mpp
>= 4 && mpp
<= 7)
105 if (mpp
>= 12 && mpp
<= 15)
111 if (mpp
>= 16 && mpp
<= 19)
116 printk(KERN_INFO
"unknown MPP type %d\n", type
);
121 void __init
orion5x_mpp_conf(struct orion5x_mpp_mode
*mode
)
123 u32 mpp_0_7_ctrl
= readl(MPP_0_7_CTRL
);
124 u32 mpp_8_15_ctrl
= readl(MPP_8_15_CTRL
);
125 u32 mpp_16_19_ctrl
= readl(MPP_16_19_CTRL
);
127 /* Initialize gpiolib. */
130 while (mode
->mpp
>= 0) {
135 if (mode
->mpp
>= 0 && mode
->mpp
<= 7)
137 else if (mode
->mpp
>= 8 && mode
->mpp
<= 15)
138 reg
= &mpp_8_15_ctrl
;
139 else if (mode
->mpp
>= 16 && mode
->mpp
<= 19)
140 reg
= &mpp_16_19_ctrl
;
142 printk(KERN_ERR
"orion5x_mpp_conf: invalid MPP "
143 "(%d)\n", mode
->mpp
);
147 num_type
= determine_type_encoding(mode
->mpp
, mode
->type
);
149 printk(KERN_ERR
"orion5x_mpp_conf: invalid MPP "
150 "combination (%d, %d)\n", mode
->mpp
,
155 shift
= (mode
->mpp
& 7) << 2;
156 *reg
&= ~(0xf << shift
);
157 *reg
|= (num_type
& 0xf) << shift
;
159 if (mode
->type
== MPP_UNUSED
&& (mode
->mpp
< 16 || is_5182()))
160 orion_gpio_set_unused(mode
->mpp
);
162 orion_gpio_set_valid(mode
->mpp
, !!(mode
->type
== MPP_GPIO
));
167 writel(mpp_0_7_ctrl
, MPP_0_7_CTRL
);
168 writel(mpp_8_15_ctrl
, MPP_8_15_CTRL
);
169 writel(mpp_16_19_ctrl
, MPP_16_19_CTRL
);