smsc_fdc37m81x.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Interface for smsc fdc48m81x Super IO chip
  3. *
  4. * Author: MontaVista Software, Inc. [email protected]
  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. pr_warn("%s: stepping on old base=0x%0*lx\n", __func__, field,
  93. g_smsc_fdc37m81x_base);
  94. g_smsc_fdc37m81x_base = port;
  95. smsc_fdc37m81x_config_beg();
  96. chip_id = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DID);
  97. if (chip_id == SMSC_FDC37M81X_CHIP_ID)
  98. smsc_fdc37m81x_config_end();
  99. else {
  100. pr_warn("%s: unknown chip id 0x%02x\n", __func__, chip_id);
  101. g_smsc_fdc37m81x_base = 0;
  102. }
  103. return g_smsc_fdc37m81x_base;
  104. }
  105. #ifdef DEBUG
  106. static void smsc_fdc37m81x_config_dump_one(const char *key, u8 dev, u8 reg)
  107. {
  108. pr_info("%s: dev=0x%02x reg=0x%02x val=0x%02x\n", key, dev, reg,
  109. smsc_fdc37m81x_rd(reg));
  110. }
  111. void smsc_fdc37m81x_config_dump(void)
  112. {
  113. u8 orig;
  114. const char *fname = __func__;
  115. smsc_fdc37m81x_config_beg();
  116. orig = smsc_fdc37m81x_rd(SMSC_FDC37M81X_DNUM);
  117. pr_info("%s: common\n", fname);
  118. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  119. SMSC_FDC37M81X_DNUM);
  120. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  121. SMSC_FDC37M81X_DID);
  122. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  123. SMSC_FDC37M81X_DREV);
  124. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  125. SMSC_FDC37M81X_PCNT);
  126. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_NONE,
  127. SMSC_FDC37M81X_PMGT);
  128. pr_info("%s: keyboard\n", fname);
  129. smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, SMSC_FDC37M81X_KBD);
  130. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  131. SMSC_FDC37M81X_ACTIVE);
  132. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  133. SMSC_FDC37M81X_INT);
  134. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  135. SMSC_FDC37M81X_INT2);
  136. smsc_fdc37m81x_config_dump_one(fname, SMSC_FDC37M81X_KBD,
  137. SMSC_FDC37M81X_LDCR_F0);
  138. smsc_dc37m81x_wr(SMSC_FDC37M81X_DNUM, orig);
  139. smsc_fdc37m81x_config_end();
  140. }
  141. #endif