linux/arch/mips/txx9/generic/smsc_fdc37m81x.c
<<
>>
Prefs
   1/*
   2 * Interface for smsc fdc48m81x Super IO chip
   3 *
   4 * Author: MontaVista Software, Inc. source@mvista.com
   5 *
   6 * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
   7 * the terms of the GNU General Public License version 2. This program
   8 * is licensed "as is" without any warranty of any kind, whether express
   9 * or implied.
  10 *
  11 * Copyright 2004 (c) MontaVista Software, Inc.
  12 */
  13#include <linux/init.h>
  14#include <linux/types.h>
  15#include <asm/io.h>
  16#include <asm/txx9/smsc_fdc37m81x.h>
  17
  18/* Common Registers */
  19#define SMSC_FDC37M81X_CONFIG_INDEX  0x00
  20#define SMSC_FDC37M81X_CONFIG_DATA   0x01
  21#define SMSC_FDC37M81X_CONF          0x02
  22#define SMSC_FDC37M81X_INDEX         0x03
  23#define SMSC_FDC37M81X_DNUM          0x07
  24#define SMSC_FDC37M81X_DID           0x20
  25#define SMSC_FDC37M81X_DREV          0x21
  26#define SMSC_FDC37M81X_PCNT          0x22
  27#define SMSC_FDC37M81X_PMGT          0x23
  28#define SMSC_FDC37M81X_OSC           0x24
  29#define SMSC_FDC37M81X_CONFPA0       0x26
  30#define SMSC_FDC37M81X_CONFPA1       0x27
  31#define SMSC_FDC37M81X_TEST4         0x2B
  32#define SMSC_FDC37M81X_TEST5         0x2C
  33#define SMSC_FDC37M81X_TEST1         0x2D
  34#define SMSC_FDC37M81X_TEST2         0x2E
  35#define SMSC_FDC37M81X_TEST3         0x2F
  36
  37/* Logical device numbers */
  38#define SMSC_FDC37M81X_FDD           0x00
  39#define SMSC_FDC37M81X_SERIAL1       0x04
  40#define SMSC_FDC37M81X_SERIAL2       0x05
  41#define SMSC_FDC37M81X_KBD           0x07
  42
  43/* Logical device Config Registers */
  44#define SMSC_FDC37M81X_ACTIVE        0x30
  45#define SMSC_FDC37M81X_BASEADDR0     0x60
  46#define SMSC_FDC37M81X_BASEADDR1     0x61
  47#define SMSC_FDC37M81X_INT           0x70
  48#define SMSC_FDC37M81X_INT2          0x72
  49#define SMSC_FDC37M81X_MODE          0xF0
  50
  51/* Chip Config Values */
  52#define SMSC_FDC37M81X_CONFIG_ENTER  0x55
  53#define SMSC_FDC37M81X_CONFIG_EXIT   0xaa
  54#define SMSC_FDC37M81X_CHIP_ID       0x4d
  55
  56static unsigned long g_smsc_fdc37m81x_base;
  57
  58static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
  59{
  60        outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  61
  62        return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
  63}
  64
  65static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
  66{
  67        outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  68        outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
  69}
  70
  71void smsc_fdc37m81x_config_beg(void)
  72{
  73        if (g_smsc_fdc37m81x_base) {
  74                outb(SMSC_FDC37M81X_CONFIG_ENTER,
  75                     g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  76        }
  77}
  78
  79void smsc_fdc37m81x_config_end(void)
  80{
  81        if (g_smsc_fdc37m81x_base)
  82                outb(SMSC_FDC37M81X_CONFIG_EXIT,
  83                     g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  84}
  85
  86u8 smsc_fdc37m81x_config_get(u8 reg)
  87{
  88        u8 val = 0;
  89
  90        if (g_smsc_fdc37m81x_base)
  91                val = smsc_fdc37m81x_rd(reg);
  92
  93        return val;
  94}
  95
  96void smsc_fdc37m81x_config_set(u8 reg, u8 val)
  97{
  98        if (g_smsc_fdc37m81x_base)
  99                smsc_dc37m81x_wr(reg, val);
 100}
 101
 102unsigned long __init smsc_fdc37m81x_init(unsigned long port)
 103{
 104        const int field = sizeof(unsigned long) * 2;
 105        u8 chip_id;
 106
 107        if (g_smsc_fdc37m81x_base)
 108                pr_warn("%s: stepping on old base=0x%0*lx\n", __func__, field,
 109                        g_smsc_fdc37m81x_base);
 110
 111        g_smsc_fdc37m81x_base = port;
 112
 113        smsc_fdc37m81x_config_beg();
 114
 115        chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
 116        if (chip_id == SMSC_FDC37M81X_CHIP_ID)
 117                smsc_fdc37m81x_config_end();
 118        else {
 119                pr_warn("%s: unknown chip id 0x%02x\n", __func__, chip_id);
 120                g_smsc_fdc37m81x_base = 0;
 121        }
 122
 123        return g_smsc_fdc37m81x_base;
 124}
 125
 126#ifdef DEBUG
 127static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg)
 128{
 129        pr_info("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
 130                smsc_fdc37m81x_rd(reg));
 131}
 132
 133void smsc_fdc37m81x_config_dump(void)
 134{
 135        u8 orig;
 136        const char *fname = __func__;
 137
 138        smsc_fdc37m81x_config_beg();
 139
 140        orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
 141
 142        pr_info("%s: common\n", fname);
 143        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
 144                                       SMSC_FDC37M81X_DNUM);
 145        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
 146                                       SMSC_FDC37M81X_DID);
 147        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
 148                                       SMSC_FDC37M81X_DREV);
 149        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
 150                                       SMSC_FDC37M81X_PCNT);
 151        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
 152                                       SMSC_FDC37M81X_PMGT);
 153
 154        pr_info("%s: keyboard\n", fname);
 155        smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
 156        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
 157                                       SMSC_FDC37M81X_ACTIVE);
 158        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
 159                                       SMSC_FDC37M81X_INT);
 160        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
 161                                       SMSC_FDC37M81X_INT2);
 162        smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
 163                                       SMSC_FDC37M81X_LDCR_F0);
 164
 165        smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
 166
 167        smsc_fdc37m81x_config_end();
 168}
 169#endif
 170