linux/arch/arm/mach-mv78xx0/mpp.c
<<
>>
Prefs
   1/*
   2 * arch/arm/mach-mv78x00/mpp.c
   3 *
   4 * MPP functions for Marvell MV78x00 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/init.h>
  13#include <linux/mbus.h>
  14#include <linux/io.h>
  15#include <asm/gpio.h>
  16#include <mach/hardware.h>
  17#include "common.h"
  18#include "mpp.h"
  19
  20static unsigned int __init mv78xx0_variant(void)
  21{
  22        u32 dev, rev;
  23
  24        mv78xx0_pcie_id(&dev, &rev);
  25
  26        if (dev == MV78100_DEV_ID && rev >= MV78100_REV_A0)
  27                return MPP_78100_A0_MASK;
  28
  29        printk(KERN_ERR "MPP setup: unknown mv78x00 variant "
  30                        "(dev %#x rev %#x)\n", dev, rev);
  31        return 0;
  32}
  33
  34#define MPP_CTRL(i)     (DEV_BUS_VIRT_BASE + (i) * 4)
  35#define MPP_NR_REGS     (1 + MPP_MAX/8)
  36
  37void __init mv78xx0_mpp_conf(unsigned int *mpp_list)
  38{
  39        u32 mpp_ctrl[MPP_NR_REGS];
  40        unsigned int variant_mask;
  41        int i;
  42
  43        variant_mask = mv78xx0_variant();
  44        if (!variant_mask)
  45                return;
  46
  47        /* Initialize gpiolib. */
  48        orion_gpio_init();
  49
  50        printk(KERN_DEBUG "initial MPP regs:");
  51        for (i = 0; i < MPP_NR_REGS; i++) {
  52                mpp_ctrl[i] = readl(MPP_CTRL(i));
  53                printk(" %08x", mpp_ctrl[i]);
  54        }
  55        printk("\n");
  56
  57        for ( ; *mpp_list; mpp_list++) {
  58                unsigned int num = MPP_NUM(*mpp_list);
  59                unsigned int sel = MPP_SEL(*mpp_list);
  60                int shift, gpio_mode;
  61
  62                if (num > MPP_MAX) {
  63                        printk(KERN_ERR "mv78xx0_mpp_conf: invalid MPP "
  64                                        "number (%u)\n", num);
  65                        continue;
  66                }
  67                if (!(*mpp_list & variant_mask)) {
  68                        printk(KERN_WARNING
  69                                        "mv78xx0_mpp_conf: requested MPP%u config "
  70                                        "unavailable on this hardware\n", num);
  71                        continue;
  72                }
  73
  74                shift = (num & 7) << 2;
  75                mpp_ctrl[num / 8] &= ~(0xf << shift);
  76                mpp_ctrl[num / 8] |= sel << shift;
  77
  78                gpio_mode = 0;
  79                if (*mpp_list & MPP_INPUT_MASK)
  80                        gpio_mode |= GPIO_INPUT_OK;
  81                if (*mpp_list & MPP_OUTPUT_MASK)
  82                        gpio_mode |= GPIO_OUTPUT_OK;
  83                if (sel != 0)
  84                        gpio_mode = 0;
  85                orion_gpio_set_valid(num, gpio_mode);
  86        }
  87
  88        printk(KERN_DEBUG "  final MPP regs:");
  89        for (i = 0; i < MPP_NR_REGS; i++) {
  90                writel(mpp_ctrl[i], MPP_CTRL(i));
  91                printk(" %08x", mpp_ctrl[i]);
  92        }
  93        printk("\n");
  94}
  95