mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-17 12:07:38 -04:00
FS#8046: H10 FM tuner support. Thanks to Przemyslaw Holubowski for doing the hard work in figuring out how to communicate with the tuner.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@15578 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
496027d8bb
commit
c495cdae59
9 changed files with 263 additions and 15 deletions
|
@ -305,6 +305,26 @@ const struct button_mapping button_context_recscreen[] = {
|
||||||
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
|
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
|
||||||
}; /* button_context_recscreen */
|
}; /* button_context_recscreen */
|
||||||
|
|
||||||
|
static const struct button_mapping button_context_radio[] = {
|
||||||
|
{ ACTION_FM_PRESET, BUTTON_RIGHT | BUTTON_REL, BUTTON_RIGHT },
|
||||||
|
{ ACTION_FM_MENU, BUTTON_RIGHT | BUTTON_REPEAT, BUTTON_NONE },
|
||||||
|
{ ACTION_FM_MODE, BUTTON_LEFT, BUTTON_NONE },
|
||||||
|
{ ACTION_FM_STOP, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_PLAY },
|
||||||
|
{ ACTION_FM_EXIT, BUTTON_POWER, BUTTON_NONE },
|
||||||
|
{ ACTION_FM_PLAY, BUTTON_PLAY | BUTTON_REL, BUTTON_PLAY },
|
||||||
|
{ ACTION_SETTINGS_INC, BUTTON_SCROLL_UP, BUTTON_NONE },
|
||||||
|
{ ACTION_SETTINGS_INCREPEAT, BUTTON_SCROLL_UP|BUTTON_REPEAT, BUTTON_NONE },
|
||||||
|
{ ACTION_SETTINGS_DEC, BUTTON_SCROLL_DOWN, BUTTON_NONE },
|
||||||
|
{ ACTION_SETTINGS_DECREPEAT, BUTTON_SCROLL_DOWN|BUTTON_REPEAT, BUTTON_NONE },
|
||||||
|
{ ACTION_STD_PREV, BUTTON_REW, BUTTON_NONE },
|
||||||
|
{ ACTION_STD_PREVREPEAT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE },
|
||||||
|
{ ACTION_STD_NEXT, BUTTON_FF, BUTTON_NONE },
|
||||||
|
{ ACTION_STD_NEXTREPEAT, BUTTON_FF|BUTTON_REPEAT, BUTTON_NONE },
|
||||||
|
|
||||||
|
LAST_ITEM_IN_LIST
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
static const struct button_mapping* get_context_mapping_remote( int context )
|
static const struct button_mapping* get_context_mapping_remote( int context )
|
||||||
{
|
{
|
||||||
context ^= CONTEXT_REMOTE;
|
context ^= CONTEXT_REMOTE;
|
||||||
|
@ -385,7 +405,8 @@ const struct button_mapping* get_context_mapping(int context)
|
||||||
return button_context_keyboard;
|
return button_context_keyboard;
|
||||||
case CONTEXT_RECSCREEN:
|
case CONTEXT_RECSCREEN:
|
||||||
return button_context_recscreen;
|
return button_context_recscreen;
|
||||||
|
case CONTEXT_FM:
|
||||||
|
return button_context_radio;
|
||||||
default:
|
default:
|
||||||
return button_context_standard;
|
return button_context_standard;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,10 @@
|
||||||
#define FM_NEXT_PRESET
|
#define FM_NEXT_PRESET
|
||||||
#define FM_PREV_PRESET
|
#define FM_PREV_PRESET
|
||||||
|
|
||||||
|
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
||||||
|
#define FM_PRESET
|
||||||
|
#define FM_MODE
|
||||||
|
|
||||||
#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
|
#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
|
||||||
#define FM_PRESET
|
#define FM_PRESET
|
||||||
#define FM_MODE
|
#define FM_MODE
|
||||||
|
|
|
@ -557,6 +557,7 @@ target/arm/i2s-pp.c
|
||||||
target/arm/iriver/h10/adc-h10.c
|
target/arm/iriver/h10/adc-h10.c
|
||||||
target/arm/iriver/h10/backlight-h10.c
|
target/arm/iriver/h10/backlight-h10.c
|
||||||
target/arm/iriver/h10/button-h10.c
|
target/arm/iriver/h10/button-h10.c
|
||||||
|
target/arm/iriver/h10/fmradio_i2c-h10.c
|
||||||
target/arm/iriver/h10/lcd-h10_20gb.c
|
target/arm/iriver/h10/lcd-h10_20gb.c
|
||||||
target/arm/iriver/h10/power-h10.c
|
target/arm/iriver/h10/power-h10.c
|
||||||
target/arm/iriver/h10/powermgmt-h10.c
|
target/arm/iriver/h10/powermgmt-h10.c
|
||||||
|
@ -573,6 +574,7 @@ target/arm/i2s-pp.c
|
||||||
target/arm/iriver/h10/adc-h10.c
|
target/arm/iriver/h10/adc-h10.c
|
||||||
target/arm/iriver/h10/backlight-h10.c
|
target/arm/iriver/h10/backlight-h10.c
|
||||||
target/arm/iriver/h10/button-h10.c
|
target/arm/iriver/h10/button-h10.c
|
||||||
|
target/arm/iriver/h10/fmradio_i2c-h10.c
|
||||||
target/arm/iriver/h10/lcd-h10_5gb.c
|
target/arm/iriver/h10/lcd-h10_5gb.c
|
||||||
target/arm/iriver/h10/power-h10.c
|
target/arm/iriver/h10/power-h10.c
|
||||||
target/arm/iriver/h10/powermgmt-h10.c
|
target/arm/iriver/h10/powermgmt-h10.c
|
||||||
|
|
|
@ -319,6 +319,15 @@ void audiohw_set_recvol(int left, int right, int type)
|
||||||
|
|
||||||
void audiohw_set_monitor(int enable)
|
void audiohw_set_monitor(int enable)
|
||||||
{
|
{
|
||||||
/* TODO: Implement for FM monitoring */
|
if(enable)
|
||||||
(void)enable;
|
{
|
||||||
|
wm8731_regs[AAPCTRL] |= AAPCTRL_BYPASS;
|
||||||
|
wm8731_regs[AAPCTRL] &=~ (AAPCTRL_DACSEL | AAPCTRL_SIDETONE);
|
||||||
|
wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wm8731_regs[AAPCTRL] &=~ AAPCTRL_BYPASS;
|
||||||
|
wm8731_regs[AAPCTRL] |= AAPCTRL_DACSEL | AAPCTRL_SIDETONE;
|
||||||
|
wm8731_write(AAPCTRL, wm8731_regs[AAPCTRL]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#define HAVE_RECORDING
|
#define HAVE_RECORDING
|
||||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||||
explicitly if different */
|
explicitly if different */
|
||||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||||
|
|
||||||
/* define the bitmask of hardware sample rates */
|
/* define the bitmask of hardware sample rates */
|
||||||
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
||||||
|
@ -88,8 +88,8 @@
|
||||||
#define AB_REPEAT_ENABLE 1
|
#define AB_REPEAT_ENABLE 1
|
||||||
|
|
||||||
/* FM Tuner */
|
/* FM Tuner */
|
||||||
/*#define CONFIG_TUNER TEA5767
|
#define CONFIG_TUNER TEA5767
|
||||||
#define CONFIG_TUNER_XTAL 32768 *//* TODO: what is this? */
|
#define CONFIG_TUNER_XTAL 32768
|
||||||
|
|
||||||
/* Define this for LCD backlight available */
|
/* Define this for LCD backlight available */
|
||||||
#define HAVE_BACKLIGHT
|
#define HAVE_BACKLIGHT
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#define HAVE_RECORDING
|
#define HAVE_RECORDING
|
||||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||||
explicitly if different */
|
explicitly if different */
|
||||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||||
|
|
||||||
/* define the bitmask of hardware sample rates */
|
/* define the bitmask of hardware sample rates */
|
||||||
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
||||||
|
@ -74,8 +74,8 @@
|
||||||
#define AB_REPEAT_ENABLE 1
|
#define AB_REPEAT_ENABLE 1
|
||||||
|
|
||||||
/* FM Tuner */
|
/* FM Tuner */
|
||||||
/*#define CONFIG_TUNER TEA5767
|
#define CONFIG_TUNER TEA5767
|
||||||
#define CONFIG_TUNER_XTAL 32768 *//* TODO: what is this? */
|
#define CONFIG_TUNER_XTAL 32768
|
||||||
|
|
||||||
/* Define this for LCD backlight available */
|
/* Define this for LCD backlight available */
|
||||||
#define HAVE_BACKLIGHT
|
#define HAVE_BACKLIGHT
|
||||||
|
|
|
@ -35,6 +35,7 @@ void audio_input_mux(int source, unsigned flags)
|
||||||
/* Prevent pops from unneeded switching */
|
/* Prevent pops from unneeded switching */
|
||||||
static int last_source = AUDIO_SRC_PLAYBACK;
|
static int last_source = AUDIO_SRC_PLAYBACK;
|
||||||
#ifdef HAVE_FMRADIO_REC
|
#ifdef HAVE_FMRADIO_REC
|
||||||
|
bool recording = flags & SRCF_RECORDING;
|
||||||
static bool last_recording = false;
|
static bool last_recording = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -62,6 +63,10 @@ void audio_input_mux(int source, unsigned flags)
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_LINEIN_REC
|
#ifdef HAVE_LINEIN_REC
|
||||||
case AUDIO_SRC_LINEIN: /* recording only */
|
case AUDIO_SRC_LINEIN: /* recording only */
|
||||||
|
#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
|
||||||
|
/* Switch line in source to line-in */
|
||||||
|
GPIO_SET_BITWISE(GPIOB_OUTPUT_VAL, 0x04);
|
||||||
|
#endif
|
||||||
if (source != last_source)
|
if (source != last_source)
|
||||||
{
|
{
|
||||||
audiohw_enable_recording(false); /* source line */
|
audiohw_enable_recording(false); /* source line */
|
||||||
|
@ -71,17 +76,20 @@ void audio_input_mux(int source, unsigned flags)
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_FMRADIO_REC
|
#ifdef HAVE_FMRADIO_REC
|
||||||
case AUDIO_SRC_FMRADIO: /* recording and playback */
|
case AUDIO_SRC_FMRADIO: /* recording and playback */
|
||||||
|
#if defined(IRIVER_H10) || defined(IRIVER_H10_5GB)
|
||||||
|
/* Switch line in source to tuner */
|
||||||
|
GPIO_CLEAR_BITWISE(GPIOB_OUTPUT_VAL, 0x04);
|
||||||
|
#endif /* Set line-in vol to 0dB*/
|
||||||
if (!recording)
|
if (!recording)
|
||||||
audiohw_set_recvol(0, 0, AUDIO_GAIN_LINEIN);
|
audiohw_set_recvol(0x17, 0x17, AUDIO_GAIN_LINEIN);
|
||||||
|
|
||||||
if (source == last_source && recording == last_recording)
|
if (source == last_source && recording == last_recording)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
last_recording = recording;
|
last_recording = recording;
|
||||||
|
|
||||||
/* I2S recording and playback */
|
audiohw_enable_recording(false); /* select line-in source */
|
||||||
audiohw_enable_recording(false); /* source line */
|
audiohw_set_monitor(!recording); /* enable bypass mode */
|
||||||
audiohw_set_monitor(!recording);
|
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
} /* end switch */
|
} /* end switch */
|
||||||
|
|
206
firmware/target/arm/iriver/h10/fmradio_i2c-h10.c
Normal file
206
firmware/target/arm/iriver/h10/fmradio_i2c-h10.c
Normal file
|
@ -0,0 +1,206 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* __________ __ ___.
|
||||||
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||||
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||||
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||||
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||||
|
* \/ \/ \/ \/ \/
|
||||||
|
* $Id$
|
||||||
|
* Physical interface of the Philips TEA5767 in iriver H10 series
|
||||||
|
*
|
||||||
|
* Copyright (C) 2002 by Linus Nielsen Feltzing
|
||||||
|
*
|
||||||
|
* All files in this archive are subject to the GNU General Public License.
|
||||||
|
* See the file COPYING in the source tree root for full license agreement.
|
||||||
|
*
|
||||||
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||||
|
* KIND, either express or implied.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
#include "config.h"
|
||||||
|
#include "cpu.h"
|
||||||
|
#include "logf.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/* cute little functions, atomic read-modify-write */
|
||||||
|
|
||||||
|
#define SDA_OUTINIT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x08)
|
||||||
|
#define SDA_HI_IN GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x08)
|
||||||
|
#define SDA_LO_OUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x08)
|
||||||
|
#define SDA (GPIOD_INPUT_VAL & 0x08)
|
||||||
|
|
||||||
|
#define SCL_INPUT GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_EN, 0x10)
|
||||||
|
#define SCL_OUTPUT GPIO_SET_BITWISE(GPIOD_OUTPUT_EN, 0x10)
|
||||||
|
#define SCL_LO GPIO_CLEAR_BITWISE(GPIOD_OUTPUT_VAL, 0x10)
|
||||||
|
#define SCL_HI GPIO_SET_BITWISE(GPIOD_OUTPUT_VAL,0x10)
|
||||||
|
#define SCL (GPIOD_INPUT_VAL & 0x10)
|
||||||
|
|
||||||
|
#define DELAY udelay(2)
|
||||||
|
|
||||||
|
static void fmradio_i2c_start(void)
|
||||||
|
{
|
||||||
|
SCL_HI;
|
||||||
|
SCL_OUTPUT;
|
||||||
|
SDA_HI_IN;
|
||||||
|
SDA_OUTINIT;
|
||||||
|
DELAY;
|
||||||
|
SDA_LO_OUT;
|
||||||
|
DELAY;
|
||||||
|
SCL_LO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fmradio_i2c_stop(void)
|
||||||
|
{
|
||||||
|
SDA_LO_OUT;
|
||||||
|
DELAY;
|
||||||
|
SCL_HI;
|
||||||
|
DELAY;
|
||||||
|
SDA_HI_IN;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate ACK or NACK */
|
||||||
|
static void fmradio_i2c_ack(bool nack)
|
||||||
|
{
|
||||||
|
/* Here's the deal. The slave is slow, and sometimes needs to wait
|
||||||
|
before it can receive the acknowledge. Therefore it forces the clock
|
||||||
|
low until it is ready. We need to poll the clock line until it goes
|
||||||
|
high before we release the ack.
|
||||||
|
|
||||||
|
In their infinite wisdom, iriver didn't pull up the SCL line, so
|
||||||
|
we have to drive the SCL high repeatedly to simulate a pullup. */
|
||||||
|
|
||||||
|
if (nack)
|
||||||
|
SDA_HI_IN;
|
||||||
|
else
|
||||||
|
SDA_LO_OUT;
|
||||||
|
DELAY;
|
||||||
|
|
||||||
|
SCL_HI;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SCL_OUTPUT; /* Set the clock to output */
|
||||||
|
SCL_INPUT; /* Set the clock to input */
|
||||||
|
DELAY;
|
||||||
|
}
|
||||||
|
while(!SCL); /* and wait for the slave to release it */
|
||||||
|
|
||||||
|
SCL_OUTPUT;
|
||||||
|
SCL_LO;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int fmradio_i2c_getack(void)
|
||||||
|
{
|
||||||
|
int ret = 1;
|
||||||
|
|
||||||
|
/* Here's the deal. The slave is slow, and sometimes needs to wait
|
||||||
|
before it can send the acknowledge. Therefore it forces the clock
|
||||||
|
low until it is ready. We need to poll the clock line until it goes
|
||||||
|
high before we read the ack.
|
||||||
|
|
||||||
|
In their infinite wisdom, iriver didn't pull up the SCL line, so
|
||||||
|
we have to drive the SCL high repeatedly to simulate a pullup. */
|
||||||
|
|
||||||
|
SDA_HI_IN;
|
||||||
|
DELAY;
|
||||||
|
|
||||||
|
SCL_HI; /* set clock to high */
|
||||||
|
do
|
||||||
|
{
|
||||||
|
SCL_OUTPUT; /* Set the clock to output */
|
||||||
|
SCL_INPUT; /* Set the clock to input */
|
||||||
|
DELAY;
|
||||||
|
}
|
||||||
|
while(!SCL); /* and wait for the slave to release it */
|
||||||
|
|
||||||
|
if (SDA)
|
||||||
|
ret = 0; /* ack failed */
|
||||||
|
|
||||||
|
SCL_OUTPUT;
|
||||||
|
SCL_LO;
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fmradio_i2c_outb(unsigned char byte)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* clock out each bit, MSB first */
|
||||||
|
for ( i=0x80; i; i>>=1 ) {
|
||||||
|
if ( i & byte )
|
||||||
|
SDA_HI_IN;
|
||||||
|
else
|
||||||
|
SDA_LO_OUT;
|
||||||
|
DELAY;
|
||||||
|
SCL_HI;
|
||||||
|
DELAY;
|
||||||
|
SCL_LO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char fmradio_i2c_inb(void)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char byte = 0;
|
||||||
|
|
||||||
|
SDA_HI_IN;
|
||||||
|
/* clock in each bit, MSB first */
|
||||||
|
for ( i=0x80; i; i>>=1 ) {
|
||||||
|
DELAY;
|
||||||
|
SCL_HI;
|
||||||
|
DELAY;
|
||||||
|
if ( SDA )
|
||||||
|
byte |= i;
|
||||||
|
SCL_LO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fmradio_i2c_write(int address, const unsigned char* buf, int count)
|
||||||
|
{
|
||||||
|
int i,x=0;
|
||||||
|
|
||||||
|
fmradio_i2c_start();
|
||||||
|
fmradio_i2c_outb(address & 0xfe);
|
||||||
|
if (fmradio_i2c_getack())
|
||||||
|
{
|
||||||
|
for (i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
fmradio_i2c_outb(buf[i]);
|
||||||
|
if (!fmradio_i2c_getack())
|
||||||
|
{
|
||||||
|
x=-2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
logf("fmradio_i2c_write() - no ack\n");
|
||||||
|
x=-1;
|
||||||
|
}
|
||||||
|
fmradio_i2c_stop();
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fmradio_i2c_read(int address, unsigned char* buf, int count)
|
||||||
|
{
|
||||||
|
int i,x=0;
|
||||||
|
|
||||||
|
fmradio_i2c_start();
|
||||||
|
fmradio_i2c_outb(address | 1);
|
||||||
|
|
||||||
|
if (fmradio_i2c_getack())
|
||||||
|
{
|
||||||
|
for (i=count; i>0; i--)
|
||||||
|
{
|
||||||
|
*buf++ = fmradio_i2c_inb();
|
||||||
|
fmradio_i2c_ack(i == 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
x=-1;
|
||||||
|
fmradio_i2c_stop();
|
||||||
|
return x;
|
||||||
|
}
|
|
@ -35,7 +35,6 @@
|
||||||
bool charger_enabled;
|
bool charger_enabled;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
|
||||||
#if CONFIG_TUNER
|
#if CONFIG_TUNER
|
||||||
|
|
||||||
bool tuner_power(bool status)
|
bool tuner_power(bool status)
|
||||||
|
@ -46,7 +45,6 @@ bool tuner_power(bool status)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* #if CONFIG_TUNER */
|
#endif /* #if CONFIG_TUNER */
|
||||||
#endif
|
|
||||||
|
|
||||||
void power_init(void)
|
void power_init(void)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue