linux/arch/arm/mach-w90x900/mfp.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/mach-w90x900/mfp.c
   3 *
   4 * Copyright (c) 2008 Nuvoton technology corporation
   5 *
   6 * Wan ZongShun <mcuos.com@gmail.com>
   7 *
   8 * This program is free software; you can redistribute it and/or modify
   9 * it under the terms of the GNU General Public License as published by
  10 * the Free Software Foundation;version 2 of the License.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/kernel.h>
  15#include <linux/device.h>
  16#include <linux/list.h>
  17#include <linux/errno.h>
  18#include <linux/err.h>
  19#include <linux/string.h>
  20#include <linux/clk.h>
  21#include <linux/mutex.h>
  22#include <linux/io.h>
  23
  24#include <mach/hardware.h>
  25
  26#define REG_MFSEL       (W90X900_VA_GCR + 0xC)
  27
  28#define GPSELF          (0x01 << 1)
  29#define GPSELC          (0x03 << 2)
  30#define GPSELD          (0x0f << 4)
  31
  32#define GPSELEI0        (0x01 << 26)
  33#define GPSELEI1        (0x01 << 27)
  34
  35#define GPIOG0TO1       (0x03 << 14)
  36#define GPIOG2TO3       (0x03 << 16)
  37#define GPIOG22TO23     (0x03 << 22)
  38#define GPIOG18TO20     (0x07 << 18)
  39
  40#define ENSPI           (0x0a << 14)
  41#define ENI2C0          (0x01 << 14)
  42#define ENI2C1          (0x01 << 16)
  43#define ENAC97          (0x02 << 22)
  44#define ENSD1           (0x02 << 18)
  45#define ENSD0           (0x0a << 4)
  46#define ENKPI           (0x02 << 2)
  47#define ENNAND          (0x01 << 2)
  48
  49static DEFINE_MUTEX(mfp_mutex);
  50
  51void mfp_set_groupf(struct device *dev)
  52{
  53        unsigned long mfpen;
  54        const char *dev_id;
  55
  56        BUG_ON(!dev);
  57
  58        mutex_lock(&mfp_mutex);
  59
  60        dev_id = dev_name(dev);
  61
  62        mfpen = __raw_readl(REG_MFSEL);
  63
  64        if (strcmp(dev_id, "nuc900-emc") == 0)
  65                mfpen |= GPSELF;/*enable mac*/
  66        else
  67                mfpen &= ~GPSELF;/*GPIOF[9:0]*/
  68
  69        __raw_writel(mfpen, REG_MFSEL);
  70
  71        mutex_unlock(&mfp_mutex);
  72}
  73EXPORT_SYMBOL(mfp_set_groupf);
  74
  75void mfp_set_groupc(struct device *dev)
  76{
  77        unsigned long mfpen;
  78        const char *dev_id;
  79
  80        BUG_ON(!dev);
  81
  82        mutex_lock(&mfp_mutex);
  83
  84        dev_id = dev_name(dev);
  85
  86        mfpen = __raw_readl(REG_MFSEL);
  87
  88        if (strcmp(dev_id, "nuc900-lcd") == 0)
  89                mfpen |= GPSELC;/*enable lcd*/
  90        else if (strcmp(dev_id, "nuc900-kpi") == 0) {
  91                mfpen &= (~GPSELC);/*enable kpi*/
  92                mfpen |= ENKPI;
  93        } else if (strcmp(dev_id, "nuc900-nand") == 0) {
  94                mfpen &= (~GPSELC);/*enable nand*/
  95                mfpen |= ENNAND;
  96        } else
  97                mfpen &= (~GPSELC);/*GPIOC[14:0]*/
  98
  99        __raw_writel(mfpen, REG_MFSEL);
 100
 101        mutex_unlock(&mfp_mutex);
 102}
 103EXPORT_SYMBOL(mfp_set_groupc);
 104
 105void mfp_set_groupi(struct device *dev)
 106{
 107        unsigned long mfpen;
 108        const char *dev_id;
 109
 110        BUG_ON(!dev);
 111
 112        mutex_lock(&mfp_mutex);
 113
 114        dev_id = dev_name(dev);
 115
 116        mfpen = __raw_readl(REG_MFSEL);
 117
 118        mfpen &= ~GPSELEI1;/*default gpio16*/
 119
 120        if (strcmp(dev_id, "nuc900-wdog") == 0)
 121                mfpen |= GPSELEI1;/*enable wdog*/
 122        else if (strcmp(dev_id, "nuc900-atapi") == 0)
 123                mfpen |= GPSELEI0;/*enable atapi*/
 124        else if (strcmp(dev_id, "nuc900-keypad") == 0)
 125                mfpen &= ~GPSELEI0;/*enable keypad*/
 126
 127        __raw_writel(mfpen, REG_MFSEL);
 128
 129        mutex_unlock(&mfp_mutex);
 130}
 131EXPORT_SYMBOL(mfp_set_groupi);
 132
 133void mfp_set_groupg(struct device *dev, const char *subname)
 134{
 135        unsigned long mfpen;
 136        const char *dev_id;
 137
 138        BUG_ON((!dev) && (!subname));
 139
 140        mutex_lock(&mfp_mutex);
 141
 142        if (subname != NULL)
 143                dev_id = subname;
 144        else
 145                dev_id = dev_name(dev);
 146
 147        mfpen = __raw_readl(REG_MFSEL);
 148
 149        if (strcmp(dev_id, "nuc900-spi") == 0) {
 150                mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);
 151                mfpen |= ENSPI;/*enable spi*/
 152        } else if (strcmp(dev_id, "nuc900-i2c0") == 0) {
 153                mfpen &= ~(GPIOG0TO1);
 154                mfpen |= ENI2C0;/*enable i2c0*/
 155        } else if (strcmp(dev_id, "nuc900-i2c1") == 0) {
 156                mfpen &= ~(GPIOG2TO3);
 157                mfpen |= ENI2C1;/*enable i2c1*/
 158        } else if (strcmp(dev_id, "nuc900-ac97") == 0) {
 159                mfpen &= ~(GPIOG22TO23);
 160                mfpen |= ENAC97;/*enable AC97*/
 161        } else if (strcmp(dev_id, "nuc900-mmc-port1") == 0) {
 162                mfpen &= ~(GPIOG18TO20);
 163                mfpen |= (ENSD1 | 0x01);/*enable sd1*/
 164        } else {
 165                mfpen &= ~(GPIOG0TO1 | GPIOG2TO3);/*GPIOG[3:0]*/
 166        }
 167
 168        __raw_writel(mfpen, REG_MFSEL);
 169
 170        mutex_unlock(&mfp_mutex);
 171}
 172EXPORT_SYMBOL(mfp_set_groupg);
 173
 174void mfp_set_groupd(struct device *dev, const char *subname)
 175{
 176        unsigned long mfpen;
 177        const char *dev_id;
 178
 179        BUG_ON((!dev) && (!subname));
 180
 181        mutex_lock(&mfp_mutex);
 182
 183        if (subname != NULL)
 184                dev_id = subname;
 185        else
 186                dev_id = dev_name(dev);
 187
 188        mfpen = __raw_readl(REG_MFSEL);
 189
 190        if (strcmp(dev_id, "nuc900-mmc-port0") == 0) {
 191                mfpen &= ~GPSELD;/*enable sd0*/
 192                mfpen |= ENSD0;
 193        } else
 194                mfpen &= (~GPSELD);
 195
 196        __raw_writel(mfpen, REG_MFSEL);
 197
 198        mutex_unlock(&mfp_mutex);
 199}
 200EXPORT_SYMBOL(mfp_set_groupd);
 201