From 8f8fbac1fddee1df554d6fe9f9ac344404257b82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Hohensohn?= Date: Fri, 15 Oct 2004 21:41:46 +0000 Subject: [PATCH] Philips tuner prepared, new middle layer to abstract which tuner is used git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5289 a1c6a512-1295-4272-9138-f99709370657 --- apps/main.c | 4 ++ apps/recorder/radio.c | 96 ++++++++------------------- apps/recorder/radio.h | 1 + firmware/SOURCES | 7 ++ firmware/drivers/fmradio_i2c.c | 41 ++++++++++++ firmware/export/config-ondiofm.h | 2 +- firmware/export/config.h | 6 +- firmware/export/fmradio_i2c.h | 26 ++++++++ firmware/export/hwcompat.h | 1 + firmware/export/tuner.h | 49 ++++++++++++++ firmware/tuner_philips.c | 70 ++++++++++++++++++++ firmware/tuner_samsung.c | 109 +++++++++++++++++++++++++++++++ 12 files changed, 340 insertions(+), 72 deletions(-) create mode 100644 firmware/drivers/fmradio_i2c.c create mode 100644 firmware/export/fmradio_i2c.h create mode 100644 firmware/export/tuner.h create mode 100644 firmware/tuner_philips.c create mode 100644 firmware/tuner_samsung.c diff --git a/apps/main.c b/apps/main.c index d391b6cd02..363e174d24 100644 --- a/apps/main.c +++ b/apps/main.c @@ -98,6 +98,7 @@ int main(void) #include "power.h" #include "talk.h" #include "plugin.h" +#include "radio.h" /*#define AUTOROCK*/ /* define this to check for "autostart.rock" on boot */ @@ -285,6 +286,9 @@ void init(void) global_settings.superbass); mpeg_init(); talk_init(); +#ifdef CONFIG_TUNER + radio_init(); +#endif #ifdef AUTOROCK if (!usb_detect()) diff --git a/apps/recorder/radio.c b/apps/recorder/radio.c index 8b2420066a..8eaff1d917 100644 --- a/apps/recorder/radio.c +++ b/apps/recorder/radio.c @@ -47,6 +47,8 @@ #include "sound_menu.h" #include "recording.h" #include "talk.h" +#include "tuner.h" +#include "hwcompat.h" #ifdef CONFIG_TUNER @@ -66,24 +68,10 @@ #define MAX_FREQ (108000000) #define MIN_FREQ (87500000) -#define PLL_FREQ_STEP 10000 #define FREQ_STEP 100000 -#define RADIO_FREQUENCY 0 -#define RADIO_MUTE 1 -#define RADIO_IF_MEASUREMENT 2 -#define RADIO_SENSITIVITY 3 -#define RADIO_FORCE_MONO 4 - -#define DEFAULT_IN1 0x100003 /* Mute */ -#define DEFAULT_IN2 0x140884 /* 5kHz, 7.2MHz crystal */ - -static int fm_in1 = DEFAULT_IN1; -static int fm_in2 = DEFAULT_IN2; - static int curr_preset = -1; static int curr_freq; -static int pll_cnt; #define MAX_PRESETS 32 static bool presets_loaded = false; @@ -101,46 +89,31 @@ void radio_load_presets(void); bool handle_radio_presets(void); bool radio_menu(void); -void radio_set(int setting, int value) +#if CONFIG_TUNER == S1A0903X01 +#define radio_set samsung_set +#define radio_get samsung_get +#elif CONFIG_TUNER == TEA5767 +#define radio_set philips_set +#define radio_get philips_get +#elif CONFIG_TUNER == (S1A0903X01 | TEA5767) +void (*radio_set)(int setting, int value); +int (*radio_get)(int setting); +#endif + +void radio_init(void) { - switch(setting) +#if CONFIG_TUNER == (S1A0903X01 | TEA5767) + if (read_hw_mask() & TUNER_MODEL) { - case RADIO_FREQUENCY: - /* We add the standard Intermediate Frequency 10.7MHz - ** before calculating the divisor - ** The reference frequency is set to 50kHz, and the VCO - ** output is prescaled by 2. - */ - - pll_cnt = (value + 10700000) / (PLL_FREQ_STEP/2) / 2; - - /* 0x100000 == FM mode - ** 0x000002 == Microprocessor controlled Mute - */ - fm_in1 = (fm_in1 & 0xfff00007) | (pll_cnt << 3); - fmradio_set(1, fm_in1); - break; - - case RADIO_MUTE: - fm_in1 = (fm_in1 & 0xfffffffe) | (value?1:0); - fmradio_set(1, fm_in1); - break; - - case RADIO_IF_MEASUREMENT: - fm_in1 = (fm_in1 & 0xfffffffb) | (value?4:0); - fmradio_set(1, fm_in1); - break; - - case RADIO_SENSITIVITY: - fm_in2 = (fm_in2 & 0xffff9fff) | ((value & 3) << 13); - fmradio_set(2, fm_in2); - break; - - case RADIO_FORCE_MONO: - fm_in2 = (fm_in2 & 0xfffffffb) | (value?0:4); - fmradio_set(2, fm_in2); - break; + radio_set = philips_set; + radio_get = philips_get; } + else + { + radio_set = samsung_set; + radio_get = samsung_get; + } +#endif } void radio_stop(void) @@ -150,15 +123,7 @@ void radio_stop(void) bool radio_hardware_present(void) { - int val; - - fmradio_set(2, 0x140885); /* 5kHz, 7.2MHz crystal, test mode 1 */ - val = fmradio_read(0); - debug_fm_detection = val; - if(val == 0x140885) - return true; - else - return false; + return radio_get(RADIO_PRESENT); } static int find_preset(int freq) @@ -184,7 +149,6 @@ bool radio_screen(void) char buf[MAX_PATH]; bool done = false; int button; - int val; int freq; int i_freq; bool stereo = false; @@ -247,9 +211,7 @@ bool radio_screen(void) curr_freq = global_settings.last_frequency * FREQ_STEP + MIN_FREQ; - fmradio_set(1, DEFAULT_IN1); - fmradio_set(2, DEFAULT_IN2); - + radio_set(RADIO_INIT, 0); radio_set(RADIO_FREQUENCY, curr_freq); radio_set(RADIO_IF_MEASUREMENT, 0); radio_set(RADIO_SENSITIVITY, 0); @@ -282,8 +244,7 @@ bool radio_screen(void) sleep(1); /* Now check how close to the IF frequency we are */ - val = fmradio_read(3); - i_freq = (val & 0x7ffff) / 80; + i_freq = radio_get(RADIO_IF_MEASURED); /* Stop searching if the IF frequency is close to 10.7MHz */ if(i_freq > 1065 && i_freq < 1075) @@ -474,8 +435,7 @@ bool radio_screen(void) { timeout = current_tick + HZ; - val = fmradio_read(3); - stereo = ((val & 0x100000)?true:false) & + stereo = radio_get(RADIO_STEREO) && !global_settings.fm_force_mono; if(stereo != last_stereo_status) { diff --git a/apps/recorder/radio.h b/apps/recorder/radio.h index 76a4af3b9f..127bea0723 100644 --- a/apps/recorder/radio.h +++ b/apps/recorder/radio.h @@ -20,6 +20,7 @@ #define RADIO_H #ifdef CONFIG_TUNER +void radio_init(void); bool radio_screen(void); void radio_stop(void); bool radio_hardware_present(void); diff --git a/firmware/SOURCES b/firmware/SOURCES index 7594c6dc1a..6df69bf2a3 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -38,7 +38,14 @@ drivers/button.c drivers/dac.c drivers/fat.c #ifdef CONFIG_TUNER +#if (CONFIG_TUNER & S1A0903X01) drivers/fmradio.c +tuner_samsung.c +#endif +#if (CONFIG_TUNER & TEA5767) +drivers/fmradio_i2c.c +tuner_philips.c +#endif #endif drivers/i2c.c #ifdef HAVE_LCD_CHARCELLS diff --git a/firmware/drivers/fmradio_i2c.c b/firmware/drivers/fmradio_i2c.c new file mode 100644 index 0000000000..93c5d2fa91 --- /dev/null +++ b/firmware/drivers/fmradio_i2c.c @@ -0,0 +1,41 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * Physical interface of the Philips TEA5767 in Archos Ondio + * + * Copyright (C) 2004 by Jörg Hohensohn + * + * 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 "lcd.h" +#include "sh7034.h" +#include "kernel.h" +#include "thread.h" +#include "debug.h" +#include "system.h" + +#ifdef CONFIG_TUNER + +/* reads 5 byte */ +void fmradio_i2c_read(unsigned char* p_data) +{ + (void)p_data; +} + +/* writes 5 bytes */ +void fmradio_i2c_set(const unsigned char* p_data) +{ + (void)p_data; +} + +#endif diff --git a/firmware/export/config-ondiofm.h b/firmware/export/config-ondiofm.h index 437f8682a8..f459934fbc 100644 --- a/firmware/export/config-ondiofm.h +++ b/firmware/export/config-ondiofm.h @@ -41,7 +41,7 @@ #define FIRMWARE_OFFSET_FILE_DATA 24 /* Define this if you have an FM Radio */ -#define CONFIG_TUNER TEA5767 +#define CONFIG_TUNER (S1A0903X01 | TEA5767) /* to be decided at runtime */ /* How to detect USB */ #define USB_FMRECORDERSTYLE 1 /* like FM, on AN1 */ diff --git a/firmware/export/config.h b/firmware/export/config.h index 76a2bd9316..823a5dc3ed 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -22,9 +22,9 @@ /* symbolic names for multiple choice configurations: */ -/* CONFIG_TUNER */ -#define S1A0903X01 0 /* Samsung */ -#define TEA5767 1 /* Philips */ +/* CONFIG_TUNER (note these are combineable bit-flags) */ +#define S1A0903X01 0x01 /* Samsung */ +#define TEA5767 0x02 /* Philips */ /* CONFIG_HWCODEC */ #define MAS3587F 3587 diff --git a/firmware/export/fmradio_i2c.h b/firmware/export/fmradio_i2c.h new file mode 100644 index 0000000000..06b7f9f7b7 --- /dev/null +++ b/firmware/export/fmradio_i2c.h @@ -0,0 +1,26 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * Physical interface of the Philips TEA5767 in Archos Ondio + * + * Copyright (C) 2004 by Jörg Hohensohn + * + * 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. + * + ****************************************************************************/ +#ifndef FMRADIO_I2C_H +#define FMRADIO_I2C_H + +void fmradio_i2c_read(unsigned char* p_data); /* reads 5 byte */ +void fmradio_i2c_set(const unsigned char* p_data); /* writes 5 bytes */ + +#endif diff --git a/firmware/export/hwcompat.h b/firmware/export/hwcompat.h index ef3892b1fa..66f29f8b16 100644 --- a/firmware/export/hwcompat.h +++ b/firmware/export/hwcompat.h @@ -27,6 +27,7 @@ #define USB_ACTIVE_HIGH 0x0100 #define PR_ACTIVE_HIGH 0x0100 #define LCD_CONTRAST_BIAS 0x0200 +#define TUNER_MODEL 0x0800 int read_rom_version(void); int read_hw_mask(void); diff --git a/firmware/export/tuner.h b/firmware/export/tuner.h new file mode 100644 index 0000000000..ae31c6d354 --- /dev/null +++ b/firmware/export/tuner.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * Tuner abstraction layer + * + * Copyright (C) 2004 Jörg Hohensohn + * + * 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. + * + ****************************************************************************/ +#ifndef __TUNER_SAMSUNG_H__ +#define __TUNER_SAMSUNG_H__ + +/* settings to the tuner layer */ +#define RADIO_INIT 0 +#define RADIO_FREQUENCY 1 +#define RADIO_MUTE 2 +#define RADIO_IF_MEASUREMENT 3 +#define RADIO_SENSITIVITY 4 +#define RADIO_FORCE_MONO 5 +/* readback from the tuner layer */ +#define RADIO_PRESENT 0 +#define RADIO_IF_MEASURED 1 +#define RADIO_STEREO 2 + +#ifdef CONFIG_TUNER + +#if (CONFIG_TUNER & S1A0903X01) +void samsung_set(int setting, int value); +int samsung_get(int setting); +#endif + +#if (CONFIG_TUNER & TEA5767) +void philips_set(int setting, int value); +int philips_get(int setting); +#endif + +#endif /* #ifdef CONFIG_TUNER */ + +#endif diff --git a/firmware/tuner_philips.c b/firmware/tuner_philips.c new file mode 100644 index 0000000000..50559af23e --- /dev/null +++ b/firmware/tuner_philips.c @@ -0,0 +1,70 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * Tuner "middleware" for Philips TEA5767 chip + * + * Copyright (C) 2004 Jörg Hohensohn + * + * 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 +#include "tuner.h" /* tuner abstraction interface */ +#include "fmradio_i2c.h" /* physical interface driver */ + +/* FIXME: this is just a dummy */ + +/* tuner abstraction layer: set something to the tuner */ +void philips_set(int setting, int value) +{ + (void)value; + switch(setting) + { + case RADIO_INIT: + break; + + case RADIO_FREQUENCY: + break; + + case RADIO_MUTE: + break; + + case RADIO_IF_MEASUREMENT: + break; + + case RADIO_SENSITIVITY: + break; + + case RADIO_FORCE_MONO: + break; + } +} + +/* tuner abstraction layer: read something from the tuner */ +int philips_get(int setting) +{ + int val = -1; + switch(setting) + { + case RADIO_PRESENT: + val = 0; /* false */ + break; + + case RADIO_IF_MEASURED: + break; + + case RADIO_STEREO: + break; + } + return val; +} diff --git a/firmware/tuner_samsung.c b/firmware/tuner_samsung.c new file mode 100644 index 0000000000..781a4bcd3e --- /dev/null +++ b/firmware/tuner_samsung.c @@ -0,0 +1,109 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * Tuner "middleware" for Samsung S1A0903X01 chip + * + * Copyright (C) 2003 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 +#include "tuner.h" /* tuner abstraction interface */ +#include "fmradio.h" /* physical interface driver */ + +#define DEFAULT_IN1 0x100003 /* Mute */ +#define DEFAULT_IN2 0x140884 /* 5kHz, 7.2MHz crystal */ +#define PLL_FREQ_STEP 10000 + +int debug_fm_detection; +static int fm_in1; +static int fm_in2; + +/* tuner abstraction layer: set something to the tuner */ +void samsung_set(int setting, int value) +{ + switch(setting) + { + case RADIO_INIT: + fm_in1 = DEFAULT_IN1; + fm_in2 = DEFAULT_IN2; + fmradio_set(1, fm_in1); + fmradio_set(2, fm_in2); + break; + + case RADIO_FREQUENCY: + { + int pll_cnt; + /* We add the standard Intermediate Frequency 10.7MHz + ** before calculating the divisor + ** The reference frequency is set to 50kHz, and the VCO + ** output is prescaled by 2. + */ + + pll_cnt = (value + 10700000) / (PLL_FREQ_STEP/2) / 2; + + /* 0x100000 == FM mode + ** 0x000002 == Microprocessor controlled Mute + */ + fm_in1 = (fm_in1 & 0xfff00007) | (pll_cnt << 3); + fmradio_set(1, fm_in1); + break; + } + + case RADIO_MUTE: + fm_in1 = (fm_in1 & 0xfffffffe) | (value?1:0); + fmradio_set(1, fm_in1); + break; + + case RADIO_IF_MEASUREMENT: + fm_in1 = (fm_in1 & 0xfffffffb) | (value?4:0); + fmradio_set(1, fm_in1); + break; + + case RADIO_SENSITIVITY: + fm_in2 = (fm_in2 & 0xffff9fff) | ((value & 3) << 13); + fmradio_set(2, fm_in2); + break; + + case RADIO_FORCE_MONO: + fm_in2 = (fm_in2 & 0xfffffffb) | (value?0:4); + fmradio_set(2, fm_in2); + break; + } +} + +/* tuner abstraction layer: read something from the tuner */ +int samsung_get(int setting) +{ + int val = -1; + switch(setting) + { + case RADIO_PRESENT: + fmradio_set(2, 0x140885); /* 5kHz, 7.2MHz crystal, test mode 1 */ + val = fmradio_read(0); + debug_fm_detection = val; + val = (val == 0x140885); + break; + + case RADIO_IF_MEASURED: + val = fmradio_read(3); + val = (val & 0x7ffff) / 80; /* convert to kHz */ + break; + + case RADIO_STEREO: + val = fmradio_read(3); + val = ((val & 0x100000) ? true : false); + } + return val; +}