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)
2 if Off/Stop key was pressed
3 if On key was pressed
4 if USB was connected */
+#if (CONFIG_KEYPAD==IPOD_3G_PAD) || (CONFIG_KEYPAD==IPOD_4G_PAD)
+# define CHARGE_SCREEN_RESUME BUTTON_SELECT
+#else
+# define CHARGE_SCREEN_RESUME BUTTON_ON
+#endif
int charging_screen(void)
{
unsigned int button;
@@ -325,7 +330,7 @@ int charging_screen(void)
gui_syncstatusbar_draw(&statusbars, false);
charging_display_info(true);
button = button_get_w_tmo(HZ/3);
- if (button == BUTTON_ON)
+ if (button == CHARGE_SCREEN_RESUME)
rc = 2;
else if (usb_detect())
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
#ifdef IPOD_ARCH
drivers/pcf50605.c
#endif
-#if (CONFIG_RTC == RTC_M41ST84W) || (CONFIG_RTC == RTC_PCF50606)
+#if (CONFIG_RTC == RTC_M41ST84W) || (CONFIG_RTC == RTC_PCF50606) || (CONFIG_RTC == RTC_PCF50605)
drivers/rtc.c
#endif
drivers/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 @@
#include "kernel.h"
#include "thread.h"
#include "adc.h"
+#include "pcf50605.h"
#include "pcf50606.h"
#if CONFIG_CPU == SH7034
@@ -119,7 +120,7 @@ static int channelnum[] =
2, /* ADC_REMOTEDETECT (ADCIN1, resistive divider) */
};
-unsigned char adc_scan(int channel)
+unsigned short adc_scan(int channel)
{
unsigned char data;
@@ -143,7 +144,7 @@ unsigned char adc_scan(int channel)
/* delay loop */
#define DELAY do { int _x; for(_x=0;_x<10;_x++);} while (0)
-unsigned char adc_scan(int channel)
+unsigned short adc_scan(int channel)
{
unsigned char data = 0;
int i;
@@ -220,8 +221,7 @@ static void adc_tick(void)
void adc_init(void)
{
-#ifdef IRIVER_H300_SERIES
-#else
+#ifndef IRIVER_H300_SERIES
or_l(0x80600080, &GPIO_FUNCTION); /* GPIO7: CS
GPIO21: Data In (to the ADC)
GPIO22: CLK
@@ -284,17 +284,45 @@ void adc_init(void)
#elif CONFIG_CPU == PP5020 || (CONFIG_CPU == PP5002)
-/* TODO: Implement adc.c */
+struct adc_struct {
+ long last_read;
+ int channelnum;
+ unsigned short data;
+};
+
+static struct adc_struct adcdata[NUM_ADC_CHANNELS];
+
+static unsigned short adc_scan(struct adc_struct *adc)
+{
+ /* Disable interrupts during the I2C transaction */
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
+ unsigned short data = pcf50605_a2d_read(adc->channelnum);
+ set_irq_level(old_irq_level);
+ /* This gives us a 13 bit value corresponding to 0-5.4 volts
+ * The range of the value is 13FB-17FA */
+ data = (data<<2)+0x13FB;
+ adc->data = data;
+
+ return data;
+}
unsigned short adc_read(int channel)
{
- (void)channel;
- return 0;
+ struct adc_struct *adc = &adcdata[channel];
+ if (adc->last_read + HZ < current_tick) {
+ adc->last_read = current_tick;
+ return adc_scan(adc);
+ } else {
+ return adcdata[channel].data;
+ }
}
void adc_init(void)
{
+ struct adc_struct *adc_battery = &adcdata[ADC_BATTERY];
+ adc_battery->channelnum = 0x3; /* ADCVIN1, subtractor */
+ adc_scan(adc_battery);
}
#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)
if (!(inb(IPOD_I2C_STATUS) & IPOD_I2C_BUSY)) {
return 0;
}
- yield();
}
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)
return 0;
}
-static int pcf50605_a2d_read(int adc_input)
+unsigned short pcf50605_a2d_read(int adc_input)
{
- int hi, lo;
+ unsigned short hi;
+ unsigned char lo;
- /* Enable ACD module */
- ipod_i2c_send(0x8, 0x33, 0x80); /* ACDC1, ACDAPE = 1 */
-
- /* select ADCIN1 - subtractor, and start sampling process */
ipod_i2c_send(0x8, 0x2f, (adc_input<<1) | 0x1); /* ADCC2, ADCMUX = adc_input, ADCSTART = 1 */
-
- /* ADCC2, wait for ADCSTART = 0 (wait for sampling to start) */
- while ((i2c_readbyte(0x8, 0x2f) & 1)) /* do nothing */;
-
- /* ADCS2, wait ADCRDY = 0 (wait for sampling to end) */
- while (!(i2c_readbyte(0x8, 0x31) & 0x80)) /* do nothing */;
-
hi = i2c_readbyte(0x8, 0x30); /* ADCS1 */
lo = (i2c_readbyte(0x8, 0x31) & 0x3); /* ADCS2 */
@@ -129,33 +119,3 @@ void pcf50605_standby_mode(void)
pcf50605_write(OOCC1, GOSTDBY | CHGWAK | EXTONWAK);
}
-int pcf50605_battery_read(void)
-{
- return pcf50605_a2d_read(0x3); /* ADCIN1, subtractor */
-}
-
-void rtc_init(void)
-{
- /* Nothing to do. */
-}
-
-int rtc_read_datetime(unsigned char* buf)
-{
- int rc;
-
- rc = pcf50605_read_multiple(0x0a, buf, 7);
-
- return rc;
-}
-
-
-int rtc_write_datetime(unsigned char* buf)
-{
- int i;
-
- for (i=0;i<7;i++) {
- ipod_i2c_send(0x8, 0x0a+i, buf[i]);
- }
-
- return 1;
-}
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)
return (adc_read(ADC_CHARGE_REGULATOR) < 0x1FF);
#elif defined(TOSHIBA_GIGABEAT_F)
return false;
+#elif defined(IPOD_ARCH)
+ /* We need to get this value a faster way than i2c */
+ return false;
#else
/* Player */
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 @@
#include "kernel.h"
#include "system.h"
#include "pcf50606.h"
+#include "pcf50605.h"
#include <stdbool.h>
#define RTC_ADR 0xd0
#define RTC_DEV_WRITE (RTC_ADR | 0x00)
#define RTC_DEV_READ (RTC_ADR | 0x01)
-#if CONFIG_RTC == RTC_PCF50606
+#if CONFIG_RTC == RTC_PCF50605
void rtc_init(void)
{
}
-int rtc_read_datetime(unsigned char* buf) {
+int rtc_read_datetime(unsigned char* buf)
+{
int rc;
- int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
-
- rc = pcf50606_read_multiple(0x0a, buf, 7);
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
- set_irq_level(oldlevel);
+ rc = pcf50605_read_multiple(0x0a, buf, 7);
+
+ set_irq_level(old_irq_level);
+
+ return rc;
+}
+
+
+int rtc_write_datetime(unsigned char* buf)
+{
+ int i;
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
+ for (i=0;i<7;i++) {
+ pcf50605_write(0x0a+i, buf[i]);
+ }
+
+ set_irq_level(old_irq_level);
+
+ return 1;
+}
+#elif CONFIG_RTC == RTC_PCF50606
+static int last_tick;
+static char rtc_buf[7];
+void rtc_init(void)
+{
+ last_tick = 0;
+}
+int rtc_read_datetime(unsigned char* buf) {
+ int rc;
+ if (last_tick + HZ/2 < current_tick) {
+ int oldlevel = set_irq_level(HIGHEST_IRQ_LEVEL);
+ last_tick = current_tick;
+ rc = pcf50606_read_multiple(0x0a, rtc_buf, 7);
+ set_irq_level(oldlevel);
+ } else {
+ rc = 7;
+ }
+ memcpy(buf, rtc_buf, 7);
return rc;
}
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)
* Note, I'm using the WM8750 datasheet as its apparently close.
*/
int wmcodec_init(void) {
- /* reset I2C */
- i2c_init();
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
/* normal outputs for CDI and I2S pin groups */
outl(inl(0x70000020) & ~0x300, 0x70000020);
@@ -109,6 +108,7 @@ int wmcodec_init(void) {
/* external dev clock to 24MHz */
outl(inl(0x70000018) & ~0xc, 0x70000018);
+ set_irq_level(old_irq_level);
return 0;
}
@@ -117,6 +117,8 @@ void wmcodec_enable_output(bool enable)
{
if (enable)
{
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
/* reset the I2S controller into known state */
i2s_reset();
@@ -140,6 +142,7 @@ void wmcodec_enable_output(bool enable)
wm8758_write(LOUTMIX,0x1); /* Enable mixer */
wm8758_write(ROUTMIX,0x1); /* Enable mixer */
wmcodec_mute(0);
+ set_irq_level(old_irq_level);
} else {
wmcodec_mute(1);
}
@@ -147,6 +150,7 @@ void wmcodec_enable_output(bool enable)
int wmcodec_set_master_vol(int vol_l, int vol_r)
{
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
/* OUT1 */
wm8758_write(LOUT1VOL, vol_l);
wm8758_write(ROUT1VOL, 0x100 | vol_r);
@@ -154,6 +158,8 @@ int wmcodec_set_master_vol(int vol_l, int vol_r)
/* OUT2 */
wm8758_write(LOUT2VOL, vol_l);
wm8758_write(ROUT2VOL, 0x100 | vol_r);
+
+ set_irq_level(old_irq_level);
return 0;
}
@@ -198,6 +204,8 @@ void wmcodec_set_treble(int value)
int wmcodec_mute(int mute)
{
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
if (mute)
{
/* Set DACMU = 1 to soft-mute the audio DACs. */
@@ -207,12 +215,16 @@ int wmcodec_mute(int mute)
wm8758_write(DACCTRL, 0x0);
}
+ set_irq_level(old_irq_level);
+
return 0;
}
/* Nice shutdown of WM8758 codec */
void wmcodec_close(void)
{
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
wmcodec_mute(1);
wm8758_write(PWRMGMT3, 0x0);
@@ -220,6 +232,8 @@ void wmcodec_close(void)
wm8758_write(PWRMGMT1, 0x0);
wm8758_write(PWRMGMT2, 0x40);
+
+ set_irq_level(old_irq_level);
}
/* Change the order of the noise shaper, 5th order is recommended above 32kHz */
@@ -231,6 +245,8 @@ void wmcodec_set_nsorder(int order)
/* Note: Disable output before calling this function */
void wmcodec_set_sample_rate(int sampling_control)
{
+ int old_irq_level = set_irq_level(HIGHEST_IRQ_LEVEL);
+
/**** We force 44.1KHz for now. ****/
(void)sampling_control;
@@ -248,6 +264,8 @@ void wmcodec_set_sample_rate(int sampling_control)
/* set srate */
wm8758_write(SRATECTRL, (0 << 1));
+
+ set_irq_level(old_irq_level);
}
void 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 @@
#define ADC_BATTERY 2
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
+#elif defined(IPOD_ARCH)
+#define NUM_ADC_CHANNELS 1
+
+#define ADC_BATTERY 0
+#define ADC_UNREG_POWER ADC_BATTERY
+
#elif defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
#define NUM_ADC_CHANNELS 4
@@ -94,7 +100,7 @@ void adc_init(void);
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)\
|| defined(IAUDIO_X5)
-unsigned char adc_scan(int channel);
+unsigned short adc_scan(int channel);
#endif
#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 @@
#define CONFIG_I2C I2C_PP5020
/* Type of mobile power */
-//#define CONFIG_BATTERY BATT_LIPOL1300
+#define CONFIG_BATTERY BATT_LIPOL1300
-#define BATTERY_SCALE_FACTOR 16665 /* FIX: this value is picked at random */
+#define BATTERY_SCALE_FACTOR 586 /* FIX: this value is picked at random */
/* Define this if the platform can charge batteries */
//#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 @@
#ifdef IPOD_ARCH
int pcf50605_read(int address);
-void pcf50605_read_multiple(int address, unsigned char* buf, int count);
+int pcf50605_read_multiple(int address, unsigned char* buf, int count);
int pcf50605_write(int address, unsigned char val);
int pcf50605_write_multiple(int address, const unsigned char* buf, int count);
-int pcf50605_battery_read(void);
+int pcf50605_a2d_read(int channel);
+bool pcf50605_charger_inserted(void);
void pcf50605_standby_mode(void);
#endif