summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_jz47xx/xduoo_x3
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_jz47xx/xduoo_x3')
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/adc-target.h28
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/ata-sd-target.h48
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/backlight-xduoo_x3.c50
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h46
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c420
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c46
-rw-r--r--firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c214
7 files changed, 852 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/adc-target.h b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/adc-target.h
new file mode 100644
index 0000000000..c47406ca21
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/adc-target.h
@@ -0,0 +1,28 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef _ADC_TARGET_H_
22#define _ADC_TARGET_H_
23
24#define NUM_ADC_CHANNELS 4
25
26#define ADC_BUTTONS 0
27
28#endif /* _ADC_TARGET_H_ */
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/ata-sd-target.h b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/ata-sd-target.h
new file mode 100644
index 0000000000..bb2cced15b
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/ata-sd-target.h
@@ -0,0 +1,48 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#ifndef ATA_SD_TARGET_H
23#define ATA_SD_TARGET_H
24
25#include "cpu.h"
26#include "system.h"
27
28#define PIN_SD1_CD (32*0+29) /* Pin to check card insertion */
29#define IRQ_SD1_CD GPIO_IRQ(PIN_SD1_CD)
30#define GPIO_SD1_CD GPIO29
31
32#define PIN_SD2_CD (32*0+28) /* Pin to check card insertion */
33#define IRQ_SD2_CD GPIO_IRQ(PIN_SD2_CD)
34#define GPIO_SD2_CD GPIO28
35
36static inline void sd_init_gpio(void)
37{
38 __gpio_as_msc1_pd_4bit();
39 __gpio_as_msc2_pb_4bit();
40
41 __gpio_as_input(PIN_SD1_CD);
42 __gpio_as_input(PIN_SD2_CD);
43
44 __gpio_disable_pull(PIN_SD1_CD);
45 __gpio_disable_pull(PIN_SD2_CD);
46}
47
48#endif
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/backlight-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/backlight-xduoo_x3.c
new file mode 100644
index 0000000000..3f00b0b67d
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/backlight-xduoo_x3.c
@@ -0,0 +1,50 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "cpu.h"
24#include "backlight-target.h"
25#include "lcd.h"
26
27bool backlight_hw_init(void)
28{
29 return true;
30}
31
32void backlight_hw_on(void)
33{
34 lcd_enable(true);
35}
36
37void backlight_hw_off(void)
38{
39 lcd_enable(false);
40}
41
42void backlight_hw_brightness(int brightness)
43{
44 lcd_set_contrast(brightness*16-1);
45}
46
47void lcd_sleep(void)
48{
49 backlight_hw_off();
50}
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h
new file mode 100644
index 0000000000..2dd94b14bc
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/button-target.h
@@ -0,0 +1,46 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#ifndef BUTTON_TARGET_H
22#define BUTTON_TARGET_H
23
24#define HAS_BUTTON_HOLD
25
26/* Main unit's buttons */
27#define BUTTON_POWER 0x00000001
28#define BUTTON_HOME 0x00000002
29#define BUTTON_OPTION 0x00000004
30#define BUTTON_PREV 0x00000008
31#define BUTTON_NEXT 0x00000010
32#define BUTTON_PLAY 0x00000020
33#define BUTTON_VOL_UP 0x00000040
34#define BUTTON_VOL_DOWN 0x00000080
35
36#define BUTTON_LEFT 0
37#define BUTTON_RIGHT 0
38
39#define BUTTON_MAIN (BUTTON_POWER | BUTTON_HOME | BUTTON_OPTION | BUTTON_PREV | \
40 BUTTON_NEXT | BUTTON_PLAY | BUTTON_VOL_UP | BUTTON_VOL_DOWN)
41
42/* Software power-off */
43#define POWEROFF_BUTTON BUTTON_POWER
44#define POWEROFF_COUNT 10
45
46#endif /* BUTTON_TARGET_H */
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
new file mode 100644
index 0000000000..89251b727d
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/lcd-xduoo_x3.c
@@ -0,0 +1,420 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "config.h"
22
23#include "lcd.h"
24#include "system.h"
25#include "cpu.h"
26#include "string.h"
27
28/* LCD pins */
29#define PIN_BL_EN (32*4+0)
30
31#define PIN_LCD_D0 (32*2+2)
32#define PIN_LCD_D1 (32*2+3)
33#define PIN_LCD_D2 (32*2+4)
34#define PIN_LCD_D3 (32*2+5)
35#define PIN_LCD_D4 (32*2+6)
36#define PIN_LCD_D5 (32*2+7)
37#define PIN_LCD_D6 (32*2+12)
38#define PIN_LCD_D7 (32*2+13)
39
40#define PIN_LCD_RD (32*2+8)
41#define PIN_LCD_DC (32*2+9)
42#define PIN_LCD_CS (32*2+14)
43#define PIN_LCD_RES (32*2+18)
44#define PIN_LCD_WR (32*2+19)
45
46/* LCD setup codes */
47#define LCD_SET_LOWER_COLUMN_ADDRESS ((char)0x00)
48#define LCD_SET_HIGHER_COLUMN_ADDRESS ((char)0x10)
49#define LCD_SET_DISPLAY_START_LINE ((char)0x40)
50#define LCD_SET_CONTRAST_CONTROL_REGISTER ((char)0x81)
51#define LCD_SET_CHARGE_PUMP ((char)0x8D)
52#define LCD_SET_SEGMENT_REMAP ((char)0xA0)
53#define LCD_SET_SEGMENT_REMAP_INV ((char)0xA1)
54#define LCD_SET_ENTIRE_DISPLAY_OFF ((char)0xA4)
55#define LCD_SET_ENTIRE_DISPLAY_ON ((char)0xA5)
56#define LCD_SET_NORMAL_DISPLAY ((char)0xA6)
57#define LCD_SET_REVERSE_DISPLAY ((char)0xA7)
58#define LCD_SET_MULTIPLEX_RATIO ((char)0xA8)
59#define LCD_SET_DC_DC ((char)0xAD)
60#define LCD_SET_DISPLAY_OFF ((char)0xAE)
61#define LCD_SET_DISPLAY_ON ((char)0xAF)
62#define LCD_SET_PAGE_ADDRESS ((char)0xB0)
63#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION ((char)0xC0)
64#define LCD_SET_COM_OUTPUT_SCAN_DIRECTION_INV ((char)0xC8)
65#define LCD_SET_DISPLAY_OFFSET ((char)0xD3)
66#define LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ ((char)0xD5)
67#define LCD_SET_VCOM_HW_CONFIGURATION ((char)0xDA)
68#define LCD_SET_VCOM_DESELECT_LEVEL ((char)0xDB)
69#define LCD_SET_PRECHARGE_PERIOD ((char)0xD9)
70#define LCD_NOP ((char)0xE3)
71
72/* LCD command codes */
73#define LCD_CNTL_CONTRAST 0x81 /* Contrast */
74#define LCD_CNTL_OUTSCAN 0xc8 /* Output scan direction */
75#define LCD_CNTL_SEGREMAP 0xa1 /* Segment remap */
76#define LCD_CNTL_DISPON 0xaf /* Display on */
77
78#define LCD_CNTL_PAGE 0xb0 /* Page address */
79#define LCD_CNTL_HIGHCOL 0x10 /* Upper column address */
80#define LCD_CNTL_LOWCOL 0x00 /* Lower column address */
81
82#define LCD_COL_OFFSET 2 /* column offset */
83
84static inline void bitdelay(void)
85{
86 unsigned int i = 15;
87 __asm__ __volatile__ (
88 ".set noreorder \n"
89 "1: \n"
90 "bne %0, $0, 1b \n"
91 "addi %0, %0, -1 \n"
92 ".set reorder \n"
93 : "=r" (i)
94 : "0" (i)
95 );
96}
97
98void lcd_hw_init(void)
99{
100 REG_GPIO_PXFUNC(2) = 0x000C73FC; /* D0-D7 RD DC CS RES WR */
101 REG_GPIO_PXSELC(2) = 0x000C73FC;
102 REG_GPIO_PXDIRS(2) = 0x000C73FC;
103 REG_GPIO_PXDATS(2) = 0x000C73FC;
104 __gpio_clear_pin(PIN_BL_EN);
105 __gpio_as_output(PIN_BL_EN);
106 __gpio_clear_pin(PIN_LCD_RES);
107 udelay(1);
108 __gpio_set_pin(PIN_LCD_RES);
109 __gpio_clear_pin(PIN_LCD_CS);
110}
111
112void lcd_write_command(int byte)
113{
114 __gpio_clear_pin(PIN_LCD_DC);
115 REG_GPIO_PXDATC(2) = 0x000030FC;
116 REG_GPIO_PXDATS(2) = ((byte & 0xC0) << 6) | ((byte & 0x3F) << 2);
117 __gpio_clear_pin(PIN_LCD_WR);
118 bitdelay();
119 __gpio_set_pin(PIN_LCD_WR);
120 bitdelay();
121}
122
123void lcd_write_data(const fb_data* p_bytes, int count)
124{
125 __gpio_set_pin(PIN_LCD_DC);
126 while (count--)
127 {
128 REG_GPIO_PXDATC(2) = 0x000030FC;
129 REG_GPIO_PXDATS(2) = ((*p_bytes & 0xC0) << 6) | ((*p_bytes & 0x3F) << 2);
130 p_bytes++;
131 __gpio_clear_pin(PIN_LCD_WR);
132 bitdelay();
133 __gpio_set_pin(PIN_LCD_WR);
134 bitdelay();
135 }
136}
137
138void lcd_enable_power(bool onoff)
139{
140 if (onoff)
141 __gpio_set_pin(PIN_BL_EN);
142 else
143 __gpio_clear_pin(PIN_BL_EN);
144}
145
146/** globals **/
147
148static bool display_on = false; /* used by lcd_enable */
149
150/*** hardware configuration ***/
151
152void lcd_set_contrast(int val)
153{
154 lcd_write_command(LCD_CNTL_CONTRAST);
155 lcd_write_command(val);
156}
157
158void lcd_set_invert_display(bool yesno)
159{
160 if (yesno)
161 lcd_write_command(LCD_SET_REVERSE_DISPLAY);
162 else
163 lcd_write_command(LCD_SET_NORMAL_DISPLAY);
164}
165
166/* turn the display upside down (call lcd_update() afterwards) */
167void lcd_set_flip(bool yesno)
168{
169 if (yesno)
170 {
171 lcd_write_command(LCD_SET_SEGMENT_REMAP);
172 lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION);
173 }
174 else
175 {
176 lcd_write_command(LCD_SET_SEGMENT_REMAP_INV);
177 lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION_INV);
178 }
179}
180
181#ifdef HAVE_LCD_ENABLE
182void lcd_enable(bool enable)
183{
184 if(display_on == enable)
185 return;
186
187 if( (display_on = enable) ) /* simple '=' is not a typo ! */
188 {
189 lcd_enable_power(enable);
190 lcd_write_command(LCD_SET_DISPLAY_ON);
191 send_event(LCD_EVENT_ACTIVATION, NULL);
192 }
193 else
194 {
195 lcd_write_command(LCD_SET_DISPLAY_OFF);
196 lcd_enable_power(enable);
197 }
198}
199
200bool lcd_active(void)
201{
202 return display_on;
203}
204#endif
205
206/* LCD init, largely based on what OF does */
207void lcd_init_device(void)
208{
209 int i;
210
211 lcd_hw_init();
212
213 /* Set display off */
214 lcd_write_command(LCD_SET_DISPLAY_OFF);
215
216 /* Set display clock and oscillator frequency */
217 lcd_write_command(LCD_SET_DISPLAY_CLOCK_AND_OSC_FREQ);
218 lcd_write_command(0x80);
219
220 /* Set multiplex ratio*/
221 lcd_write_command(LCD_SET_MULTIPLEX_RATIO);
222 lcd_write_command(0x3F);
223
224 /* Set display offset */
225 lcd_write_command(LCD_SET_DISPLAY_OFFSET);
226 lcd_write_command(0x00);
227
228 /* Set starting line as 0 */
229 lcd_write_command(LCD_SET_DISPLAY_START_LINE);
230
231 /* Set charge pump */
232 lcd_write_command(LCD_SET_CHARGE_PUMP);
233 lcd_write_command(0x14); /* VCC Generated by Internal DC/DC Circuit */
234
235 /* Column 131 is remapped to SEG0 */
236 lcd_write_command(LCD_SET_SEGMENT_REMAP_INV);
237
238 /* Invert COM scan direction (N-1 to 0) */
239 lcd_write_command(LCD_SET_COM_OUTPUT_SCAN_DIRECTION_INV);
240
241 /* Set COM hardware configuration */
242 lcd_write_command(LCD_SET_VCOM_HW_CONFIGURATION);
243 lcd_write_command(0x12);
244
245 /* Set contrast control */
246 lcd_write_command(LCD_SET_CONTRAST_CONTROL_REGISTER);
247 lcd_write_command(0xCF); /* VCC Generated by Internal DC/DC Circuit */
248
249 /* Set pre-charge period */
250 lcd_write_command(LCD_SET_PRECHARGE_PERIOD);
251 lcd_write_command(0xF1); /* VCC Generated by Internal DC/DC Circuit */
252
253 /* Set VCOM deselect level */
254 lcd_write_command(LCD_SET_VCOM_DESELECT_LEVEL);
255 lcd_write_command(0x40);
256
257 /* Set normal display mode (not every pixel ON) */
258 lcd_write_command(LCD_SET_ENTIRE_DISPLAY_OFF);
259
260 /* Set normal display mode (not inverted) */
261 lcd_write_command(LCD_SET_NORMAL_DISPLAY);
262
263 fb_data p_bytes[LCD_WIDTH + 2 * LCD_COL_OFFSET];
264 memset(p_bytes, 0, sizeof(p_bytes)); /* fills with 0 : pixel off */
265 for(i = 0; i < 8; i++)
266 {
267 lcd_write_command (LCD_SET_PAGE_ADDRESS | (i /*& 0xf*/));
268 lcd_write_data(p_bytes, LCD_WIDTH + 2 * LCD_COL_OFFSET);
269 }
270
271 lcd_enable(true);
272
273 lcd_update();
274}
275
276/*** Update functions ***/
277
278/* Performance function that works with an external buffer
279 note that by and bheight are in 8-pixel units! */
280void lcd_blit_mono(const unsigned char *data, int x, int by, int width,
281 int bheight, int stride)
282{
283 if(!display_on)
284 return;
285
286 /* Copy display bitmap to hardware */
287 while (bheight--)
288 {
289 lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
290 lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET)>>4) & 0xf));
291 lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
292
293 lcd_write_data(data, width);
294 data += stride;
295 }
296}
297
298
299#ifndef BOOTLOADER
300/* Helper function for lcd_grey_phase_blit(). */
301void lcd_grey_data(unsigned char *values, unsigned char *phases, int count) ICODE_ATTR;
302void lcd_grey_data(unsigned char *values, unsigned char *phases, int count)
303{
304 unsigned char a, b, c, d;
305
306 __gpio_set_pin(PIN_LCD_DC);
307 while(count--)
308 {
309 c = 0;
310 d = 8;
311 while(d--)
312 {
313 a = *phases;
314 b = *values++;
315 b += a & ~0x80;
316 *phases++ = b;
317 c <<= 1;
318 c |= a >> 7;
319 }
320 REG_GPIO_PXDATC(2) = 0x000030FC;
321 REG_GPIO_PXDATS(2) = ((c & 0xC0) << 6) | ((c & 0x3F) << 2);
322 __gpio_clear_pin(PIN_LCD_WR);
323 bitdelay();
324 __gpio_set_pin(PIN_LCD_WR);
325 bitdelay();
326 }
327}
328
329/* Performance function that works with an external buffer
330 note that by and bheight are in 8-pixel units! */
331void lcd_blit_grey_phase(unsigned char *values, unsigned char *phases,
332 int x, int by, int width, int bheight, int stride)
333{
334 if(!display_on)
335 return;
336
337 stride <<= 3; /* 8 pixels per block */
338 /* Copy display bitmap to hardware */
339 while (bheight--)
340 {
341 lcd_write_command (LCD_CNTL_PAGE | (by++ & 0xf));
342 lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET)>>4) & 0xf));
343 lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
344
345 lcd_grey_data(values, phases, width);
346
347 values += stride;
348 phases += stride;
349 }
350}
351#endif
352
353/* Update the display.
354 This must be called after all other LCD functions that change the display. */
355void lcd_update(void) ICODE_ATTR;
356void lcd_update(void)
357{
358 int y;
359
360 if(!display_on)
361 return;
362
363 /* Copy display bitmap to hardware */
364 for (y = 0; y < LCD_FBHEIGHT; y++)
365 {
366 lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
367 lcd_write_command (LCD_CNTL_HIGHCOL | ((LCD_COL_OFFSET >> 4) & 0xf));
368 lcd_write_command (LCD_CNTL_LOWCOL | (LCD_COL_OFFSET & 0xf));
369
370 lcd_write_data (FBADDR(0, y), LCD_WIDTH);
371 }
372}
373
374/* Update a fraction of the display. */
375void lcd_update_rect(int, int, int, int) ICODE_ATTR;
376void lcd_update_rect(int x, int y, int width, int height)
377{
378 int ymax;
379
380 if(!display_on)
381 return;
382
383 /* The Y coordinates have to work on even 8 pixel rows */
384 if (x < 0)
385 {
386 width += x;
387 x = 0;
388 }
389
390 if (x + width > LCD_WIDTH)
391 width = LCD_WIDTH - x;
392
393 if (width <= 0)
394 return; /* nothing left to do, 0 is harmful to lcd_write_data() */
395
396 if (y < 0)
397 {
398 height += y;
399 y = 0;
400 }
401
402 if (y + height > LCD_HEIGHT)
403 height = LCD_HEIGHT - y;
404
405 if (height <= 0)
406 return; /* nothing left to do */
407
408 ymax = (y + height-1) >> 3;
409 y >>= 3;
410
411 /* Copy specified rectange bitmap to hardware */
412 for (; y <= ymax; y++)
413 {
414 lcd_write_command (LCD_CNTL_PAGE | (y & 0xf));
415 lcd_write_command (LCD_CNTL_HIGHCOL | (((x+LCD_COL_OFFSET) >> 4) & 0xf));
416 lcd_write_command (LCD_CNTL_LOWCOL | ((x+LCD_COL_OFFSET) & 0xf));
417
418 lcd_write_data (FBADDR(x,y), width);
419 }
420}
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c
new file mode 100644
index 0000000000..9ae602ba56
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/power-xduoo_x3.c
@@ -0,0 +1,46 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "power.h"
24#include "cpu.h"
25
26#define CHARGE_STAT_GPIO (32*1+6) /* STAT port */
27
28/* Detect which power sources are present. */
29unsigned int power_input_status(void)
30{
31 if(!__gpio_get_pin(CHARGE_STAT_GPIO))
32 return POWER_INPUT_USB_CHARGER;
33
34 return POWER_INPUT_NONE;
35}
36
37void power_init(void)
38{
39 __gpio_as_input(CHARGE_STAT_GPIO);
40 __gpio_disable_pull(CHARGE_STAT_GPIO);
41}
42
43bool charging_state(void)
44{
45 return (power_input_status() == POWER_INPUT_USB_CHARGER);
46}
diff --git a/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
new file mode 100644
index 0000000000..d4a3548305
--- /dev/null
+++ b/firmware/target/mips/ingenic_jz47xx/xduoo_x3/sadc-xduoo_x3.c
@@ -0,0 +1,214 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2016 by Roman Stolyarov
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22#include "config.h"
23#include "system.h"
24#include "cpu.h"
25#include "button.h"
26#include "button-target.h"
27#include "powermgmt.h"
28#include "kernel.h"
29#include "backlight.h"
30#include "logf.h"
31#include "adc.h"
32
33#define PIN_BTN_POWER (32*0+30)
34#define PIN_BTN_HOLD (32*1+15)
35
36#define PIN_KEY_INT (32*4+13)
37#define KEY_INT_IRQ GPIO141
38
39#define PIN_CHARGE_CON (32*1+7)
40
41#define PIN_PH_DECT (32*1+11)
42#define IRQ_PH_DECT GPIO_IRQ(PIN_PH_DECT)
43#define GPIO_PH_DECT GPIO43
44
45#define PIN_LO_DECT (32*1+12)
46#define IRQ_LO_DECT GPIO_IRQ(PIN_LO_DECT)
47#define GPIO_LO_DECT GPIO44
48
49static volatile unsigned short bat_val,key_val;
50
51bool headphones_inserted(void)
52{
53 return (__gpio_get_pin(PIN_PH_DECT) != 0);
54}
55
56void button_init_device(void)
57{
58 key_val = 0xfff;
59
60 __gpio_as_input(PIN_BTN_POWER);
61 __gpio_as_input(PIN_BTN_HOLD);
62
63 __gpio_disable_pull(PIN_BTN_POWER);
64 __gpio_disable_pull(PIN_BTN_HOLD);
65
66 __gpio_as_irq_fall_edge(PIN_KEY_INT);
67 system_enable_irq(GPIO_IRQ(PIN_KEY_INT));
68
69 __gpio_set_pin(PIN_CHARGE_CON); /* 0.7 A */
70 __gpio_as_output(PIN_CHARGE_CON);
71
72 __gpio_as_input(PIN_LO_DECT);
73 __gpio_as_input(PIN_PH_DECT);
74
75 __gpio_disable_pull(PIN_LO_DECT);
76 __gpio_disable_pull(PIN_PH_DECT);
77}
78
79bool button_hold(void)
80{
81 return (__gpio_get_pin(PIN_BTN_HOLD) ? true : false);
82}
83
84int button_read_device(void)
85{
86 static bool hold_button = false;
87 bool hold_button_old;
88
89 hold_button_old = hold_button;
90 hold_button = (__gpio_get_pin(PIN_BTN_HOLD) ? true : false);
91
92 int btn = BUTTON_NONE;
93 bool gpio_btn = (__gpio_get_pin(PIN_BTN_POWER) ? false : true);
94
95 REG_SADC_ADCFG = ADCFG_VBAT_SEL + ADCFG_CMD_AUX(1);
96 REG_SADC_ADENA = ADENA_VBATEN + ADENA_AUXEN;
97
98#ifndef BOOTLOADER
99 if (hold_button != hold_button_old) {
100 backlight_hold_changed(hold_button);
101 }
102 if (hold_button) {
103 return BUTTON_NONE;
104 }
105#endif
106
107 if (gpio_btn)
108 btn |= BUTTON_POWER;
109
110 if (key_val < 261)
111 btn |= BUTTON_VOL_UP;
112 else
113 if (key_val < 653)
114 btn |= BUTTON_VOL_DOWN;
115 else
116 if (key_val < 1101)
117 btn |= BUTTON_PREV;
118 else
119 if (key_val < 1498)
120 btn |= BUTTON_NEXT;
121 else
122 if (key_val < 1839)
123 btn |= BUTTON_PLAY;
124 else
125 if (key_val < 2213)
126 btn |= BUTTON_OPTION;
127 else
128 if (key_val < 2600)
129 btn |= BUTTON_HOME;
130
131 return btn;
132}
133
134/* called on button press interrupt */
135void KEY_INT_IRQ(void)
136{
137}
138
139const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
140{
141 /* 5% */
142 3634
143};
144
145const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
146{
147 /* 0% */
148 3300
149};
150
151
152/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
153const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
154{
155 { 3300, 3652, 3704, 3730, 3753, 3786, 3836, 3906, 3973, 4061, 4160 }
156};
157
158#if CONFIG_CHARGING
159/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
160const unsigned short percent_to_volt_charge[11] =
161 { 3300, 3652, 3704, 3730, 3753, 3786, 3836, 3906, 3973, 4061, 4160 };
162#endif /* CONFIG_CHARGING */
163
164/* VBAT = (BDATA/1024) * 2.5V */
165#define BATTERY_SCALE_FACTOR 2460
166
167/* Returns battery voltage from ADC [millivolts] */
168int _battery_voltage(void)
169{
170 return (bat_val*BATTERY_SCALE_FACTOR)>>10;
171}
172
173void adc_init(void)
174{
175 bat_val = 0xfff;
176
177 __cpm_start_sadc();
178 mdelay(10);
179 REG_SADC_ADENA = 0; /* Power Up */
180 mdelay(70);
181 REG_SADC_ADSTATE = 0;
182 REG_SADC_ADCTRL = ADCTRL_MASK_ALL - ADCTRL_ARDYM - ADCTRL_VRDYM;
183 REG_SADC_ADCFG = ADCFG_VBAT_SEL + ADCFG_CMD_AUX(1);
184 REG_SADC_ADCLK = (4 << 16) | (1 << 8) | 59; /* 200KHz */
185 system_enable_irq(IRQ_SADC);
186}
187
188void adc_close(void)
189{
190 REG_SADC_ADENA = ADENA_POWER; /* Power Down */
191 __intc_mask_irq(IRQ_SADC);
192 mdelay(20);
193 __cpm_stop_sadc();
194}
195
196/* Interrupt handler */
197void SADC(void)
198{
199 unsigned char state;
200 unsigned char sadcstate;
201
202 sadcstate = REG_SADC_ADSTATE;
203 state = REG_SADC_ADSTATE & (~REG_SADC_ADCTRL);
204 REG_SADC_ADSTATE &= sadcstate;
205
206 if(state & ADCTRL_ARDYM)
207 {
208 key_val = REG_SADC_ADADAT;
209 }
210 if(state & ADCTRL_VRDYM)
211 {
212 bat_val = REG_SADC_ADVDAT;
213 }
214}