Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 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> |
Atsushi Nemoto | 22b1d70 | 2008-07-11 00:31:36 +0900 | [diff] [blame] | 16 | #include <asm/txx9/smsc_fdc37m81x.h> |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 17 | |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 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 | |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 56 | static unsigned long g_smsc_fdc37m81x_base; |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 57 | |
| 58 | static 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 | |
| 65 | static 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 | |
| 71 | void 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 | |
| 79 | void 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 | |
| 86 | u8 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 | |
| 96 | void smsc_fdc37m81x_config_set(u8 reg, u8 val) |
| 97 | { |
| 98 | if (g_smsc_fdc37m81x_base) |
| 99 | smsc_dc37m81x_wr(reg, val); |
| 100 | } |
| 101 | |
| 102 | unsigned 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) |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 108 | printk(KERN_WARNING "%s: stepping on old base=0x%0*lx\n", |
| 109 | __func__, |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 110 | field, g_smsc_fdc37m81x_base); |
| 111 | |
| 112 | g_smsc_fdc37m81x_base = port; |
| 113 | |
| 114 | smsc_fdc37m81x_config_beg(); |
| 115 | |
| 116 | chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID); |
| 117 | if (chip_id == SMSC_FDC37M81X_CHIP_ID) |
| 118 | smsc_fdc37m81x_config_end(); |
| 119 | else { |
André Goddard Rosa | af901ca | 2009-11-14 13:09:05 -0200 | [diff] [blame] | 120 | printk(KERN_WARNING "%s: unknown chip id 0x%02x\n", __func__, |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 121 | chip_id); |
| 122 | g_smsc_fdc37m81x_base = 0; |
| 123 | } |
| 124 | |
| 125 | return g_smsc_fdc37m81x_base; |
| 126 | } |
| 127 | |
| 128 | #ifdef DEBUG |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 129 | static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg) |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 130 | { |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 131 | printk(KERN_INFO "%s: dev=0x%02x reg=0x%02x val=0x%02x\n", |
| 132 | key, dev, reg, |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 133 | smsc_fdc37m81x_rd(reg)); |
| 134 | } |
| 135 | |
| 136 | void smsc_fdc37m81x_config_dump(void) |
| 137 | { |
| 138 | u8 orig; |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 139 | const char *fname = __func__; |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 140 | |
| 141 | smsc_fdc37m81x_config_beg(); |
| 142 | |
| 143 | orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM); |
| 144 | |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 145 | printk(KERN_INFO "%s: common\n", fname); |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 146 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, |
| 147 | SMSC_FDC37M81X_DNUM); |
| 148 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, |
| 149 | SMSC_FDC37M81X_DID); |
| 150 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, |
| 151 | SMSC_FDC37M81X_DREV); |
| 152 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, |
| 153 | SMSC_FDC37M81X_PCNT); |
| 154 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE, |
| 155 | SMSC_FDC37M81X_PMGT); |
| 156 | |
Atsushi Nemoto | bb72f1f | 2008-07-24 00:25:21 +0900 | [diff] [blame] | 157 | printk(KERN_INFO "%s: keyboard\n", fname); |
Manish Lachwani | e8f05de | 2005-01-22 09:23:38 -0800 | [diff] [blame] | 158 | smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD); |
| 159 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, |
| 160 | SMSC_FDC37M81X_ACTIVE); |
| 161 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, |
| 162 | SMSC_FDC37M81X_INT); |
| 163 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, |
| 164 | SMSC_FDC37M81X_INT2); |
| 165 | smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD, |
| 166 | SMSC_FDC37M81X_LDCR_F0); |
| 167 | |
| 168 | smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig); |
| 169 | |
| 170 | smsc_fdc37m81x_config_end(); |
| 171 | } |
| 172 | #endif |