baed9eb078a32fb49f43ade1ccb7704553ad580b
[osmocom-bb.git] / src / target / firmware / display / st7558.c
1 /* Sitronix ST7558 LCD Driver */
2
3 /* (C) 2010 by Harald Welte <laforge@gnumonks.org>
4  *
5  * All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22
23 #include <stdint.h>
24 #include <stdio.h>
25
26 #include <debug.h>
27 #include <delay.h>
28 #include <memory.h>
29 #include <i2c.h>
30 #include <display.h>
31 #include <calypso/clock.h>
32
33 #define MORE_CONTROL    0x80
34 #define CONTROL_RS_RAM  0x40
35 #define CONTROL_RS_CMD  0x00
36 #define Y_ADDR(n)       (0x40|((n)&0xf))
37 #define X_ADDR(n)       (0x80|((n)&0x3f))
38
39 static const uint8_t setup[] = { CONTROL_RS_CMD, 0x2e, 0x21, 0x12, 0xc0, 0x0b, 0x20, 0x11, 0x00, 0x40, 0x80 };
40 static const uint8_t home[] = { CONTROL_RS_CMD, Y_ADDR(0), X_ADDR(0) };
41
42 /* video modes */
43 static const uint8_t invert[] = { CONTROL_RS_CMD, 0x20, 0x0d };
44 static const uint8_t normal[] = { CONTROL_RS_CMD, 0x20, 0x0c };
45 static const uint8_t off[] = { CONTROL_RS_CMD, 0x20, 0x08 };
46
47 #define ST7558_SLAVE_ADDR       0x3c
48 static int st7558_write(const uint8_t *data, int len)
49 {
50         int rc = i2c_write(ST7558_SLAVE_ADDR, data[0], 1, data+1, len-1);
51         /* FIXME: find out why this is needed! */
52         delay_ms(10);
53         return rc;
54 }
55
56 static const uint8_t zero16[] = { CONTROL_RS_RAM,
57                         0, 0, 0, 0, 0, 0, 0, 0,
58                         0, 0, 0, 0, 0, 0, 0, 0 };
59 static void st7558_clrscr(void)
60 {
61         int i;
62
63         st7558_write(home, sizeof(home));
64
65         for (i = 0; i < 102*9; i += 16)
66                 st7558_write(zero16, sizeof(zero16));
67
68         st7558_write(home, sizeof(home));
69 }
70
71 static void st7558_init(void)
72 {
73         /* Release nRESET */
74         calypso_reset_set(RESET_EXT, 0);
75
76         i2c_init(0,0);
77         delay_ms(10);
78
79         st7558_write(setup, sizeof(setup));
80         st7558_clrscr();
81 }
82
83 static void st7558_set_attr(unsigned long attr)
84 {
85         if (attr & DISP_ATTR_INVERT)
86                 st7558_write(invert, sizeof(invert));
87 }
88
89 static void st7558_unset_attr(unsigned long attr)
90 {
91         if (attr & DISP_ATTR_INVERT)
92                 st7558_write(normal, sizeof(normal));
93 }
94
95 /* FIXME: we need a mini-libc */
96 static void *mcpy(uint8_t *dst, const uint8_t *src, int len)
97 {
98         while (len--)
99                 *dst++ = *src++;
100
101         return dst;
102 }
103
104 extern const unsigned char fontdata_r8x8[];
105
106 static void st7558_putc(unsigned char c)
107 {
108         uint8_t putc_buf[16];
109         uint8_t bytes_per_char = 8;
110
111         putc_buf[0] = CONTROL_RS_RAM;
112         mcpy(putc_buf+1, fontdata_r8x8+(c*bytes_per_char), bytes_per_char);
113         st7558_write(putc_buf, 1+bytes_per_char);
114 }
115
116 const struct display_driver st7558_display = {
117         .name = "st7558",
118         .init = &st7558_init,
119         .clrscr = &st7558_clrscr,
120         .set_attr = &st7558_set_attr,
121         .unset_attr = &st7558_unset_attr,
122         .putc = &st7558_putc,
123 };