~ubuntu-branches/ubuntu/precise/linux-lowlatency/precise

« back to all changes in this revision

Viewing changes to arch/arm/mach-dove/mpp.c

  • Committer: Package Import Robot
  • Author(s): Alessio Igor Bogani
  • Date: 2011-10-26 11:13:05 UTC
  • Revision ID: package-import@ubuntu.com-20111026111305-tz023xykf0i6eosh
Tags: upstream-3.2.0
ImportĀ upstreamĀ versionĀ 3.2.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * arch/arm/mach-dove/mpp.c
 
3
 *
 
4
 * MPP functions for Marvell Dove SoCs
 
5
 *
 
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.
 
9
 */
 
10
 
 
11
#include <linux/kernel.h>
 
12
#include <linux/gpio.h>
 
13
#include <linux/io.h>
 
14
#include <plat/mpp.h>
 
15
#include <mach/dove.h>
 
16
#include "mpp.h"
 
17
 
 
18
struct dove_mpp_grp {
 
19
        int start;
 
20
        int end;
 
21
};
 
22
 
 
23
/* Map a group to a range of GPIO pins in that group */
 
24
static const struct dove_mpp_grp dove_mpp_grp[] = {
 
25
        [MPP_24_39] = {
 
26
                .start  = 24,
 
27
                .end    = 39,
 
28
        },
 
29
        [MPP_40_45] = {
 
30
                .start  = 40,
 
31
                .end    = 45,
 
32
        },
 
33
        [MPP_46_51] = {
 
34
                .start  = 46,
 
35
                .end    = 51,
 
36
        },
 
37
        [MPP_58_61] = {
 
38
                .start  = 58,
 
39
                .end    = 61,
 
40
        },
 
41
        [MPP_62_63] = {
 
42
                .start  = 62,
 
43
                .end    = 63,
 
44
        },
 
45
};
 
46
 
 
47
/* Enable gpio for a range of pins. mode should be a combination of
 
48
   GPIO_OUTPUT_OK | GPIO_INPUT_OK */
 
49
static void dove_mpp_gpio_mode(int start, int end, int gpio_mode)
 
50
{
 
51
        int i;
 
52
 
 
53
        for (i = start; i <= end; i++)
 
54
                orion_gpio_set_valid(i, gpio_mode);
 
55
}
 
56
 
 
57
/* Dump all the extra MPP registers. The platform code will dump the
 
58
   registers for pins 0-23. */
 
59
static void dove_mpp_dump_regs(void)
 
60
{
 
61
        pr_debug("PMU_CTRL4_CTRL: %08x\n",
 
62
                 readl(DOVE_MPP_CTRL4_VIRT_BASE));
 
63
 
 
64
        pr_debug("PMU_MPP_GENERAL_CTRL: %08x\n",
 
65
                 readl(DOVE_PMU_MPP_GENERAL_CTRL));
 
66
 
 
67
        pr_debug("MPP_GENERAL: %08x\n", readl(DOVE_MPP_GENERAL_VIRT_BASE));
 
68
}
 
69
 
 
70
static void dove_mpp_cfg_nfc(int sel)
 
71
{
 
72
        u32 mpp_gen_cfg = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 
73
 
 
74
        mpp_gen_cfg &= ~0x1;
 
75
        mpp_gen_cfg |= sel;
 
76
        writel(mpp_gen_cfg, DOVE_MPP_GENERAL_VIRT_BASE);
 
77
 
 
78
        dove_mpp_gpio_mode(64, 71, GPIO_OUTPUT_OK);
 
79
}
 
80
 
 
81
static void dove_mpp_cfg_au1(int sel)
 
82
{
 
83
        u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 
84
        u32 ssp_ctrl1 = readl(DOVE_SSP_CTRL_STATUS_1);
 
85
        u32 mpp_gen_ctrl = readl(DOVE_MPP_GENERAL_VIRT_BASE);
 
86
        u32 global_cfg_2 = readl(DOVE_GLOBAL_CONFIG_2);
 
87
 
 
88
        mpp_ctrl4 &= ~(DOVE_AU1_GPIO_SEL);
 
89
        ssp_ctrl1 &= ~(DOVE_SSP_ON_AU1);
 
90
        mpp_gen_ctrl &= ~(DOVE_AU1_SPDIFO_GPIO_EN);
 
91
        global_cfg_2 &= ~(DOVE_TWSI_OPTION3_GPIO);
 
92
 
 
93
        if (!sel || sel == 0x2)
 
94
                dove_mpp_gpio_mode(52, 57, 0);
 
95
        else
 
96
                dove_mpp_gpio_mode(52, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
 
97
 
 
98
        if (sel & 0x1) {
 
99
                global_cfg_2 |= DOVE_TWSI_OPTION3_GPIO;
 
100
                dove_mpp_gpio_mode(56, 57, 0);
 
101
        }
 
102
        if (sel & 0x2) {
 
103
                mpp_gen_ctrl |= DOVE_AU1_SPDIFO_GPIO_EN;
 
104
                dove_mpp_gpio_mode(57, 57, GPIO_OUTPUT_OK | GPIO_INPUT_OK);
 
105
        }
 
106
        if (sel & 0x4) {
 
107
                ssp_ctrl1 |= DOVE_SSP_ON_AU1;
 
108
                dove_mpp_gpio_mode(52, 55, 0);
 
109
        }
 
110
        if (sel & 0x8)
 
111
                mpp_ctrl4 |= DOVE_AU1_GPIO_SEL;
 
112
 
 
113
        writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
 
114
        writel(ssp_ctrl1, DOVE_SSP_CTRL_STATUS_1);
 
115
        writel(mpp_gen_ctrl, DOVE_MPP_GENERAL_VIRT_BASE);
 
116
        writel(global_cfg_2, DOVE_GLOBAL_CONFIG_2);
 
117
}
 
118
 
 
119
/* Configure the group registers, enabling GPIO if sel indicates the
 
120
   pin is to be used for GPIO */
 
121
static void dove_mpp_conf_grp(unsigned int *mpp_grp_list)
 
122
{
 
123
        u32 mpp_ctrl4 = readl(DOVE_MPP_CTRL4_VIRT_BASE);
 
124
        int gpio_mode;
 
125
 
 
126
        for ( ; *mpp_grp_list; mpp_grp_list++) {
 
127
                unsigned int num = MPP_NUM(*mpp_grp_list);
 
128
                unsigned int sel = MPP_SEL(*mpp_grp_list);
 
129
 
 
130
                if (num > MPP_GRP_MAX) {
 
131
                        pr_err("dove: invalid MPP GRP number (%u)\n", num);
 
132
                        continue;
 
133
                }
 
134
 
 
135
                mpp_ctrl4 &= ~(0x1 << num);
 
136
                mpp_ctrl4 |= sel << num;
 
137
 
 
138
                gpio_mode = sel ? GPIO_OUTPUT_OK | GPIO_INPUT_OK : 0;
 
139
                dove_mpp_gpio_mode(dove_mpp_grp[num].start,
 
140
                                   dove_mpp_grp[num].end, gpio_mode);
 
141
        }
 
142
        writel(mpp_ctrl4, DOVE_MPP_CTRL4_VIRT_BASE);
 
143
}
 
144
 
 
145
/* Configure the various MPP pins on Dove */
 
146
void __init dove_mpp_conf(unsigned int *mpp_list,
 
147
                          unsigned int *mpp_grp_list,
 
148
                          unsigned int grp_au1_52_57,
 
149
                          unsigned int grp_nfc_64_71)
 
150
{
 
151
        dove_mpp_dump_regs();
 
152
 
 
153
        /* Use platform code for pins 0-23 */
 
154
        orion_mpp_conf(mpp_list, 0, MPP_MAX, DOVE_MPP_VIRT_BASE);
 
155
 
 
156
        dove_mpp_conf_grp(mpp_grp_list);
 
157
        dove_mpp_cfg_au1(grp_au1_52_57);
 
158
        dove_mpp_cfg_nfc(grp_nfc_64_71);
 
159
 
 
160
        dove_mpp_dump_regs();
 
161
}