mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 02:27:39 -04:00
iPod Classic: ADC updates
Add code to read USB D+/D- and accessory ADCs, it is shown in HW debug menu, might be useful in future for RB and/or the bootloader to identify external USB chargers. Change-Id: Ia48ca5e06bb7ddc52bb55abedde6734653ce8dba
This commit is contained in:
parent
a25d0c58aa
commit
adbd2969e6
7 changed files with 201 additions and 57 deletions
|
@ -198,12 +198,12 @@ enum pcf5063X_reg_mbcc2 {
|
||||||
|
|
||||||
enum pcf5063X_reg_adcc1 {
|
enum pcf5063X_reg_adcc1 {
|
||||||
PCF5063X_ADCC1_ADCSTART = 0x01,
|
PCF5063X_ADCC1_ADCSTART = 0x01,
|
||||||
PCF5063X_ADCC1_RES_10BIT = 0x02,
|
PCF5063X_ADCC1_RES_10BIT = 0x00,
|
||||||
|
PCF5063X_ADCC1_RES_8BIT = 0x02,
|
||||||
PCF5063X_ADCC1_AVERAGE_NO = 0x00,
|
PCF5063X_ADCC1_AVERAGE_NO = 0x00,
|
||||||
PCF5063X_ADCC1_AVERAGE_4 = 0x04,
|
PCF5063X_ADCC1_AVERAGE_4 = 0x04,
|
||||||
PCF5063X_ADCC1_AVERAGE_8 = 0x08,
|
PCF5063X_ADCC1_AVERAGE_8 = 0x08,
|
||||||
PCF5063X_ADCC1_AVERAGE_16 = 0x0c,
|
PCF5063X_ADCC1_AVERAGE_16 = 0x0c,
|
||||||
|
|
||||||
PCF5063X_ADCC1_MUX_BATSNS_RES = 0x00,
|
PCF5063X_ADCC1_MUX_BATSNS_RES = 0x00,
|
||||||
PCF5063X_ADCC1_MUX_BATSNS_SUBTR = 0x10,
|
PCF5063X_ADCC1_MUX_BATSNS_SUBTR = 0x10,
|
||||||
PCF5063X_ADCC1_MUX_ADCIN2_RES = 0x20,
|
PCF5063X_ADCC1_MUX_ADCIN2_RES = 0x20,
|
||||||
|
@ -211,6 +211,7 @@ enum pcf5063X_reg_adcc1 {
|
||||||
PCF5063X_ADCC1_MUX_BATTEMP = 0x60,
|
PCF5063X_ADCC1_MUX_BATTEMP = 0x60,
|
||||||
PCF5063X_ADCC1_MUX_ADCIN1 = 0x70,
|
PCF5063X_ADCC1_MUX_ADCIN1 = 0x70,
|
||||||
};
|
};
|
||||||
|
#define PCF5063X_ADCC1_RES_MASK 0x02
|
||||||
#define PCF5063X_ADCC1_AVERAGE_MASK 0x0c
|
#define PCF5063X_ADCC1_AVERAGE_MASK 0x0c
|
||||||
#define PCF5063X_ADCC1_ADCMUX_MASK 0xf0
|
#define PCF5063X_ADCC1_ADCMUX_MASK 0xf0
|
||||||
|
|
||||||
|
@ -219,9 +220,11 @@ enum pcf5063X_reg_adcc2 {
|
||||||
PCF5063X_ADCC2_RATIO_BATTEMP = 0x01,
|
PCF5063X_ADCC2_RATIO_BATTEMP = 0x01,
|
||||||
PCF5063X_ADCC2_RATIO_ADCIN1 = 0x02,
|
PCF5063X_ADCC2_RATIO_ADCIN1 = 0x02,
|
||||||
PCF5063X_ADCC2_RATIO_BOTH = 0x03,
|
PCF5063X_ADCC2_RATIO_BOTH = 0x03,
|
||||||
|
PCF5063X_ADCC2_RATIOSETTL_10US = 0x00,
|
||||||
PCF5063X_ADCC2_RATIOSETTL_100US = 0x04,
|
PCF5063X_ADCC2_RATIOSETTL_100US = 0x04,
|
||||||
};
|
};
|
||||||
#define PCF5063X_ADCC2_RATIO_MASK 0x03
|
#define PCF5063X_ADCC2_RATIO_MASK 0x03
|
||||||
|
#define PCF5063X_ADCC2_RATIOSETTL_MASK 0x04
|
||||||
|
|
||||||
enum pcf5063X_reg_adcc3 {
|
enum pcf5063X_reg_adcc3 {
|
||||||
PCF5063X_ADCC3_ACCSW_EN = 0x01,
|
PCF5063X_ADCC3_ACCSW_EN = 0x01,
|
||||||
|
@ -229,6 +232,7 @@ enum pcf5063X_reg_adcc3 {
|
||||||
PCF5063X_ADCC3_RES_DIV_TWO = 0x10,
|
PCF5063X_ADCC3_RES_DIV_TWO = 0x10,
|
||||||
PCF5063X_ADCC3_RES_DIV_THREE = 0x00,
|
PCF5063X_ADCC3_RES_DIV_THREE = 0x00,
|
||||||
};
|
};
|
||||||
|
#define PCF5063X_ADCC3_RES_DIV_MASK 0x10
|
||||||
|
|
||||||
enum pcf5063X_reg_adcs3 {
|
enum pcf5063X_reg_adcs3 {
|
||||||
PCF5063X_ADCS3_REF_NTCSW = 0x00,
|
PCF5063X_ADCS3_REF_NTCSW = 0x00,
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
*
|
*
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
@ -28,6 +29,7 @@
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
|
#include "adc.h"
|
||||||
#include "pmu-target.h"
|
#include "pmu-target.h"
|
||||||
#include "pcm-target.h"
|
#include "pcm-target.h"
|
||||||
#ifdef HAVE_SERIAL
|
#ifdef HAVE_SERIAL
|
||||||
|
@ -133,12 +135,20 @@ bool dbg_hw_info(void)
|
||||||
_DEBUG_PRINTF("accessory present: %s",
|
_DEBUG_PRINTF("accessory present: %s",
|
||||||
pmu_accessory_present() ? "true" : "false");
|
pmu_accessory_present() ? "true" : "false");
|
||||||
#endif
|
#endif
|
||||||
|
line++;
|
||||||
|
_DEBUG_PRINTF("ADC:");
|
||||||
|
_DEBUG_PRINTF("%s: %d mV", adc_name(ADC_BATTERY),
|
||||||
|
adc_read_battery_voltage());
|
||||||
|
_DEBUG_PRINTF("%s: %d Ohms", adc_name(ADC_ACCESSORY),
|
||||||
|
adc_read_accessory_resistor());
|
||||||
|
_DEBUG_PRINTF("USB D+: %d mV", adc_read_usbdata_voltage(true));
|
||||||
|
_DEBUG_PRINTF("USB D-: %d mV", adc_read_usbdata_voltage(false));
|
||||||
line++;
|
line++;
|
||||||
extern unsigned long i2c_rd_err, i2c_wr_err;
|
extern unsigned long i2c_rd_err, i2c_wr_err;
|
||||||
_DEBUG_PRINTF("i2c rd/wr errors: %lu/%lu", i2c_rd_err, i2c_wr_err);
|
_DEBUG_PRINTF("i2c rd/wr errors: %lu/%lu", i2c_rd_err, i2c_wr_err);
|
||||||
}
|
}
|
||||||
#ifdef UC870X_DEBUG
|
#ifdef UC870X_DEBUG
|
||||||
else if(state==2)
|
else if(state==(max_states-1))
|
||||||
{
|
{
|
||||||
extern struct uartc_port ser_port;
|
extern struct uartc_port ser_port;
|
||||||
bool opened = !!ser_port.uartc->port_l[ser_port.id];
|
bool opened = !!ser_port.uartc->port_l[ser_port.id];
|
||||||
|
|
|
@ -28,12 +28,90 @@
|
||||||
#include "pmu-target.h"
|
#include "pmu-target.h"
|
||||||
#include "kernel.h"
|
#include "kernel.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* MS_TO_TICKS converts a milisecond time period into the
|
||||||
|
* corresponding amount of ticks. If the time period cannot
|
||||||
|
* be accurately measured in ticks it will round up.
|
||||||
|
*/
|
||||||
|
#define MS_PER_HZ (1000/HZ)
|
||||||
|
#define MS_TO_TICKS(x) (((x)+MS_PER_HZ-1)/MS_PER_HZ)
|
||||||
|
|
||||||
|
static const struct pmu_adc_channel adc_channels[] =
|
||||||
|
{
|
||||||
|
[ADC_BATTERY] =
|
||||||
|
{
|
||||||
|
.name = "Battery",
|
||||||
|
.adcc1 = PCF5063X_ADCC1_MUX_BATSNS_SUBTR
|
||||||
|
| PCF5063X_ADCC1_AVERAGE_4
|
||||||
|
| PCF5063X_ADCC1_RES_10BIT,
|
||||||
|
},
|
||||||
|
|
||||||
|
[ADC_USBDATA] =
|
||||||
|
{
|
||||||
|
.name = "USB D+/D-",
|
||||||
|
.adcc1 = PCF5063X_ADCC1_MUX_ADCIN2_RES
|
||||||
|
| PCF5063X_ADCC1_AVERAGE_16
|
||||||
|
| PCF5063X_ADCC1_RES_10BIT,
|
||||||
|
.adcc3 = PCF5063X_ADCC3_RES_DIV_THREE,
|
||||||
|
},
|
||||||
|
|
||||||
|
[ADC_ACCESSORY] =
|
||||||
|
{
|
||||||
|
.name = "Accessory",
|
||||||
|
.adcc1 = PCF5063X_ADCC1_MUX_ADCIN1
|
||||||
|
| PCF5063X_ADCC1_AVERAGE_16
|
||||||
|
| PCF5063X_ADCC1_RES_10BIT,
|
||||||
|
.adcc2 = PCF5063X_ADCC2_RATIO_ADCIN1
|
||||||
|
| PCF5063X_ADCC2_RATIOSETTL_10US,
|
||||||
|
.adcc3 = PCF5063X_ADCC3_ACCSW_EN,
|
||||||
|
.bias_dly = MS_TO_TICKS(50),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *adc_name(int channel)
|
||||||
|
{
|
||||||
|
return adc_channels[channel].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned short adc_read_millivolts(int channel)
|
||||||
|
{
|
||||||
|
const struct pmu_adc_channel *ch = &adc_channels[channel];
|
||||||
|
return pmu_adc_raw2mv(ch, pmu_read_adc(ch));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns battery voltage [millivolts] */
|
||||||
|
unsigned int adc_read_battery_voltage(void)
|
||||||
|
{
|
||||||
|
return adc_read_millivolts(ADC_BATTERY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns USB D+/D- voltage from ADC [millivolts] */
|
||||||
|
unsigned int adc_read_usbdata_voltage(bool dp)
|
||||||
|
{
|
||||||
|
unsigned int mvolts;
|
||||||
|
int gpio = dp ? 0xb0300 : 0xb0200; /* select D+/D- */
|
||||||
|
GPIOCMD = gpio | 0xf; /* route to ADCIN2 */
|
||||||
|
mvolts = adc_read_millivolts(ADC_USBDATA);
|
||||||
|
GPIOCMD = gpio | 0xe; /* unroute */
|
||||||
|
return mvolts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns resistor connected to "Accessory identify" pin [ohms] */
|
||||||
|
#define IAP_DEVICE_RESISTOR 100000 /* ohms */
|
||||||
|
int adc_read_accessory_resistor(void)
|
||||||
|
{
|
||||||
|
int raw = pmu_read_adc(&adc_channels[ADC_ACCESSORY]);
|
||||||
|
return (1023-raw) ? raw * IAP_DEVICE_RESISTOR / (1023-raw)
|
||||||
|
: -1 /* open circuit */;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* API functions */
|
||||||
unsigned short adc_read(int channel)
|
unsigned short adc_read(int channel)
|
||||||
{
|
{
|
||||||
return pmu_read_adc(channel);
|
return pmu_read_adc(&adc_channels[channel]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adc_init(void)
|
void adc_init(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,13 +21,23 @@
|
||||||
#ifndef _ADC_TARGET_H_
|
#ifndef _ADC_TARGET_H_
|
||||||
#define _ADC_TARGET_H_
|
#define _ADC_TARGET_H_
|
||||||
|
|
||||||
#define NUM_ADC_CHANNELS 4
|
#include <stdbool.h>
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
#define ADC_UNKNOWN_0 0
|
enum
|
||||||
#define ADC_UNKNOWN_1 1
|
{
|
||||||
#define ADC_BATTERY 2
|
ADC_BATTERY = 0,
|
||||||
#define ADC_UNKNOWN_3 3
|
ADC_USBDATA,
|
||||||
|
ADC_ACCESSORY,
|
||||||
|
NUM_ADC_CHANNELS
|
||||||
|
};
|
||||||
|
|
||||||
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
|
#define ADC_UNREG_POWER ADC_BATTERY /* For compatibility */
|
||||||
|
|
||||||
|
unsigned short adc_read_millivolts(int channel);
|
||||||
|
unsigned int adc_read_battery_voltage(void);
|
||||||
|
unsigned int adc_read_usbdata_voltage(bool dp);
|
||||||
|
int adc_read_accessory_resistor(void);
|
||||||
|
const char *adc_name(int channel);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -24,12 +24,11 @@
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
|
|
||||||
#include "pmu-target.h"
|
#include "pmu-target.h"
|
||||||
|
#include "adc-target.h"
|
||||||
#include "i2c-s5l8702.h"
|
#include "i2c-s5l8702.h"
|
||||||
#include "gpio-s5l8702.h"
|
#include "gpio-s5l8702.h"
|
||||||
|
|
||||||
|
|
||||||
static struct mutex pmu_adc_mutex;
|
|
||||||
|
|
||||||
int pmu_read_multiple(int address, int count, unsigned char* buffer)
|
int pmu_read_multiple(int address, int count, unsigned char* buffer)
|
||||||
{
|
{
|
||||||
return i2c_read(0, 0xe6, address, count, buffer);
|
return i2c_read(0, 0xe6, address, count, buffer);
|
||||||
|
@ -54,35 +53,6 @@ int pmu_write(int address, unsigned char val)
|
||||||
return pmu_write_multiple(address, 1, &val);
|
return pmu_write_multiple(address, 1, &val);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pmu_read_adc(unsigned int adc)
|
|
||||||
{
|
|
||||||
int data = 0;
|
|
||||||
mutex_lock(&pmu_adc_mutex);
|
|
||||||
pmu_write(0x54, 5 | (adc << 4));
|
|
||||||
while ((data & 0x80) == 0)
|
|
||||||
{
|
|
||||||
yield();
|
|
||||||
data = pmu_read(0x57);
|
|
||||||
}
|
|
||||||
int value = (pmu_read(0x55) << 2) | (data & 3);
|
|
||||||
mutex_unlock(&pmu_adc_mutex);
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* millivolts */
|
|
||||||
int pmu_read_battery_voltage(void)
|
|
||||||
{
|
|
||||||
return (pmu_read_adc(1) * 2000 / 1023) + 2250;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* milliamps */
|
|
||||||
int pmu_read_battery_current(void)
|
|
||||||
{
|
|
||||||
//TODO: Figure out how to read the battery current
|
|
||||||
// return pmu_read_adc(2);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void pmu_ldo_on_in_standby(unsigned int ldo, int onoff)
|
void pmu_ldo_on_in_standby(unsigned int ldo, int onoff)
|
||||||
{
|
{
|
||||||
if (ldo < 4)
|
if (ldo < 4)
|
||||||
|
@ -142,18 +112,87 @@ void pmu_write_rtc(unsigned char* buffer)
|
||||||
pmu_write_multiple(0x59, 7, buffer);
|
pmu_write_multiple(0x59, 7, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADC
|
||||||
|
*/
|
||||||
|
#define ADC_FULL_SCALE 2000
|
||||||
|
#define ADC_FULL_SCALE_VISA 2400
|
||||||
|
#define ADC_SUBTR_OFFSET 2250
|
||||||
|
|
||||||
|
static struct mutex pmu_adc_mutex;
|
||||||
|
|
||||||
|
/* converts raw 8/10-bit value to millivolts */
|
||||||
|
unsigned short pmu_adc_raw2mv(
|
||||||
|
const struct pmu_adc_channel *ch, unsigned short raw)
|
||||||
|
{
|
||||||
|
int full_scale = ADC_FULL_SCALE;
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
switch (ch->adcc1 & PCF5063X_ADCC1_ADCMUX_MASK)
|
||||||
|
{
|
||||||
|
case PCF5063X_ADCC1_MUX_BATSNS_RES:
|
||||||
|
case PCF5063X_ADCC1_MUX_ADCIN2_RES:
|
||||||
|
full_scale *= ((ch->adcc1 & PCF5063X_ADCC3_RES_DIV_MASK) ==
|
||||||
|
PCF5063X_ADCC3_RES_DIV_TWO) ? 2 : 3;
|
||||||
|
break;
|
||||||
|
case PCF5063X_ADCC1_MUX_BATSNS_SUBTR:
|
||||||
|
case PCF5063X_ADCC1_MUX_ADCIN2_SUBTR:
|
||||||
|
offset = ADC_SUBTR_OFFSET;
|
||||||
|
break;
|
||||||
|
case PCF5063X_ADCC1_MUX_BATTEMP:
|
||||||
|
if (ch->adcc2 & PCF5063X_ADCC2_RATIO_BATTEMP)
|
||||||
|
full_scale = ADC_FULL_SCALE_VISA;
|
||||||
|
break;
|
||||||
|
case PCF5063X_ADCC1_MUX_ADCIN1:
|
||||||
|
if (ch->adcc2 & PCF5063X_ADCC2_RATIO_ADCIN1)
|
||||||
|
full_scale = ADC_FULL_SCALE_VISA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
int nrb = ((ch->adcc1 & PCF5063X_ADCC1_RES_MASK) ==
|
||||||
|
PCF5063X_ADCC1_RES_8BIT) ? 8 : 10;
|
||||||
|
return (raw * full_scale / ((1<<nrb)-1)) + offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns raw value, 8 or 10-bit resolution */
|
||||||
|
unsigned short pmu_read_adc(const struct pmu_adc_channel *ch)
|
||||||
|
{
|
||||||
|
mutex_lock(&pmu_adc_mutex);
|
||||||
|
|
||||||
|
pmu_write(PCF5063X_REG_ADCC3, ch->adcc3);
|
||||||
|
if (ch->bias_dly)
|
||||||
|
sleep(ch->bias_dly);
|
||||||
|
uint8_t buf[2] = { ch->adcc2, ch->adcc1 | PCF5063X_ADCC1_ADCSTART };
|
||||||
|
pmu_write_multiple(PCF5063X_REG_ADCC2, 2, buf);
|
||||||
|
|
||||||
|
int adcs3 = 0;
|
||||||
|
while (!(adcs3 & PCF5063X_ADCS3_ADCRDY))
|
||||||
|
{
|
||||||
|
yield();
|
||||||
|
adcs3 = pmu_read(PCF5063X_REG_ADCS3);
|
||||||
|
}
|
||||||
|
|
||||||
|
int raw = pmu_read(PCF5063X_REG_ADCS1);
|
||||||
|
if ((ch->adcc1 & PCF5063X_ADCC1_RES_MASK) == PCF5063X_ADCC1_RES_10BIT)
|
||||||
|
raw = (raw << 2) | (adcs3 & PCF5063X_ADCS3_ADCDAT1L_MASK);
|
||||||
|
|
||||||
|
mutex_unlock(&pmu_adc_mutex);
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* eINT
|
* eINT
|
||||||
*/
|
*/
|
||||||
#define Q_EINT 0
|
#define Q_EINT 0
|
||||||
|
|
||||||
static char pmu_thread_stack[DEFAULT_STACK_SIZE/4];
|
static char pmu_thread_stack[DEFAULT_STACK_SIZE/2];
|
||||||
static struct event_queue pmu_queue;
|
static struct event_queue pmu_queue;
|
||||||
static unsigned char ints_msk[6];
|
static unsigned char ints_msk[6];
|
||||||
|
|
||||||
static void pmu_eint_isr(struct eint_handler*);
|
static void pmu_eint_isr(struct eint_handler*);
|
||||||
|
|
||||||
static struct eint_handler pmu_eint = {
|
static struct eint_handler pmu_eint =
|
||||||
|
{
|
||||||
.gpio_n = GPIO_EINT_PMU,
|
.gpio_n = GPIO_EINT_PMU,
|
||||||
.type = EIC_INTTYPE_LEVEL,
|
.type = EIC_INTTYPE_LEVEL,
|
||||||
.level = EIC_INTLEVEL_LOW,
|
.level = EIC_INTLEVEL_LOW,
|
||||||
|
@ -355,10 +394,11 @@ void pmu_preinit(void)
|
||||||
PCF5063X_REG_STBYCTL1, 0x0,
|
PCF5063X_REG_STBYCTL1, 0x0,
|
||||||
PCF5063X_REG_STBYCTL2, 0x8c,
|
PCF5063X_REG_STBYCTL2, 0x8c,
|
||||||
|
|
||||||
/* GPIO1,2 = input, GPIO3 = output */
|
/* GPIO1,2 = input, GPIO3 = output High (NoPower default) */
|
||||||
PCF5063X_REG_GPIOCTL, 0x3,
|
PCF5063X_REG_GPIOCTL, 0x3,
|
||||||
PCF5063X_REG_GPIO1CFG, 0x0,
|
PCF5063X_REG_GPIO1CFG, 0x0,
|
||||||
PCF5063X_REG_GPIO2CFG, 0x0,
|
PCF5063X_REG_GPIO2CFG, 0x0,
|
||||||
|
PCF5063X_REG_GPIO3CFG, 0x7,
|
||||||
|
|
||||||
/* DOWN2 converter (SDRAM): 1800 mV, enabled,
|
/* DOWN2 converter (SDRAM): 1800 mV, enabled,
|
||||||
startup current limit = 15mA*0x10 (TBC) */
|
startup current limit = 15mA*0x10 (TBC) */
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
#ifndef __PMU_TARGET_H__
|
#ifndef __PMU_TARGET_H__
|
||||||
#define __PMU_TARGET_H__
|
#define __PMU_TARGET_H__
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
|
@ -72,14 +73,22 @@ enum pcf50635_reg_gpiostat {
|
||||||
* GPIO3: output, unknown
|
* GPIO3: output, unknown
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct pmu_adc_channel
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
uint8_t adcc1;
|
||||||
|
uint8_t adcc2;
|
||||||
|
uint8_t adcc3;
|
||||||
|
uint8_t bias_dly; /* RB ticks */
|
||||||
|
};
|
||||||
|
|
||||||
unsigned char pmu_read(int address);
|
unsigned char pmu_read(int address);
|
||||||
int pmu_write(int address, unsigned char val);
|
int pmu_write(int address, unsigned char val);
|
||||||
int pmu_read_multiple(int address, int count, unsigned char* buffer);
|
int pmu_read_multiple(int address, int count, unsigned char* buffer);
|
||||||
int pmu_write_multiple(int address, int count, unsigned char* buffer);
|
int pmu_write_multiple(int address, int count, unsigned char* buffer);
|
||||||
int pmu_read_adc(unsigned int adc);
|
unsigned short pmu_read_adc(const struct pmu_adc_channel *ch);
|
||||||
int pmu_read_battery_voltage(void);
|
unsigned short pmu_adc_raw2mv(
|
||||||
int pmu_read_battery_current(void);
|
const struct pmu_adc_channel *ch, unsigned short raw);
|
||||||
void pmu_init(void);
|
void pmu_init(void);
|
||||||
void pmu_ldo_on_in_standby(unsigned int ldo, int onoff);
|
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_set_voltage(unsigned int ldo, unsigned char voltage);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "pmu-target.h"
|
#include "pmu-target.h"
|
||||||
#include "power.h"
|
#include "power.h"
|
||||||
#include "audiohw.h"
|
#include "audiohw.h"
|
||||||
|
#include "adc-target.h"
|
||||||
|
|
||||||
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
|
||||||
{
|
{
|
||||||
|
@ -49,20 +50,12 @@ const unsigned short percent_to_volt_charge[11] =
|
||||||
};
|
};
|
||||||
#endif /* CONFIG_CHARGING */
|
#endif /* CONFIG_CHARGING */
|
||||||
|
|
||||||
/* ADC should read 0x3ff=6.00V */
|
|
||||||
#define BATTERY_SCALE_FACTOR 6000
|
|
||||||
/* full-scale ADC readout (2^10) in millivolt */
|
|
||||||
|
|
||||||
|
|
||||||
/* Returns battery voltage from ADC [millivolts] */
|
/* Returns battery voltage from ADC [millivolts] */
|
||||||
int _battery_voltage(void)
|
int _battery_voltage(void)
|
||||||
{
|
{
|
||||||
int compensation = (10 * (pmu_read_battery_current() - 7)) / 12;
|
return adc_read_battery_voltage();
|
||||||
if (charging_state()) return pmu_read_battery_voltage() - compensation;
|
|
||||||
return pmu_read_battery_voltage() + compensation;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef HAVE_ACCESSORY_SUPPLY
|
#ifdef HAVE_ACCESSORY_SUPPLY
|
||||||
void accessory_supply_set(bool enable)
|
void accessory_supply_set(bool enable)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue