smsc_fdc37m81x.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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. /* Common Registers */
  18. #define SMSC_FDC37M81X_CONFIG_INDEX 0x00
  19. #define SMSC_FDC37M81X_CONFIG_DATA 0x01
  20. #define SMSC_FDC37M81X_CONF 0x02
  21. #define SMSC_FDC37M81X_INDEX 0x03
  22. #define SMSC_FDC37M81X_DNUM 0x07
  23. #define SMSC_FDC37M81X_DID 0x20
  24. #define SMSC_FDC37M81X_DREV 0x21
  25. #define SMSC_FDC37M81X_PCNT 0x22
  26. #define SMSC_FDC37M81X_PMGT 0x23
  27. #define SMSC_FDC37M81X_OSC 0x24
  28. #define SMSC_FDC37M81X_CONFPA0 0x26
  29. #define SMSC_FDC37M81X_CONFPA1 0x27
  30. #define SMSC_FDC37M81X_TEST4 0x2B
  31. #define SMSC_FDC37M81X_TEST5 0x2C
  32. #define SMSC_FDC37M81X_TEST1 0x2D
  33. #define SMSC_FDC37M81X_TEST2 0x2E
  34. #define SMSC_FDC37M81X_TEST3 0x2F
  35. /* Logical device numbers */
  36. #define SMSC_FDC37M81X_FDD 0x00
  37. #define SMSC_FDC37M81X_SERIAL1 0x04
  38. #define SMSC_FDC37M81X_SERIAL2 0x05
  39. #define SMSC_FDC37M81X_KBD 0x07
  40. /* Logical device Config Registers */
  41. #define SMSC_FDC37M81X_ACTIVE 0x30
  42. #define SMSC_FDC37M81X_BASEADDR0 0x60
  43. #define SMSC_FDC37M81X_BASEADDR1 0x61
  44. #define SMSC_FDC37M81X_INT 0x70
  45. #define SMSC_FDC37M81X_INT2 0x72
  46. #define SMSC_FDC37M81X_MODE 0xF0
  47. /* Chip Config Values */
  48. #define SMSC_FDC37M81X_CONFIG_ENTER 0x55
  49. #define SMSC_FDC37M81X_CONFIG_EXIT 0xaa
  50. #define SMSC_FDC37M81X_CHIP_ID 0x4d
  51. static unsigned long g_smsc_fdc37m81x_base;
  52. static inline unsigned char smsc_fdc37m81x_rd(unsigned char index)
  53. {
  54. outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  55. return inb(g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
  56. }
  57. static inline void smsc_dc37m81x_wr(unsigned char index, unsigned char data)
  58. {
  59. outb(index, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  60. outb(data, g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_DATA);
  61. }
  62. void smsc_fdc37m81x_config_beg(void)
  63. {
  64. if (g_smsc_fdc37m81x_base) {
  65. outb(SMSC_FDC37M81X_CONFIG_ENTER,
  66. g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  67. }
  68. }
  69. void smsc_fdc37m81x_config_end(void)
  70. {
  71. if (g_smsc_fdc37m81x_base)
  72. outb(SMSC_FDC37M81X_CONFIG_EXIT,
  73. g_smsc_fdc37m81x_base + SMSC_FDC37M81X_CONFIG_INDEX);
  74. }
  75. u8 smsc_fdc37m81x_config_get(u8 reg)
  76. {
  77. u8 val = 0;
  78. if (g_smsc_fdc37m81x_base)
  79. val = smsc_fdc37m81x_rd(reg);
  80. return val;
  81. }
  82. void smsc_fdc37m81x_config_set(u8 reg, u8 val)
  83. {
  84. if (g_smsc_fdc37m81x_base)
  85. smsc_dc37m81x_wr(reg, val);
  86. }
  87. unsigned long __init smsc_fdc37m81x_init(unsigned long port)
  88. {
  89. const int field = sizeof(unsigned long) * 2;
  90. u8 chip_id;
  91. if (g_smsc_fdc37m81x_base)
  92. printk(KERN_WARNING "%s: stepping on old base=0x%0*lx\n",
  93. __func__,
  94. field, g_smsc_fdc37m81x_base);
  95. g_smsc_fdc37m81x_base = port;
  96. smsc_fdc37m81x_config_beg();
  97. chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
  98. if (chip_id == SMSC_FDC37M81X_CHIP_ID)
  99. smsc_fdc37m81x_config_end();
  100. else {
  101. printk(KERN_WARNING "%s: unknown chip id 0x%02x\n", __func__,
  102. chip_id);
  103. g_smsc_fdc37m81x_base = 0;
  104. }
  105. return g_smsc_fdc37m81x_base;
  106. }
  107. #ifdef DEBUG
  108. static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg)
  109. {
  110. printk(KERN_INFO "%s: dev=0x%02x reg=0x%02x val=0x%02x\n",
  111. key, dev, reg,
  112. smsc_fdc37m81x_rd(reg));
  113. }
  114. void smsc_fdc37m81x_config_dump(void)
  115. {
  116. u8 orig;
  117. const char *fname = __func__;
  118. smsc_fdc37m81x_config_beg();
  119. orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
  120. printk(KERN_INFO "%s: common\n", fname);
  121. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  122. SMSC_FDC37M81X_DNUM);
  123. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  124. SMSC_FDC37M81X_DID);
  125. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  126. SMSC_FDC37M81X_DREV);
  127. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  128. SMSC_FDC37M81X_PCNT);
  129. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  130. SMSC_FDC37M81X_PMGT);
  131. printk(KERN_INFO "%s: keyboard\n", fname);
  132. smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
  133. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  134. SMSC_FDC37M81X_ACTIVE);
  135. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  136. SMSC_FDC37M81X_INT);
  137. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  138. SMSC_FDC37M81X_INT2);
  139. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  140. SMSC_FDC37M81X_LDCR_F0);
  141. smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
  142. smsc_fdc37m81x_config_end();
  143. }
  144. #endif