0001
0002 #include <linux/string.h>
0003 #include <linux/kernel.h>
0004 #include <linux/errno.h>
0005 #include <linux/bitops.h>
0006 #include <linux/ptrace.h>
0007 #include <linux/adb.h>
0008 #include <linux/pmu.h>
0009 #include <linux/cuda.h>
0010 #include <linux/of.h>
0011 #include <asm/machdep.h>
0012 #include <asm/io.h>
0013 #include <asm/page.h>
0014 #include <asm/xmon.h>
0015 #include <asm/bootx.h>
0016 #include <asm/errno.h>
0017 #include <asm/pmac_feature.h>
0018 #include <asm/processor.h>
0019 #include <asm/delay.h>
0020 #include <asm/btext.h>
0021 #include <asm/time.h>
0022 #include <asm/udbg.h>
0023
0024
0025
0026
0027
0028
0029
0030 static void (*udbg_adb_old_putc)(char c);
0031 static int (*udbg_adb_old_getc)(void);
0032 static int (*udbg_adb_old_getc_poll)(void);
0033
0034 static enum {
0035 input_adb_none,
0036 input_adb_pmu,
0037 input_adb_cuda,
0038 } input_type = input_adb_none;
0039
0040 int xmon_wants_key, xmon_adb_keycode;
0041
0042 static inline void udbg_adb_poll(void)
0043 {
0044 #ifdef CONFIG_ADB_PMU
0045 if (input_type == input_adb_pmu)
0046 pmu_poll_adb();
0047 #endif
0048 #ifdef CONFIG_ADB_CUDA
0049 if (input_type == input_adb_cuda)
0050 cuda_poll();
0051 #endif
0052 }
0053
0054 #ifdef CONFIG_BOOTX_TEXT
0055
0056 static int udbg_adb_use_btext;
0057 static int xmon_adb_shiftstate;
0058
0059 static unsigned char xmon_keytab[128] =
0060 "asdfhgzxcv\000bqwer"
0061 "yt123465=97-80]o"
0062 "u[ip\rlj'k;\\,/nm."
0063 "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"
0064 "\0.\0*\0+\0\0\0\0\0/\r\0-\0"
0065 "\0\0000123456789\0\0\0";
0066
0067 static unsigned char xmon_shift_keytab[128] =
0068 "ASDFHGZXCV\000BQWER"
0069 "YT!@#$^%+(&_*)}O"
0070 "U{IP\rLJ\"K:|<?NM>"
0071 "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"
0072 "\0.\0*\0+\0\0\0\0\0/\r\0-\0"
0073 "\0\0000123456789\0\0\0";
0074
0075 static int udbg_adb_local_getc(void)
0076 {
0077 int k, t, on;
0078
0079 xmon_wants_key = 1;
0080 for (;;) {
0081 xmon_adb_keycode = -1;
0082 t = 0;
0083 on = 0;
0084 k = -1;
0085 do {
0086 if (--t < 0) {
0087 on = 1 - on;
0088 btext_drawchar(on? 0xdb: 0x20);
0089 btext_drawchar('\b');
0090 t = 200000;
0091 }
0092 udbg_adb_poll();
0093 if (udbg_adb_old_getc_poll)
0094 k = udbg_adb_old_getc_poll();
0095 } while (k == -1 && xmon_adb_keycode == -1);
0096 if (on)
0097 btext_drawstring(" \b");
0098 if (k != -1)
0099 return k;
0100 k = xmon_adb_keycode;
0101
0102
0103 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
0104 xmon_adb_shiftstate = (k & 0x80) == 0;
0105 continue;
0106 }
0107 if (k >= 0x80)
0108 continue;
0109 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
0110 if (k != 0)
0111 break;
0112 }
0113 xmon_wants_key = 0;
0114 return k;
0115 }
0116 #endif
0117
0118 static int udbg_adb_getc(void)
0119 {
0120 #ifdef CONFIG_BOOTX_TEXT
0121 if (udbg_adb_use_btext && input_type != input_adb_none)
0122 return udbg_adb_local_getc();
0123 #endif
0124 if (udbg_adb_old_getc)
0125 return udbg_adb_old_getc();
0126 return -1;
0127 }
0128
0129
0130
0131
0132
0133
0134 static int udbg_adb_getc_poll(void)
0135 {
0136 udbg_adb_poll();
0137
0138 if (udbg_adb_old_getc_poll)
0139 return udbg_adb_old_getc_poll();
0140 return -1;
0141 }
0142
0143 static void udbg_adb_putc(char c)
0144 {
0145 #ifdef CONFIG_BOOTX_TEXT
0146 if (udbg_adb_use_btext)
0147 btext_drawchar(c);
0148 #endif
0149 if (udbg_adb_old_putc)
0150 return udbg_adb_old_putc(c);
0151 }
0152
0153 void __init udbg_adb_init_early(void)
0154 {
0155 #ifdef CONFIG_BOOTX_TEXT
0156 if (btext_find_display(1) == 0) {
0157 udbg_adb_use_btext = 1;
0158 udbg_putc = udbg_adb_putc;
0159 }
0160 #endif
0161 }
0162
0163 int __init udbg_adb_init(int force_btext)
0164 {
0165 struct device_node *np;
0166
0167
0168 udbg_adb_old_putc = udbg_putc;
0169 udbg_adb_old_getc = udbg_getc;
0170 udbg_adb_old_getc_poll = udbg_getc_poll;
0171
0172
0173 if (udbg_adb_old_putc == udbg_adb_putc)
0174 udbg_adb_old_putc = NULL;
0175 #ifdef CONFIG_BOOTX_TEXT
0176 if (udbg_adb_old_putc == btext_drawchar)
0177 udbg_adb_old_putc = NULL;
0178 #endif
0179
0180
0181 udbg_putc = udbg_adb_putc;
0182 udbg_getc = udbg_adb_getc;
0183 udbg_getc_poll = udbg_adb_getc_poll;
0184
0185 #ifdef CONFIG_BOOTX_TEXT
0186
0187 if (btext_find_display(force_btext) == 0)
0188 udbg_adb_use_btext = 1;
0189 #endif
0190
0191
0192
0193
0194
0195 for_each_node_by_name(np, "keyboard") {
0196 struct device_node *parent = of_get_parent(np);
0197 int found = of_node_is_type(parent, "adb");
0198 of_node_put(parent);
0199 if (found)
0200 break;
0201 }
0202 if (np == NULL)
0203 return -ENODEV;
0204 of_node_put(np);
0205
0206 #ifdef CONFIG_ADB_PMU
0207 if (find_via_pmu())
0208 input_type = input_adb_pmu;
0209 #endif
0210 #ifdef CONFIG_ADB_CUDA
0211 if (find_via_cuda())
0212 input_type = input_adb_cuda;
0213 #endif
0214
0215
0216 if (input_type == input_adb_none)
0217 return -ENODEV;
0218
0219 return 0;
0220 }