Merge remote branch 'origin/bug_530_add_dm800se_support'
[enigma2.git] / lib / gdi / lcd.cpp
1 #include <lib/gdi/lcd.h>
2
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/ioctl.h>
6
7 #include <dbox/fp.h>
8 #include <dbox/lcd-ks0713.h>
9
10 #include <lib/gdi/esize.h>
11 #include <lib/base/init.h>
12 #include <lib/base/init_num.h>
13 #include <lib/gdi/glcddc.h>
14
15 eDBoxLCD *eDBoxLCD::instance;
16
17 eLCD::eLCD()
18 {
19         lcdfd = -1;
20         locked=0;
21 }
22
23 void eLCD::setSize(int xres, int yres, int bpp)
24 {
25         res = eSize(xres, yres);
26         _buffer=new unsigned char[xres * yres * bpp/8];
27         memset(_buffer, 0, res.height()*res.width()*bpp/8);
28         _stride=res.width()*bpp/8;
29         eDebug("lcd buffer %p %d bytes, stride %d", _buffer, xres*yres*bpp/8, _stride);
30 }
31
32 eLCD::~eLCD()
33 {
34         delete [] _buffer;
35 }
36
37 int eLCD::lock()
38 {
39         if (locked)
40                 return -1;
41
42         locked=1;
43         return lcdfd;
44 }
45
46 void eLCD::unlock()
47 {
48         locked=0;
49 }
50
51 eDBoxLCD::eDBoxLCD()
52 {
53         int xres=132, yres=64, bpp=8;
54         is_oled = 0;
55 #ifndef NO_LCD
56         lcdfd = open("/dev/dbox/oled0", O_RDWR);
57         if (lcdfd < 0)
58         {
59                 FILE *f=fopen("/proc/stb/lcd/oled_brightness", "w");
60                 if (!f)
61                         f = fopen("/proc/stb/fp/oled_brightness", "w");
62                 if (f)
63                 {
64                         is_oled = 2;
65                         fclose(f);
66                 }
67                 lcdfd = open("/dev/dbox/lcd0", O_RDWR);
68         } else
69         {
70                 eDebug("found OLED display!");
71                 is_oled = 1;
72         }
73 #else
74         lcdfd = -1;
75 #endif
76         instance=this;
77
78         if (lcdfd<0)
79                 eDebug("couldn't open LCD - load lcd.o!");
80         else
81         {
82                 int i=LCD_MODE_BIN;
83                 ioctl(lcdfd, LCD_IOCTL_ASC_MODE, &i);
84                 inverted=0;
85                 FILE *f = fopen("/proc/stb/lcd/xres", "r");
86                 if (f)
87                 {
88                         int tmp;
89                         if (fscanf(f, "%x", &tmp) == 1)
90                                 xres = tmp;
91                         fclose(f);
92                         f = fopen("/proc/stb/lcd/yres", "r");
93                         if (f)
94                         {
95                                 if (fscanf(f, "%x", &tmp) == 1)
96                                         yres = tmp;
97                                 fclose(f);
98                                 f = fopen("/proc/stb/lcd/bpp", "r");
99                                 if (f)
100                                 {
101                                         if (fscanf(f, "%x", &tmp) == 1)
102                                                 bpp = tmp;
103                                         fclose(f);
104                                 }
105                         }
106                         is_oled = 3;
107                 }
108         }
109         setSize(xres, yres, bpp);
110 }
111
112 void eDBoxLCD::setInverted(unsigned char inv)
113 {
114         inverted=inv;
115         update();
116 }
117
118 int eDBoxLCD::setLCDContrast(int contrast)
119 {
120         int fp;
121         if((fp=open("/dev/dbox/fp0", O_RDWR))<=0)
122         {
123                 eDebug("[LCD] can't open /dev/dbox/fp0");
124                 return(-1);
125         }
126
127         if(ioctl(lcdfd, LCD_IOCTL_SRV, &contrast))
128         {
129                 eDebug("[LCD] can't set lcd contrast");
130         }
131         close(fp);
132         return(0);
133 }
134
135 int eDBoxLCD::setLCDBrightness(int brightness)
136 {
137         eDebug("setLCDBrightness %d", brightness);
138         FILE *f=fopen("/proc/stb/lcd/oled_brightness", "w");
139         if (!f)
140                 f = fopen("/proc/stb/fp/oled_brightness", "w");
141         if (f)
142         {
143                 if (fprintf(f, "%d", brightness) == 0)
144                         eDebug("write /proc/stb/lcd/oled_brightness failed!! (%m)");
145                 fclose(f);
146         }
147         else
148         {
149                 int fp;
150                 if((fp=open("/dev/dbox/fp0", O_RDWR))<=0)
151                 {
152                         eDebug("[LCD] can't open /dev/dbox/fp0");
153                         return(-1);
154                 }
155
156                 if(ioctl(fp, FP_IOCTL_LCD_DIMM, &brightness)<=0)
157                         eDebug("[LCD] can't set lcd brightness (%m)");
158                 close(fp);
159         }
160         return(0);
161 }
162
163 eDBoxLCD::~eDBoxLCD()
164 {
165         if (lcdfd>=0)
166         {
167                 close(lcdfd);
168                 lcdfd=-1;
169         }
170 }
171
172 eDBoxLCD *eDBoxLCD::getInstance()
173 {
174         return instance;
175 }
176
177 void eDBoxLCD::update()
178 {
179         if (lcdfd >= 0)
180         {
181                 if (!is_oled || is_oled == 2)
182                 {
183                         unsigned char raw[132*8];
184                         int x, y, yy;
185                         for (y=0; y<8; y++)
186                         {
187                                 for (x=0; x<132; x++)
188                                 {
189                                         int pix=0;
190                                         for (yy=0; yy<8; yy++)
191                                         {
192                                                 pix|=(_buffer[(y*8+yy)*132+x]>=108)<<yy;
193                                         }
194                                         raw[y*132+x]=(pix^inverted);
195                                 }
196                         }
197                         write(lcdfd, raw, 132*8);
198                 }
199                 else if (is_oled == 3)
200                         write(lcdfd, _buffer, _stride * res.height());
201                 else
202                 {
203                         unsigned char raw[64*64];
204                         int x, y;
205                         memset(raw, 0, 64*64);
206                         for (y=0; y<64; y++)
207                         {
208                                 int pix=0;
209                                 for (x=0; x<128 / 2; x++)
210                                 {
211                                         pix = (_buffer[y*132 + x * 2 + 2] & 0xF0) |(_buffer[y*132 + x * 2 + 1 + 2] >> 4);
212                                         if (inverted)
213                                                 pix = 0xFF - pix;
214                                         raw[y*64+x] = pix;
215                                 }
216                         }
217                         write(lcdfd, raw, 64*64);
218                 }
219         }
220 }
221