Patch #5347 by Rani Hod - Adds FM radio and recording features to the iAudio X5.
Also includes a rewrite of the Coldfire I2C driver to include both read and write. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10272 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
e8818efbe9
commit
ed4d7a33bd
15 changed files with 450 additions and 168 deletions
|
@ -72,7 +72,7 @@
|
|||
#else
|
||||
#define pcmbuf_init()
|
||||
#endif
|
||||
#if (defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)) && !defined(SIMULATOR)
|
||||
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||
#include "pcm_record.h"
|
||||
#define SETTINGS_RESET BUTTON_REC
|
||||
#endif
|
||||
|
@ -425,7 +425,7 @@ void init(void)
|
|||
talk_init();
|
||||
|
||||
audio_init();
|
||||
#if (defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)) && !defined(SIMULATOR)
|
||||
#if (CONFIG_CODEC == SWCODEC) && defined(HAVE_RECORDING) && !defined(SIMULATOR)
|
||||
pcm_rec_init();
|
||||
#endif
|
||||
|
||||
|
|
|
@ -64,7 +64,13 @@
|
|||
#ifdef CONFIG_TUNER
|
||||
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
#ifdef HAVE_UDA1380
|
||||
#include "uda1380.h"
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
#include "tlv320.h"
|
||||
#endif
|
||||
|
||||
#include "pcm_record.h"
|
||||
#endif
|
||||
|
||||
|
@ -109,6 +115,35 @@
|
|||
#define FM_STOP BUTTON_OFF
|
||||
#define FM_RC_STOP BUTTON_RC_STOP
|
||||
|
||||
#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
|
||||
/* pause/play - short PLAY */
|
||||
#define FM_PLAY_PRE BUTTON_PLAY
|
||||
#define FM_RC_PLAY_PRE BUTTON_RC_PLAY
|
||||
#define FM_PLAY (BUTTON_PLAY | BUTTON_REL)
|
||||
#define FM_RC_PLAY (BUTTON_RC_PLAY | BUTTON_REL)
|
||||
/* preset/scan mode - long PLAY */
|
||||
#define FM_MODE (BUTTON_PLAY | BUTTON_REPEAT)
|
||||
#define FM_RC_MODE (BUTTON_RC_PLAY | BUTTON_REPEAT)
|
||||
/* preset menu - short SELECT */
|
||||
#define FM_PRESET_PRE BUTTON_SELECT
|
||||
#define FM_RC_PRESET_PRE BUTTON_RC_MENU
|
||||
#define FM_PRESET (BUTTON_SELECT | BUTTON_REL)
|
||||
#define FM_RC_PRESET (BUTTON_RC_MENU | BUTTON_REL)
|
||||
/* fm menu - long SELECT */
|
||||
#define FM_MENU (BUTTON_SELECT | BUTTON_REPEAT)
|
||||
#define FM_RC_MENU (BUTTON_RC_MENU | BUTTON_REPEAT)
|
||||
/* main menu(exit radio while playing) - REC */
|
||||
#define FM_EXIT_PRE BUTTON_REC
|
||||
#define FM_EXIT (BUTTON_REC | BUTTON_REL)
|
||||
#define FM_RC_EXIT_PRE BUTTON_RC_MODE
|
||||
#define FM_RC_EXIT (BUTTON_RC_MODE | BUTTON_REL)
|
||||
/* prev/next preset on the remote - REW/FF */
|
||||
#define FM_NEXT_PRESET (BUTTON_RC_FF | BUTTON_REL)
|
||||
#define FM_PREV_PRESET (BUTTON_RC_REW | BUTTON_REL)
|
||||
/* stop and exit radio - ON */
|
||||
#define FM_STOP BUTTON_POWER
|
||||
#define FM_RC_STOP (BUTTON_RC_MODE | BUTTON_REPEAT)
|
||||
|
||||
#elif CONFIG_KEYPAD == ONDIO_PAD /* restricted keypad */
|
||||
#define FM_MENU (BUTTON_MENU | BUTTON_REPEAT)
|
||||
#define FM_RECORD_DBLPRE BUTTON_MENU
|
||||
|
@ -158,7 +193,7 @@ int radio_get(int setting);
|
|||
#if CONFIG_TUNER == S1A0903X01 /* FM recorder */
|
||||
#define radio_set samsung_set
|
||||
#define radio_get samsung_get
|
||||
#elif CONFIG_TUNER == TEA5767 /* Iriver */
|
||||
#elif CONFIG_TUNER == TEA5767 /* iriver, iaudio */
|
||||
#define radio_set philips_set
|
||||
#define radio_get philips_get
|
||||
#elif CONFIG_TUNER == (S1A0903X01 | TEA5767) /* OndioFM */
|
||||
|
@ -387,8 +422,15 @@ bool radio_screen(void)
|
|||
|
||||
#else
|
||||
peak_meter_enabled = false;
|
||||
|
||||
#ifdef HAVE_UDA1380
|
||||
uda1380_enable_recording(false);
|
||||
uda1380_set_monitor(true);
|
||||
#elif defined(HAVE_TLV320)
|
||||
//tlv320_enable_recording(false);
|
||||
tlv320_set_recvol(23, 23, AUDIO_GAIN_LINEIN); /* 0dB */
|
||||
tlv320_set_monitor(true);
|
||||
#endif
|
||||
|
||||
/* Set the input multiplexer to FM */
|
||||
pcm_rec_mux(1);
|
||||
|
@ -971,7 +1013,7 @@ bool radio_screen(void)
|
|||
while(1)
|
||||
{
|
||||
button = button_get(true);
|
||||
if(button == (BUTTON_OFF | BUTTON_REL))
|
||||
if(button == (FM_STOP | BUTTON_REL))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1004,6 +1046,11 @@ bool radio_screen(void)
|
|||
radio_stop();
|
||||
#ifndef SIMULATOR /* SIMULATOR. Catch FMRADIO_OFF status for the sim. */
|
||||
#if CONFIG_CODEC == SWCODEC
|
||||
#ifdef HAVE_TLV320
|
||||
//tlv320_disable_recording();
|
||||
tlv320_set_monitor(false);
|
||||
#endif
|
||||
|
||||
pcm_rec_mux(0); /* Line In */
|
||||
peak_meter_enabled = true;
|
||||
#endif
|
||||
|
@ -1320,7 +1367,7 @@ int handle_radio_presets_cb(int key, int m)
|
|||
key = BUTTON_NONE;
|
||||
break;
|
||||
#endif
|
||||
#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD)
|
||||
#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD) && (CONFIG_KEYPAD != IAUDIO_X5_PAD)
|
||||
#ifdef FM_PRESET
|
||||
case FM_PRESET:
|
||||
menu_draw(m);
|
||||
|
@ -1565,7 +1612,7 @@ int radio_menu_cb(int key, int m)
|
|||
(void)m;
|
||||
switch(key)
|
||||
{
|
||||
#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD)
|
||||
#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD) && (CONFIG_KEYPAD != IAUDIO_X5_PAD)
|
||||
#ifdef MENU_ENTER2
|
||||
case MENU_ENTER2:
|
||||
#endif
|
||||
|
@ -1574,7 +1621,7 @@ int radio_menu_cb(int key, int m)
|
|||
key = BUTTON_NONE; /* eat the downpress, next menu reacts on release */
|
||||
break;
|
||||
|
||||
#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD)
|
||||
#if (CONFIG_KEYPAD != IRIVER_H100_PAD) && (CONFIG_KEYPAD != IRIVER_H300_PAD) && (CONFIG_KEYPAD != IAUDIO_X5_PAD)
|
||||
#ifdef MENU_ENTER2
|
||||
case MENU_ENTER2 | BUTTON_REL:
|
||||
#endif
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
#ifdef HAVE_UDA1380
|
||||
#include "uda1380.h"
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
#include "tlv320.h"
|
||||
#endif
|
||||
|
||||
#include "mp3_playback.h"
|
||||
#include "mas.h"
|
||||
|
@ -109,6 +112,16 @@
|
|||
#define REC_RC_PREV BUTTON_RC_REW
|
||||
#define REC_RC_SETTINGS BUTTON_RC_MODE
|
||||
|
||||
#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
|
||||
#define REC_SHUTDOWN (BUTTON_POWER | BUTTON_REPEAT)
|
||||
#define REC_STOPEXIT BUTTON_POWER
|
||||
#define REC_RECPAUSE BUTTON_REC
|
||||
#define REC_INC BUTTON_RIGHT
|
||||
#define REC_DEC BUTTON_LEFT
|
||||
#define REC_NEXT BUTTON_DOWN
|
||||
#define REC_PREV BUTTON_UP
|
||||
#define REC_SETTINGS BUTTON_PLAY
|
||||
|
||||
#elif CONFIG_KEYPAD == GMINI100_PAD
|
||||
#define REC_SHUTDOWN (BUTTON_OFF | BUTTON_REPEAT)
|
||||
#define REC_STOPEXIT BUTTON_OFF
|
||||
|
@ -362,6 +375,9 @@ bool recording_screen(void)
|
|||
audio_stop();
|
||||
/* Set peak meter to recording mode */
|
||||
peak_meter_playback(false);
|
||||
#ifdef IAUDIO_X5
|
||||
pcm_rec_mux(0); /* select line-in (not radio) */
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_SPDIF_IN) && !defined(SIMULATOR)
|
||||
if (global_settings.rec_source == SOURCE_SPDIF)
|
||||
|
|
|
@ -27,6 +27,22 @@
|
|||
|
||||
#if (CONFIG_TUNER & TEA5767)
|
||||
#if (CONFIG_I2C == I2C_COLDFIRE)
|
||||
|
||||
#ifdef IAUDIO_X5
|
||||
#include "i2c-coldfire.h"
|
||||
|
||||
int fmradio_i2c_write(unsigned char address, const unsigned char* buf,
|
||||
int count)
|
||||
{
|
||||
return i2c_write(I2C_IFACE_0, address, buf, count);
|
||||
}
|
||||
|
||||
int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count)
|
||||
{
|
||||
return i2c_read(I2C_IFACE_0, address, buf, count);
|
||||
}
|
||||
#else
|
||||
|
||||
/* cute little functions, atomic read-modify-write */
|
||||
/* SDA is GPIO1,23 */
|
||||
|
||||
|
@ -242,6 +258,7 @@ int fmradio_i2c_read(int address, unsigned char* buf, int count)
|
|||
fmradio_i2c_stop();
|
||||
return x;
|
||||
}
|
||||
#endif /* ! IAUDIO_X5 */
|
||||
#else
|
||||
/* cute little functions, atomic read-modify-write */
|
||||
/* SDA is PB4 */
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2005 by Andy Young
|
||||
|
@ -23,17 +24,16 @@
|
|||
#include "system.h"
|
||||
#include "i2c-coldfire.h"
|
||||
|
||||
#define I2C_DEVICE_1 ((volatile unsigned char *)&MADR)
|
||||
#define I2C_DEVICE_2 ((volatile unsigned char *)&MADR2)
|
||||
|
||||
/* Local functions definitions */
|
||||
/* --- Local functions - declarations --- */
|
||||
|
||||
static int i2c_write_byte(int device, unsigned char data);
|
||||
static int i2c_gen_start(int device);
|
||||
static void i2c_gen_stop(int device);
|
||||
static volatile unsigned char *i2c_get_addr(int device);
|
||||
static int i2c_start(volatile unsigned char *iface);
|
||||
static int i2c_wait_for_slave(volatile unsigned char *iface);
|
||||
static int i2c_outb(volatile unsigned char *iface, unsigned char byte);
|
||||
inline void i2c_stop(volatile unsigned char *iface);
|
||||
|
||||
/* Public functions */
|
||||
|
||||
/* --- Public functions - implementation --- */
|
||||
|
||||
void i2c_init(void)
|
||||
{
|
||||
|
@ -55,14 +55,15 @@ void i2c_init(void)
|
|||
#endif
|
||||
|
||||
/* I2C Clock divisor = 160 => 124.1556 MHz / 2 / 160 = 388.08 kHz */
|
||||
MFDR = 0x0d;
|
||||
MFDR = 0x0d;
|
||||
MFDR2 = 0x0d;
|
||||
|
||||
#ifdef IAUDIO_X5
|
||||
MBCR = IEN; /* Enable interface */
|
||||
MBCR = IEN; /* Enable interface */
|
||||
MBCR2 = IEN;
|
||||
#endif
|
||||
|
||||
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
|
||||
#if defined(IRIVER_H100_SERIES) || defined(IRIVER_H300_SERIES)
|
||||
/* Audio Codec */
|
||||
MBDR = 0; /* iRiver firmware does this */
|
||||
MBCR = IEN; /* Enable interface */
|
||||
|
@ -72,109 +73,169 @@ void i2c_init(void)
|
|||
void i2c_close(void)
|
||||
{
|
||||
MBCR = 0;
|
||||
MBCR2 = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes bytes to the selected device.
|
||||
/*
|
||||
* Writes bytes to a I2C device.
|
||||
*
|
||||
* Use device=1 for bus 1 at 0x40000280
|
||||
* Use device=2 for bus 2 at 0x80000440
|
||||
*
|
||||
* Returns number of bytes successfully send or -1 if START failed
|
||||
* Returns number of bytes successfully sent or a negative value on error.
|
||||
*/
|
||||
int i2c_write(int device, unsigned char *buf, int count)
|
||||
int i2c_write(volatile unsigned char *iface, unsigned char addr,
|
||||
const unsigned char *buf, int count)
|
||||
{
|
||||
int i;
|
||||
int rc;
|
||||
int i, rc;
|
||||
|
||||
rc = i2c_gen_start(device);
|
||||
if ( ! count)
|
||||
return 0;
|
||||
|
||||
rc = i2c_start(iface);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
rc = i2c_outb(iface, addr & 0xfe);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
logf("i2c: gen_start failed (d=%d)", device);
|
||||
return rc*10 - 1;
|
||||
}
|
||||
|
||||
for (i=0; i<count; i++)
|
||||
{
|
||||
rc = i2c_write_byte(device, buf[i]);
|
||||
rc = i2c_outb(iface, *buf++);
|
||||
if (rc < 0)
|
||||
{
|
||||
logf("i2c: write failed at (d=%d,i=%d)", device, i);
|
||||
return rc*10 - 2;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
i2c_gen_stop(device);
|
||||
|
||||
i2c_stop(iface);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/* Write a byte to the interface, returns 0 on success, -1 otherwise. */
|
||||
int i2c_write_byte(int device, unsigned char data)
|
||||
/*
|
||||
* Reads bytes from a I2C device.
|
||||
*
|
||||
* Returns number of bytes successfully received or a negative value on error.
|
||||
*/
|
||||
int i2c_read(volatile unsigned char *iface, unsigned char addr,
|
||||
unsigned char *buf, int count)
|
||||
{
|
||||
volatile unsigned char *regs = i2c_get_addr(device);
|
||||
int i, rc;
|
||||
|
||||
long count = 0;
|
||||
if ( ! count)
|
||||
return 0;
|
||||
|
||||
rc = i2c_start(iface);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
regs[O_MBDR] = data; /* Write data byte */
|
||||
rc = i2c_outb(iface, addr | 1);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Wait for bus busy */
|
||||
while (!(regs[O_MBSR] & IBB) && count < MAX_LOOP)
|
||||
count++;
|
||||
/* Switch to Rx mode */
|
||||
iface[O_MBCR] &= ~MTX;
|
||||
iface[O_MBCR] &= ~TXAK;
|
||||
|
||||
/* Dummy read */
|
||||
rc = (int) iface[O_MBDR];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
rc = i2c_wait_for_slave(iface);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
if (count >= MAX_LOOP)
|
||||
return -1;
|
||||
if (i == count-2)
|
||||
/* Don't ACK the next-to-last byte */
|
||||
iface[O_MBCR] |= TXAK;
|
||||
|
||||
if (i == count-1)
|
||||
/* Generate STOP before reading last byte */
|
||||
i2c_stop(iface);
|
||||
|
||||
count = 0;
|
||||
|
||||
/* Wait for interrupt flag */
|
||||
while (!(regs[O_MBSR] & IFF) && count < MAX_LOOP)
|
||||
count++;
|
||||
|
||||
if (count >= MAX_LOOP)
|
||||
return -2;
|
||||
|
||||
regs[O_MBSR] &= ~IFF; /* Clear interrupt flag */
|
||||
|
||||
if (!(regs[O_MBSR] & ICF)) /* Check that transfer is complete */
|
||||
return -3;
|
||||
|
||||
if (regs[O_MBSR] & RXAK) /* Check that the byte has been ACKed */
|
||||
return -4;
|
||||
|
||||
return 0;
|
||||
*buf++ = iface[O_MBDR];
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/* --- Local functions - implementation --- */
|
||||
|
||||
/* Returns 0 on success, -1 on failure */
|
||||
int i2c_gen_start(int device)
|
||||
/* Begin I2C session on the given interface.
|
||||
*
|
||||
* Returns 0 on success, negative value on error.
|
||||
*/
|
||||
int i2c_start(volatile unsigned char *iface)
|
||||
{
|
||||
volatile unsigned char *regs = i2c_get_addr(device);
|
||||
long count = 0;
|
||||
|
||||
/* Wait for bus to become free */
|
||||
while ((regs[O_MBSR] & IBB) && (count < MAX_LOOP))
|
||||
count++;
|
||||
|
||||
if (count >= MAX_LOOP)
|
||||
int j = MAX_LOOP;
|
||||
while (--j && (iface[O_MBSR] & IBB))
|
||||
;
|
||||
if (!j)
|
||||
{
|
||||
logf("i2c: bus is busy (iface=%08x)", iface);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Generate START and prepare for write */
|
||||
iface[O_MBCR] |= (MSTA | TXAK | MTX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
regs[O_MBCR] |= MSTA | MTX; /* Generate START */
|
||||
|
||||
/* Wait for slave to act on given I2C interface.
|
||||
*
|
||||
* Returns 0 on success, negative value on error.
|
||||
*/
|
||||
int i2c_wait_for_slave(volatile unsigned char *iface)
|
||||
{
|
||||
int j = MAX_LOOP;
|
||||
while (--j && ! (iface[O_MBSR] & IFF))
|
||||
;
|
||||
if (!j)
|
||||
{
|
||||
logf("i2c: IFF not set (iface=%08x)", iface);
|
||||
i2c_stop(iface);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Clear interrupt flag */
|
||||
iface[O_MBSR] &= ~IFF;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void i2c_gen_stop(int device)
|
||||
{
|
||||
volatile unsigned char *regs = i2c_get_addr(device);
|
||||
regs[O_MBCR] &= ~MSTA; /* Clear MSTA to generate STOP */
|
||||
}
|
||||
|
||||
|
||||
volatile unsigned char *i2c_get_addr(int device)
|
||||
/* Write the given byte to the given I2C interface.
|
||||
*
|
||||
* Returns 0 on success, negative value on error.
|
||||
*/
|
||||
int i2c_outb(volatile unsigned char *iface, unsigned char byte)
|
||||
{
|
||||
if (device == 1)
|
||||
return I2C_DEVICE_1;
|
||||
int rc;
|
||||
|
||||
return I2C_DEVICE_2;
|
||||
iface[O_MBDR] = byte;
|
||||
|
||||
rc = i2c_wait_for_slave(iface);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
/* Check that transfer is complete */
|
||||
if ( !(iface[O_MBSR] & ICF))
|
||||
{
|
||||
logf("i2c: transfer error (iface=%08x)", iface);
|
||||
i2c_stop(iface);
|
||||
return -3;
|
||||
}
|
||||
|
||||
/* Check that the byte has been ACKed */
|
||||
if (iface[O_MBSR] & RXAK)
|
||||
{
|
||||
logf("i2c: no ACK (iface=%08x)", iface);
|
||||
i2c_stop(iface);
|
||||
return -4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* End I2C session on the given interface. */
|
||||
inline void i2c_stop(volatile unsigned char *iface)
|
||||
{
|
||||
iface[O_MBCR] &= ~MSTA;
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "string.h"
|
||||
#include "file.h"
|
||||
#include "buffer.h"
|
||||
#include "audio.h"
|
||||
|
||||
#include "i2c-coldfire.h"
|
||||
#include "tlv320.h"
|
||||
|
@ -46,14 +47,13 @@ unsigned tlv320_regs[0xf];
|
|||
|
||||
void tlv320_write_reg(unsigned reg, unsigned value)
|
||||
{
|
||||
unsigned char data[3];
|
||||
unsigned char data[2];
|
||||
|
||||
data[0] = TLV320_ADDR;
|
||||
/* The register address is the high 7 bits and the data the low 9 bits */
|
||||
data[1] = (reg << 1) | ((value >> 8) & 1);
|
||||
data[2] = value & 0xff;
|
||||
data[0] = (reg << 1) | ((value >> 8) & 1);
|
||||
data[1] = value & 0xff;
|
||||
|
||||
if (i2c_write(1, data, 3) != 3)
|
||||
if (i2c_write(I2C_IFACE_0, TLV320_ADDR, data, 2) != 2)
|
||||
{
|
||||
logf("tlv320 error reg=0x%x", reg);
|
||||
return;
|
||||
|
@ -73,15 +73,16 @@ void tlv320_init(void)
|
|||
|
||||
/* Initialize all registers */
|
||||
|
||||
tlv320_write_reg(REG_PC, 0x00); /* All ON */
|
||||
tlv320_set_linein_vol(0, 0);
|
||||
tlv320_write_reg(REG_PC, PC_ADC|PC_MIC|PC_LINE); /* All ON except ADC, MIC and LINE */
|
||||
tlv320_set_recvol(0, 0, AUDIO_GAIN_MIC);
|
||||
tlv320_set_recvol(0, 0, AUDIO_GAIN_LINEIN);
|
||||
tlv320_mute(true);
|
||||
tlv320_write_reg(REG_AAP, AAP_DAC|AAP_MICM);
|
||||
tlv320_write_reg(REG_DAP, 0x00); /* No deemphasis */
|
||||
tlv320_write_reg(REG_DAIF, DAIF_IWL_16|DAIF_FOR_I2S);
|
||||
tlv320_set_headphone_vol(0, 0);
|
||||
tlv320_write_reg(REG_DIA, DIA_ACT);
|
||||
tlv320_write_reg(REG_SRC, (8 << 2)); /* 44.1kHz */
|
||||
tlv320_write_reg(REG_SRC, (1 << 5)); /* 44.1kHz */
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -114,18 +115,30 @@ void tlv320_set_headphone_vol(int vol_l, int vol_r)
|
|||
}
|
||||
|
||||
/**
|
||||
* Sets left and right linein volume (31(max) to 0(muted))
|
||||
* Set recording volume
|
||||
*
|
||||
* Line in : 0 .. 31 => Volume -34.5 .. 12 dB
|
||||
* Mic (left): 0 .. 1 => Volume 0 .. 20 dB
|
||||
*
|
||||
*/
|
||||
void tlv320_set_linein_vol(int vol_l, int vol_r)
|
||||
void tlv320_set_recvol(int left, int right, int type)
|
||||
{
|
||||
unsigned value_l = tlv320_regs[REG_LLIV];
|
||||
unsigned value_r = tlv320_regs[REG_RLIV];
|
||||
if (type == AUDIO_GAIN_MIC)
|
||||
{
|
||||
unsigned value_aap = tlv320_regs[REG_AAP];
|
||||
|
||||
if (left)
|
||||
value_aap |= AAP_MICB; /* Enable mic boost (20dB) */
|
||||
else
|
||||
value_aap &= ~AAP_MICB;
|
||||
|
||||
value_l |= LLIV_LIV(vol_l);
|
||||
value_r |= RLIV_RIV(vol_r);
|
||||
|
||||
tlv320_write_reg(REG_LLIV, value_l);
|
||||
tlv320_write_reg(REG_RLIV, value_r);
|
||||
tlv320_write_reg(REG_AAP, value_aap);
|
||||
|
||||
} else if (type == AUDIO_GAIN_LINEIN)
|
||||
{
|
||||
tlv320_write_reg(REG_LLIV, LLIV_LIV(left));
|
||||
tlv320_write_reg(REG_RLIV, RLIV_RIV(right));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -148,10 +161,11 @@ void tlv320_mute(bool mute)
|
|||
value_r = RHV_RHV(tlv320.vol_r);
|
||||
}
|
||||
|
||||
tlv320_write_reg(REG_LHV, value_r);
|
||||
tlv320_write_reg(REG_LHV, value_l);
|
||||
tlv320_write_reg(REG_RHV, value_r);
|
||||
}
|
||||
|
||||
/* Nice shutdown of TLV320 codec */
|
||||
void tlv320_close()
|
||||
{
|
||||
tlv320_write_reg(REG_PC, 0xFF); /* All OFF */
|
||||
|
@ -159,35 +173,66 @@ void tlv320_close()
|
|||
|
||||
void tlv320_enable_recording(bool source_mic)
|
||||
{
|
||||
unsigned value_pc = tlv320_regs[REG_PC];
|
||||
unsigned value_aap = tlv320_regs[REG_AAP];
|
||||
|
||||
/* select source*/
|
||||
unsigned value_daif = tlv320_regs[REG_DAIF];
|
||||
unsigned value_aap, value_pc;
|
||||
|
||||
if (source_mic)
|
||||
{
|
||||
value_aap &= ~AAP_INSEL;
|
||||
value_pc |= PC_MIC;
|
||||
/* select mic and enable mic boost (20 dB) */
|
||||
value_aap = AAP_DAC | AAP_INSEL | AAP_MICB;
|
||||
value_pc = PC_LINE; /* power down line-in */
|
||||
}
|
||||
else
|
||||
{
|
||||
value_aap |= AAP_INSEL;
|
||||
value_pc |= PC_LINE;
|
||||
value_aap = AAP_DAC | AAP_MICM;
|
||||
value_pc = PC_MIC; /* power down mic */
|
||||
}
|
||||
|
||||
/* poweron adc */
|
||||
value_pc |= PC_ADC;
|
||||
tlv320_write_reg(REG_PC, value_pc);
|
||||
sleep(HZ/8);
|
||||
|
||||
tlv320_write_reg(REG_AAP, value_aap);
|
||||
tlv320_write_reg(REG_PC, value_pc);
|
||||
sleep(HZ/8);
|
||||
|
||||
/* Enable MASTER mode (start sending I2S data to the CPU) */
|
||||
value_daif |= DAIF_MS;
|
||||
tlv320_write_reg(REG_DAIF, value_daif);
|
||||
}
|
||||
|
||||
|
||||
void tlv320_disable_recording()
|
||||
{
|
||||
unsigned value = tlv320_regs[REG_PC];
|
||||
unsigned value_pc = tlv320_regs[REG_PC];
|
||||
unsigned value_aap = tlv320_regs[REG_AAP];
|
||||
unsigned value_daif = tlv320_regs[REG_DAIF];
|
||||
|
||||
/* powerdown mic, linein and adc */
|
||||
value &= ~(PC_MIC | PC_LINE | PC_ADC);
|
||||
value_daif &= ~DAIF_MS; /* disable MASTER mode */
|
||||
tlv320_write_reg(REG_DAIF, value_daif);
|
||||
|
||||
value_aap |= AAP_MICM; /* mute mic */
|
||||
tlv320_write_reg(REG_PC, value_aap);
|
||||
|
||||
/* powerdown mic, linein and adc */
|
||||
tlv320_write_reg(REG_PC, value);
|
||||
value_pc |= (PC_MIC|PC_LINE|PC_ADC); /* power down mic, line-in and adc */
|
||||
tlv320_write_reg(REG_PC, value_pc);
|
||||
|
||||
sleep(HZ/8);
|
||||
}
|
||||
|
||||
void tlv320_set_monitor(bool enable)
|
||||
{
|
||||
unsigned value_aap, value_pc;
|
||||
if (enable)
|
||||
{
|
||||
value_aap = AAP_BYPASS | AAP_MICM;
|
||||
value_pc = (PC_MIC|PC_DAC|PC_ADC); /* power down mic, dac and adc */
|
||||
}
|
||||
else
|
||||
{
|
||||
value_aap = AAP_DAC | AAP_MICM;
|
||||
value_pc = (PC_MIC|PC_LINE|PC_ADC); /* power down mic, line-in and adc */
|
||||
}
|
||||
tlv320_write_reg(REG_AAP, value_aap);
|
||||
tlv320_write_reg(REG_PC, value_pc);
|
||||
|
||||
sleep(HZ/8);
|
||||
}
|
||||
|
||||
|
|
|
@ -76,14 +76,13 @@ unsigned short uda1380_defaults[2*NUM_DEFAULT_REGS] =
|
|||
/* Returns 0 if register was written or -1 if write failed */
|
||||
int uda1380_write_reg(unsigned char reg, unsigned short value)
|
||||
{
|
||||
unsigned char data[4];
|
||||
unsigned char data[3];
|
||||
|
||||
data[0] = UDA1380_ADDR;
|
||||
data[1] = reg;
|
||||
data[2] = value >> 8;
|
||||
data[3] = value & 0xff;
|
||||
data[0] = reg;
|
||||
data[1] = value >> 8;
|
||||
data[2] = value & 0xff;
|
||||
|
||||
if (i2c_write(1, data, 4) != 4)
|
||||
if (i2c_write(I2C_IFACE_0, UDA1380_ADDR, data, 3) != 3)
|
||||
{
|
||||
DEBUGF("uda1380 error reg=0x%x", reg);
|
||||
return -1;
|
||||
|
@ -322,21 +321,20 @@ void uda1380_set_recvol(int left, int right, int type)
|
|||
{
|
||||
/* for this order we can combine both registers,
|
||||
making the glitch even smaller */
|
||||
unsigned char data[6];
|
||||
unsigned char data[5];
|
||||
unsigned short value_dec;
|
||||
unsigned short value_pga;
|
||||
value_dec = DEC_VOLL(left) | DEC_VOLR(right);
|
||||
value_pga = (uda1380_regs[REG_PGA] & ~PGA_GAIN_MASK)
|
||||
| PGA_GAINL(left_ag) | PGA_GAINR(right_ag);
|
||||
|
||||
data[0] = UDA1380_ADDR;
|
||||
data[1] = REG_DEC_VOL;
|
||||
data[2] = value_dec >> 8;
|
||||
data[3] = value_dec & 0xff;
|
||||
data[4] = value_pga >> 8;
|
||||
data[5] = value_pga & 0xff;
|
||||
data[0] = REG_DEC_VOL;
|
||||
data[1] = value_dec >> 8;
|
||||
data[2] = value_dec & 0xff;
|
||||
data[3] = value_pga >> 8;
|
||||
data[4] = value_pga & 0xff;
|
||||
|
||||
if (i2c_write(1, data, 6) != 6)
|
||||
if (i2c_write(I2C_IFACE_0, UDA1380_ADDR, data, 5) != 5)
|
||||
{
|
||||
DEBUGF("uda1380 error reg=combi rec gain");
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#define MODEL_NUMBER 10
|
||||
|
||||
/* define this if you have recording possibility */
|
||||
/*#define HAVE_RECORDING 1*/
|
||||
#define HAVE_RECORDING 1
|
||||
|
||||
/* define this if you have a bitmap LCD display */
|
||||
#define HAVE_LCD_BITMAP 1
|
||||
|
@ -53,6 +53,11 @@
|
|||
/* The number of bytes reserved for loadable plugins */
|
||||
#define PLUGIN_BUFFER_SIZE 0x80000
|
||||
|
||||
/* FM Tuner */
|
||||
#define CONFIG_TUNER TEA5767
|
||||
#define CONFIG_TUNER_XTAL 32768
|
||||
|
||||
|
||||
#define BATTERY_CAPACITY_DEFAULT 950 /* default battery capacity */
|
||||
|
||||
#ifndef SIMULATOR
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#ifndef FMRADIO_I2C_H
|
||||
#define FMRADIO_I2C_H
|
||||
|
||||
int fmradio_i2c_write(int address, const unsigned char* buf, int count);
|
||||
int fmradio_i2c_read(int address, unsigned char* buf, int count);
|
||||
int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count);
|
||||
int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -26,10 +26,18 @@
|
|||
#ifndef _I2C_COLDFIRE_H
|
||||
#define _I2C_COLDFIRE_H
|
||||
|
||||
void i2c_init(void);
|
||||
int i2c_write(int device, unsigned char *buf, int count);
|
||||
void i2c_close(void);
|
||||
#include "cpu.h"
|
||||
|
||||
void i2c_init(void);
|
||||
int i2c_read (volatile unsigned char *iface, unsigned char addr,
|
||||
unsigned char *buf, int count);
|
||||
int i2c_write(volatile unsigned char *iface, unsigned char addr,
|
||||
const unsigned char *buf, int count);
|
||||
void i2c_close(void);
|
||||
void i2c_adjust_prescale(int multiplier);
|
||||
|
||||
#define I2C_IFACE_0 ((volatile unsigned char *)&MADR)
|
||||
#define I2C_IFACE_1 ((volatile unsigned char *)&MADR2)
|
||||
|
||||
#define MAX_LOOP 0x100 /* TODO: select a better value */
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ enum {
|
|||
SOUND_MDB_ENABLE,
|
||||
SOUND_SUPERBASS,
|
||||
#endif
|
||||
#if CONFIG_CODEC == MAS3587F || defined(HAVE_UDA1380)
|
||||
#if CONFIG_CODEC == MAS3587F || defined(HAVE_UDA1380) || defined(HAVE_TLV320)
|
||||
SOUND_LEFT_GAIN,
|
||||
SOUND_RIGHT_GAIN,
|
||||
SOUND_MIC_GAIN,
|
||||
|
|
|
@ -26,11 +26,12 @@ extern void tlv320_init(void);
|
|||
extern void tlv320_reset(void);
|
||||
extern void tlv320_enable_output(bool enable);
|
||||
extern void tlv320_set_headphone_vol(int vol_l, int vol_r);
|
||||
extern void tlv320_set_linein_vol(int vol_l, int vol_r);
|
||||
extern void tlv320_set_recvol(int left, int right, int type);
|
||||
extern void tlv320_mute(bool mute);
|
||||
extern void tlv320_close(void);
|
||||
extern void tlv320_enable_recording(bool source_mic);
|
||||
extern void tlv320_disable_recording(void);
|
||||
extern void tlv320_set_monitor(bool enable);
|
||||
|
||||
#define HEADPHONE_MUTE 0x30 /* 0110000 = -73db */
|
||||
|
||||
|
|
|
@ -31,7 +31,12 @@
|
|||
#include "cpu.h"
|
||||
#include "i2c.h"
|
||||
#include "power.h"
|
||||
#ifdef HAVE_UDA1380
|
||||
#include "uda1380.h"
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
#include "tlv320.h"
|
||||
#endif
|
||||
#include "system.h"
|
||||
#include "usb.h"
|
||||
|
||||
|
@ -51,14 +56,14 @@ extern int boost_counter; /* used for boost check */
|
|||
|
||||
/***************************************************************************/
|
||||
|
||||
static volatile bool is_recording; /* We are recording */
|
||||
static volatile bool is_stopping; /* Are we going to stop */
|
||||
static volatile bool is_paused; /* We have paused */
|
||||
static volatile bool is_error; /* An error has occured */
|
||||
static bool is_recording; /* We are recording */
|
||||
static bool is_stopping; /* Are we going to stop */
|
||||
static bool is_paused; /* We have paused */
|
||||
static bool is_error; /* An error has occured */
|
||||
|
||||
static volatile unsigned long num_rec_bytes; /* Num bytes recorded */
|
||||
static volatile unsigned long num_file_bytes; /* Num bytes written to current file */
|
||||
static volatile int error_count; /* Number of DMA errors */
|
||||
static unsigned long num_rec_bytes; /* Num bytes recorded */
|
||||
static unsigned long num_file_bytes; /* Num bytes written to current file */
|
||||
static int error_count; /* Number of DMA errors */
|
||||
|
||||
static long record_start_time; /* Value of current_tick when recording was started */
|
||||
static long pause_start_time; /* Value of current_tick when pause was started */
|
||||
|
@ -69,7 +74,7 @@ static int rec_source; /* Current recording source */
|
|||
static int wav_file;
|
||||
static char recording_filename[MAX_PATH];
|
||||
|
||||
static volatile bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done;
|
||||
static bool init_done, close_done, record_done, stop_done, pause_done, resume_done, new_file_done;
|
||||
|
||||
static short peak_left, peak_right;
|
||||
|
||||
|
@ -90,16 +95,23 @@ static unsigned int rec_buffer_offset;
|
|||
static unsigned char *rec_buffer; /* Circular recording buffer */
|
||||
static int num_chunks; /* Number of chunks available in rec_buffer */
|
||||
|
||||
|
||||
#ifdef IAUDIO_X5
|
||||
#define SET_IIS_PLAY(x) IIS1CONFIG = (x);
|
||||
#define SET_IIS_REC(x) IIS1CONFIG = (x);
|
||||
#else
|
||||
#define SET_IIS_PLAY(x) IIS2CONFIG = (x);
|
||||
#define SET_IIS_REC(x) IIS1CONFIG = (x);
|
||||
#endif
|
||||
|
||||
/*
|
||||
Overrun occures when DMA needs to write a new chunk and write_index == read_index
|
||||
Solution to this is to optimize pcmrec_callback, use cpu_boost or save to disk
|
||||
more often.
|
||||
*/
|
||||
|
||||
static volatile int write_index; /* Current chunk the DMA is writing to */
|
||||
static volatile int read_index; /* Oldest chunk that is not written to disk */
|
||||
static volatile int read2_index; /* Latest chunk that has not been converted to little endian */
|
||||
static int write_index; /* Current chunk the DMA is writing to */
|
||||
static int read_index; /* Oldest chunk that is not written to disk */
|
||||
static int read2_index; /* Latest chunk that has not been converted to little endian */
|
||||
static long pre_record_ticks; /* pre-record time expressed in ticks */
|
||||
static int pre_record_chunks; /* pre-record time expressed in chunks */
|
||||
|
||||
|
@ -137,7 +149,7 @@ void pcm_rec_init(void)
|
|||
|
||||
|
||||
/* Initializes recording:
|
||||
* - Set up the UDA1380 for recording
|
||||
* - Set up the UDA1380/TLV320 for recording
|
||||
* - Prepare for DMA transfers
|
||||
*/
|
||||
|
||||
|
@ -292,14 +304,26 @@ void audio_set_recording_options(int frequency, int quality,
|
|||
case 0:
|
||||
/* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
|
||||
DATAINCONTROL = 0xc020;
|
||||
|
||||
#ifdef HAVE_UDA1380
|
||||
uda1380_enable_recording(true);
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
tlv320_enable_recording(true);
|
||||
#endif
|
||||
break;
|
||||
|
||||
/* line-in */
|
||||
case 1:
|
||||
/* Generate int. when 6 samples in FIFO, PDIR2 src = IIS1recv */
|
||||
DATAINCONTROL = 0xc020;
|
||||
|
||||
#ifdef HAVE_UDA1380
|
||||
uda1380_enable_recording(false);
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
tlv320_enable_recording(false);
|
||||
#endif
|
||||
break;
|
||||
#ifdef HAVE_SPDIF_IN
|
||||
/* SPDIF */
|
||||
|
@ -322,7 +346,8 @@ void audio_set_recording_options(int frequency, int quality,
|
|||
|
||||
/* Monitoring: route the signals through the coldfire audio interface. */
|
||||
|
||||
IIS2CONFIG = 0x800; /* Reset before reprogram */
|
||||
SET_IIS_PLAY(0x800); /* Reset before reprogram */
|
||||
|
||||
#ifdef HAVE_SPDIF_IN
|
||||
if (source == 2) {
|
||||
/* SCLK2 = Audioclk/4 (can't use EBUin clock), TXSRC = EBU1rcv, 64 bclk/wclk */
|
||||
|
@ -340,21 +365,27 @@ void audio_set_recording_options(int frequency, int quality,
|
|||
}
|
||||
#else
|
||||
/* SCLK2 follow IIS1 (UDA clock), TXSRC = IIS1rcv, 64 bclk/wclk */
|
||||
IIS2CONFIG = (8 << 12) | (4 << 8) | (4 << 2);
|
||||
SET_IIS_PLAY( (8 << 12) | (4 << 8) | (4 << 2) );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Note that microphone is mono, only left value is used
|
||||
* See uda1380_set_recvol() for exact ranges.
|
||||
* See {uda1380,tlv320}_set_recvol() for exact ranges.
|
||||
*
|
||||
* @param type 0=line-in (radio), 1=mic
|
||||
*
|
||||
*/
|
||||
void audio_set_recording_gain(int left, int right, int type)
|
||||
{
|
||||
//logf("rcmrec: t=%d l=%d r=%d", type, left, right);
|
||||
#ifdef HAVE_UDA1380
|
||||
uda1380_set_recvol(left, right, type);
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
tlv320_set_recvol(left, right, type);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -987,7 +1018,7 @@ static void pcmrec_init(void)
|
|||
|
||||
logf("num_chunks: %d", num_chunks);
|
||||
|
||||
IIS1CONFIG = 0x800; /* Stop any playback */
|
||||
SET_IIS_PLAY(0x800); /* Stop any playback */
|
||||
AUDIOGLOB |= 0x180; /* IIS1 fifo auto sync = on, PDIR2 auto sync = on */
|
||||
DATAINCONTROL = 0xc000; /* Generate Interrupt when 6 samples in fifo */
|
||||
|
||||
|
@ -1007,7 +1038,12 @@ static void pcmrec_init(void)
|
|||
|
||||
static void pcmrec_close(void)
|
||||
{
|
||||
#ifdef HAVE_UDA1380
|
||||
uda1380_disable_recording();
|
||||
#endif
|
||||
#ifdef HAVE_TLV320
|
||||
tlv320_disable_recording();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SPDIF_POWER
|
||||
spdif_power_enable(spdif_power_setting);
|
||||
|
@ -1091,7 +1127,7 @@ void pcm_rec_mux(int source)
|
|||
|
||||
or_l(0x40000000, &GPIO_ENABLE);
|
||||
or_l(0x40000000, &GPIO_FUNCTION);
|
||||
#else
|
||||
#elif defined(IRIVER_H100_SERIES)
|
||||
if(source == 0)
|
||||
and_l(~0x00800000, &GPIO_OUT); /* Line In */
|
||||
else
|
||||
|
@ -1099,5 +1135,16 @@ void pcm_rec_mux(int source)
|
|||
|
||||
or_l(0x00800000, &GPIO_ENABLE);
|
||||
or_l(0x00800000, &GPIO_FUNCTION);
|
||||
|
||||
#elif defined(IAUDIO_X5)
|
||||
if(source == 0)
|
||||
or_l((1<<29), &GPIO_OUT); /* Line In */
|
||||
else
|
||||
and_l(~(1<<29), &GPIO_OUT); /* FM radio */
|
||||
|
||||
or_l((1<<29), &GPIO_ENABLE);
|
||||
or_l((1<<29), &GPIO_FUNCTION);
|
||||
|
||||
/* iAudio x5 */
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -111,7 +111,11 @@ static const struct sound_settings_info sound_settings_table[] = {
|
|||
[SOUND_LEFT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
|
||||
[SOUND_RIGHT_GAIN] = {"dB", 1, 1,-128, 96, 0, NULL},
|
||||
[SOUND_MIC_GAIN] = {"dB", 1, 1,-128, 108, 16, NULL},
|
||||
#endif
|
||||
#elif defined(HAVE_TLV320)
|
||||
[SOUND_LEFT_GAIN] = {"dB", 1, 1, 0, 31, 23, NULL},
|
||||
[SOUND_RIGHT_GAIN] = {"dB", 1, 1, 0, 31, 23, NULL},
|
||||
[SOUND_MIC_GAIN] = {"dB", 1, 1, 0, 1, 1, NULL},
|
||||
#endif
|
||||
};
|
||||
|
||||
const char *sound_unit(int setting)
|
||||
|
@ -901,6 +905,25 @@ int sound_val2phys(int setting, int value)
|
|||
break;
|
||||
}
|
||||
return result;
|
||||
#elif defined(HAVE_TLV320)
|
||||
int result = 0;
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case SOUND_LEFT_GAIN:
|
||||
case SOUND_RIGHT_GAIN:
|
||||
result = (value - 23) * 15; /* (x - 23)/1.5 *10 */
|
||||
break;
|
||||
|
||||
case SOUND_MIC_GAIN:
|
||||
result = value * 200; /* 0 or 20 dB */
|
||||
break;
|
||||
|
||||
default:
|
||||
result = value;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void)setting;
|
||||
return value;
|
||||
|
|
|
@ -64,6 +64,20 @@ void power_off(void)
|
|||
yield();
|
||||
}
|
||||
|
||||
static bool powered = false;
|
||||
|
||||
bool radio_powered()
|
||||
{
|
||||
return powered;
|
||||
}
|
||||
|
||||
bool radio_power(bool status)
|
||||
{
|
||||
bool old_status = powered;
|
||||
powered = status;
|
||||
return old_status;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool charger_inserted(void)
|
||||
|
|
Loading…
Reference in a new issue