ipod6g: Move pmu_is_hibernated() from bootloader to PMU driver, misc fixes

Added better comments about the PMU registers, added pmu_set_cpu_voltage() (still unused).

Credit: Cástor Muñoz <cmvidal@gmail.com>
Change-Id: I0ca21a49ece007c913c1b199952009e4dcae80e5
This commit is contained in:
Vencislav Atanasov 2024-11-27 01:43:40 +02:00 committed by Solomon Peachy
parent 6b348d7f75
commit 9b4bab7e0a
3 changed files with 59 additions and 32 deletions

View file

@ -279,13 +279,6 @@ static int kernel_launch_onb(void)
return rc;
}
static bool pmu_is_hibernated(void)
{
/* OF sets GPIO3 to low when SDRAM is hibernated */
return !(pmu_rd(PCF5063X_REG_GPIO3CFG) & 7) &&
!(pmu_rd(PCF5063X_REG_OOCSHDWN) & PCF5063X_OOCSHDWN_COLDBOOT);
}
/* The boot sequence is executed on power-on or reset. After power-up
* the device could come from a state of hibernation, OF hibernates
* the iPod after an inactive period of ~30 minutes (FW 1.1.2), on

View file

@ -102,6 +102,15 @@ void pmu_enter_standby(void)
pmu_write(0xc, 1);
}
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void pmu_set_cpu_voltage(bool high)
{
pmu_write(PCF5063X_REG_DOWN1OUT,
high ? 0x13 /*1100mV*/ : 0xf /*1000mV*/);
}
#endif
#if (CONFIG_RTC == RTC_NANO2G)
void pmu_read_rtc(unsigned char* buffer)
{
pmu_read_multiple(0x59, 7, buffer);
@ -111,6 +120,7 @@ void pmu_write_rtc(unsigned char* buffer)
{
pmu_write_multiple(0x59, 7, buffer);
}
#endif
/*
* ADC
@ -467,3 +477,16 @@ void pmu_preinit(void)
pmu_rd_multiple(PCF5063X_REG_INT1, 5, rd_buf);
pmu_rd(PCF50635_REG_INT6);
}
#ifdef BOOTLOADER
bool pmu_is_hibernated(void)
{
/* OF sets GPIO3 to low when SDRAM is hibernated */
bool gpio3out, coldboot;
/* get (previously) configured output selection for GPIO3 */
gpio3out = (pmu_rd(PCF5063X_REG_GPIO3CFG) & 7);
/* coldboot: when set, device has been in NoPower state */
coldboot = (pmu_rd(PCF5063X_REG_OOCSHDWN) & PCF5063X_OOCSHDWN_COLDBOOT);
return !coldboot && !gpio3out;
}
#endif

View file

@ -29,38 +29,40 @@
#include "pcf5063x.h"
/* undocummented PMU registers */
#define PCF50635_REG_INT6 0x85
#define PCF50635_REG_INT6M 0x86
#define PCF50635_REG_GPIOSTAT 0x87
#define PCF50635_REG_INT6 0x85
#define PCF50635_REG_INT6M 0x86
#define PCF50635_REG_GPIOSTAT 0x87
enum pcf50635_reg_int6 {
PCF50635_INT6_GPIO1 = 0x01, /* TBC */
PCF50635_INT6_GPIO2 = 0x02,
PCF50635_INT6_GPIO3 = 0x04, /* TBC */
};
enum pcf50635_reg_gpiostat {
PCF50635_GPIOSTAT_GPIO1 = 0x01, /* TBC */
PCF50635_GPIOSTAT_GPIO2 = 0x02,
PCF50635_GPIOSTAT_GPIO3 = 0x04, /* TBC */
};
/* GPIO for external PMU interrupt */
#define GPIO_EINT_PMU 0x7b
/* LDOs */
#define LDO_UNK1 1 /* TBC: SoC voltage (USB) */
#define LDO_UNK2 2 /* TBC: SoC voltage (I/O) */
/* LDOs - enumeration starts at 1 as pcf50635 DS does */
#define LDO_UNK1 1 /* SoC voltage (USB+TBC section) */
#define LDO_UNK2 2 /* SoC voltage (I/O+TBC section) */
#define LDO_LCD 3
#define LDO_CODEC 4
#define LDO_UNK5 5 /* TBC: nano3g NAND */
#define LDO_UNK5 5 /* not used */
#define LDO_CWHEEL 6
#define LDO_ACCY 7 /* HCLDO */
/*
* Other LDOs:
* AUTOLDO: Hard Disk
* DOWN1: CPU
* DOWN2: SDRAM
* MEMLDO: SDRAM self-refresh (TBC)
* DOWN1: Vcore
* DOWN2: SDRAM
* MEMLDO: SDRAM self-refresh (TBC)
*
* EXTON inputs:
* EXTON1: button/holdswitch related (TBC)
@ -68,11 +70,13 @@ enum pcf50635_reg_gpiostat {
* EXTON3: ACCESSORY (Low when present)
*
* PMU GPIO:
* GPIO1: input, Mikey (jack remote ctrl) interrupt (TBC)
* GPIO1: input, Mikey (jack remote ctrl) interrupt
* GPIO2: input, hold switch (TBC)
* GPIO3: output, unknown
* GPIO3: output, OF uses it as a flag to detect hibernation state,
* it is unknown where/if this output is connected.
*/
struct pmu_adc_channel
{
const char *name;
@ -82,23 +86,38 @@ struct pmu_adc_channel
uint8_t bias_dly; /* RB ticks */
};
void pmu_preinit(void);
void pmu_init(void);
unsigned char pmu_read(int address);
int pmu_write(int address, unsigned char val);
int pmu_read_multiple(int address, int count, unsigned char* buffer);
int pmu_write_multiple(int address, int count, unsigned char* buffer);
unsigned short pmu_read_adc(const struct pmu_adc_channel *ch);
unsigned short pmu_adc_raw2mv(
const struct pmu_adc_channel *ch, unsigned short raw);
void pmu_init(void);
#ifdef BOOTLOADER
unsigned char pmu_rd(int address);
int pmu_wr(int address, unsigned char val);
int pmu_rd_multiple(int address, int count, unsigned char* buffer);
int pmu_wr_multiple(int address, int count, unsigned char* buffer);
bool pmu_is_hibernated(void);
#endif
void pmu_ldo_on_in_standby(unsigned int ldo, int onoff);
void pmu_ldo_set_voltage(unsigned int ldo, unsigned char voltage);
void pmu_ldo_power_on(unsigned int ldo);
void pmu_ldo_power_off(unsigned int ldo);
void pmu_set_wake_condition(unsigned char condition);
void pmu_enter_standby(void);
void pmu_hdd_power(bool on);
#ifdef HAVE_ADJUSTABLE_CPU_FREQ
void pmu_set_cpu_voltage(bool high);
#endif
#if (CONFIG_RTC == RTC_NANO2G)
void pmu_read_rtc(unsigned char* buffer);
void pmu_write_rtc(unsigned char* buffer);
void pmu_hdd_power(bool on);
#endif
unsigned short pmu_read_adc(const struct pmu_adc_channel *ch);
unsigned short pmu_adc_raw2mv(
const struct pmu_adc_channel *ch, unsigned short raw);
int pmu_holdswitch_locked(void);
#if CONFIG_CHARGING
@ -108,12 +127,4 @@ int pmu_firewire_present(void);
int pmu_accessory_present(void);
#endif
void pmu_preinit(void);
#ifdef BOOTLOADER
unsigned char pmu_rd(int address);
int pmu_wr(int address, unsigned char val);
int pmu_rd_multiple(int address, int count, unsigned char* buffer);
int pmu_wr_multiple(int address, int count, unsigned char* buffer);
#endif
#endif /* __PMU_TARGET_H__ */