diff options
Diffstat (limited to 'firmware/target/arm/sandisk')
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/adc-e200.c | 92 | ||||
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/adc-target.h | 42 | ||||
-rw-r--r-- | firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | 255 |
3 files changed, 384 insertions, 5 deletions
diff --git a/firmware/target/arm/sandisk/sansa-e200/adc-e200.c b/firmware/target/arm/sandisk/sansa-e200/adc-e200.c new file mode 100644 index 0000000000..fbfa7d698a --- /dev/null +++ b/firmware/target/arm/sandisk/sansa-e200/adc-e200.c | |||
@@ -0,0 +1,92 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #include "config.h" | ||
20 | #include "cpu.h" | ||
21 | #include "system.h" | ||
22 | #include "kernel.h" | ||
23 | #include "thread.h" | ||
24 | #include "adc.h" | ||
25 | |||
26 | static unsigned short adcdata[NUM_ADC_CHANNELS]; | ||
27 | |||
28 | /* Scan ADC so that adcdata[channel] gets updated */ | ||
29 | unsigned short adc_scan(int channel) | ||
30 | { | ||
31 | unsigned int adc_data_1; | ||
32 | unsigned int adc_data_2; | ||
33 | |||
34 | /* Initialise */ | ||
35 | ADC_ADDR=0x130; | ||
36 | ADC_STATUS=0; /* 4 bytes, 1 per channel. Each byte is 0 if the channel is | ||
37 | off, 0x40 if the channel is on */ | ||
38 | |||
39 | /* Enable Channel */ | ||
40 | ADC_ADDR |= (0x1000000<<channel); | ||
41 | |||
42 | /* Start? */ | ||
43 | ADC_ADDR |= 0x20000000; | ||
44 | ADC_ADDR |= 0x80000000; | ||
45 | |||
46 | /* ADC_DATA_1 and ADC_DATA_2 are both four bytes, one byte per channel. | ||
47 | For each channel, ADC_DATA_1 stores the 8-bit msb, ADC_DATA_2 stores the | ||
48 | 2-bit lsb (in bits 0 and 1). Each channel is 10 bits total. */ | ||
49 | adc_data_1 = ((ADC_DATA_1 >> (8*channel)) & 0xff); | ||
50 | adc_data_2 = ((ADC_DATA_2 >> (8*channel+6)) & 0x3); | ||
51 | |||
52 | adcdata[channel] = (adc_data_1<<2 | adc_data_2); | ||
53 | |||
54 | return adcdata[channel]; | ||
55 | } | ||
56 | |||
57 | /* Read 10-bit channel data */ | ||
58 | unsigned short adc_read(int channel) | ||
59 | { | ||
60 | return adcdata[channel]; | ||
61 | } | ||
62 | |||
63 | static int adc_counter; | ||
64 | |||
65 | static void adc_tick(void) | ||
66 | { | ||
67 | if(++adc_counter == HZ) | ||
68 | { | ||
69 | adc_counter = 0; | ||
70 | adc_scan(ADC_0); | ||
71 | adc_scan(ADC_1); | ||
72 | adc_scan(ADC_2); | ||
73 | adc_scan(ADC_3); | ||
74 | } | ||
75 | } | ||
76 | |||
77 | void adc_init(void) | ||
78 | { | ||
79 | /* Enable ADC */ | ||
80 | ADC_ENABLE_ADDR |= ADC_ENABLE; | ||
81 | |||
82 | /* Initialise */ | ||
83 | ADC_INIT=0; | ||
84 | |||
85 | /* Force a scan of all channels to get initial values */ | ||
86 | adc_scan(ADC_0); | ||
87 | adc_scan(ADC_1); | ||
88 | adc_scan(ADC_2); | ||
89 | adc_scan(ADC_3); | ||
90 | |||
91 | tick_add_task(adc_tick); | ||
92 | } | ||
diff --git a/firmware/target/arm/sandisk/sansa-e200/adc-target.h b/firmware/target/arm/sandisk/sansa-e200/adc-target.h index a7b884767c..526f99e43b 100644 --- a/firmware/target/arm/sandisk/sansa-e200/adc-target.h +++ b/firmware/target/arm/sandisk/sansa-e200/adc-target.h | |||
@@ -1,4 +1,42 @@ | |||
1 | /* blank */ | 1 | /*************************************************************************** |
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2006 by Barry Wardell | ||
11 | * | ||
12 | * All files in this archive are subject to the GNU General Public License. | ||
13 | * See the file COPYING in the source tree root for full license agreement. | ||
14 | * | ||
15 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | * KIND, either express or implied. | ||
17 | * | ||
18 | ****************************************************************************/ | ||
19 | #ifndef _ADC_TARGET_H_ | ||
20 | #define _ADC_TARGET_H_ | ||
2 | 21 | ||
3 | #define ADC_UNREG_POWER 0 /* made up to let powermgmt.c compile */ | 22 | #define ADC_ENABLE_ADDR (*(volatile unsigned long*)(0x70000010)) |
23 | #define ADC_ENABLE 0x1100 | ||
4 | 24 | ||
25 | #define ADC_ADDR (*(volatile unsigned long*)(0x7000ad00)) | ||
26 | #define ADC_STATUS (*(volatile unsigned long*)(0x7000ad04)) | ||
27 | #define ADC_DATA_1 (*(volatile unsigned long*)(0x7000ad20)) | ||
28 | #define ADC_DATA_2 (*(volatile unsigned long*)(0x7000ad24)) | ||
29 | #define ADC_INIT (*(volatile unsigned long*)(0x7000ad2c)) | ||
30 | |||
31 | #define NUM_ADC_CHANNELS 4 | ||
32 | |||
33 | #define ADC_0 0 | ||
34 | #define ADC_1 1 | ||
35 | #define ADC_2 2 | ||
36 | #define ADC_3 3 | ||
37 | #define ADC_UNREG_POWER ADC_0 /* For compatibility */ | ||
38 | |||
39 | /* Force a scan now */ | ||
40 | unsigned short adc_scan(int channel); | ||
41 | |||
42 | #endif | ||
diff --git a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c index dedb196c70..2ee191faa5 100644 --- a/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c +++ b/firmware/target/arm/sandisk/sansa-e200/lcd-e200.c | |||
@@ -1,15 +1,264 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Rockbox driver for Sansa e200 LCDs | ||
11 | * | ||
12 | * Based on reverse engineering done my MrH | ||
13 | * | ||
14 | * Copyright (c) 2006 Daniel Ankers | ||
15 | * | ||
16 | * All files in this archive are subject to the GNU General Public License. | ||
17 | * See the file COPYING in the source tree root for full license agreement. | ||
18 | * | ||
19 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
20 | * KIND, either express or implied. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | #include "config.h" | ||
24 | #include "cpu.h" | ||
25 | #include "lcd.h" | ||
26 | #include "kernel.h" | ||
27 | #include "system.h" | ||
1 | 28 | ||
2 | void lcd_update(void) | 29 | #define LCD_DATA_IN_GPIO GPIOB_INPUT_VAL |
30 | #define LCD_DATA_IN_PIN 6 | ||
31 | |||
32 | #define LCD_DATA_OUT_GPIO GPIOB_OUTPUT_VAL | ||
33 | #define LCD_DATA_OUT_PIN 7 | ||
34 | |||
35 | #define LCD_CLOCK_GPIO GPIOB_OUTPUT_VAL | ||
36 | #define LCD_CLOCK_PIN 5 | ||
37 | |||
38 | #define LCD_CS_GPIO GPIOD_OUTPUT_VAL | ||
39 | #define LCD_CS_PIN 6 | ||
40 | |||
41 | #define LCD_REG_0 (*(volatile unsigned long *)(0xc2000000)) | ||
42 | #define LCD_REG_1 (*(volatile unsigned long *)(0xc2000004)) | ||
43 | #define LCD_REG_2 (*(volatile unsigned long *)(0xc2000008)) | ||
44 | #define LCD_REG_3 (*(volatile unsigned long *)(0xc200000c)) | ||
45 | #define LCD_REG_4 (*(volatile unsigned long *)(0xc2000010)) | ||
46 | #define LCD_REG_5 (*(volatile unsigned long *)(0xc2000014)) | ||
47 | #define LCD_REG_6 (*(volatile unsigned long *)(0xc2000018)) | ||
48 | #define LCD_REG_7 (*(volatile unsigned long *)(0xc200001c)) | ||
49 | #define LCD_REG_8 (*(volatile unsigned long *)(0xc2000020)) | ||
50 | #define LCD_REG_9 (*(volatile unsigned long *)(0xc2000024)) | ||
51 | #define LCD_FB_BASE_REG (*(volatile unsigned long *)(0xc2000028)) | ||
52 | |||
53 | static inline void lcd_init_gpio(void) | ||
54 | { | ||
55 | GPIOB_ENABLE |= (1<<7); | ||
56 | GPIOB_ENABLE |= (1<<5); | ||
57 | GPIOB_OUTPUT_EN |= (1<<7); | ||
58 | GPIOB_OUTPUT_EN |= (1<<5); | ||
59 | GPIOD_ENABLE |= (1<<6); | ||
60 | GPIOD_OUTPUT_EN |= (1<<6); | ||
61 | } | ||
62 | |||
63 | static inline void lcd_bus_idle(void) | ||
64 | { | ||
65 | LCD_CLOCK_GPIO |= (1 << LCD_CLOCK_PIN); | ||
66 | LCD_DATA_OUT_GPIO |= (1 << LCD_DATA_OUT_PIN); | ||
67 | } | ||
68 | |||
69 | static inline void lcd_send_byte(unsigned char byte) | ||
3 | { | 70 | { |
4 | 71 | ||
72 | int i; | ||
73 | |||
74 | for (i = 7; i >=0 ; i--) | ||
75 | { | ||
76 | LCD_CLOCK_GPIO &= ~(1 << LCD_CLOCK_PIN); | ||
77 | if ((byte >> i) & 1) | ||
78 | { | ||
79 | LCD_DATA_OUT_GPIO |= (1 << LCD_DATA_OUT_PIN); | ||
80 | } else { | ||
81 | LCD_DATA_OUT_GPIO &= ~(1 << LCD_DATA_OUT_PIN); | ||
82 | } | ||
83 | udelay(1); | ||
84 | LCD_CLOCK_GPIO |= (1 << LCD_CLOCK_PIN); | ||
85 | udelay(1); | ||
86 | lcd_bus_idle(); | ||
87 | udelay(3); | ||
88 | } | ||
89 | } | ||
90 | |||
91 | static inline void lcd_send_msg(unsigned char cmd, unsigned int data) | ||
92 | { | ||
93 | lcd_bus_idle(); | ||
94 | udelay(1); | ||
95 | LCD_CS_GPIO &= ~(1 << LCD_CS_PIN); | ||
96 | udelay(10); | ||
97 | lcd_send_byte(cmd); | ||
98 | lcd_send_byte((unsigned char)(data >> 8)); | ||
99 | lcd_send_byte((unsigned char)(data & 0xff)); | ||
100 | LCD_CS_GPIO |= (1 << LCD_CS_PIN); | ||
101 | udelay(1); | ||
102 | lcd_bus_idle(); | ||
103 | } | ||
104 | |||
105 | static inline void lcd_write_reg(unsigned int reg, unsigned int data) | ||
106 | { | ||
107 | lcd_send_msg(0x70, reg); | ||
108 | lcd_send_msg(0x72, data); | ||
109 | } | ||
110 | |||
111 | inline void lcd_init_device(void) | ||
112 | { | ||
113 | /* All this is magic worked out by MrH */ | ||
114 | |||
115 | /* Init GPIO ports */ | ||
116 | lcd_init_gpio(); | ||
117 | /* Controller init */ | ||
118 | outl((inl(0x70000084) | (1 << 28)), 0x70000084); | ||
119 | outl((inl(0x70000080) & ~(1 << 28)), 0x70000080); | ||
120 | outl(((inl(0x70000010) & (0x03ffffff)) | (0x15 << 26)), 0x70000010); | ||
121 | outl(((inl(0x70000014) & (0x0fffffff)) | (0x5 << 28)), 0x70000014); | ||
122 | outl((inl(0x70000020) & ~(0x3 << 10)), 0x70000020); | ||
123 | outl((inl(0x6000600c) | (1 << 26)), 0x6000600c); /* Enable controller */ | ||
124 | outl(0x6, 0x600060d0); | ||
125 | outl((inl(0x60006004) | (1 << 26)), 0x60006004); /* Reset controller? */ | ||
126 | outl((inl(0x70000020) & ~(1 << 14)), 0x70000020); | ||
127 | lcd_bus_idle(); | ||
128 | outl((inl(0x60006004) & ~(1 << 26)), 0x60006004); /* Clear reset? */ | ||
129 | udelay(1000); | ||
130 | |||
131 | LCD_REG_0 = (LCD_REG_0 & (0x00ffffff)) | (0x22 << 24); | ||
132 | LCD_REG_0 = (LCD_REG_0 & (0xff00ffff)) | (0x14 << 16); | ||
133 | LCD_REG_0 = (LCD_REG_0 & (0xffffc0ff)) | (0x3 << 8); | ||
134 | LCD_REG_0 = (LCD_REG_0 & (0xffffffc0)) | (0xa); | ||
135 | |||
136 | LCD_REG_1 &= 0x00ffffff; | ||
137 | LCD_REG_1 &= 0xff00ffff; | ||
138 | LCD_REG_1 = (LCD_REG_1 & 0xffff03ff) | (0x2 << 10); | ||
139 | LCD_REG_1 = (LCD_REG_1 & 0xfffffc00) | (0xdd); | ||
140 | |||
141 | LCD_REG_2 |= (1 << 5); | ||
142 | LCD_REG_2 |= (1 << 6); | ||
143 | LCD_REG_2 = (LCD_REG_2 & 0xfffffcff) | (0x2 << 8); | ||
144 | |||
145 | LCD_REG_7 &= (0xf800ffff); | ||
146 | LCD_REG_7 &= (0xfffff800); | ||
147 | |||
148 | LCD_REG_8 = (LCD_REG_8 & (0xf800ffff)) | (0xb0 << 16); | ||
149 | LCD_REG_8 = (LCD_REG_8 & (0xfffff800)) | (0xde); /* X-Y Geometry? */ | ||
150 | |||
151 | LCD_REG_5 |= 0xc; | ||
152 | LCD_REG_5 = (LCD_REG_5 & ~(0x70)) | (0x3 << 4); | ||
153 | LCD_REG_5 |= 2; | ||
154 | |||
155 | LCD_REG_6 &= ~(1 << 15); | ||
156 | LCD_REG_6 |= (0xe00); | ||
157 | LCD_REG_6 = (LCD_REG_6 & (0xffffff1f)) | (0x4 << 5); | ||
158 | LCD_REG_6 |= (1 << 4); | ||
159 | |||
160 | LCD_REG_5 &= ~(1 << 7); | ||
161 | LCD_FB_BASE_REG = (unsigned long)lcd_framebuffer; | ||
162 | |||
163 | udelay(100000); | ||
164 | |||
165 | /* LCD init */ | ||
166 | outl((inl(0x70000080) & ~(1 << 28)), 0x70000080); | ||
167 | udelay(10000); | ||
168 | outl((inl(0x70000080) | (1 << 28)), 0x70000080); | ||
169 | udelay(10000); | ||
170 | |||
171 | lcd_write_reg(16, 0x4444); | ||
172 | lcd_write_reg(17, 0x0001); | ||
173 | lcd_write_reg(18, 0x0003); | ||
174 | lcd_write_reg(19, 0x1119); | ||
175 | lcd_write_reg(18, 0x0013); | ||
176 | udelay(50000); | ||
177 | |||
178 | lcd_write_reg(16, 0x4440); | ||
179 | lcd_write_reg(19, 0x3119); | ||
180 | udelay(150000); | ||
181 | |||
182 | lcd_write_reg(1, 0x101b); | ||
183 | lcd_write_reg(2, 0x0700); | ||
184 | lcd_write_reg(3, 0x6020); | ||
185 | lcd_write_reg(4, 0x0000); | ||
186 | lcd_write_reg(5, 0x0000); | ||
187 | lcd_write_reg(8, 0x0102); | ||
188 | lcd_write_reg(9, 0x0000); | ||
189 | lcd_write_reg(11, 0x4400); | ||
190 | lcd_write_reg(12, 0x0110); | ||
191 | |||
192 | lcd_write_reg(64, 0x0000); | ||
193 | lcd_write_reg(65, 0x0000); | ||
194 | lcd_write_reg(66, (219 << 8)); /* Screen resolution? */ | ||
195 | lcd_write_reg(67, 0x0000); | ||
196 | lcd_write_reg(68, (175 << 8)); | ||
197 | lcd_write_reg(69, (219 << 8)); | ||
198 | |||
199 | lcd_write_reg(48, 0x0000); | ||
200 | lcd_write_reg(49, 0x0704); | ||
201 | lcd_write_reg(50, 0x0107); | ||
202 | lcd_write_reg(51, 0x0704); | ||
203 | lcd_write_reg(52, 0x0107); | ||
204 | lcd_write_reg(53, 0x0002); | ||
205 | lcd_write_reg(54, 0x0707); | ||
206 | lcd_write_reg(55, 0x0503); | ||
207 | lcd_write_reg(56, 0x0000); | ||
208 | lcd_write_reg(57, 0x0000); | ||
209 | |||
210 | lcd_write_reg(33, 175); | ||
211 | |||
212 | lcd_write_reg(12, 0x0110); | ||
213 | |||
214 | lcd_write_reg(16, 0x4740); | ||
215 | |||
216 | lcd_write_reg(7, 0x0045); | ||
217 | |||
218 | udelay(50000); | ||
219 | |||
220 | lcd_write_reg(7, 0x0065); | ||
221 | lcd_write_reg(7, 0x0067); | ||
222 | |||
223 | udelay(50000); | ||
224 | |||
225 | lcd_write_reg(7, 0x0077); | ||
226 | lcd_send_msg(0x70, 34); | ||
5 | } | 227 | } |
6 | 228 | ||
7 | void lcd_update_rect(int x, int y, int width, int height) | 229 | inline void lcd_update(void) |
8 | { | 230 | { |
231 | if(!(LCD_REG_6 & 1)) | ||
232 | LCD_REG_6 |= 1; | ||
233 | } | ||
9 | 234 | ||
235 | inline void lcd_update_rect(int x, int y, int width, int height) | ||
236 | { | ||
237 | (void) x; | ||
238 | (void) y; | ||
239 | (void) width; | ||
240 | (void) height; | ||
241 | lcd_update(); | ||
10 | } | 242 | } |
11 | 243 | ||
12 | void lcd_init_device(void) | 244 | |
245 | /*** hardware configuration ***/ | ||
246 | |||
247 | void lcd_set_contrast(int val) | ||
248 | { | ||
249 | /* TODO: Implement lcd_set_contrast() */ | ||
250 | (void)val; | ||
251 | } | ||
252 | |||
253 | void lcd_set_invert_display(bool yesno) | ||
13 | { | 254 | { |
255 | /* TODO: Implement lcd_set_invert_display() */ | ||
256 | (void)yesno; | ||
257 | } | ||
14 | 258 | ||
259 | /* turn the display upside down (call lcd_update() afterwards) */ | ||
260 | void lcd_set_flip(bool yesno) | ||
261 | { | ||
262 | /* TODO: Implement lcd_set_flip() */ | ||
263 | (void)yesno; | ||
15 | } | 264 | } |