mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-09 13:12:37 -05:00
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:
parent
d7b57e33d9
commit
253eb79db3
14 changed files with 1403 additions and 108 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
@ -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]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue