summaryrefslogtreecommitdiff
path: root/firmware/target/arm/sandisk
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/sandisk')
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/adc-e200.c92
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/adc-target.h42
-rw-r--r--firmware/target/arm/sandisk/sansa-e200/lcd-e200.c255
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
26static unsigned short adcdata[NUM_ADC_CHANNELS];
27
28/* Scan ADC so that adcdata[channel] gets updated */
29unsigned 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 */
58unsigned short adc_read(int channel)
59{
60 return adcdata[channel];
61}
62
63static int adc_counter;
64
65static 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
77void 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 */
40unsigned 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
2void 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
53static 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
63static 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
69static 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
91static 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
105static 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
111inline 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
7void lcd_update_rect(int x, int y, int width, int height) 229inline void lcd_update(void)
8{ 230{
231 if(!(LCD_REG_6 & 1))
232 LCD_REG_6 |= 1;
233}
9 234
235inline 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
12void lcd_init_device(void) 244
245/*** hardware configuration ***/
246
247void lcd_set_contrast(int val)
248{
249 /* TODO: Implement lcd_set_contrast() */
250 (void)val;
251}
252
253void 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) */
260void lcd_set_flip(bool yesno)
261{
262 /* TODO: Implement lcd_set_flip() */
263 (void)yesno;
15} 264}