summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/pc386/console/console_edison.c
blob: d5e44aed86da348d8918a7f027f7568633169b29 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94

#include <bsp.h>
#include <libchip/serial.h>

/* XXX hack until real support is available, code copied from libchip */
#define NS16550_RECEIVE_BUFFER   0
#define NS16550_TRANSMIT_BUFFER  0
#define NS16550_INTERRUPT_ENABLE 1
#define NS16550_INTERRUPT_ID     2
#define NS16550_FIFO_CONTROL     2
#define NS16550_LINE_CONTROL     3
#define NS16550_MODEM_CONTROL    4
#define NS16550_LINE_STATUS      5
#define NS16550_MODEM_STATUS     6
#define NS16550_SCRATCH_PAD      7
#define NS16550_FRACTIONAL_DIVIDER 10

/* status bits we use in line status */

#define SP_LSR_TX     0x40
#define SP_LSR_THOLD  0x20
#define SP_LSR_RDY    0x01
static volatile uint8_t *edison_com = (volatile uint8_t *)0xff010180;

void edison_write_polled(int minor, char cChar);
int edison_inbyte_nonblocking_polled(int minor);

static int edison_open(int major, int minor, void *arg)
{
  return 0;
}

static int edison_close(int major, int minor, void *arg)
{
  return 0;
}

int edison_inbyte_nonblocking_polled(int minor)
{
  if ( edison_com[NS16550_LINE_STATUS] & 0x01 )
    return (int) edison_com[NS16550_RECEIVE_BUFFER];
  return -1;
}

static ssize_t edison_write_support_polled(int minor, const char *buf, size_t len)
{
  ssize_t i;

  for ( i=0 ; i<len ; i++ ) {
#if 0
    if ( (edison_com[NS16550_LINE_STATUS] & SP_LSR_TX) == 0 )
      break;
#else
    while ( (edison_com[NS16550_LINE_STATUS] & SP_LSR_TX) == 0x00 )
      /* wait until ready */;
#endif
    edison_com[NS16550_TRANSMIT_BUFFER] = (uint8_t) buf[i];
  }
  return i;
}

static void edison_init(int minor)
{
}

void edison_write_polled(int minor, char cChar)
{
  while ( (edison_com[NS16550_LINE_STATUS] & SP_LSR_TX) == 0x00 )
    /* wait until ready */;
  edison_com[NS16550_TRANSMIT_BUFFER] = (uint8_t) cChar;
}

static bool edison_probe(int minor)
{
  return true;
}

static int edison_set_attributes(int minor, const struct termios *t)
{
  return 0;
}

const console_fns edison_fns =
{
  edison_probe,                       /* deviceProbe */
  edison_open,                        /* deviceFirstOpen */
  edison_close,                       /* deviceLastClose */
  edison_inbyte_nonblocking_polled,   /* deviceRead */
  edison_write_support_polled,        /* deviceWrite */
  edison_init,                        /* deviceInitialize */
  edison_write_polled,                /* deviceWritePolled */
  edison_set_attributes,              /* deviceSetAttributes */
  FALSE,                              /* deviceOutputUsesInterrupts */
};