root/arch/powerpc/platforms/powermac/udbg_adb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. udbg_adb_poll
  2. udbg_adb_local_getc
  3. udbg_adb_getc
  4. udbg_adb_getc_poll
  5. udbg_adb_putc
  6. udbg_adb_init_early
  7. udbg_adb_init

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include <linux/string.h>
   3 #include <linux/kernel.h>
   4 #include <linux/errno.h>
   5 #include <linux/bitops.h>
   6 #include <linux/ptrace.h>
   7 #include <linux/adb.h>
   8 #include <linux/pmu.h>
   9 #include <linux/cuda.h>
  10 #include <asm/machdep.h>
  11 #include <asm/io.h>
  12 #include <asm/page.h>
  13 #include <asm/xmon.h>
  14 #include <asm/prom.h>
  15 #include <asm/bootx.h>
  16 #include <asm/errno.h>
  17 #include <asm/pmac_feature.h>
  18 #include <asm/processor.h>
  19 #include <asm/delay.h>
  20 #include <asm/btext.h>
  21 #include <asm/time.h>
  22 #include <asm/udbg.h>
  23 
  24 /*
  25  * This implementation is "special", it can "patch" the current
  26  * udbg implementation and work on top of it. It must thus be
  27  * initialized last
  28  */
  29 
  30 static void (*udbg_adb_old_putc)(char c);
  31 static int (*udbg_adb_old_getc)(void);
  32 static int (*udbg_adb_old_getc_poll)(void);
  33 
  34 static enum {
  35         input_adb_none,
  36         input_adb_pmu,
  37         input_adb_cuda,
  38 } input_type = input_adb_none;
  39 
  40 int xmon_wants_key, xmon_adb_keycode;
  41 
  42 static inline void udbg_adb_poll(void)
  43 {
  44 #ifdef CONFIG_ADB_PMU
  45         if (input_type == input_adb_pmu)
  46                 pmu_poll_adb();
  47 #endif /* CONFIG_ADB_PMU */
  48 #ifdef CONFIG_ADB_CUDA
  49         if (input_type == input_adb_cuda)
  50                 cuda_poll();
  51 #endif /* CONFIG_ADB_CUDA */
  52 }
  53 
  54 #ifdef CONFIG_BOOTX_TEXT
  55 
  56 static int udbg_adb_use_btext;
  57 static int xmon_adb_shiftstate;
  58 
  59 static unsigned char xmon_keytab[128] =
  60         "asdfhgzxcv\000bqwer"                           /* 0x00 - 0x0f */
  61         "yt123465=97-80]o"                              /* 0x10 - 0x1f */
  62         "u[ip\rlj'k;\\,/nm."                            /* 0x20 - 0x2f */
  63         "\t `\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
  64         "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
  65         "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
  66 
  67 static unsigned char xmon_shift_keytab[128] =
  68         "ASDFHGZXCV\000BQWER"                           /* 0x00 - 0x0f */
  69         "YT!@#$^%+(&_*)}O"                              /* 0x10 - 0x1f */
  70         "U{IP\rLJ\"K:|<?NM>"                            /* 0x20 - 0x2f */
  71         "\t ~\177\0\033\0\0\0\0\0\0\0\0\0\0"            /* 0x30 - 0x3f */
  72         "\0.\0*\0+\0\0\0\0\0/\r\0-\0"                   /* 0x40 - 0x4f */
  73         "\0\0000123456789\0\0\0";                       /* 0x50 - 0x5f */
  74 
  75 static int udbg_adb_local_getc(void)
  76 {
  77         int k, t, on;
  78 
  79         xmon_wants_key = 1;
  80         for (;;) {
  81                 xmon_adb_keycode = -1;
  82                 t = 0;
  83                 on = 0;
  84                 k = -1;
  85                 do {
  86                         if (--t < 0) {
  87                                 on = 1 - on;
  88                                 btext_drawchar(on? 0xdb: 0x20);
  89                                 btext_drawchar('\b');
  90                                 t = 200000;
  91                         }
  92                         udbg_adb_poll();
  93                         if (udbg_adb_old_getc_poll)
  94                                 k = udbg_adb_old_getc_poll();
  95                 } while (k == -1 && xmon_adb_keycode == -1);
  96                 if (on)
  97                         btext_drawstring(" \b");
  98                 if (k != -1)
  99                         return k;
 100                 k = xmon_adb_keycode;
 101 
 102                 /* test for shift keys */
 103                 if ((k & 0x7f) == 0x38 || (k & 0x7f) == 0x7b) {
 104                         xmon_adb_shiftstate = (k & 0x80) == 0;
 105                         continue;
 106                 }
 107                 if (k >= 0x80)
 108                         continue;       /* ignore up transitions */
 109                 k = (xmon_adb_shiftstate? xmon_shift_keytab: xmon_keytab)[k];
 110                 if (k != 0)
 111                         break;
 112         }
 113         xmon_wants_key = 0;
 114         return k;
 115 }
 116 #endif /* CONFIG_BOOTX_TEXT */
 117 
 118 static int udbg_adb_getc(void)
 119 {
 120 #ifdef CONFIG_BOOTX_TEXT
 121         if (udbg_adb_use_btext && input_type != input_adb_none)
 122                 return udbg_adb_local_getc();
 123 #endif
 124         if (udbg_adb_old_getc)
 125                 return udbg_adb_old_getc();
 126         return -1;
 127 }
 128 
 129 /* getc_poll() is not really used, unless you have the xmon-over modem
 130  * hack that doesn't quite concern us here, thus we just poll the low level
 131  * ADB driver to prevent it from timing out and call back the original poll
 132  * routine.
 133  */
 134 static int udbg_adb_getc_poll(void)
 135 {
 136         udbg_adb_poll();
 137 
 138         if (udbg_adb_old_getc_poll)
 139                 return udbg_adb_old_getc_poll();
 140         return -1;
 141 }
 142 
 143 static void udbg_adb_putc(char c)
 144 {
 145 #ifdef CONFIG_BOOTX_TEXT
 146         if (udbg_adb_use_btext)
 147                 btext_drawchar(c);
 148 #endif
 149         if (udbg_adb_old_putc)
 150                 return udbg_adb_old_putc(c);
 151 }
 152 
 153 void __init udbg_adb_init_early(void)
 154 {
 155 #ifdef CONFIG_BOOTX_TEXT
 156         if (btext_find_display(1) == 0) {
 157                 udbg_adb_use_btext = 1;
 158                 udbg_putc = udbg_adb_putc;
 159         }
 160 #endif
 161 }
 162 
 163 int __init udbg_adb_init(int force_btext)
 164 {
 165         struct device_node *np;
 166 
 167         /* Capture existing callbacks */
 168         udbg_adb_old_putc = udbg_putc;
 169         udbg_adb_old_getc = udbg_getc;
 170         udbg_adb_old_getc_poll = udbg_getc_poll;
 171 
 172         /* Check if our early init was already called */
 173         if (udbg_adb_old_putc == udbg_adb_putc)
 174                 udbg_adb_old_putc = NULL;
 175 #ifdef CONFIG_BOOTX_TEXT
 176         if (udbg_adb_old_putc == btext_drawchar)
 177                 udbg_adb_old_putc = NULL;
 178 #endif
 179 
 180         /* Set ours as output */
 181         udbg_putc = udbg_adb_putc;
 182         udbg_getc = udbg_adb_getc;
 183         udbg_getc_poll = udbg_adb_getc_poll;
 184 
 185 #ifdef CONFIG_BOOTX_TEXT
 186         /* Check if we should use btext output */
 187         if (btext_find_display(force_btext) == 0)
 188                 udbg_adb_use_btext = 1;
 189 #endif
 190 
 191         /* See if there is a keyboard in the device tree with a parent
 192          * of type "adb". If not, we return a failure, but we keep the
 193          * bext output set for now
 194          */
 195         for_each_node_by_name(np, "keyboard") {
 196                 struct device_node *parent = of_get_parent(np);
 197                 int found = of_node_is_type(parent, "adb");
 198                 of_node_put(parent);
 199                 if (found)
 200                         break;
 201         }
 202         if (np == NULL)
 203                 return -ENODEV;
 204         of_node_put(np);
 205 
 206 #ifdef CONFIG_ADB_PMU
 207         if (find_via_pmu())
 208                 input_type = input_adb_pmu;
 209 #endif
 210 #ifdef CONFIG_ADB_CUDA
 211         if (find_via_cuda())
 212                 input_type = input_adb_cuda;
 213 #endif
 214 
 215         /* Same as above: nothing found, keep btext set for output */
 216         if (input_type == input_adb_none)
 217                 return -ENODEV;
 218 
 219         return 0;
 220 }

/* [<][>][^][v][top][bottom][index][help] */