erosqnative: hw4 support

Support hw4 units with AXP2101 PMU

Bootloader successfully compiles and loads onto device.
The LCD appears to be identical to hw3 units.
Scroll wheel and buttons work
Audio output works, including volume.
HP/LO detect works
Rockbox build is generic
GPIO gating logic seems to be working as intended now.

 - Added new GPIO definitions - some significant overlaps with pins
    from previous hardware revisions...
 - Added some GPIO definitions for older players we didn't know about
 - Add register definitions for AXP2101 from datasheet
    (these are very different from AXP192!)
 - Add AXP2101 regulator definitions, need to support multiple step
    sizes per regulator.
 - Verify AXP2101 voltage set multi-range logic
 - Verify AXP2101 voltage get multi-range logic
 - Make AXP2101 its own driver
 - AXP2101 driver should be "minimally viable", though I think
    there is some extra functionality that could be implemented.
 - Disabling the coulomb counter stuff - we could maybe make
   the E-Gauge work for the same purpose, but it only appears to
   be used on the debug screen at the moment so it doesn't seem
   like it's worth the effort.
 - Found new button GPIOs
 - Found error in my GPIO setting logic, blue light works now!
 - Set LDO/DCDC output voltages to OF's settings, as far as
   I can tell.
 - Determined we probably want TCS1421_CFG1:0 to be 0x00,
   for UFP behavior
 - Tested this rb build with both old and new bootloaders on hw1.5,
   hw2, hw4 in as many configurations as I can think of, works across
   the board.
 - Bootloader can install itself on hw4, so nand chip isn't novel
 - Uninstallation file can be made by patcher script, works on hw4
 - Installation file can be made by patcher script, works on hw4
 - Added HW4 to rbutil, manual

Change-Id: I5b75782273e81c2c6f2b9c79501c8b7cbf88391f
This commit is contained in:
Dana Conrad 2024-10-13 21:19:42 +00:00 committed by Solomon Peachy
parent d7b57e33d9
commit 253eb79db3
14 changed files with 1403 additions and 108 deletions

View file

@ -31,6 +31,7 @@
#include "eros_qn_codec.h"
#include <string.h>
#include <stdbool.h>
#include "devicedata.h"
#ifndef BOOTLOADER
# include "lcd.h"
@ -75,13 +76,16 @@ volatile signed int enc_position = 0;
/* Value of headphone detect register */
static uint8_t hp_detect_reg = 0x00;
static uint8_t hp_detect_reg_old = 0x00;
#ifndef BOOTLOADER
static uint8_t hp_detect_debounce1 = 0x00;
#endif
static uint8_t hp_detect_debounce2 = 0x00;
static uint8_t debounce_count = 0;
/* Interval to poll the register */
#define HPD_POLL_TIME (HZ/4)
#ifndef BOOTLOADER
static int hp_detect_tmo_cb(struct timeout* tmo)
{
if (hp_detect_debounce1 == hp_detect_debounce2){
@ -100,41 +104,54 @@ static int hp_detect_tmo_cb(struct timeout* tmo)
return HPD_POLL_TIME;
}
static void hp_detect_init(void)
static void hp_detect_init(int version)
{
static struct timeout tmo;
static const uint8_t gpio_reg = AXP192_REG_GPIOSTATE1;
static i2c_descriptor desc = {
.slave_addr = AXP_PMU_ADDR,
.bus_cond = I2C_START | I2C_STOP,
.tran_mode = I2C_READ,
.buffer[0] = (void*)&gpio_reg,
.count[0] = 1,
.buffer[1] = &hp_detect_debounce1,
.count[1] = 1,
.callback = NULL,
.arg = 0,
.next = NULL,
};
if (version <= 3) {
static struct timeout tmo;
static const uint8_t gpio_reg = AXP192_REG_GPIOSTATE1;
static i2c_descriptor desc = {
.slave_addr = AXP_PMU_ADDR,
.bus_cond = I2C_START | I2C_STOP,
.tran_mode = I2C_READ,
.buffer[0] = (void*)&gpio_reg,
.count[0] = 1,
.buffer[1] = &hp_detect_debounce1,
.count[1] = 1,
.callback = NULL,
.arg = 0,
.next = NULL,
};
/* Headphone and LO detects are wired to AXP192 GPIOs 0 and 1,
* set them to inputs. */
i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO0FUNCTION, 0x01); /* HP detect */
i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO1FUNCTION, 0x01); /* LO detect */
/* Headphone and LO detects are wired to AXP192 GPIOs 0 and 1,
* set them to inputs. */
i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO0FUNCTION, 0x01); /* HP detect */
i2c_reg_write1(AXP_PMU_BUS, AXP_PMU_ADDR, AXP192_REG_GPIO1FUNCTION, 0x01); /* LO detect */
/* Get an initial reading before startup */
int r = i2c_reg_read1(AXP_PMU_BUS, AXP_PMU_ADDR, gpio_reg);
if(r >= 0)
{
hp_detect_reg = r;
hp_detect_debounce1 = r;
hp_detect_debounce2 = r;
/* Get an initial reading before startup */
int r = i2c_reg_read1(AXP_PMU_BUS, AXP_PMU_ADDR, gpio_reg);
if(r >= 0)
{
hp_detect_reg = r;
hp_detect_debounce1 = r;
hp_detect_debounce2 = r;
hp_detect_reg_old = hp_detect_reg;
}
/* Poll the register every second */
timeout_register(&tmo, &hp_detect_tmo_cb, HPD_POLL_TIME, (intptr_t)&desc);
} else {
uint32_t b = REG_GPIO_PIN(GPIO_B);
// initialize headphone detect variables
// HP_detect PB14 --> bit 4
// LO_detect PB22 --> bit 5
hp_detect_reg = ( (b>>10)&(0x10) | (b>>17)&(0x20) );
hp_detect_debounce1 = hp_detect_reg;
hp_detect_debounce2 = hp_detect_reg;
hp_detect_reg_old = hp_detect_reg;
}
/* Poll the register every second */
timeout_register(&tmo, &hp_detect_tmo_cb, HPD_POLL_TIME, (intptr_t)&desc);
}
#endif
bool headphones_inserted(void)
{
@ -187,7 +204,9 @@ void button_init_device(void)
gpio_enable_irq(GPIO_BTN_SCROLL_B);
/* Set up headphone and line out detect polling */
hp_detect_init();
#ifndef BOOTLOADER
hp_detect_init(device_data.lcd_version);
#endif
}
/* wheel Quadrature line A interrupt */
@ -238,16 +257,49 @@ int button_read_device(void)
if((a & (1 << 16)) == 0) r |= BUTTON_PLAY;
if((a & (1 << 17)) == 0) r |= BUTTON_VOL_UP;
if((a & (1 << 19)) == 0) r |= BUTTON_VOL_DOWN;
if((b & (1 << 7)) == 0) r |= BUTTON_POWER;
#ifdef BOOTLOADER
# if EROSQN_VER >= 4
if((b & (1 << 31)) == 0) r |= BUTTON_POWER;
if((a & (1 << 18)) == 0) r |= BUTTON_BACK;
# else
if((b & (1 << 7)) == 0) r |= BUTTON_POWER;
if((d & (1 << 5)) == 0) r |= BUTTON_BACK;
# endif
#else
if (device_data.lcd_version >= 4){
if((b & (1 << 31)) == 0) r |= BUTTON_POWER;
if((a & (1 << 18)) == 0) r |= BUTTON_BACK;
} else {
if((b & (1 << 7)) == 0) r |= BUTTON_POWER;
if((d & (1 << 5)) == 0) r |= BUTTON_BACK;
}
#endif
if((b & (1 << 28)) == 0) r |= BUTTON_MENU;
if((b & (1 << 28)) == 0) r |= BUTTON_MENU;
if((d & (1 << 4)) == 0) r |= BUTTON_PREV;
if((d & (1 << 5)) == 0) r |= BUTTON_BACK;
if((c & (1 << 24)) == 0) r |= BUTTON_NEXT;
#ifndef BOOTLOADER
if (device_data.lcd_version >= 4){
// get new HP/LO detect states
// HP_detect PB14 --> hp_detect bit 4
// LO_detect PB22 --> hp_detect bit 5
hp_detect_debounce1 = ( (b>>10)&(0x10) | (b>>17)&(0x20) );
// enter them into the debounce process
if (hp_detect_debounce1 == hp_detect_debounce2){
if (debounce_count >= 2){
debounce_count = 2;
} else {
debounce_count = debounce_count + 1;
}
} else {
debounce_count = 0;
hp_detect_debounce2 = hp_detect_debounce1;
}
}
#endif
/* check encoder - from testing, each indent is 2 state changes or so */
if (enc_position > 1)
{

View file

@ -1,21 +1,21 @@
/* -------------------- NOTES ------------------- */
/* I don't think we have any devices on I2C1, the pins /may/ be reused. */
/* DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0)) */
/* OF has SD Card power listed as 0x2a - PB10, but it seems to work without. */
/* I think BT power reg is pin 0x53 - C19 */
/* USB_DETECT D3 chosen by trial-and-error. */
/* I have a suspicion this isn't right for AXP_IRQ,
* and it's not used right now anyway. copied from m3k. */
/* DEFINE_GPIO(AXP_IRQ, GPIO_PB(10), GPIOF_INPUT) */
/* ---------------------------------------------- */
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
/* ======================================================= */
/* DO NOT CHANGE THE ORDER OF THESE DEFINES */
/* WITHOUT CONSIDERING GPIO-X1000.C!! */
/* ======================================================= */
/* WARNING WARNING WARNING WARNING WARNING WARNING WARNING */
/**************************/
/* PIN GROUPINGS */
/************************ */
/* Name Port Pins Function */
DEFINE_PINGROUP(LCD_DATA, GPIO_A, 0xffff << 0, GPIOF_DEVICE(1))
DEFINE_PINGROUP(LCD_CONTROL, GPIO_B, 0x1a << 16, GPIOF_DEVICE(1))
@ -26,11 +26,24 @@ DEFINE_PINGROUP(I2C1, GPIO_C, 3 << 26, GPIOF_DEVICE(0))
DEFINE_PINGROUP(I2C2, GPIO_D, 3 << 0, GPIOF_DEVICE(1))
/* Name Pin Function */
/*************************/
/* AUDIO STUFF */
/*************************/
/* mute DAC: 0 - mute, 1 - play */
/* Note: This seems to actually be power to the DAC in general,
* at least on the ES9018K2M devices. Was "DAC_XMIT". */
DEFINE_GPIO(DAC_PWR, GPIO_PB(12), GPIOF_OUTPUT(0))
/* Headphone Amp power */
DEFINE_GPIO(HPAMP_POWER, GPIO_PB(6), GPIOF_OUTPUT(0))
/* DAC AVDD */
DEFINE_GPIO(DAC_ANALOG_PWR, GPIO_PB(9), GPIOF_OUTPUT(0))
/* SPDIF power? */
// gpio 53 --> port B, pin 21
DEFINE_GPIO(SPDIF_PWR, GPIO_PB(21), GPIOF_OUTPUT(0))
/* mute HP amp: 0 - mute, 1 - play */
DEFINE_GPIO(HPAMP_SHDN, GPIO_PB(8), GPIOF_OUTPUT(0))
@ -43,33 +56,123 @@ DEFINE_GPIO(STEREOSW_MUTE, GPIO_PB(15), GPIOF_OUTPUT(1))
*/
DEFINE_GPIO(STEREOSW_SEL, GPIO_PB(5), GPIOF_OUTPUT(0))
/* DAC AVDD */
DEFINE_GPIO(DAC_ANALOG_PWR, GPIO_PB(9), GPIOF_OUTPUT(0))
/* Headphone Amp power */
DEFINE_GPIO(HPAMP_POWER, GPIO_PB(6), GPIOF_OUTPUT(0))
/**************/
/* SD and USB */
/**************/
/* SD card */
DEFINE_GPIO(MMC_PWR, GPIO_PB(10), GPIOF_OUTPUT(1))
DEFINE_GPIO(MSC0_CD, GPIO_PB(11), GPIOF_INPUT)
/* USB */
/* USB_DETECT D3 chosen by trial-and-error. */
DEFINE_GPIO(USB_DETECT, GPIO_PD(3), GPIOF_INPUT)
DEFINE_GPIO(USB_DRVVBUS, GPIO_PB(25), GPIOF_OUTPUT(0))
/* TCS1421_CFG (USB) CFG1 */
// set TCS1421_CFG0:1 to 00, Upstream Facing Port (tried others, they don't work)
// GPIO 62 --> PORT B, PIN 30
DEFINE_GPIO(TCS1421_CFG1, GPIO_PB(30), GPIOF_OUTPUT(0))
/* BL POWER */
// gpio 89 --> port c, pin 25
// oh, this is probably backlight power, isn't it?
DEFINE_GPIO(BL_PWR, GPIO_PC(25), GPIOF_OUTPUT(0))
/************/
/* LCD */
/************/
/* LCD */
DEFINE_GPIO(LCD_PWR, GPIO_PB(14), GPIOF_OUTPUT(0))
DEFINE_GPIO(LCD_RESET, GPIO_PB(13), GPIOF_OUTPUT(0))
DEFINE_GPIO(LCD_CE, GPIO_PB(18), GPIOF_OUTPUT(1))
DEFINE_GPIO(LCD_RD, GPIO_PB(16), GPIOF_OUTPUT(1))
/************/
/* BUTTONS */
/************/
/* Buttons */
DEFINE_GPIO(BTN_PLAY, GPIO_PA(16), GPIOF_INPUT)
DEFINE_GPIO(BTN_VOL_UP, GPIO_PA(17), GPIOF_INPUT)
DEFINE_GPIO(BTN_VOL_DOWN, GPIO_PA(19), GPIOF_INPUT)
DEFINE_GPIO(BTN_POWER, GPIO_PB(7), GPIOF_INPUT)
DEFINE_GPIO(BTN_MENU, GPIO_PB(28), GPIOF_INPUT)
DEFINE_GPIO(BTN_BACK, GPIO_PD(5), GPIOF_INPUT)
DEFINE_GPIO(BTN_PREV, GPIO_PD(4), GPIOF_INPUT)
DEFINE_GPIO(BTN_NEXT, GPIO_PC(24), GPIOF_INPUT)
DEFINE_GPIO(BTN_SCROLL_A, GPIO_PB(24), GPIOF_INPUT)
DEFINE_GPIO(BTN_SCROLL_B, GPIO_PB(23), GPIOF_INPUT)
/**********************/
/* BLUETOOTH STUFF */
/**********************/
/* BT Power */
// GPIO 86 --> Port C, Pin 22
DEFINE_GPIO(BT_PWR, GPIO_PC(22), GPIOF_OUTPUT(0))
/****************************** */
/* HW1/2/3-ONLY STUFF */
/****************************** */
DEFINE_GPIO(HW1_START, GPIO_PC(0), GPIOF_OUTPUT(0))
/************/
/* BUTTONS */
/************/
DEFINE_GPIO(BTN_BACK_HW1, GPIO_PD(5), GPIOF_INPUT)
DEFINE_GPIO(BTN_POWER_HW1, GPIO_PB(7), GPIOF_INPUT)
/**********************/
/* BLUETOOTH STUFF */
/**********************/
// GPIO 83 --> port C, pin 19
DEFINE_GPIO(BT_REG_ON_HW1, GPIO_PC(19), GPIOF_OUTPUT(0))
/************/
/* LCD */
/************/
/* LCD */
DEFINE_GPIO(LCD_PWR_HW1, GPIO_PB(14), GPIOF_OUTPUT(0))
DEFINE_GPIO(HW1_END, GPIO_PC(0), GPIOF_OUTPUT(0))
/****************************** */
/* HW4-ONLY STUFF */
/****************************** */
DEFINE_GPIO(HW4_START, GPIO_PC(0), GPIOF_OUTPUT(0))
DEFINE_GPIO(BLUELIGHT_HW4, GPIO_PB(7), GPIOF_OUTPUT(1))
/************/
/* BUTTONS */
/************/
DEFINE_GPIO(BTN_BACK_HW4, GPIO_PA(18), GPIOF_INPUT)
DEFINE_GPIO(BTN_POWER_HW4, GPIO_PB(31), GPIOF_INPUT)
/**********************/
/* BLUETOOTH STUFF */
/**********************/
/* bt_wake_host */
// gpio 84 --> port C, pin 20
DEFINE_GPIO(BT_WAKE_HOST, GPIO_PC(20), GPIOF_INPUT)
/* host_wake_bt */
// gpio 83 --> port C, pin 19
DEFINE_GPIO(HOST_WAKE_BT, GPIO_PC(19), GPIOF_OUTPUT(0))
/**************/
/* USB */
/**************/
/* USB_TCS1421_CFG0 */
// set TCS1421_CFG0:1 to 00, Upstream Facing Port (tried others, they don't work)
// gpio 101 --> port D, pin 5
DEFINE_GPIO(TCS1421_CFG0, GPIO_PD(5), GPIOF_OUTPUT(0))
/***************/
/* PLUG DETECT */
/***************/
/* HP_DETECT */
// gpio 46 --> port B, pin 14
DEFINE_GPIO(HP_DETECT_HW4, GPIO_PB(14), GPIOF_INPUT)
/* LO_DETECT */
// gpio 54 --> Port B, pin 22
DEFINE_GPIO(LO_DETECT_HW4, GPIO_PB(22), GPIOF_INPUT)
DEFINE_GPIO(HW4_END, GPIO_PC(0), GPIOF_OUTPUT(0))

View file

@ -292,7 +292,16 @@ void lcd_tgt_enable(bool enable)
{
if(enable) {
/* power up the panel */
gpio_set_level(GPIO_LCD_PWR, 1);
#ifdef BOOTLOADER
# if EROSQN_VER <= 3
gpio_set_level(GPIO_LCD_PWR_HW1, 1);
# endif
#else
if (device_data.lcd_version <= 3)
{
gpio_set_level(GPIO_LCD_PWR_HW1, 1);
}
#endif
mdelay(20);
gpio_set_level(GPIO_LCD_RESET, 1);
mdelay(12);
@ -307,13 +316,13 @@ void lcd_tgt_enable(bool enable)
gpio_set_level(GPIO_LCD_CE, 0);
#ifdef BOOTLOADER
# if EROSQN_VER == 3
# if EROSQN_VER >= 3
lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]);
# else
lcd_exec_commands(&erosqnative_lcd_cmd_enable_v1[0]);
# endif
#else
if (device_data.lcd_version == 3)
if (device_data.lcd_version >= 3)
{
lcd_exec_commands(&erosqnative_lcd_cmd_enable_v3[0]);
}

View file

@ -29,7 +29,9 @@
# include "usb_core.h"
#endif
#include "axp-pmu.h"
#include "axp-2101.h"
#include "i2c-x1000.h"
#include "devicedata.h"
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
@ -58,30 +60,94 @@ void power_init(void)
{
/* Initialize driver */
i2c_x1000_set_freq(2, I2C_FREQ_400K);
axp_init();
/* Set lowest sample rate */
axp_adc_set_rate(AXP_ADC_RATE_25HZ);
int devicever;
#if defined(BOOTLOADER)
devicever = EROSQN_VER;
#else
devicever = device_data.lcd_version;
#endif
if (devicever >= 4){
uint8_t regread;
axp2101_init();
/* Enable required ADCs */
axp2101_adc_set_enabled(
(1 << AXP2101_ADC_VBAT_VOLTAGE) |
(1 << AXP2101_ADC_VBUS_VOLTAGE) |
(1 << AXP2101_ADC_VSYS_VOLTAGE) |
(1 << AXP2101_ADC_VBUS_VOLTAGE) |
(1 << AXP2101_ADC_TS_VOLTAGE) |
(1 << AXP2101_ADC_DIE_TEMPERATURE));
/* Enable required ADCs */
axp_adc_set_enabled(
(1 << ADC_BATTERY_VOLTAGE) |
(1 << ADC_CHARGE_CURRENT) |
(1 << ADC_DISCHARGE_CURRENT) |
(1 << ADC_VBUS_VOLTAGE) |
(1 << ADC_VBUS_CURRENT) |
(1 << ADC_INTERNAL_TEMP) |
(1 << ADC_APS_VOLTAGE));
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP2101_REG_DCDC_ONOFF, 0, 0x1f, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP2101_REG_LDO_ONOFF0, 0, 0xff, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP2101_REG_LDO_ONOFF1, 0, 0x01, NULL);
/* Turn on all power outputs */
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_PWROUTPUTCTRL2, 0, 0x5f, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_DCDCWORKINGMODE, 0, 0xc0, NULL);
// set power button delay to 1s to match earlier devices
regread = i2c_reg_read1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP2101_REG_LOGICTHRESH);
if ((regread&0x03) != 0x02){
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP2101_REG_LOGICTHRESH, 0x03, 0, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP2101_REG_LOGICTHRESH, 0, 0x02, NULL);
}
// These match the OF as far as I can discern
// TODO: These values are set in EFUSE apparently, could
// do a "check then set if necessary"...
// Also if we had a fresh device we could verify what
// the OF sets.
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC1, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC2, 1200);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC3, 2800);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC4, 1800);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DCDC5, 1400);
/* Set the default charging current. This is the same as the
* OF's setting, although it's not strictly within the USB spec. */
axp_set_charge_current(780);
axp2101_supply_set_voltage(AXP2101_SUPPLY_ALDO1, 2500);
axp2101_supply_set_voltage(AXP2101_SUPPLY_ALDO2, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_ALDO3, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_ALDO4, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_BLDO1, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_BLDO2, 3300);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DLDO1, 2500);
axp2101_supply_set_voltage(AXP2101_SUPPLY_DLDO2, 1250);
axp2101_supply_set_voltage(AXP2101_SUPPLY_VCPUS, 500);
/* Set the default charging current. This is the same as the
* OF's setting, although it's not strictly within the USB spec. */
axp2101_set_charge_current(780);
} else {
axp_init();
/* Set lowest sample rate */
axp_adc_set_rate(AXP_ADC_RATE_25HZ);
/* Enable required ADCs */
axp_adc_set_enabled(
(1 << ADC_BATTERY_VOLTAGE) |
(1 << ADC_CHARGE_CURRENT) |
(1 << ADC_DISCHARGE_CURRENT) |
(1 << ADC_VBUS_VOLTAGE) |
(1 << ADC_VBUS_CURRENT) |
(1 << ADC_INTERNAL_TEMP) |
(1 << ADC_APS_VOLTAGE));
/* TODO: Set Output Voltages! */
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_PWROUTPUTCTRL2, 0, 0x5f, NULL);
i2c_reg_modify1(AXP_PMU_BUS, AXP_PMU_ADDR,
AXP_REG_DCDCWORKINGMODE, 0, 0xc0, NULL);
/* Set the default charging current. This is the same as the
* OF's setting, although it's not strictly within the USB spec. */
axp_set_charge_current(780);
}
#ifdef BOOTLOADER
/* Delay to give power outputs time to stabilize.
@ -95,7 +161,18 @@ void power_init(void)
#ifdef HAVE_USB_CHARGING_ENABLE
void usb_charging_maxcurrent_change(int maxcurrent)
{
axp_set_charge_current(maxcurrent);
int devicever;
#if defined(BOOTLOADER)
devicever = EROSQN_VER;
#else
devicever = device_data.lcd_version;
#endif
if (devicever >= 4){
axp2101_set_charge_current(maxcurrent);
} else {
axp_set_charge_current(maxcurrent);
}
}
#endif
@ -105,26 +182,64 @@ void adc_init(void)
void power_off(void)
{
axp_power_off();
int devicever;
#if defined(BOOTLOADER)
devicever = EROSQN_VER;
#else
devicever = device_data.lcd_version;
#endif
if (devicever >= 4){
axp2101_power_off();
} else {
axp_power_off();
}
while(1);
}
bool charging_state(void)
{
return axp_battery_status() == AXP_BATT_CHARGING;
int devicever;
#if defined(BOOTLOADER)
devicever = EROSQN_VER;
#else
devicever = device_data.lcd_version;
#endif
if (devicever >= 4){
return axp2101_battery_status() == AXP2101_BATT_CHARGING;
} else {
return axp_battery_status() == AXP_BATT_CHARGING;
}
}
int _battery_voltage(void)
{
return axp_adc_read(ADC_BATTERY_VOLTAGE);
int devicever;
#if defined(BOOTLOADER)
devicever = EROSQN_VER;
#else
devicever = device_data.lcd_version;
#endif
if (devicever >= 4){
return axp2101_adc_read(AXP2101_ADC_VBAT_VOLTAGE);
} else {
return axp_adc_read(ADC_BATTERY_VOLTAGE);
}
}
#if CONFIG_BATTERY_MEASURE & CURRENT_MEASURE
int _battery_current(void)
{
if(charging_state())
return axp_adc_read(ADC_CHARGE_CURRENT);
else
return axp_adc_read(ADC_DISCHARGE_CURRENT);
int devicever;
#if defined(BOOTLOADER)
devicever = EROSQN_VER;
#else
devicever = device_data.lcd_version;
#endif
if (devicever <= 3){
if(charging_state())
return axp_adc_read(ADC_CHARGE_CURRENT);
else
return axp_adc_read(ADC_DISCHARGE_CURRENT);
}
}
#endif

View file

@ -20,6 +20,9 @@
****************************************************************************/
#include "gpio-x1000.h"
#if defined(EROS_QN)
# include "devicedata.h"
#endif
static const struct gpio_setting gpio_settings[PIN_COUNT] INITDATA_ATTR = {
#define DEFINE_GPIO(_name, _gpio, _func) \
@ -59,6 +62,14 @@ static const char* const pingroup_names[PINGROUP_COUNT] = {
void gpio_init(void)
{
#if defined(EROS_QN)
int devicever;
# if defined(BOOTLOADER)
devicever = EROSQN_VER;
# else
devicever = device_data.lcd_version;
# endif
#endif
/* Apply all initial GPIO settings */
for(int i = 0; i < PINGROUP_COUNT; ++i) {
const struct pingroup_setting* d = &pingroup_settings[i];
@ -68,8 +79,29 @@ void gpio_init(void)
for(int i = 0; i < PIN_COUNT; ++i) {
const struct gpio_setting* d = &gpio_settings[i];
#ifdef EROS_QN
// eros_qn only
// There surely has to be a nicer way to do this...
// Note: PIN_ indicates position in the list,
// GPIO_ indicates actual port/pin number
// (so if you want to go based on order of the list, use the PIN_ designator!)
if((d->gpio != GPIO_NONE) &&\
((i < PIN_HW1_START) ||\
(devicever <= 3 &&\
(i > PIN_HW1_START && i < PIN_HW1_END))\
||\
(devicever >= 4 &&\
(i > PIN_HW4_START && i < PIN_HW4_END))))
// if((d->gpio != GPIO_NONE) && (d->gpio != GPIO_BTN_POWER_HW1))
#else
// non-eros_qn devices
if(d->gpio != GPIO_NONE)
#endif
{
gpioz_configure(GPION_PORT(d->gpio), GPION_MASK(d->gpio), d->func);
}
}
/* Any GPIO pins left in an IRQ trigger state need to be switched off,