diff options
-rw-r--r-- | apps/screens.c | 7 | ||||
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/drivers/adc.c | 42 | ||||
-rw-r--r-- | firmware/drivers/i2c-pp5020.c | 1 | ||||
-rw-r--r-- | firmware/drivers/pcf50605.c | 46 | ||||
-rw-r--r-- | firmware/drivers/power.c | 3 | ||||
-rw-r--r-- | firmware/drivers/rtc.c | 50 | ||||
-rw-r--r-- | firmware/drivers/wm8758.c | 22 | ||||
-rw-r--r-- | firmware/export/adc.h | 8 | ||||
-rw-r--r-- | firmware/export/config-ipodvideo.h | 4 | ||||
-rw-r--r-- | firmware/export/pcf50605.h | 5 |
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 |