summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/screens.c7
-rw-r--r--firmware/SOURCES2
-rw-r--r--firmware/drivers/adc.c42
-rw-r--r--firmware/drivers/i2c-pp5020.c1
-rw-r--r--firmware/drivers/pcf50605.c46
-rw-r--r--firmware/drivers/power.c3
-rw-r--r--firmware/drivers/rtc.c50
-rw-r--r--firmware/drivers/wm8758.c22
-rw-r--r--firmware/export/adc.h8
-rw-r--r--firmware/export/config-ipodvideo.h4
-rw-r--r--firmware/export/pcf50605.h5
11 files changed, 124 insertions, 66 deletions
diff --git a/apps/screens.c b/apps/screens.c
index 634d5cf8d1..d01d2acb41 100644
--- a/apps/screens.c
+++ b/apps/screens.c
@@ -300,6 +300,11 @@ void charging_display_info(bool animate)
300 2 if Off/Stop key was pressed 300 2 if Off/Stop key was pressed
301 3 if On key was pressed 301 3 if On key was pressed
302 4 if USB was connected */ 302 4 if USB was connected */
303#if (CONFIG_KEYPAD==IPOD_3G_PAD) || (CONFIG_KEYPAD==IPOD_4G_PAD)
304# define CHARGE_SCREEN_RESUME BUTTON_SELECT
305#else
306# define CHARGE_SCREEN_RESUME BUTTON_ON
307#endif
303int charging_screen(void) 308int charging_screen(void)
304{ 309{
305 unsigned int button; 310 unsigned int button;
@@ -325,7 +330,7 @@ int charging_screen(void)
325 gui_syncstatusbar_draw(&statusbars, false); 330 gui_syncstatusbar_draw(&statusbars, false);
326 charging_display_info(true); 331 charging_display_info(true);
327 button = button_get_w_tmo(HZ/3); 332 button = button_get_w_tmo(HZ/3);
328 if (button == BUTTON_ON) 333 if (button == CHARGE_SCREEN_RESUME)
329 rc = 2; 334 rc = 2;
330 else if (usb_detect()) 335 else if (usb_detect())
331 rc = 3; 336 rc = 3;
diff --git a/firmware/SOURCES b/firmware/SOURCES
index 7ebfba38e1..f09c7d1aab 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -134,7 +134,7 @@ drivers/pcf50606.c
134#ifdef IPOD_ARCH 134#ifdef IPOD_ARCH
135drivers/pcf50605.c 135drivers/pcf50605.c
136#endif 136#endif
137#if (CONFIG_RTC == RTC_M41ST84W) || (CONFIG_RTC == RTC_PCF50606) 137#if (CONFIG_RTC == RTC_M41ST84W) || (CONFIG_RTC == RTC_PCF50606) || (CONFIG_RTC == RTC_PCF50605)
138drivers/rtc.c 138drivers/rtc.c
139#endif 139#endif
140drivers/serial.c 140drivers/serial.c
diff --git a/firmware/drivers/adc.c b/firmware/drivers/adc.c
index 6e1c57766a..1755fafb99 100644
--- a/firmware/drivers/adc.c
+++ b/firmware/drivers/adc.c
@@ -22,6 +22,7 @@
22#include "kernel.h" 22#include "kernel.h"
23#include "thread.h" 23#include "thread.h"
24#include "adc.h" 24#include "adc.h"
25#include "pcf50605.h"
25#include "pcf50606.h" 26#include "pcf50606.h"
26 27
27#if CONFIG_CPU == SH7034 28#if CONFIG_CPU == SH7034
@@ -119,7 +120,7 @@ static int channelnum[] =
119 2, /* ADC_REMOTEDETECT (ADCIN1, resistive divider) */ 120 2, /* ADC_REMOTEDETECT (ADCIN1, resistive divider) */
120}; 121};
121 122
122unsigned char adc_scan(int channel) 123unsigned short adc_scan(int channel)
123{ 124{
124 unsigned char data; 125 unsigned char data;
125 126
@@ -143,7 +144,7 @@ unsigned char adc_scan(int channel)
143/* delay loop */ 144/* delay loop */
144#define DELAY do { int _x; for(_x=0;_x<10;_x++);} while (0) 145#define DELAY do { int _x; for(_x=0;_x<10;_x++);} while (0)
145 146
146unsigned char adc_scan(int channel) 147unsigned short adc_scan(int channel)
147{ 148{
148 unsigned char data = 0; 149 unsigned char data = 0;
149 int i; 150 int i;
@@ -220,8 +221,7 @@ static void adc_tick(void)
220 221
221void adc_init(void) 222void adc_init(void)
222{ 223{
223#ifdef IRIVER_H300_SERIES 224#ifndef IRIVER_H300_SERIES
224#else
225 or_l(0x80600080, &GPIO_FUNCTION); /* GPIO7: CS 225 or_l(0x80600080, &GPIO_FUNCTION); /* GPIO7: CS
226 GPIO21: Data In (to the ADC) 226 GPIO21: Data In (to the ADC)
227 GPIO22: CLK 227 GPIO22: CLK
@@ -284,17 +284,45 @@ void adc_init(void)
284 284
285#elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002) 285#elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002)
286 286
287/* TODO: Implement adc.c */ 287struct adc_struct {
288 long last_read;
289 int channelnum;
290 unsigned short data;
291};
292
293static struct adc_struct adcdata[NUM_ADC_CHANNELS];
294
295static unsigned short adc_scan(struct adc_struct *adc)
296{
297 /* Disable interrupts during the I2C transaction */
298 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
299 unsigned short data = pcf50605_a2d_read(adc->channelnum);
300 set_irq_level(old_irq_level);
301 /* This gives us a 13 bit value corresponding to 0-5.4 volts
302 * The range of the value is 13FB-17FA */
303 data = (data<<2)+0x13FB;
304 adc->data = data;
305
306 return data;
307}
288 308
289unsigned short adc_read(int channel) 309unsigned short adc_read(int channel)
290{ 310{
291 (void)channel; 311 struct adc_struct *adc = &adcdata[channel];
292 return 0; 312 if (adc->last_read + HZ < current_tick) {
313 adc->last_read = current_tick;
314 return adc_scan(adc);
315 } else {
316 return adcdata[channel].data;
317 }
293} 318}
294 319
295void adc_init(void) 320void adc_init(void)
296{ 321{
322 struct adc_struct *adc_battery = &adcdata[ADC_BATTERY];
323 adc_battery->channelnum = 0x3; /* ADCVIN1, subtractor */
297 324
325 adc_scan(adc_battery);
298} 326}
299 327
300#elif CONFIG_CPU == PNX0101 328#elif CONFIG_CPU == PNX0101
diff --git a/firmware/drivers/i2c-pp5020.c b/firmware/drivers/i2c-pp5020.c
index 9f26d3be6e..522ddbed77 100644
--- a/firmware/drivers/i2c-pp5020.c
+++ b/firmware/drivers/i2c-pp5020.c
@@ -57,7 +57,6 @@ static int ipod_i2c_wait_not_busy(void)
57 if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) { 57 if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) {
58 return 0; 58 return 0;
59 } 59 }
60 yield();
61 } 60 }
62 61
63 return -1; 62 return -1;
diff --git a/firmware/drivers/pcf50605.c b/firmware/drivers/pcf50605.c
index 122ba6ee38..7d2036e807 100644
--- a/firmware/drivers/pcf50605.c
+++ b/firmware/drivers/pcf50605.c
@@ -98,22 +98,12 @@ int pcf50605_write_multiple(int address, const unsigned char* buf, int count)
98 return 0; 98 return 0;
99} 99}
100 100
101static int pcf50605_a2d_read(int adc_input) 101unsigned short pcf50605_a2d_read(int adc_input)
102{ 102{
103 int hi, lo; 103 unsigned short hi;
104 unsigned char lo;
104 105
105 /* Enable ACD module */
106 ipod_i2c_send(0x8, 0x33, 0x80); /* ACDC1, ACDAPE = 1 */
107
108 /* select ADCIN1 - subtractor, and start sampling process */
109 ipod_i2c_send(0x8, 0x2f, (adc_input<<1) | 0x1); /* ADCC2, ADCMUX = adc_input, ADCSTART = 1 */ 106 ipod_i2c_send(0x8, 0x2f, (adc_input<<1) | 0x1); /* ADCC2, ADCMUX = adc_input, ADCSTART = 1 */
110
111 /* ADCC2, wait for ADCSTART = 0 (wait for sampling to start) */
112 while ((i2c_readbyte(0x8, 0x2f) & 1)) /* do nothing */;
113
114 /* ADCS2, wait ADCRDY = 0 (wait for sampling to end) */
115 while (!(i2c_readbyte(0x8, 0x31) & 0x80)) /* do nothing */;
116
117 hi = i2c_readbyte(0x8, 0x30); /* ADCS1 */ 107 hi = i2c_readbyte(0x8, 0x30); /* ADCS1 */
118 lo = (i2c_readbyte(0x8, 0x31) & 0x3); /* ADCS2 */ 108 lo = (i2c_readbyte(0x8, 0x31) & 0x3); /* ADCS2 */
119 109
@@ -129,33 +119,3 @@ void pcf50605_standby_mode(void)
129 pcf50605_write(OOCC1, GOSTDBY | CHGWAK | EXTONWAK); 119 pcf50605_write(OOCC1, GOSTDBY | CHGWAK | EXTONWAK);
130} 120}
131 121
132int pcf50605_battery_read(void)
133{
134 return pcf50605_a2d_read(0x3); /* ADCIN1, subtractor */
135}
136
137void rtc_init(void)
138{
139 /* Nothing to do. */
140}
141
142int rtc_read_datetime(unsigned char* buf)
143{
144 int rc;
145
146 rc = pcf50605_read_multiple(0x0a, buf, 7);
147
148 return rc;
149}
150
151
152int rtc_write_datetime(unsigned char* buf)
153{
154 int i;
155
156 for (i=0;i<7;i++) {
157 ipod_i2c_send(0x8, 0x0a+i, buf[i]);
158 }
159
160 return 1;
161}
diff --git a/firmware/drivers/power.c b/firmware/drivers/power.c
index c6d49f5aa9..9f3a10cc84 100644
--- a/firmware/drivers/power.c
+++ b/firmware/drivers/power.c
@@ -123,6 +123,9 @@ bool charger_inserted(void)
123 return (adc_read(ADC_CHARGE_REGULATOR) < 0x1FF); 123 return (adc_read(ADC_CHARGE_REGULATOR) < 0x1FF);
124#elif defined(TOSHIBA_GIGABEAT_F) 124#elif defined(TOSHIBA_GIGABEAT_F)
125 return false; 125 return false;
126#elif defined(IPOD_ARCH)
127 /* We need to get this value a faster way than i2c */
128 return false;
126#else 129#else
127 /* Player */ 130 /* Player */
128 return (PADR & 1) == 0; 131 return (PADR & 1) == 0;
diff --git a/firmware/drivers/rtc.c b/firmware/drivers/rtc.c
index 0e6d68eb1a..6458092348 100644
--- a/firmware/drivers/rtc.c
+++ b/firmware/drivers/rtc.c
@@ -23,24 +23,62 @@
23#include "kernel.h" 23#include "kernel.h"
24#include "system.h" 24#include "system.h"
25#include "pcf50606.h" 25#include "pcf50606.h"
26#include "pcf50605.h"
26#include <stdbool.h> 27#include <stdbool.h>
27 28
28#define RTC_ADR 0xd0 29#define RTC_ADR 0xd0
29#define RTC_DEV_WRITE (RTC_ADR | 0x00) 30#define RTC_DEV_WRITE (RTC_ADR | 0x00)
30#define RTC_DEV_READ (RTC_ADR | 0x01) 31#define RTC_DEV_READ (RTC_ADR | 0x01)
31 32
32#if CONFIG_RTC == RTC_PCF50606 33#if CONFIG_RTC == RTC_PCF50605
33void rtc_init(void) 34void rtc_init(void)
34{ 35{
35} 36}
36int rtc_read_datetime(unsigned char* buf) { 37int rtc_read_datetime(unsigned char* buf)
38{
37 int rc; 39 int rc;
38 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL); 40 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
39
40 rc = pcf50606_read_multiple(0x0a, buf, 7);
41 41
42 set_irq_level(oldlevel); 42 rc = pcf50605_read_multiple(0x0a, buf, 7);
43
44 set_irq_level(old_irq_level);
45
46 return rc;
47}
48
49
50int rtc_write_datetime(unsigned char* buf)
51{
52 int i;
53 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
54
55 for (i=0;i<7;i++) {
56 pcf50605_write(0x0a+i, buf[i]);
57 }
58
59 set_irq_level(old_irq_level);
60
61 return 1;
62}
63#elif CONFIG_RTC == RTC_PCF50606
64static int last_tick;
65static char rtc_buf[7];
66void rtc_init(void)
67{
68 last_tick = 0;
69}
43 70
71int rtc_read_datetime(unsigned char* buf) {
72 int rc;
73 if (last_tick + HZ/2 < current_tick) {
74 int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
75 last_tick = current_tick;
76 rc = pcf50606_read_multiple(0x0a, rtc_buf, 7);
77 set_irq_level(oldlevel);
78 } else {
79 rc = 7;
80 }
81 memcpy(buf, rtc_buf, 7);
44 return rc; 82 return rc;
45} 83}
46 84
diff --git a/firmware/drivers/wm8758.c b/firmware/drivers/wm8758.c
index aec6f3b598..7c9ac77395 100644
--- a/firmware/drivers/wm8758.c
+++ b/firmware/drivers/wm8758.c
@@ -86,8 +86,7 @@ void wm8758_write(int reg, int data)
86 * Note, I'm using the WM8750 datasheet as its apparently close. 86 * Note, I'm using the WM8750 datasheet as its apparently close.
87 */ 87 */
88int wmcodec_init(void) { 88int wmcodec_init(void) {
89 /* reset I2C */ 89 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
90 i2c_init();
91 90
92 /* normal outputs for CDI and I2S pin groups */ 91 /* normal outputs for CDI and I2S pin groups */
93 outl(inl(0x70000020) & ~0x300, 0x70000020); 92 outl(inl(0x70000020) & ~0x300, 0x70000020);
@@ -109,6 +108,7 @@ int wmcodec_init(void) {
109 /* external dev clock to 24MHz */ 108 /* external dev clock to 24MHz */
110 outl(inl(0x70000018) & ~0xc, 0x70000018); 109 outl(inl(0x70000018) & ~0xc, 0x70000018);
111 110
111 set_irq_level(old_irq_level);
112 return 0; 112 return 0;
113} 113}
114 114
@@ -117,6 +117,8 @@ void wmcodec_enable_output(bool enable)
117{ 117{
118 if (enable) 118 if (enable)
119 { 119 {
120 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
121
120 /* reset the I2S controller into known state */ 122 /* reset the I2S controller into known state */
121 i2s_reset(); 123 i2s_reset();
122 124
@@ -140,6 +142,7 @@ void wmcodec_enable_output(bool enable)
140 wm8758_write(LOUTMIX,0x1); /* Enable mixer */ 142 wm8758_write(LOUTMIX,0x1); /* Enable mixer */
141 wm8758_write(ROUTMIX,0x1); /* Enable mixer */ 143 wm8758_write(ROUTMIX,0x1); /* Enable mixer */
142 wmcodec_mute(0); 144 wmcodec_mute(0);
145 set_irq_level(old_irq_level);
143 } else { 146 } else {
144 wmcodec_mute(1); 147 wmcodec_mute(1);
145 } 148 }
@@ -147,6 +150,7 @@ void wmcodec_enable_output(bool enable)
147 150
148int wmcodec_set_master_vol(int vol_l, int vol_r) 151int wmcodec_set_master_vol(int vol_l, int vol_r)
149{ 152{
153 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
150 /* OUT1 */ 154 /* OUT1 */
151 wm8758_write(LOUT1VOL, vol_l); 155 wm8758_write(LOUT1VOL, vol_l);
152 wm8758_write(ROUT1VOL, 0x100 | vol_r); 156 wm8758_write(ROUT1VOL, 0x100 | vol_r);
@@ -154,6 +158,8 @@ int wmcodec_set_master_vol(int vol_l, int vol_r)
154 /* OUT2 */ 158 /* OUT2 */
155 wm8758_write(LOUT2VOL, vol_l); 159 wm8758_write(LOUT2VOL, vol_l);
156 wm8758_write(ROUT2VOL, 0x100 | vol_r); 160 wm8758_write(ROUT2VOL, 0x100 | vol_r);
161
162 set_irq_level(old_irq_level);
157 163
158 return 0; 164 return 0;
159} 165}
@@ -198,6 +204,8 @@ void wmcodec_set_treble(int value)
198 204
199int wmcodec_mute(int mute) 205int wmcodec_mute(int mute)
200{ 206{
207 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
208
201 if (mute) 209 if (mute)
202 { 210 {
203 /* Set DACMU = 1 to soft-mute the audio DACs. */ 211 /* Set DACMU = 1 to soft-mute the audio DACs. */
@@ -207,12 +215,16 @@ int wmcodec_mute(int mute)
207 wm8758_write(DACCTRL, 0x0); 215 wm8758_write(DACCTRL, 0x0);
208 } 216 }
209 217
218 set_irq_level(old_irq_level);
219
210 return 0; 220 return 0;
211} 221}
212 222
213/* Nice shutdown of WM8758 codec */ 223/* Nice shutdown of WM8758 codec */
214void wmcodec_close(void) 224void wmcodec_close(void)
215{ 225{
226 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
227
216 wmcodec_mute(1); 228 wmcodec_mute(1);
217 229
218 wm8758_write(PWRMGMT3, 0x0); 230 wm8758_write(PWRMGMT3, 0x0);
@@ -220,6 +232,8 @@ void wmcodec_close(void)
220 wm8758_write(PWRMGMT1, 0x0); 232 wm8758_write(PWRMGMT1, 0x0);
221 233
222 wm8758_write(PWRMGMT2, 0x40); 234 wm8758_write(PWRMGMT2, 0x40);
235
236 set_irq_level(old_irq_level);
223} 237}
224 238
225/* Change the order of the noise shaper, 5th order is recommended above 32kHz */ 239/* Change the order of the noise shaper, 5th order is recommended above 32kHz */
@@ -231,6 +245,8 @@ void wmcodec_set_nsorder(int order)
231/* Note: Disable output before calling this function */ 245/* Note: Disable output before calling this function */
232void wmcodec_set_sample_rate(int sampling_control) 246void wmcodec_set_sample_rate(int sampling_control)
233{ 247{
248 int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
249
234 /**** We force 44.1KHz for now. ****/ 250 /**** We force 44.1KHz for now. ****/
235 (void)sampling_control; 251 (void)sampling_control;
236 252
@@ -248,6 +264,8 @@ void wmcodec_set_sample_rate(int sampling_control)
248 264
249 /* set srate */ 265 /* set srate */
250 wm8758_write(SRATECTRL, (0 << 1)); 266 wm8758_write(SRATECTRL, (0 << 1));
267
268 set_irq_level(old_irq_level);
251} 269}
252 270
253void wmcodec_enable_recording(bool source_mic) 271void wmcodec_enable_recording(bool source_mic)
diff --git a/firmware/export/adc.h b/firmware/export/adc.h
index 454c102403..b0a83d9bd0 100644
--- a/firmware/export/adc.h
+++ b/firmware/export/adc.h
@@ -29,6 +29,12 @@
29#define ADC_BATTERY 2 29#define ADC_BATTERY 2
30#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */ 30#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
31 31
32#elif defined(IPOD_ARCH)
33#define NUM_ADC_CHANNELS 1
34
35#define ADC_BATTERY 0
36#define ADC_UNREG_POWER ADC_BATTERY
37
32#elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES) 38#elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
33#define NUM_ADC_CHANNELS 4 39#define NUM_ADC_CHANNELS 4
34 40
@@ -94,7 +100,7 @@ void adc_init(void);
94 100
95#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)\ 101#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)\
96 || defined(IAUDIO_X5) 102 || defined(IAUDIO_X5)
97unsigned char adc_scan(int channel); 103unsigned short adc_scan(int channel);
98#endif 104#endif
99 105
100#endif 106#endif
diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h
index 2bf0396a21..1fa778dbc4 100644
--- a/firmware/export/config-ipodvideo.h
+++ b/firmware/export/config-ipodvideo.h
@@ -59,9 +59,9 @@
59#define CONFIG_I2C I2C_PP5020 59#define CONFIG_I2C I2C_PP5020
60 60
61/* Type of mobile power */ 61/* Type of mobile power */
62//#define CONFIG_BATTERY BATT_LIPOL1300 62#define CONFIG_BATTERY BATT_LIPOL1300
63 63
64#define BATTERY_SCALE_FACTOR 16665 /* FIX: this value is picked at random */ 64#define BATTERY_SCALE_FACTOR 586 /* FIX: this value is picked at random */
65 65
66/* Define this if the platform can charge batteries */ 66/* Define this if the platform can charge batteries */
67//#define HAVE_CHARGING 1 67//#define HAVE_CHARGING 1
diff --git a/firmware/export/pcf50605.h b/firmware/export/pcf50605.h
index 95fcaff8fb..4ea1379e4a 100644
--- a/firmware/export/pcf50605.h
+++ b/firmware/export/pcf50605.h
@@ -22,10 +22,11 @@
22 22
23#ifdef IPOD_ARCH 23#ifdef IPOD_ARCH
24int pcf50605_read(int address); 24int pcf50605_read(int address);
25void pcf50605_read_multiple(int address, unsigned char* buf, int count); 25int pcf50605_read_multiple(int address, unsigned char* buf, int count);
26int pcf50605_write(int address, unsigned char val); 26int pcf50605_write(int address, unsigned char val);
27int pcf50605_write_multiple(int address, const unsigned char* buf, int count); 27int pcf50605_write_multiple(int address, const unsigned char* buf, int count);
28int pcf50605_battery_read(void); 28int pcf50605_a2d_read(int channel);
29bool pcf50605_charger_inserted(void);
29void pcf50605_standby_mode(void); 30void pcf50605_standby_mode(void);
30#endif 31#endif
31 32