2 * arch/arm/mach-dove/mpp.c
4 * MPP functions for Marvell Dove 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/gpio.h>
15 #include <mach/dove.h>
20 #define MPP_CTRL(i) ((i) == 3 ? \
21 DOVE_MPP_CTRL4_VIRT_BASE : \
22 DOVE_MPP_VIRT_BASE + (i) * 4)
23 #define PMU_SIG_REGS 2
24 #define PMU_SIG_CTRL(i) (DOVE_PMU_SIG_CTRL + (i) * 4)
31 static struct dove_mpp_grp dove_mpp_grp
[] = {
54 static void dove_mpp_gpio_mode(int start
, int end
, int gpio_mode
)
58 for (i
= start
; i
<= end
; i
++)
59 orion_gpio_set_valid(i
, gpio_mode
);
62 static void dove_mpp_dump_regs(void)
67 pr_debug("MPP_CTRL regs:");
68 for (i
= 0; i
< MPP_NR_REGS
; i
++)
69 printk(" %08x", readl(MPP_CTRL(i
)));
72 pr_debug("PMU_SIG_CTRL regs:");
73 for (i
= 0; i
< PMU_SIG_REGS
; i
++)
74 printk(" %08x", readl(PMU_SIG_CTRL(i
)));
77 pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n", readl(DOVE_PMU_MPP_GENERAL_CTRL
));
78 pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE
));
82 static void dove_mpp_cfg_nfc(int sel
)
84 u32 mpp_gen_cfg
= readl(DOVE_MPP_GENERAL_VIRT_BASE
);
88 writel(mpp_gen_cfg
, DOVE_MPP_GENERAL_VIRT_BASE
);
90 dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK
);
93 static void dove_mpp_cfg_au1(int sel
)
95 u32 mpp_ctrl4
= readl(DOVE_MPP_CTRL4_VIRT_BASE
);
96 u32 ssp_ctrl1
= readl(DOVE_SSP_CTRL_STATUS_1
);
97 u32 mpp_gen_ctrl
= readl(DOVE_MPP_GENERAL_VIRT_BASE
);
98 u32 global_cfg_2
= readl(DOVE_GLOBAL_CONFIG_2
);
100 mpp_ctrl4
&= ~(DOVE_AU1_GPIO_SEL
);
101 ssp_ctrl1
&= ~(DOVE_SSP_ON_AU1
);
102 mpp_gen_ctrl
&= ~(DOVE_AU1_SPDIFO_GPIO_EN
);
103 global_cfg_2
&= ~(DOVE_TWSI_OPTION3_GPIO
);
105 if (!sel
|| sel
== 0x2)
106 dove_mpp_gpio_mode(52, 57, 0);
108 dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK
| GPIO_INPUT_OK
);
111 global_cfg_2
|= DOVE_TWSI_OPTION3_GPIO
;
112 dove_mpp_gpio_mode(56, 57, 0);
115 mpp_gen_ctrl
|= DOVE_AU1_SPDIFO_GPIO_EN
;
116 dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK
| GPIO_INPUT_OK
);
119 ssp_ctrl1
|= DOVE_SSP_ON_AU1
;
120 dove_mpp_gpio_mode(52, 55, 0);
123 mpp_ctrl4
|= DOVE_AU1_GPIO_SEL
;
125 writel(mpp_ctrl4
, DOVE_MPP_CTRL4_VIRT_BASE
);
126 writel(ssp_ctrl1
, DOVE_SSP_CTRL_STATUS_1
);
127 writel(mpp_gen_ctrl
, DOVE_MPP_GENERAL_VIRT_BASE
);
128 writel(global_cfg_2
, DOVE_GLOBAL_CONFIG_2
);
131 static void dove_mpp_conf_grp(int num
, int sel
, u32
*mpp_ctrl
)
133 int start
= dove_mpp_grp
[num
].start
;
134 int end
= dove_mpp_grp
[num
].end
;
135 int gpio_mode
= sel
? GPIO_OUTPUT_OK
| GPIO_INPUT_OK
: 0;
137 *mpp_ctrl
&= ~(0x1 << num
);
138 *mpp_ctrl
|= sel
<< num
;
140 dove_mpp_gpio_mode(start
, end
, gpio_mode
);
143 void __init
dove_mpp_conf(unsigned int *mpp_list
)
145 u32 mpp_ctrl
[MPP_NR_REGS
];
146 u32 pmu_mpp_ctrl
= 0;
147 u32 pmu_sig_ctrl
[PMU_SIG_REGS
];
150 /* Initialize gpiolib. */
153 for (i
= 0; i
< MPP_NR_REGS
; i
++)
154 mpp_ctrl
[i
] = readl(MPP_CTRL(i
));
156 for (i
= 0; i
< PMU_SIG_REGS
; i
++)
157 pmu_sig_ctrl
[i
] = readl(PMU_SIG_CTRL(i
));
159 pmu_mpp_ctrl
= readl(DOVE_PMU_MPP_GENERAL_CTRL
);
161 dove_mpp_dump_regs();
163 for ( ; *mpp_list
!= MPP_END
; mpp_list
++) {
164 unsigned int num
= MPP_NUM(*mpp_list
);
165 unsigned int sel
= MPP_SEL(*mpp_list
);
166 int shift
, gpio_mode
;
169 pr_err("dove: invalid MPP number (%u)\n", num
);
173 if (*mpp_list
& MPP_NFC_MASK
) {
174 dove_mpp_cfg_nfc(sel
);
178 if (*mpp_list
& MPP_AU1_MASK
) {
179 dove_mpp_cfg_au1(sel
);
183 if (*mpp_list
& MPP_GRP_MASK
) {
184 dove_mpp_conf_grp(num
, sel
, &mpp_ctrl
[3]);
188 shift
= (num
& 7) << 2;
189 if (*mpp_list
& MPP_PMU_MASK
) {
190 pmu_mpp_ctrl
|= (0x1 << num
);
191 pmu_sig_ctrl
[num
/ 8] &= ~(0xf << shift
);
192 pmu_sig_ctrl
[num
/ 8] |= 0xf << shift
;
195 mpp_ctrl
[num
/ 8] &= ~(0xf << shift
);
196 mpp_ctrl
[num
/ 8] |= sel
<< shift
;
197 gpio_mode
= GPIO_OUTPUT_OK
| GPIO_INPUT_OK
;
200 orion_gpio_set_valid(num
, gpio_mode
);
203 for (i
= 0; i
< MPP_NR_REGS
; i
++)
204 writel(mpp_ctrl
[i
], MPP_CTRL(i
));
206 for (i
= 0; i
< PMU_SIG_REGS
; i
++)
207 writel(pmu_sig_ctrl
[i
], PMU_SIG_CTRL(i
));
209 writel(pmu_mpp_ctrl
, DOVE_PMU_MPP_GENERAL_CTRL
);
211 dove_mpp_dump_regs();