summaryrefslogtreecommitdiff
path: root/firmware/target/arm/pbell/vibe500
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/pbell/vibe500')
-rw-r--r--firmware/target/arm/pbell/vibe500/adc-target.h35
-rw-r--r--firmware/target/arm/pbell/vibe500/backlight-target.h38
-rw-r--r--firmware/target/arm/pbell/vibe500/backlight-vibe500.c87
-rw-r--r--firmware/target/arm/pbell/vibe500/button-target.h65
-rw-r--r--firmware/target/arm/pbell/vibe500/button-vibe500.c114
-rw-r--r--firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S556
-rw-r--r--firmware/target/arm/pbell/vibe500/lcd-vibe500.c503
-rw-r--r--firmware/target/arm/pbell/vibe500/power-vibe500.c103
-rw-r--r--firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c57
-rw-r--r--firmware/target/arm/pbell/vibe500/usb-target.h29
10 files changed, 1587 insertions, 0 deletions
diff --git a/firmware/target/arm/pbell/vibe500/adc-target.h b/firmware/target/arm/pbell/vibe500/adc-target.h
new file mode 100644
index 0000000000..79a3f2d8ab
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/adc-target.h
@@ -0,0 +1,35 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 by Szymon Dziok
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 1
25
26#define ADC_BATTERY 0
27#define ADC_UNKNOWN_1 1
28#define ADC_UNKNOWN_2 2
29#define ADC_UNKNOWN_3 3
30#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
31
32/* Force a scan now */
33unsigned short adc_scan(int channel);
34
35#endif
diff --git a/firmware/target/arm/pbell/vibe500/backlight-target.h b/firmware/target/arm/pbell/vibe500/backlight-target.h
new file mode 100644
index 0000000000..7fd6d877fb
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/backlight-target.h
@@ -0,0 +1,38 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 by Szymon Dziok
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 BACKLIGHT_TARGET_H
22#define BACKLIGHT_TARGET_H
23
24#define _backlight_init() true
25void _backlight_on(void);
26void _backlight_off(void);
27
28#ifdef HAVE_BACKLIGHT_BRIGHTNESS
29void _backlight_set_brightness(int brightness);
30#endif
31
32#ifdef HAVE_BUTTON_LIGHT
33void _buttonlight_on(void);
34void _buttonlight_off(void);
35void _buttonlight_set_brightness(int brightness);
36#endif
37
38#endif /* BACKLIGHT_TARGET.H */
diff --git a/firmware/target/arm/pbell/vibe500/backlight-vibe500.c b/firmware/target/arm/pbell/vibe500/backlight-vibe500.c
new file mode 100644
index 0000000000..727370633b
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/backlight-vibe500.c
@@ -0,0 +1,87 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 by Szymon Dziok
11 * Based on the Iriver H10 and the Philips HD1630 code.
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "config.h"
23#include "cpu.h"
24#include "system.h"
25#include "backlight.h"
26#include "backlight-target.h"
27#include "lcd.h"
28#include "synaptics-mep.h"
29
30void _backlight_on(void)
31{
32#ifdef HAVE_LCD_ENABLE
33 lcd_enable(true); /* power on lcd + visible display */
34#endif
35 GPIO_SET_BITWISE(GPIOJ_OUTPUT_VAL, 0x01);
36}
37
38void _backlight_off(void)
39{
40 GPIO_CLEAR_BITWISE(GPIOJ_OUTPUT_VAL, 0x01);
41#ifdef HAVE_LCD_ENABLE
42 lcd_enable(false); /* power off visible display */
43#endif
44}
45
46#ifdef HAVE_BACKLIGHT_BRIGHTNESS
47static const int brightness_vals[16] =
48 {255,237,219,201,183,165,147,130,112,94,76,58,40,22,5,0};
49
50void _backlight_set_brightness(int brightness)
51{
52 /* From PB Vibe Bootloader and OF */
53 DEV_INIT1&=0xFFFF3F3F;
54 DEV_INIT1+=0x4000;
55 DEV_EN |= 0x20000;
56 outl(0x80000000 | (brightness_vals[brightness-1] << 16), 0x7000a010);
57}
58#endif
59
60#ifdef HAVE_BUTTON_LIGHT
61static unsigned short buttonlight_status = 0;
62
63void _buttonlight_on(void)
64{
65 if (!buttonlight_status)
66 {
67 touchpad_set_buttonlights(0x0f, 0);
68 buttonlight_status = 1;
69 }
70}
71
72void _buttonlight_off(void)
73{
74 if (buttonlight_status)
75 {
76 touchpad_set_buttonlights(0x00, 0);
77 buttonlight_status = 0;
78 }
79}
80
81void _buttonlight_set_brightness(int brightness)
82{
83 /* no brightness control, but lights stays on - for compatibility */
84 touchpad_set_buttonlights(0x0f, brightness);
85 buttonlight_status = 1;
86}
87#endif
diff --git a/firmware/target/arm/pbell/vibe500/button-target.h b/firmware/target/arm/pbell/vibe500/button-target.h
new file mode 100644
index 0000000000..8190b4313b
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/button-target.h
@@ -0,0 +1,65 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 by Szymon Dziok
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#include <stdbool.h>
25#include "config.h"
26
27#define MEP_BUTTON_HEADER 0x19
28#define MEP_BUTTON_ID 0x09
29#define MEP_ABSOLUTE_HEADER 0x0b
30
31#define HAS_BUTTON_HOLD
32
33bool button_hold(void);
34void button_init_device(void);
35int button_read_device(void);
36
37#ifndef BOOTLOADER
38void button_int(void);
39#endif
40
41
42#define BUTTON_POWER 0x00000001
43#define BUTTON_MENU 0x00000002
44#define BUTTON_PLAY 0x00000004
45#define BUTTON_PREV 0x00000008
46#define BUTTON_NEXT 0x00000010
47#define BUTTON_REC 0x00000020 /* RECORD */
48#define BUTTON_UP 0x00000040 /* Scrollstrip up move */
49#define BUTTON_DOWN 0x00000080 /* Scrollstrip down move */
50#define BUTTON_OK 0x00000100
51#define BUTTON_CANCEL 0x00000200
52
53/* there are no LEFT/RIGHT buttons, but other parts of the code expect them */
54#define BUTTON_LEFT 0x00000400
55#define BUTTON_RIGHT 0x00000800
56
57#define BUTTON_MAIN 0x00000fff
58
59#define BUTTON_REMOTE 0
60
61#define POWEROFF_BUTTON BUTTON_POWER
62#define POWEROFF_COUNT 10
63
64#endif /* _BUTTON_TARGET_H_ */
65
diff --git a/firmware/target/arm/pbell/vibe500/button-vibe500.c b/firmware/target/arm/pbell/vibe500/button-vibe500.c
new file mode 100644
index 0000000000..c95e996ef8
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/button-vibe500.c
@@ -0,0 +1,114 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 Szymon Dziok
11 * Based on the Iriver H10 and the Philips HD1630 code
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22
23#include "system.h"
24#include "button.h"
25#include "backlight.h"
26#include "synaptics-mep.h"
27
28static int int_btn = BUTTON_NONE;
29static int old_pos = -1;
30
31void button_init_device(void)
32{
33}
34
35/*
36 * Button interrupt handler
37 */
38void button_int(void)
39{
40 char data[4];
41 int val;
42
43 int_btn = BUTTON_NONE;
44
45 val = touchpad_read_device(data, 4);
46
47 if (val == MEP_BUTTON_HEADER)
48 {
49 /* Buttons packet */
50 if (data[1] & 0x1)
51 int_btn |= BUTTON_MENU;
52 if (data[1] & 0x2)
53 int_btn |= BUTTON_PLAY;
54 if (data[1] & 0x4)
55 int_btn |= BUTTON_NEXT;
56 if (data[1] & 0x8)
57 int_btn |= BUTTON_PREV;
58 }
59 else if (val == MEP_ABSOLUTE_HEADER)
60 {
61 /* Absolute packet - the finger is on the vertical strip.
62 Position ranges from 1-4095, with 1 at the bottom. */
63 val = ((data[1] >> 4) << 8) | data[2]; /* position */
64
65 if (val > 0)
66 {
67 int scr_pos = val >> 8; /* split the scrollstrip into 16 regions */
68 if ((old_pos<scr_pos)&&(old_pos!=-1)) int_btn = BUTTON_DOWN;
69 if ((old_pos>scr_pos)&&(old_pos!=-1)) int_btn = BUTTON_UP;
70 old_pos = scr_pos;
71 }
72 else old_pos=-1;
73 }
74}
75
76int button_read_device(void)
77{
78 int buttons = int_btn;
79 unsigned char state;
80 static bool hold_button = false;
81 bool hold_button_old;
82
83 hold_button_old = hold_button;
84 hold_button = button_hold();
85
86#ifndef BOOTLOADER
87 if (hold_button != hold_button_old)
88 {
89 backlight_hold_changed(hold_button);
90 }
91#endif
92
93 /* device buttons */
94 if (!hold_button)
95 {
96 /* Read Record, OK, C */
97 state = GPIOA_INPUT_VAL;
98 if ((state & 0x01)==0) buttons|=BUTTON_REC;
99 if ((state & 0x40)==0) buttons|=BUTTON_OK;
100 if ((state & 0x08)==0) buttons|=BUTTON_CANCEL;
101
102 /* Read POWER button */
103 if ((GPIOD_INPUT_VAL & 0x40)==0) buttons|=BUTTON_POWER;
104 }
105 else return BUTTON_NONE;
106 return buttons;
107}
108
109bool button_hold(void)
110{
111 /* GPIOK 01000000B - HOLD when bit not set */
112 return (GPIOK_INPUT_VAL & 0x40)?false:true;
113}
114
diff --git a/firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S b/firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S
new file mode 100644
index 0000000000..06e78d2aa1
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/lcd-as-vibe500.S
@@ -0,0 +1,556 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2007-2008 by Michael Sevakis
11 * Adapted for the Packard Bell Vibe 500 by Szymon Dziok
12 *
13 * Packard Bell Vibe 500 LCD assembly routines
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation; either version 2
18 * of the License, or (at your option) any later version.
19 *
20 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
21 * KIND, either express or implied.
22 *
23 ****************************************************************************/
24
25#include "config.h"
26#include "cpu.h"
27
28/****************************************************************************
29 * void lcd_write_yuv_420_lines(unsigned char const * const src[3],
30 * int width,
31 * int stride);
32 *
33 * |R| |1.000000 -0.000001 1.402000| |Y'|
34 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
35 * |B| |1.000000 1.772000 0.000000| |Pr|
36 * Scaled, normalized, rounded and tweaked to yield RGB 565:
37 * |R| |74 0 101| |Y' - 16| >> 9
38 * |G| = |74 -24 -51| |Cb - 128| >> 8
39 * |B| |74 128 0| |Cr - 128| >> 9
40 *
41 * Write four RGB565 pixels in the following order on each loop:
42 * 1 3 + > down
43 * 2 4 \/ left
44 */
45 .section .icode, "ax", %progbits
46 .align 2
47 .global lcd_write_yuv420_lines
48 .type lcd_write_yuv420_lines, %function
49lcd_write_yuv420_lines:
50 @ r0 = yuv_src
51 @ r1 = width
52 @ r2 = stride
53 stmfd sp!, { r4-r11, lr } @ save non-scratch
54 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
55 @ r5 = yuv_src[1] = Cb_p
56 @ r6 = yuv_src[2] = Cr_p
57 @
58 ldr r0, =LCD1_BASE @
59 @
60 sub r2, r2, #1 @ Adjust stride because of increment
6110: @ loop line @
62 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
63 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
64 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
65 @
66 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*74
67 add r12, r7, r7, asl #2 @ actually (Y' - 16)*37 and shift right
68 add r7, r12, r7, asl #5 @ by one less when adding - same for all
69 @
70 sub r8, r8, #128 @ Cb -= 128
71 sub r9, r9, #128 @ Cr -= 128
72 @
73 add r10, r9, r9, asl #1 @ r10 = Cr*51 + Cb*24
74 add r10, r10, r10, asl #4 @
75 add r10, r10, r8, asl #3 @
76 add r10, r10, r8, asl #4 @
77 @
78 add r11, r9, r9, asl #2 @ r9 = Cr*101
79 add r11, r11, r9, asl #5 @
80 add r9, r11, r9, asl #6 @
81 @
82 add r8, r8, #2 @ r8 = bu = (Cb*128 + 128) >> 8
83 mov r8, r8, asr #2 @
84 add r9, r9, #256 @ r9 = rv = (r8 + 256) >> 9
85 mov r9, r9, asr #9 @
86 rsb r10, r10, #128 @ r10 = guv = (-r9 + 128) >> 8
87 mov r10, r10, asr #8 @
88 @ compute R, G, and B
89 add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
90 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
91 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
92 @
93 orr r12, r3, r11 @ check if clamping is needed...
94 orr r12, r12, r7, asr #1 @ ...at all
95 cmp r12, #31 @
96 bls 15f @ no clamp @
97 cmp r3, #31 @ clamp b
98 mvnhi r3, r3, asr #31 @
99 andhi r3, r3, #31 @
100 cmp r11, #31 @ clamp r
101 mvnhi r11, r11, asr #31 @
102 andhi r11, r11, #31 @
103 cmp r7, #63 @ clamp g
104 mvnhi r7, r7, asr #31 @
105 andhi r7, r7, #63 @
10615: @ no clamp @
107 @
108 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
109 @
110 orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
111 orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
112 @
113 movs r7, r3, lsr #8 @ store pixel
11420: @
115 ldr r11, [r0] @
116 tst r11, #LCD1_BUSY_MASK @
117 bne 20b @
118 str r7, [r0, #0x10] @
11925: @
120 ldr r11, [r0] @
121 tst r11, #LCD1_BUSY_MASK @
122 bne 25b @
123 str r3, [r0, #0x10] @
124 @
125 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
126 add r12, r7, r7, asl #2 @
127 add r7, r12, r7, asl #5 @
128 @ compute R, G, and B
129 add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
130 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
131 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
132 @
133 orr r12, r3, r11 @ check if clamping is needed...
134 orr r12, r12, r7, asr #1 @ ...at all
135 cmp r12, #31 @
136 bls 15f @ no clamp @
137 cmp r3, #31 @ clamp b
138 mvnhi r3, r3, asr #31 @
139 andhi r3, r3, #31 @
140 cmp r11, #31 @ clamp r
141 mvnhi r11, r11, asr #31 @
142 andhi r11, r11, #31 @
143 cmp r7, #63 @ clamp g
144 mvnhi r7, r7, asr #31 @
145 andhi r7, r7, #63 @
14615: @ no clamp @
147 @
148 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
149 @
150 orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
151 orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
152 @
153 movs r7, r3, lsr #8 @ store pixel
15420: @
155 ldr r11, [r0] @
156 tst r11, #LCD1_BUSY_MASK @
157 bne 20b @
158 str r7, [r0, #0x10] @
15925: @
160 ldr r11, [r0] @
161 tst r11, #LCD1_BUSY_MASK @
162 bne 25b @
163 str r3, [r0, #0x10] @
164 @
165 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
166 add r12, r7, r7, asl #2 @
167 add r7, r12, r7, asl #5 @
168 @ compute R, G, and B
169 add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
170 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
171 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
172 @
173 orr r12, r3, r11 @ check if clamping is needed...
174 orr r12, r12, r7, asr #1 @ ...at all
175 cmp r12, #31 @
176 bls 15f @ no clamp @
177 cmp r3, #31 @ clamp b
178 mvnhi r3, r3, asr #31 @
179 andhi r3, r3, #31 @
180 cmp r11, #31 @ clamp r
181 mvnhi r11, r11, asr #31 @
182 andhi r11, r11, #31 @
183 cmp r7, #63 @ clamp g
184 mvnhi r7, r7, asr #31 @
185 andhi r7, r7, #63 @
18615: @ no clamp @
187 @
188 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
189 @
190 orr r3, r3, r7, lsl #5 @ r3 = b | (g << 5)
191 orr r3, r3, r11, lsl #11 @ r3 |= (r << 11)
192 @
193 movs r7, r3, lsr #8 @ store pixel
19420: @
195 ldr r11, [r0] @
196 tst r11, #LCD1_BUSY_MASK @
197 bne 20b @
198 str r7, [r0, #0x10] @
19925: @
200 ldr r11, [r0] @
201 tst r11, #LCD1_BUSY_MASK @
202 bne 25b @
203 str r3, [r0, #0x10] @
204 @
205 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*74
206 add r12, r7, r7, asl #2 @
207 add r7, r12, r7, asl #5 @
208 @ compute R, G, and B
209 add r3, r8, r7, asr #8 @ r3 = b = (Y >> 9) + bu
210 add r11, r9, r7, asr #8 @ r11 = r = (Y >> 9) + rv
211 add r7, r10, r7, asr #7 @ r7 = g = (Y >> 8) + guv
212 @
213 orr r12, r3, r11 @ check if clamping is needed...
214 orr r12, r12, r7, asr #1 @ ...at all
215 cmp r12, #31 @
216 bls 15f @ no clamp @
217 cmp r3, #31 @ clamp b
218 mvnhi r3, r3, asr #31 @
219 andhi r3, r3, #31 @
220 cmp r11, #31 @ clamp r
221 mvnhi r11, r11, asr #31 @
222 andhi r11, r11, #31 @
223 cmp r7, #63 @ clamp g
224 mvnhi r7, r7, asr #31 @
225 andhi r7, r7, #63 @
22615: @ no clamp @
227 @
228 orr r3, r3, r11, lsl #11 @ r3 = b | (r << 11)
229 orr r3, r3, r7, lsl #5 @ r3 |= (g << 5)
230 @
231 movs r7, r3, lsr #8 @ store pixel
23220: @
233 ldr r11, [r0] @
234 tst r11, #LCD1_BUSY_MASK @
235 bne 20b @
236 str r7, [r0, #0x10] @
23725: @
238 ldr r11, [r0] @
239 tst r11, #LCD1_BUSY_MASK @
240 bne 25b @
241 str r3, [r0, #0x10] @
242 @
243 subs r1, r1, #2 @ subtract block from width
244 bgt 10b @ loop line @
245 @
246 ldmfd sp!, { r4-r11, pc } @ restore registers and return
247 .ltorg @ dump constant pool
248 .size lcd_write_yuv420_lines, .-lcd_write_yuv420_lines
249
250
251/****************************************************************************
252 * void lcd_write_yuv_420_lines_odither(unsigned char const * const src[3],
253 * int width,
254 * int stride,
255 * int x_screen,
256 * int y_screen);
257 *
258 * |R| |1.000000 -0.000001 1.402000| |Y'|
259 * |G| = |1.000000 -0.334136 -0.714136| |Pb|
260 * |B| |1.000000 1.772000 0.000000| |Pr|
261 * Red scaled at twice g & b but at same precision to place it in correct
262 * bit position after multiply and leave instruction count lower.
263 * |R| |258 0 408| |Y' - 16|
264 * |G| = |149 -49 -104| |Cb - 128|
265 * |B| |149 258 0| |Cr - 128|
266 *
267 * Write four RGB565 pixels in the following order on each loop:
268 * 1 3 + > down
269 * 2 4 \/ left
270 *
271 * Kernel pattern (raw|use order):
272 * 5 3 4 2 row0 row2 > down
273 * 1 7 0 6 | 5 1 3 7 4 0 2 6 col0 left
274 * 4 2 5 3 | 4 0 2 6 5 1 3 7 col2 \/
275 * 0 6 1 7
276 */
277 .section .icode, "ax", %progbits
278 .align 2
279 .global lcd_write_yuv420_lines_odither
280 .type lcd_write_yuv420_lines_odither, %function
281lcd_write_yuv420_lines_odither:
282 @ r0 = yuv_src
283 @ r1 = width
284 @ r2 = stride
285 @ r3 = x_screen
286 @ [sp] = y_screen
287 stmfd sp!, { r4-r11, lr } @ save non-scratch
288 ldmia r0, { r4, r5, r6 } @ r4 = yuv_src[0] = Y'_p
289 @ r5 = yuv_src[1] = Cb_p
290 @ r6 = yuv_src[2] = Cr_p
291 @
292 ldr r0, [sp, #40] @ Line up pattern and kernel quadrant
293 eor r14, r3, r0 @
294 and r14, r14, #0x2 @
295 mov r14, r14, lsl #6 @ 0x00 or 0x80
296 @
297 ldr r0, =LCD1_BASE @
298 @
299 sub r2, r2, #1 @ Adjust stride because of increment
30010: @ loop line @
301 @
302 ldrb r7, [r4], #1 @ r7 = *Y'_p++;
303 ldrb r8, [r5], #1 @ r8 = *Cb_p++;
304 ldrb r9, [r6], #1 @ r9 = *Cr_p++;
305 @
306 eor r14, r14, #0x80 @ flip pattern quadrant
307 @
308 sub r7, r7, #16 @ r7 = Y = (Y' - 16)*149
309 add r12, r7, r7, asl #2 @
310 add r12, r12, r12, asl #4 @
311 add r7, r12, r7, asl #6 @
312 @
313 sub r8, r8, #128 @ Cb -= 128
314 sub r9, r9, #128 @ Cr -= 128
315 @
316 add r10, r8, r8, asl #4 @ r10 = guv = Cr*104 + Cb*49
317 add r10, r10, r8, asl #5 @
318 add r10, r10, r9, asl #3 @
319 add r10, r10, r9, asl #5 @
320 add r10, r10, r9, asl #6 @
321 @
322 mov r8, r8, asl #1 @ r8 = bu = Cb*258
323 add r8, r8, r8, asl #7 @
324 @
325 add r9, r9, r9, asl #1 @ r9 = rv = Cr*408
326 add r9, r9, r9, asl #4 @
327 mov r9, r9, asl #3 @
328 @
329 @ compute R, G, and B
330 add r3, r8, r7 @ r3 = b' = Y + bu
331 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
332 rsb r7, r10, r7 @ r7 = g' = Y + guv
333 @
334 @ r8 = bu, r9 = rv, r10 = guv
335 @
336 sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
337 add r3, r12, r3, lsr #8 @
338 @
339 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
340 add r11, r12, r11, lsr #8 @
341 @
342 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
343 add r7, r12, r7, lsr #8 @
344 @
345 add r12, r14, #0x200 @
346 @
347 add r3, r3, r12 @ b = r3 + delta
348 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
349 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
350 @
351 orr r12, r3, r11, asr #1 @ check if clamping is needed...
352 orr r12, r12, r7 @ ...at all
353 movs r12, r12, asr #15 @
354 beq 15f @ no clamp @
355 movs r12, r3, asr #15 @ clamp b
356 mvnne r3, r12, lsr #15 @
357 andne r3, r3, #0x7c00 @ mask b only if clamped
358 movs r12, r11, asr #16 @ clamp r
359 mvnne r11, r12, lsr #16 @
360 movs r12, r7, asr #15 @ clamp g
361 mvnne r7, r12, lsr #15 @
36215: @ no clamp @
363 @
364 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
365 @
366 and r11, r11, #0xf800 @ pack pixel
367 and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
368 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
369 orr r3, r11, r3, lsr #10 @ (b >> 10)
370 @
371 movs r7, r3, lsr #8 @ store pixel
37220: @
373 ldr r11, [r0] @
374 tst r11, #LCD1_BUSY_MASK @
375 bne 20b @
376 str r7, [r0, #0x10] @
37725: @
378 ldr r11, [r0] @
379 tst r11, #LCD1_BUSY_MASK @
380 bne 25b @
381 str r3, [r0, #0x10] @
382 @
383 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
384 add r12, r7, r7, asl #2 @
385 add r12, r12, r12, asl #4 @
386 add r7, r12, r7, asl #6 @
387 @ compute R, G, and B
388 add r3, r8, r7 @ r3 = b' = Y + bu
389 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
390 rsb r7, r10, r7 @ r7 = g' = Y + guv
391 @
392 sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
393 add r3, r12, r3, lsr #8 @
394 @
395 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
396 add r11, r12, r11, lsr #8 @
397 @
398 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
399 add r7, r12, r7, lsr #8 @
400 @
401 @ This element is zero - use r14 @
402 @
403 add r3, r3, r14 @ b = r3 + delta
404 add r11, r11, r14, lsl #1 @ r = r11 + delta*2
405 add r7, r7, r14, lsr #1 @ g = r7 + delta/2
406 @
407 orr r12, r3, r11, asr #1 @ check if clamping is needed...
408 orr r12, r12, r7 @ ...at all
409 movs r12, r12, asr #15 @
410 beq 15f @ no clamp @
411 movs r12, r3, asr #15 @ clamp b
412 mvnne r3, r12, lsr #15 @
413 andne r3, r3, #0x7c00 @ mask b only if clamped
414 movs r12, r11, asr #16 @ clamp r
415 mvnne r11, r12, lsr #16 @
416 movs r12, r7, asr #15 @ clamp g
417 mvnne r7, r12, lsr #15 @
41815: @ no clamp @
419 @
420 ldrb r12, [r4], #1 @ r12 = Y' = *(Y'_p++)
421 @
422 and r11, r11, #0xf800 @ pack pixel
423 and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
424 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
425 orr r3, r11, r3, lsr #10 @ (b >> 10)
426 @
427 movs r7, r3, lsr #8 @ store pixel
42820: @
429 ldr r11, [r0] @
430 tst r11, #LCD1_BUSY_MASK @
431 bne 20b @
432 str r7, [r0, #0x10] @
43325: @
434 ldr r11, [r0] @
435 tst r11, #LCD1_BUSY_MASK @
436 bne 25b @
437 str r3, [r0, #0x10] @
438 @
439 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
440 add r12, r7, r7, asl #2 @
441 add r12, r12, r12, asl #4 @
442 add r7, r12, r7, asl #6 @
443 @ compute R, G, and B
444 add r3, r8, r7 @ r3 = b' = Y + bu
445 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
446 rsb r7, r10, r7 @ r7 = g' = Y + guv
447 @
448 @ r8 = bu, r9 = rv, r10 = guv
449 @
450 sub r12, r3, r3, lsr #5 @ r3 = 31/32*b' + b'/256
451 add r3, r12, r3, lsr #8 @
452 @
453 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r' + r'/256
454 add r11, r12, r11, lsr #8 @
455 @
456 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g' + g'/256
457 add r7, r12, r7, lsr #8 @
458 @
459 add r12, r14, #0x100 @
460 @
461 add r3, r3, r12 @ b = r3 + delta
462 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
463 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
464 @
465 orr r12, r3, r11, asr #1 @ check if clamping is needed...
466 orr r12, r12, r7 @ ...at all
467 movs r12, r12, asr #15 @
468 beq 15f @ no clamp @
469 movs r12, r3, asr #15 @ clamp b
470 mvnne r3, r12, lsr #15 @
471 andne r3, r3, #0x7c00 @ mask b only if clamped
472 movs r12, r11, asr #16 @ clamp r
473 mvnne r11, r12, lsr #16 @
474 movs r12, r7, asr #15 @ clamp g
475 mvnne r7, r12, lsr #15 @
47615: @ no clamp @
477 @
478 ldrb r12, [r4, r2] @ r12 = Y' = *(Y'_p + stride)
479 @
480 and r11, r11, #0xf800 @ pack pixel
481 and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
482 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
483 orr r3, r11, r3, lsr #10 @ (b >> 10)
484 @
485 movs r7, r3, lsr #8 @ store pixel
48620: @
487 ldr r11, [r0] @
488 tst r11, #LCD1_BUSY_MASK @
489 bne 20b @
490 str r7, [r0, #0x10] @
49125: @
492 ldr r11, [r0] @
493 tst r11, #LCD1_BUSY_MASK @
494 bne 25b @
495 str r3, [r0, #0x10] @
496 @
497 sub r7, r12, #16 @ r7 = Y = (Y' - 16)*149
498 add r12, r7, r7, asl #2 @
499 add r12, r12, r12, asl #4 @
500 add r7, r12, r7, asl #6 @
501 @ compute R, G, and B
502 add r3, r8, r7 @ r3 = b' = Y + bu
503 add r11, r9, r7, asl #1 @ r11 = r' = Y*2 + rv
504 rsb r7, r10, r7 @ r7 = g' = Y + guv
505 @
506 sub r12, r3, r3, lsr #5 @ r3 = 31/32*b + b/256
507 add r3, r12, r3, lsr #8 @
508 @
509 sub r12, r11, r11, lsr #5 @ r11 = 31/32*r + r/256
510 add r11, r12, r11, lsr #8 @
511 @
512 sub r12, r7, r7, lsr #6 @ r7 = 63/64*g + g/256
513 add r7, r12, r7, lsr #8 @
514 @
515 add r12, r14, #0x300 @
516 @
517 add r3, r3, r12 @ b = r3 + delta
518 add r11, r11, r12, lsl #1 @ r = r11 + delta*2
519 add r7, r7, r12, lsr #1 @ g = r7 + delta/2
520 @
521 orr r12, r3, r11, asr #1 @ check if clamping is needed...
522 orr r12, r12, r7 @ ...at all
523 movs r12, r12, asr #15 @
524 beq 15f @ no clamp @
525 movs r12, r3, asr #15 @ clamp b
526 mvnne r3, r12, lsr #15 @
527 andne r3, r3, #0x7c00 @ mask b only if clamped
528 movs r12, r11, asr #16 @ clamp r
529 mvnne r11, r12, lsr #16 @
530 movs r12, r7, asr #15 @ clamp g
531 mvnne r7, r12, lsr #15 @
53215: @ no clamp @
533 @
534 and r11, r11, #0xf800 @ pack pixel
535 and r7, r7, #0x7e00 @ r3 = pixel = (r & 0xf800) |
536 orr r11, r11, r7, lsr #4 @ ((g & 0x7e00) >> 4) |
537 orr r3, r11, r3, lsr #10 @ (b >> 10)
538 @
539 movs r7, r3, lsr #8 @ store pixel
54020: @
541 ldr r11, [r0] @
542 tst r11, #LCD1_BUSY_MASK @
543 bne 20b @
544 str r7, [r0, #0x10] @
54525: @
546 ldr r11, [r0] @
547 tst r11, #LCD1_BUSY_MASK @
548 bne 25b @
549 str r3, [r0, #0x10] @
550 @
551 subs r1, r1, #2 @ subtract block from width
552 bgt 10b @ loop line @
553 @
554 ldmfd sp!, { r4-r11, pc } @ restore registers and return
555 .ltorg @ dump constant pool
556 .size lcd_write_yuv420_lines_odither, .-lcd_write_yuv420_lines_odither
diff --git a/firmware/target/arm/pbell/vibe500/lcd-vibe500.c b/firmware/target/arm/pbell/vibe500/lcd-vibe500.c
new file mode 100644
index 0000000000..ca483f74ea
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/lcd-vibe500.c
@@ -0,0 +1,503 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 by Szymon Dziok
11 * Based on the Iriver H10 code by Barry Wardell
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 ****************************************************************************/
22#include "config.h"
23#include "cpu.h"
24#include "lcd.h"
25#include "kernel.h"
26#include "system.h"
27
28/** Initialized in lcd_init_device() **/
29/* Is the power turned on? */
30static bool power_on;
31/* Is the display turned on? */
32static bool display_on;
33/* Reverse flag. Must be remembered when display is turned off. */
34static unsigned short disp_control_rev;
35/* Contrast setting << 8 */
36static int lcd_contrast;
37
38static unsigned lcd_yuv_options SHAREDBSS_ATTR = 0;
39
40/* Forward declarations */
41#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
42static void lcd_display_off(void);
43#endif
44
45/* register defines for the Renesas HD66773R */
46/*
47 In Packard Bell from the OF - it seems to be
48 HD66774(gate) with HD66772(source) - registers
49 are very similar but not all the same
50*/
51#define R_START_OSC 0x00
52#define R_DEVICE_CODE_READ 0x00
53#define R_DRV_OUTPUT_CONTROL 0x01
54#define R_DRV_AC_CONTROL 0x02
55#define R_POWER_CONTROL1 0x03
56#define R_POWER_CONTROL2 0x04
57#define R_ENTRY_MODE 0x05
58#define R_COMPARE_REG 0x06
59#define R_DISP_CONTROL 0x07
60#define R_FRAME_CYCLE_CONTROL 0x0b
61#define R_POWER_CONTROL3 0x0c
62#define R_POWER_CONTROL4 0x0d
63#define R_POWER_CONTROL5 0x0e
64#define R_GATE_SCAN_START_POS 0x0f
65#define R_VERT_SCROLL_CONTROL 0x11
66#define R_1ST_SCR_DRV_POS 0x14
67#define R_2ND_SCR_DRV_POS 0x15
68#define R_HORIZ_RAM_ADDR_POS 0x16
69#define R_VERT_RAM_ADDR_POS 0x17
70#define R_RAM_WRITE_DATA_MASK 0x20
71#define R_RAM_ADDR_SET 0x21
72#define R_WRITE_DATA_2_GRAM 0x22
73#define R_RAM_READ_DATA 0x22
74#define R_GAMMA_FINE_ADJ_POS1 0x30
75#define R_GAMMA_FINE_ADJ_POS2 0x31
76#define R_GAMMA_FINE_ADJ_POS3 0x32
77#define R_GAMMA_GRAD_ADJ_POS 0x33
78#define R_GAMMA_FINE_ADJ_NEG1 0x34
79#define R_GAMMA_FINE_ADJ_NEG2 0x35
80#define R_GAMMA_FINE_ADJ_NEG3 0x36
81#define R_GAMMA_GRAD_ADJ_NEG 0x37
82#define R_GAMMA_AMP_ADJ_POS 0x3a
83#define R_GAMMA_AMP_ADJ_NEG 0x3b
84
85static inline void lcd_wait_write(void)
86{
87 while (LCD1_CONTROL & LCD1_BUSY_MASK);
88}
89
90/* Send command */
91static inline void lcd_send_cmd(unsigned v)
92{
93 lcd_wait_write();
94 LCD1_CMD = (v >> 8);
95 lcd_wait_write();
96 LCD1_CMD = (v & 0xff);
97}
98
99/* Send 16-bit data */
100static inline void lcd_send_data(unsigned v)
101{
102 lcd_wait_write();
103 LCD1_DATA = (v >> 8);
104 lcd_wait_write();
105 LCD1_DATA = (v & 0xff);
106}
107
108/* Send 16-bit data byte-swapped. */
109static inline void lcd_send_data_swapped(unsigned v)
110{
111 lcd_wait_write();
112 LCD1_DATA = (v & 0xff);
113 lcd_wait_write();
114 LCD1_DATA = (v >> 8);
115}
116
117/* Write value to register */
118static void lcd_write_reg(int reg, int val)
119{
120 lcd_send_cmd(reg);
121 lcd_send_data(val);
122}
123
124/*** hardware configuration ***/
125
126int lcd_default_contrast(void)
127{
128 return DEFAULT_CONTRAST_SETTING;
129}
130
131void lcd_set_contrast(int val)
132{
133 lcd_contrast = (val&0x1f) << 8;
134 if (!power_on) return;
135
136 /* VCOMG=1, VDV4-0=xxxxx, VCM4-0=11000 */
137 lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
138}
139
140void lcd_set_invert_display(bool yesno)
141{
142 if (yesno == (disp_control_rev == 0x0000))
143 return;
144
145 disp_control_rev = yesno ? 0x0000 : 0x0004;
146
147 if (!display_on)
148 return;
149
150 /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=11 */
151 lcd_write_reg(R_DISP_CONTROL, 0x0033 | disp_control_rev);
152}
153
154/* turn the display upside down (call lcd_update() afterwards) */
155void lcd_set_flip(bool yesno)
156{
157 if (!power_on)
158 return;
159
160 /* SM=0, GS=x, SS=x, NL4-0=10011 (G1-G160) */
161 lcd_write_reg(R_DRV_OUTPUT_CONTROL, yesno ? 0x0313 : 0x0013);
162}
163
164/* LCD init */
165void lcd_init_device(void)
166{
167 power_on = true;
168 display_on = true;
169 disp_control_rev = 0x0004;
170 lcd_contrast = DEFAULT_CONTRAST_SETTING << 8;
171}
172
173#ifdef HAVE_LCD_SLEEP
174static void lcd_power_on(void)
175{
176 /* from the OF */
177 lcd_write_reg(R_START_OSC,0x01); /* START_OSC */
178 sleep(HZ/40); /* 25ms */
179 /* set 396x160 dots, SM=0, GS=x, SS=0, NL4-0=10011 G1-G160)*/
180 lcd_write_reg(R_DRV_OUTPUT_CONTROL,0x13);
181 /* FLD1-0=01 (1 field), B/C=1, EOR=1 (C-pat), NW5-0=000000 (1 row) */
182 lcd_write_reg(R_DRV_AC_CONTROL,7 << 8);
183 /* DIT=0, BGR=1, HWM=0, I/D1-0=0 - decrement AC, AM=1, LG2-0=000 */
184 lcd_write_reg(R_ENTRY_MODE,0x1008);
185 lcd_write_reg(0x25,0x0000); /* - ?? */
186 lcd_write_reg(0x26,0x0202); /* - ?? */
187 lcd_write_reg(0x0A,0x0000); /* - ?? */
188 lcd_write_reg(R_FRAME_CYCLE_CONTROL,0x0000);
189 lcd_write_reg(R_POWER_CONTROL4,0x0000);
190 sleep(HZ/67); /* 15ms */
191 lcd_write_reg(R_POWER_CONTROL5,0x0000);
192 sleep(HZ/67); /* 15ms */
193 lcd_write_reg(R_POWER_CONTROL3,0x0000);
194 lcd_write_reg(0x09,0x0008); /* - ?? */
195 sleep(HZ/67); /* 15ms */
196 lcd_write_reg(R_POWER_CONTROL4,0x0003);
197 sleep(HZ/67); /* 15ms */
198 lcd_write_reg(R_POWER_CONTROL5,0x1019);
199 sleep(HZ/20); /* 50ms */
200 lcd_write_reg(R_POWER_CONTROL4,0x0013);
201 sleep(HZ/67); /* 15ms */
202 lcd_write_reg(R_POWER_CONTROL1,0x0010);
203 sleep(HZ/67); /* 15ms */
204 lcd_write_reg(0x09,0x0000); /* - ?? */
205 sleep(HZ/67); /* 15ms */
206 lcd_write_reg(R_POWER_CONTROL1,0x0010);
207 sleep(HZ/67); /* 15ms */
208 lcd_write_reg(R_POWER_CONTROL5,0x3019);
209 sleep(HZ/6.6);/* 150ms */
210 lcd_write_reg(0x09,0x0002); /* - ?? */
211 sleep(HZ/67); /* 15ms */
212 lcd_write_reg(R_POWER_CONTROL4,0x0018);
213 sleep(HZ/20); /* 50ms */
214 /* RAM Address set (0x0000) */
215 lcd_write_reg(R_RAM_ADDR_SET,0x0000);
216 /* Gamma settings */
217 lcd_write_reg(R_GAMMA_FINE_ADJ_POS1,0x0004);
218 lcd_write_reg(R_GAMMA_FINE_ADJ_POS2,0x0606);
219 lcd_write_reg(R_GAMMA_FINE_ADJ_POS3,0x0505);
220 lcd_write_reg(R_GAMMA_GRAD_ADJ_POS,0x0206);
221 lcd_write_reg(R_GAMMA_FINE_ADJ_NEG1,0x0505);
222 lcd_write_reg(R_GAMMA_FINE_ADJ_NEG2,0x0707);
223 lcd_write_reg(R_GAMMA_FINE_ADJ_NEG3,0x0105);
224 lcd_write_reg(R_GAMMA_GRAD_ADJ_NEG,0x0301);
225 lcd_write_reg(R_GAMMA_AMP_ADJ_POS,0x1A00);
226 lcd_write_reg(R_GAMMA_AMP_ADJ_NEG,0x010E);
227
228 lcd_write_reg(R_GATE_SCAN_START_POS,0x0000);
229 /* Horizontal ram address start/end position (0,127); */
230 lcd_write_reg(R_HORIZ_RAM_ADDR_POS,0x7F00);
231 /* Vertical ram address start/end position (0,159); */
232 lcd_write_reg(R_VERT_RAM_ADDR_POS,0x9F00);
233
234 lcd_write_reg(R_DISP_CONTROL,0x0005);
235 sleep(HZ/25); /* 40ms */
236 lcd_write_reg(R_DISP_CONTROL,0x0025);
237 lcd_write_reg(R_DISP_CONTROL,0x0027);
238 sleep(HZ/25); /* 40ms */
239 lcd_write_reg(R_DISP_CONTROL,0x0033 | disp_control_rev);
240 sleep(HZ/100); /* 10ms */
241 lcd_write_reg(R_POWER_CONTROL1,0x0110);
242 lcd_write_reg(R_FRAME_CYCLE_CONTROL,0x0000);
243 lcd_write_reg(R_POWER_CONTROL4,0x0013);
244 lcd_write_reg(R_POWER_CONTROL5,0x2018 | lcd_contrast);
245 sleep(HZ/20); /* 50ms */
246
247 power_on = true;
248}
249
250static void lcd_power_off(void)
251{
252 /* Display must be off first */
253 if (display_on)
254 lcd_display_off();
255
256 /* power_on = false; */
257
258 /** Power OFF sequence **/
259 /* The method is unknown */
260}
261
262void lcd_sleep(void)
263{
264 if (power_on)
265 lcd_power_off();
266
267 /* Set standby mode */
268 /* Because we dont know how to power off display
269 we cannot set standby */
270 /* BT2-0=000, DC2-0=000, AP2-0=000, SLP=0, STB=1 */
271 /* lcd_write_reg(R_POWER_CONTROL1, 0x0001); */
272}
273#endif
274
275#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
276static void lcd_display_off(void)
277{
278 display_on = false;
279
280 /** Display OFF sequence **/
281 /* In the OF it is called "EnterStandby" */
282
283 /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=1, REV=x, D1-0=10 */
284 lcd_write_reg(R_DISP_CONTROL, 0x0032 | disp_control_rev);
285 sleep(HZ/22); /* 45ms */
286 /* PT1-0=00, VLE2-1=00, SPT=0, GON=1, DTE=0, REV=x, D1-0=10 */
287 lcd_write_reg(R_DISP_CONTROL, 0x0022 | disp_control_rev);
288 sleep(HZ/22); /* 45ms */
289 /* PT1-0=00, VLE2-1=00, SPT=0, GON=0, DTE=0, REV=0, D1-0=00 */
290 lcd_write_reg(R_DISP_CONTROL, 0x0000);
291
292 lcd_write_reg(R_POWER_CONTROL1, 0x0000);
293 lcd_write_reg(0x09, 0x0000); /* -?? */
294 lcd_write_reg(R_POWER_CONTROL4, 0x0000);
295
296 sleep(HZ/22); /* 45ms */
297}
298#endif
299
300#if defined(HAVE_LCD_ENABLE)
301static void lcd_display_on(void)
302{
303 /* Be sure power is on first */
304 if (!power_on)
305 lcd_power_on();
306
307 /** Display ON Sequence **/
308 /* In the OF it is called "ExitStandby" */
309
310 lcd_write_reg(R_START_OSC,1);
311 sleep(HZ/40); /* 25ms */
312 lcd_write_reg(R_POWER_CONTROL4,0);
313 sleep(HZ/67); /* 15ms */
314 lcd_write_reg(R_POWER_CONTROL5,0);
315 sleep(HZ/67); /* 15ms */
316 lcd_write_reg(R_DISP_CONTROL,0);
317 sleep(HZ/67); /* 15ms */
318 lcd_write_reg(R_POWER_CONTROL3,0);
319 lcd_write_reg(0x09,8); /* -?? */
320 sleep(HZ/67); /* 15ms */
321 lcd_write_reg(R_POWER_CONTROL4,3);
322 sleep(HZ/67); /* 15ms */
323 lcd_write_reg(R_POWER_CONTROL5,0x1019);
324 sleep(HZ/20); /* 50ms */
325 lcd_write_reg(R_POWER_CONTROL4,0x13);
326 sleep(HZ/67); /* 15ms */
327 lcd_write_reg(R_POWER_CONTROL1,0x10);
328 sleep(HZ/20); /* 50ms */
329 lcd_write_reg(0x09,0); /* -?? */
330 sleep(HZ/67); /* 15ms */
331 lcd_write_reg(R_POWER_CONTROL1,0x10);
332 sleep(HZ/67); /* 15ms */
333 lcd_write_reg(R_POWER_CONTROL5,0x3019);
334 sleep(HZ/6.6);/* 150ms */
335 lcd_write_reg(0x09,2); /* -?? */
336 sleep(HZ/20); /* 50ms */
337 lcd_write_reg(R_DISP_CONTROL,5);
338 sleep(HZ/22); /* 45ms */
339 lcd_write_reg(R_DISP_CONTROL,0x25);
340 sleep(HZ/22); /* 45ms */
341 lcd_write_reg(R_DISP_CONTROL,0x27);
342 sleep(HZ/25); /* 40ms */
343 lcd_write_reg(R_DISP_CONTROL,0x33 | disp_control_rev);
344 sleep(HZ/22); /* 45ms */
345 /* fix contrast */
346 lcd_write_reg(R_POWER_CONTROL5, 0x2018 | lcd_contrast);
347
348 display_on = true;
349}
350
351void lcd_enable(bool on)
352{
353 if (on == display_on)
354 return;
355
356 if (on)
357 {
358 lcd_display_on();
359 /* Probably out of sync and we don't wanna pepper the code with
360 lcd_update() calls for this. */
361 lcd_update();
362 send_event(LCD_EVENT_ACTIVATION, NULL);
363 }
364 else
365 {
366 lcd_display_off();
367 }
368}
369#endif
370
371#if defined(HAVE_LCD_ENABLE) || defined(HAVE_LCD_SLEEP)
372bool lcd_active(void)
373{
374 return display_on;
375}
376#endif
377
378/*** update functions ***/
379
380void lcd_yuv_set_options(unsigned options)
381{
382 lcd_yuv_options = options;
383}
384
385/* Line write helper function for lcd_yuv_blit. Write two lines of yuv420. */
386
387extern void lcd_write_yuv420_lines(unsigned char const * const src[3],
388 int width,
389 int stride);
390extern void lcd_write_yuv420_lines_odither(unsigned char const * const src[3],
391 int width,
392 int stride,
393 int x_screen, /* To align dither pattern */
394 int y_screen);
395
396/* Performance function to blit a YUV bitmap directly to the LCD */
397void lcd_blit_yuv(unsigned char * const src[3],
398 int src_x, int src_y, int stride,
399 int x, int y, int width, int height)
400{
401 const unsigned char *yuv_src[3];
402 const unsigned char *ysrc_max;
403 int y0;
404 int options;
405
406 if (!display_on)
407 return;
408
409 width &= ~1;
410 height &= ~1;
411
412 lcd_write_reg(R_VERT_RAM_ADDR_POS, ((LCD_WIDTH - 1 - x) << 8) |
413 ((LCD_WIDTH-1) - (x + width - 1)));
414
415 y0 = LCD_HEIGHT - 1 - y;
416
417 lcd_write_reg(R_ENTRY_MODE,0x1000);
418
419 yuv_src[0] = src[0] + src_y * stride + src_x;
420 yuv_src[1] = src[1] + (src_y * stride >> 2) + (src_x >> 1);
421 yuv_src[2] = src[2] + (yuv_src[1] - src[1]);
422 ysrc_max = yuv_src[0] + height * stride;
423
424 options = lcd_yuv_options;
425
426 do
427 {
428 lcd_write_reg(R_HORIZ_RAM_ADDR_POS, (y0 << 8) | (y0 - 1));
429 lcd_write_reg(R_RAM_ADDR_SET, ((LCD_WIDTH - 1 - x) << 8) | y0);
430
431 /* start drawing */
432 lcd_send_cmd(R_WRITE_DATA_2_GRAM);
433
434 if (options & LCD_YUV_DITHER)
435 {
436 lcd_write_yuv420_lines_odither(yuv_src, width, stride,x, y);
437 y -= 2;
438 }
439 else
440 {
441 lcd_write_yuv420_lines(yuv_src, width, stride);
442 }
443
444 y0 -= 2;
445 yuv_src[0] += stride << 1;
446 yuv_src[1] += stride >> 1;
447 yuv_src[2] += stride >> 1;
448 }
449 while (yuv_src[0] < ysrc_max);
450 lcd_write_reg(R_ENTRY_MODE,0x1008);
451}
452
453/* Update a fraction of the display. */
454void lcd_update_rect(int x0, int y0, int width, int height)
455{
456 const fb_data *addr;
457 int x1, y1;
458
459 if (!display_on)
460 return;
461
462 if ((width<=0)||(height<=0))
463 return;
464
465 if ((x0 + width)>=LCD_WIDTH)
466 width = LCD_WIDTH - x0;
467 if ((y0 + height)>=LCD_HEIGHT)
468 height = LCD_HEIGHT - y0;
469
470 y1 = (y0 + height) - 1;
471 x1 = (x0 + width) - 1;
472
473 /* In the PB Vibe LCD is flipped and the RAM addresses are decremented */
474 lcd_send_cmd(R_HORIZ_RAM_ADDR_POS);
475 lcd_send_data( (((LCD_HEIGHT-1)-y0) << 8) | ((LCD_HEIGHT-1)-y1));
476
477 lcd_send_cmd(R_VERT_RAM_ADDR_POS);
478 lcd_send_data( (((LCD_WIDTH -1)-x0) << 8) | ((LCD_WIDTH -1)-x1));
479
480 lcd_send_cmd(R_RAM_ADDR_SET);
481 lcd_send_data( (((LCD_WIDTH -1)-x0) << 8) | ((LCD_HEIGHT-1)-y0));
482
483 /* start drawing */
484 lcd_send_cmd(R_WRITE_DATA_2_GRAM);
485
486 addr = &lcd_framebuffer[y0][x0];
487
488 int c, r;
489 for (r = 0; r < height; r++)
490 {
491 for (c = 0; c < width; c++)
492 lcd_send_data_swapped(*addr++);
493 addr += LCD_WIDTH - width;
494 }
495}
496
497/* Update the display.
498 This must be called after all other LCD
499 functions that change the display. */
500void lcd_update(void)
501{
502 lcd_update_rect(0, 0, LCD_WIDTH, LCD_HEIGHT);
503}
diff --git a/firmware/target/arm/pbell/vibe500/power-vibe500.c b/firmware/target/arm/pbell/vibe500/power-vibe500.c
new file mode 100644
index 0000000000..e55c69e033
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/power-vibe500.c
@@ -0,0 +1,103 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2009 by Szymon Dziok
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 <stdbool.h>
25#include "kernel.h"
26#include "system.h"
27#include "power.h"
28#include "logf.h"
29#include "usb.h"
30#include "synaptics-mep.h"
31
32void power_init(void)
33{
34 GPIOD_ENABLE |= 0x80; /* enable ACK */
35 GPIOA_ENABLE |= (0x10 | 0x20); /* enable DATA, CLK */
36
37 GPIOD_OUTPUT_EN |= 0x80; /* set ACK */
38 GPIOD_OUTPUT_VAL |= 0x80; /* high */
39
40 GPIOA_OUTPUT_EN &= ~0x20; /* CLK */
41
42 GPIOA_OUTPUT_EN |= 0x10; /* set DATA */
43 GPIOA_OUTPUT_VAL |= 0x10; /* high */
44
45 if (!touchpad_init())
46 {
47 logf("touchpad not ready");
48 }
49 /* Sound unmute (on) */
50 GPIO_CLEAR_BITWISE(GPIOL_OUTPUT_VAL, 0x10);
51}
52
53unsigned int power_input_status(void)
54{
55 unsigned int status = POWER_INPUT_NONE;
56 /* GPIOL - external charger connected */
57 if (GPIOL_INPUT_VAL & 0x20)
58 status = POWER_INPUT_MAIN_CHARGER;
59 /* GPIOL - usb connected */
60 if (GPIOL_INPUT_VAL & 0x04)
61 status |= POWER_INPUT_USB_CHARGER;
62
63 return status;
64}
65
66void ide_power_enable(bool on)
67{
68 if(on){
69 GPIO_SET_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
70 DEV_EN |= DEV_IDE0;
71 } else
72 {
73 DEV_EN &= ~DEV_IDE0;
74 GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
75 }
76}
77
78bool ide_powered(void)
79{
80 return ((GPIOC_INPUT_VAL & 0x08) == 1);
81}
82
83void power_off(void)
84{
85 /* from the OF */
86/*
87 DEV_INIT2 |= DEV_I2S;
88 GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x10);
89 sleep(HZ/100);
90 GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x10);
91 sleep(HZ);
92 GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x80);
93 sleep(HZ);
94 GPIO_CLEAR_BITWISE(GPIOC_OUTPUT_VAL, 0x08);
95 GPO32_VAL |= 0x40000000;
96 GPO32_ENABLE |= 0x40000000;
97*/
98 /* Sound mute (off) */
99 DEV_INIT2 |= DEV_I2S;
100 GPIO_SET_BITWISE(GPIOL_OUTPUT_VAL, 0x10);
101 /* shutdown bit */
102 GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x80);
103}
diff --git a/firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c b/firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c
new file mode 100644
index 0000000000..d84881cea1
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/powermgmt-vibe500.c
@@ -0,0 +1,57 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2002 by Heikki Hannikainen, Uwe Freese
11 * Revisions copyright (C) 2005 by Gerald Van Baren
12 * Copyright (C) 2009 by Szymon Dziok
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
18 *
19 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
20 * KIND, either express or implied.
21 *
22 ****************************************************************************/
23
24#include "config.h"
25#include "adc.h"
26#include "powermgmt.h"
27
28const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
29{
30 3515
31};
32
33const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
34{
35 3486
36};
37
38/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
39const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
40{
41 { 3474, 3515, 3556, 3597, 3638, 3679, 3720, 3761, 3802, 3843, 3884 }
42};
43
44/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
45const unsigned short percent_to_volt_charge[11] =
46{
47 3474, 3515, 3556, 3597, 3638, 3679, 3720, 3761, 3802, 3843, 3884
48};
49
50#define BATTERY_SCALE_FACTOR 4200
51/* full-scale ADC readout (2^10) in millivolt */
52
53/* Returns battery voltage from ADC [millivolts] */
54unsigned int battery_adc_voltage(void)
55{
56 return (adc_read(ADC_UNREG_POWER) * BATTERY_SCALE_FACTOR) >> 10;
57}
diff --git a/firmware/target/arm/pbell/vibe500/usb-target.h b/firmware/target/arm/pbell/vibe500/usb-target.h
new file mode 100644
index 0000000000..a453a7cbfa
--- /dev/null
+++ b/firmware/target/arm/pbell/vibe500/usb-target.h
@@ -0,0 +1,29 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id:$
9 *
10 * Copyright (C) 2006 by Barry Wardell
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/* Based off x5 version */
23
24#ifndef USB_TARGET_H
25#define USB_TARGET_H
26
27bool usb_init_device(void);
28
29#endif