Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Interface for smsc fdc48m81x Super IO chip
0003  *
0004  * Author: MontaVista Software, Inc. source@mvista.com
0005  *
0006  * 2001-2003 (c) MontaVista Software, Inc. This file is licensed under
0007  * the terms of the GNU General Public License version 2. This program
0008  * is licensed "as is" without any warranty of any kind, whether express
0009  * or implied.
0010  *
0011  * Copyright 2004 (c) MontaVista Software, Inc.
0012  */
0013 #include <linux/init.h>
0014 #include <linux/types.h>
0015 #include <asm/io.h>
0016 #include <asm/txx9/smsc_fdc37m81x.h>
0017 
0018 /* Common Registers */
0019 #define SMSC_FDC37M81X_CONFIG_INDEX  0x00
0020 #define SMSC_FDC37M81X_CONFIG_DATA   0x01
0021 #define SMSC_FDC37M81X_CONF      0x02
0022 #define SMSC_FDC37M81X_INDEX         0x03
0023 #define SMSC_FDC37M81X_DNUM      0x07
0024 #define SMSC_FDC37M81X_DID       0x20
0025 #define SMSC_FDC37M81X_DREV      0x21
0026 #define SMSC_FDC37M81X_PCNT      0x22
0027 #define SMSC_FDC37M81X_PMGT      0x23
0028 #define SMSC_FDC37M81X_OSC       0x24
0029 #define SMSC_FDC37M81X_CONFPA0       0x26
0030 #define SMSC_FDC37M81X_CONFPA1       0x27
0031 #define SMSC_FDC37M81X_TEST4         0x2B
0032 #define SMSC_FDC37M81X_TEST5         0x2C
0033 #define SMSC_FDC37M81X_TEST1         0x2D
0034 #define SMSC_FDC37M81X_TEST2         0x2E
0035 #define SMSC_FDC37M81X_TEST3         0x2F
0036 
0037 /* Logical device numbers */
0038 #define SMSC_FDC37M81X_FDD       0x00
0039 #define SMSC_FDC37M81X_SERIAL1       0x04
0040 #define SMSC_FDC37M81X_SERIAL2       0x05
0041 #define SMSC_FDC37M81X_KBD       0x07
0042 
0043 /* Logical device Config Registers */
0044 #define SMSC_FDC37M81X_ACTIVE        0x30
0045 #define SMSC_FDC37M81X_BASEADDR0     0x60
0046 #define SMSC_FDC37M81X_BASEADDR1     0x61
0047 #define SMSC_FDC37M81X_INT       0x70
0048 #define SMSC_FDC37M81X_INT2      0x72
0049 #define SMSC_FDC37M81X_MODE      0xF0
0050 
0051 /* Chip Config Values */
0052 #define SMSC_FDC37M81X_CONFIG_ENTER  0x55
0053 #define SMSC_FDC37M81X_CONFIG_EXIT   0xaa
0054 #define SMSC_FDC37M81X_CHIP_ID       0x4d
0055 
0056 static unsigned long g_smsc_fdc37m81x_base;
0057 
0058 static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
0059 {
0060     outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
0061 
0062     return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
0063 }
0064 
0065 static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
0066 {
0067     outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
0068     outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
0069 }
0070 
0071 void smsc_fdc37m81x_config_beg(void)
0072 {
0073     if (g_smsc_fdc37m81x_base) {
0074         outb(SMSC_FDC37M81X_CONFIG_ENTER,
0075              g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
0076     }
0077 }
0078 
0079 void smsc_fdc37m81x_config_end(void)
0080 {
0081     if (g_smsc_fdc37m81x_base)
0082         outb(SMSC_FDC37M81X_CONFIG_EXIT,
0083              g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
0084 }
0085 
0086 u8 smsc_fdc37m81x_config_get(u8 reg)
0087 {
0088     u8 val = 0;
0089 
0090     if (g_smsc_fdc37m81x_base)
0091         val = smsc_fdc37m81x_rd(reg);
0092 
0093     return val;
0094 }
0095 
0096 void smsc_fdc37m81x_config_set(u8 reg, u8 val)
0097 {
0098     if (g_smsc_fdc37m81x_base)
0099         smsc_dc37m81x_wr(reg, val);
0100 }
0101 
0102 unsigned long __init smsc_fdc37m81x_init(unsigned long port)
0103 {
0104     const int field = sizeof(unsigned long) * 2;
0105     u8 chip_id;
0106 
0107     if (g_smsc_fdc37m81x_base)
0108         pr_warn("%s: stepping on old base=0x%0*lx\n", __func__, field,
0109             g_smsc_fdc37m81x_base);
0110 
0111     g_smsc_fdc37m81x_base = port;
0112 
0113     smsc_fdc37m81x_config_beg();
0114 
0115     chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
0116     if (chip_id == SMSC_FDC37M81X_CHIP_ID)
0117         smsc_fdc37m81x_config_end();
0118     else {
0119         pr_warn("%s: unknown chip id 0x%02x\n", __func__, chip_id);
0120         g_smsc_fdc37m81x_base = 0;
0121     }
0122 
0123     return g_smsc_fdc37m81x_base;
0124 }
0125 
0126 #ifdef DEBUG
0127 static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg)
0128 {
0129     pr_info("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
0130         smsc_fdc37m81x_rd(reg));
0131 }
0132 
0133 void smsc_fdc37m81x_config_dump(void)
0134 {
0135     u8 orig;
0136     const char *fname = __func__;
0137 
0138     smsc_fdc37m81x_config_beg();
0139 
0140     orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
0141 
0142     pr_info("%s: common\n", fname);
0143     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
0144                        SMSC_FDC37M81X_DNUM);
0145     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
0146                        SMSC_FDC37M81X_DID);
0147     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
0148                        SMSC_FDC37M81X_DREV);
0149     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
0150                        SMSC_FDC37M81X_PCNT);
0151     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
0152                        SMSC_FDC37M81X_PMGT);
0153 
0154     pr_info("%s: keyboard\n", fname);
0155     smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
0156     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
0157                        SMSC_FDC37M81X_ACTIVE);
0158     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
0159                        SMSC_FDC37M81X_INT);
0160     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
0161                        SMSC_FDC37M81X_INT2);
0162     smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
0163                        SMSC_FDC37M81X_LDCR_F0);
0164 
0165     smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
0166 
0167     smsc_fdc37m81x_config_end();
0168 }
0169 #endif