From ff8e76e9e534dde1e6a57a84d49b89dad847cafd Mon Sep 17 00:00:00 2001 From: Bertrik Sikken Date: Wed, 16 Jun 2010 20:29:08 +0000 Subject: The mystery FM chip in some Sansa Clip+ players has been identified as a RDA5802, so rename files and functions. Also fix several bugs. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26871 a1c6a512-1295-4272-9138-f99709370657 --- firmware/SOURCES | 6 +- firmware/drivers/tuner/fmclipplus.c | 328 -------------------- firmware/drivers/tuner/rda5802.c | 333 +++++++++++++++++++++ firmware/export/config.h | 2 +- firmware/export/config/sansaclipplus.h | 2 +- firmware/export/fmclipplus.h | 54 ---- firmware/export/rda5802.h | 54 ++++ firmware/export/tuner.h | 6 +- .../arm/as3525/sansa-clipplus/tuner-clipplus.c | 4 +- firmware/tuner.c | 16 +- 10 files changed, 405 insertions(+), 400 deletions(-) delete mode 100644 firmware/drivers/tuner/fmclipplus.c create mode 100644 firmware/drivers/tuner/rda5802.c delete mode 100644 firmware/export/fmclipplus.h create mode 100644 firmware/export/rda5802.h (limited to 'firmware') diff --git a/firmware/SOURCES b/firmware/SOURCES index b49382a0e9..1c2922c273 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -248,9 +248,9 @@ drivers/tuner/si4700.c #if (CONFIG_TUNER & IPOD_REMOTE_TUNER) drivers/tuner/ipod_remote_tuner.c #endif /* (CONFIG_TUNER & IPOD_REMOTE_TUNER) */ -#if (CONFIG_TUNER & FMCLIPPLUS) -drivers/tuner/fmclipplus.c -#endif /* (CONFIG_TUNER & FMCLIPPLUS) */ +#if (CONFIG_TUNER & RDA5802) +drivers/tuner/rda5802.c +#endif /* (CONFIG_TUNER & RDA5802) */ #endif /*SIMULATOR */ #endif /* CONFIG_TUNER */ #endif /* BOOTLOADER */ diff --git a/firmware/drivers/tuner/fmclipplus.c b/firmware/drivers/tuner/fmclipplus.c deleted file mode 100644 index 1922662d78..0000000000 --- a/firmware/drivers/tuner/fmclipplus.c +++ /dev/null @@ -1,328 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * $Id$ - * - * Tuner "middleware" for unidentified Silicon Labs chip present in some - * Sansa Clip+ players - * - * Copyright (C) 2010 Bertrik Sikken - * Copyright (C) 2008 Nils Wallménius (si4700 code that this was based on) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ -#include "config.h" -#include -#include -#include -#include "kernel.h" -#include "tuner.h" /* tuner abstraction interface */ -#include "fmradio.h" -#include "fmradio_i2c.h" /* physical interface driver */ - -#define SEEK_THRESHOLD 0x10 - -#define I2C_ADR 0x20 - -/** Registers and bits **/ -#define POWERCFG 0x2 -#define CHANNEL 0x3 -#define SYSCONFIG1 0x4 -#define SYSCONFIG2 0x5 -#define SYSCONFIG3 0x6 - -#define READCHAN 0xA -#define STATUSRSSI 0xB -#define IDENT 0xC - - -/* POWERCFG (0x2) */ -#define POWERCFG_DMUTE (0x1 << 14) -#define POWERCFG_MONO (0x1 << 13) -#define POWERCFG_ENABLE (0x1 << 0) - -/* CHANNEL (0x3) */ -#define CHANNEL_CHAN (0x3ff << 6) - #define CHANNEL_CHANw(x) (((x) << 6) & CHANNEL_CHAN) -#define CHANNEL_TUNE (0x1 << 4) -#define CHANNEL_BAND (0x3 << 2) - #define CHANNEL_BANDw(x) (((x) << 2) & CHANNEL_BAND) - #define CHANNEL_BANDr(x) (((x) & CHANNEL_BAND) >> 2) - #define CHANNEL_BAND_875_1080 (0x0 << 2) /* tenth-megahertz */ - #define CHANNEL_BAND_760_1080 (0x1 << 2) - #define CHANNEL_BAND_760_900 (0x2 << 2) -#define CHANNEL_SPACE (0x3 << 0) - #define CHANNEL_SPACEw(x) (((x) << 0) & CHANNEL_SPACE) - #define CHANNEL_SPACEr(x) (((x) & CHANNEL_SPACE) >> 0) - #define CHANNEL_SPACE_200KHZ (0x0 << 0) - #define CHANNEL_SPACE_100KHZ (0x1 << 0) - #define CHANNEL_SPACE_50KHZ (0x2 << 0) - -/* SYSCONFIG1 (0x4) */ -#define SYSCONFIG1_DE (0x1 << 11) - -/* READCHAN (0xA) */ -#define READCHAN_READCHAN (0x3ff << 0) - #define READCHAN_READCHANr(x) (((x) & READCHAN_READCHAN) >> 0) -#define READCHAN_STC (0x1 << 14) -#define READCHAN_ST (0x1 << 10) - -/* STATUSRSSI (0xB) */ -#define STATUSRSSI_RSSI (0x3F << 10) - #define STATUSRSSI_RSSIr(x) (((x) & STATUSRSSI_RSSI) >> 10) -#define STATUSRSSI_AFCRL (0x1 << 8) - -static const uint16_t initvals[32] = { - 0x8110, 0x4580, 0xC401, 0x1B90, - 0x0400, 0x866F, 0x8000, 0x4712, - 0x5EC6, 0x0000, 0x406E, 0x2D80, - 0x5803, 0x5804, 0x5804, 0x5804, - - 0x0047, 0x9000, 0xF587, 0x0009, - 0x00F1, 0x41C0, 0x41E0, 0x506F, - 0x5592, 0x007D, 0x10A0, 0x0780, - 0x311D, 0x4006, 0x1F9B, 0x4C2B -}; - -static bool tuner_present = false; -static int curr_frequency = 87500000; /* Current station frequency (HZ) */ -static uint16_t cache[32]; - -/* reads registers from radio at offset 0x0A into cache */ -static void fmclipplus_read(int len) -{ - int i; - unsigned char buf[64]; - unsigned char *ptr = buf; - uint16_t data; - - fmradio_i2c_read(I2C_ADR, buf, len * 2); - for (i = 0; i < len; i++) { - data = ptr[0] << 8 | ptr[1]; - cache[(i + READCHAN) & 0x1F] = data; - ptr += 2; - } -} - -/* writes registers from cache to radio at offset 0x02 */ -static void fmclipplus_write(int len) -{ - int i; - unsigned char buf[64]; - unsigned char *ptr = buf; - uint16_t data; - - for (i = 0; i < len; i++) { - data = cache[(i + POWERCFG) & 0x1F]; - *ptr++ = (data >> 8) & 0xFF; - *ptr++ = data & 0xFF; - } - fmradio_i2c_write(I2C_ADR, buf, len * 2); -} - -static uint16_t fmclipplus_read_reg(int reg) -{ - fmclipplus_read(((reg - READCHAN) & 0x1F) + 1); - return cache[reg]; -} - -static void fmclipplus_write_reg(int reg, uint16_t value) -{ - cache[reg] = value; -} - -static void fmclipplus_write_cache(void) -{ - fmclipplus_write(5); -} - -static void fmclipplus_write_masked(int reg, uint16_t bits, uint16_t mask) -{ - fmclipplus_write_reg(reg, (cache[reg] & ~mask) | (bits & mask)); -} - -static void fmclipplus_write_clear(int reg, uint16_t mask) -{ - fmclipplus_write_reg(reg, cache[reg] & ~mask); -} - -static void fmclipplus_sleep(int snooze) -{ - if (snooze) { - fmclipplus_write_masked(POWERCFG, 0, 0xFF); - } - else { - fmclipplus_write_masked(POWERCFG, 1, 0xFF); - } - fmclipplus_write_cache(); -} - -bool fmclipplus_detect(void) -{ - return ((fmclipplus_read_reg(IDENT) & 0xFF00) == 0x5800); - } - -void fmclipplus_init(void) -{ - if (fmclipplus_detect()) { - tuner_present = true; - - // send pre-initialisation value - fmclipplus_write_reg(POWERCFG, 0x200); - fmclipplus_write(2); - sleep(HZ * 10 / 100); - - // write initialisation values - memcpy(cache, initvals, sizeof(cache)); - fmclipplus_write(32); - sleep(HZ * 70 / 1000); - } -} - -static void fmclipplus_set_frequency(int freq) -{ - int i; - - /* check BAND and spacings */ - fmclipplus_read_reg(STATUSRSSI); - int start = CHANNEL_BANDr(cache[CHANNEL]) & 1 ? 76000000 : 87000000; - int chan = (freq - start) / 50000; - - curr_frequency = freq; - - for (i = 0; i < 5; i++) { - /* tune and wait a bit */ - fmclipplus_write_masked(CHANNEL, CHANNEL_CHANw(chan) | CHANNEL_TUNE, - CHANNEL_CHAN | CHANNEL_TUNE); - fmclipplus_write_cache(); - sleep(HZ * 70 / 1000); - fmclipplus_write_clear(CHANNEL, CHANNEL_TUNE); - fmclipplus_write_cache(); - - /* check if tuning was successful */ - fmclipplus_read_reg(STATUSRSSI); - if (cache[READCHAN] & READCHAN_STC) { - if (READCHAN_READCHANr(cache[READCHAN]) == chan) { - break; - } - } - } -} - -static int fmclipplus_tuned(void) -{ - /* Primitive tuning check: sufficient level and AFC not railed */ - uint16_t status = fmclipplus_read_reg(STATUSRSSI); - if (STATUSRSSI_RSSIr(status) >= SEEK_THRESHOLD && - (status & STATUSRSSI_AFCRL) == 0) { - return 1; - } - - return 0; -} - -static void fmclipplus_set_region(int region) -{ - const struct fmclipplus_region_data *rd = &fmclipplus_region_data[region]; - uint16_t bandspacing = CHANNEL_BANDw(rd->band) | - CHANNEL_SPACEw(CHANNEL_SPACE_50KHZ); - uint16_t oldbs = cache[CHANNEL] & (CHANNEL_BAND | CHANNEL_SPACE); - - fmclipplus_write_masked(SYSCONFIG1, rd->deemphasis ? SYSCONFIG1_DE : 0, - SYSCONFIG1_DE); - fmclipplus_write_masked(CHANNEL, bandspacing, CHANNEL_BAND | CHANNEL_SPACE); - fmclipplus_write_cache(); - - /* Retune if this region change would change the channel number. */ - if (oldbs != bandspacing) { - fmclipplus_set_frequency(curr_frequency); - } -} - -static bool fmclipplus_st(void) -{ - return (fmclipplus_read_reg(READCHAN) & READCHAN_ST); -} - -/* tuner abstraction layer: set something to the tuner */ -int fmclipplus_set(int setting, int value) -{ - switch (setting) { - case RADIO_SLEEP: - if (value != 2) { - fmclipplus_sleep(value); - } - break; - - case RADIO_FREQUENCY: - fmclipplus_set_frequency(value); - break; - - case RADIO_SCAN_FREQUENCY: - fmclipplus_set_frequency(value); - return fmclipplus_tuned(); - - case RADIO_MUTE: - fmclipplus_write_masked(POWERCFG, value ? 0 : POWERCFG_DMUTE, - POWERCFG_DMUTE); - fmclipplus_write_masked(SYSCONFIG1, (3 << 9), (3 << 9)); - fmclipplus_write_masked(SYSCONFIG2, (0xF << 0), (0xF << 0)); - fmclipplus_write_cache(); - break; - - case RADIO_REGION: - fmclipplus_set_region(value); - break; - - case RADIO_FORCE_MONO: - fmclipplus_write_masked(POWERCFG, value ? POWERCFG_MONO : 0, - POWERCFG_MONO); - fmclipplus_write_cache(); - break; - - default: - return -1; - } - - return 1; -} - -/* tuner abstraction layer: read something from the tuner */ -int fmclipplus_get(int setting) -{ - int val = -1; /* default for unsupported query */ - - switch (setting) { - case RADIO_PRESENT: - val = tuner_present ? 1 : 0; - break; - - case RADIO_TUNED: - val = fmclipplus_tuned(); - break; - - case RADIO_STEREO: - val = fmclipplus_st(); - break; - } - - return val; -} - -void fmclipplus_dbg_info(struct fmclipplus_dbg_info *nfo) -{ - fmclipplus_read(32); - memcpy(nfo->regs, cache, sizeof (nfo->regs)); -} - diff --git a/firmware/drivers/tuner/rda5802.c b/firmware/drivers/tuner/rda5802.c new file mode 100644 index 0000000000..a505b6b382 --- /dev/null +++ b/firmware/drivers/tuner/rda5802.c @@ -0,0 +1,333 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Tuner "middleware" for RDA5802 chip present in some Sansa Clip+ players + * + * Copyright (C) 2010 Bertrik Sikken + * Copyright (C) 2008 Nils Wallménius (si4700 code that this was based on) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "config.h" +#include +#include +#include +#include "kernel.h" +#include "tuner.h" /* tuner abstraction interface */ +#include "fmradio.h" +#include "fmradio_i2c.h" /* physical interface driver */ + +#define SEEK_THRESHOLD 0x16 + +#define I2C_ADR 0x20 + +/** Registers and bits **/ +#define POWERCFG 0x2 +#define CHANNEL 0x3 +#define SYSCONFIG1 0x4 +#define SYSCONFIG2 0x5 +#define SYSCONFIG3 0x6 + +#define READCHAN 0xA +#define STATUSRSSI 0xB +#define IDENT 0xC + + +/* POWERCFG (0x2) */ +#define POWERCFG_DMUTE (0x1 << 14) +#define POWERCFG_MONO (0x1 << 13) +#define POWERCFG_SOFT_RESET (0x1 << 1) +#define POWERCFG_ENABLE (0x1 << 0) + +/* CHANNEL (0x3) */ +#define CHANNEL_CHAN (0x3ff << 6) + #define CHANNEL_CHANw(x) (((x) << 6) & CHANNEL_CHAN) +#define CHANNEL_TUNE (0x1 << 4) +#define CHANNEL_BAND (0x3 << 2) + #define CHANNEL_BANDw(x) (((x) << 2) & CHANNEL_BAND) + #define CHANNEL_BANDr(x) (((x) & CHANNEL_BAND) >> 2) + #define CHANNEL_BAND_875_1080 (0x0 << 2) /* tenth-megahertz */ + #define CHANNEL_BAND_760_1080 (0x1 << 2) + #define CHANNEL_BAND_760_900 (0x2 << 2) + #define CHANNEL_BAND_650_760 (0x3 << 2) +#define CHANNEL_SPACE (0x3 << 0) + #define CHANNEL_SPACEw(x) (((x) << 0) & CHANNEL_SPACE) + #define CHANNEL_SPACEr(x) (((x) & CHANNEL_SPACE) >> 0) + #define CHANNEL_SPACE_100KHZ (0x0 << 0) + #define CHANNEL_SPACE_200KHZ (0x1 << 0) + #define CHANNEL_SPACE_50KHZ (0x2 << 0) + +/* SYSCONFIG1 (0x4) */ +#define SYSCONFIG1_DE (0x1 << 11) + #define SYSCONFIG1_SMUTE (0x1 << 9) + +/* SYSCONFIG2 (0x5) */ +#define SYSCONFIG2_VOLUME (0xF << 0) + +/* READCHAN (0xA) */ +#define READCHAN_READCHAN (0x3ff << 0) + #define READCHAN_READCHANr(x) (((x) & READCHAN_READCHAN) >> 0) +#define READCHAN_STC (0x1 << 14) +#define READCHAN_ST (0x1 << 10) + +/* STATUSRSSI (0xB) */ +#define STATUSRSSI_RSSI (0x7F << 9) + #define STATUSRSSI_RSSIr(x) (((x) & STATUSRSSI_RSSI) >> 9) +#define STATUSRSSI_FM_TRUE (0x1 << 8) + +static const uint16_t initvals[16] = { + 0x0000, 0x0000, 0xC401, 0x1B90, + 0x0400, 0x866F, 0x8000, 0x4712, + 0x5EC6, 0x0000, 0x406E, 0x2D80, + 0x5803, 0x5804, 0x5804, 0x5804 +}; + +static bool tuner_present = false; +static int curr_frequency = 87500000; /* Current station frequency (HZ) */ +static uint16_t cache[16]; + +/* reads registers from radio at offset 0x0A into cache */ +static void rda5802_read(int len) +{ + int i; + unsigned char buf[128]; + unsigned char *ptr = buf; + uint16_t data; + + fmradio_i2c_read(I2C_ADR, buf, len * 2); + for (i = 0; i < len; i++) { + data = ptr[0] << 8 | ptr[1]; + cache[READCHAN + i] = data; + ptr += 2; + } +} + +/* writes registers from cache to radio at offset 0x02 */ +static void rda5802_write(int len) +{ + int i; + unsigned char buf[64]; + unsigned char *ptr = buf; + uint16_t data; + + for (i = 0; i < len; i++) { + data = cache[POWERCFG + i]; + *ptr++ = (data >> 8) & 0xFF; + *ptr++ = data & 0xFF; + } + fmradio_i2c_write(I2C_ADR, buf, len * 2); +} + +static uint16_t rda5802_read_reg(int reg) +{ + rda5802_read((reg - READCHAN) + 1); + return cache[reg]; +} + +static void rda5802_write_reg(int reg, uint16_t value) +{ + cache[reg] = value; +} + +static void rda5802_write_cache(void) +{ + rda5802_write(5); +} + +static void rda5802_write_masked(int reg, uint16_t bits, uint16_t mask) +{ + rda5802_write_reg(reg, (cache[reg] & ~mask) | (bits & mask)); +} + +static void rda5802_write_clear(int reg, uint16_t mask) +{ + rda5802_write_reg(reg, cache[reg] & ~mask); +} + +static void rda5802_write_set(int reg, uint16_t mask) +{ + rda5802_write_reg(reg, cache[reg] | mask); +} + +static void rda5802_sleep(int snooze) +{ + if (snooze) { + rda5802_write_clear(POWERCFG, POWERCFG_ENABLE); + } + else { + rda5802_write_set(POWERCFG, POWERCFG_ENABLE); + } + rda5802_write_cache(); +} + +bool rda5802_detect(void) +{ + return ((rda5802_read_reg(IDENT) & 0xFF00) == 0x5800); + } + +void rda5802_init(void) +{ + if (rda5802_detect()) { + tuner_present = true; + + // soft-reset + rda5802_write_reg(POWERCFG, POWERCFG_SOFT_RESET); + rda5802_write(1); + sleep(HZ * 10 / 1000); + + // write initialisation values + memcpy(cache, initvals, sizeof(cache)); + rda5802_write(16); + sleep(HZ * 70 / 1000); + } +} + +static void rda5802_set_frequency(int freq) +{ + int i; + uint16_t readchan; + + /* check BAND and spacings */ + int start = CHANNEL_BANDr(cache[CHANNEL]) & 1 ? 76000000 : 87000000; + int chan = (freq - start) / 50000; + + curr_frequency = freq; + + for (i = 0; i < 5; i++) { + /* tune and wait a bit */ + rda5802_write_masked(CHANNEL, CHANNEL_CHANw(chan) | CHANNEL_TUNE, + CHANNEL_CHAN | CHANNEL_TUNE); + rda5802_write_cache(); + sleep(HZ * 70 / 1000); + rda5802_write_clear(CHANNEL, CHANNEL_TUNE); + rda5802_write_cache(); + + /* check if tuning was successful */ + readchan = rda5802_read_reg(READCHAN); + if (readchan & READCHAN_STC) { + if (READCHAN_READCHANr(readchan) == chan) { + break; + } + } + } +} + +static int rda5802_tuned(void) +{ + /* Primitive tuning check: sufficient level and AFC not railed */ + uint16_t status = rda5802_read_reg(STATUSRSSI); + if (STATUSRSSI_RSSIr(status) >= SEEK_THRESHOLD && + (status & STATUSRSSI_FM_TRUE)) { + return 1; + } + + return 0; +} + +static void rda5802_set_region(int region) +{ + const struct rda5802_region_data *rd = &rda5802_region_data[region]; + uint16_t bandspacing = CHANNEL_BANDw(rd->band) | + CHANNEL_SPACEw(CHANNEL_SPACE_50KHZ); + uint16_t oldbs = cache[CHANNEL] & (CHANNEL_BAND | CHANNEL_SPACE); + + rda5802_write_masked(SYSCONFIG1, rd->deemphasis ? SYSCONFIG1_DE : 0, + SYSCONFIG1_DE); + rda5802_write_masked(CHANNEL, bandspacing, CHANNEL_BAND | CHANNEL_SPACE); + rda5802_write_cache(); + + /* Retune if this region change would change the channel number. */ + if (oldbs != bandspacing) { + rda5802_set_frequency(curr_frequency); + } +} + +static bool rda5802_st(void) +{ + return (rda5802_read_reg(READCHAN) & READCHAN_ST); +} + +/* tuner abstraction layer: set something to the tuner */ +int rda5802_set(int setting, int value) +{ + switch (setting) { + case RADIO_SLEEP: + if (value != 2) { + rda5802_sleep(value); + } + break; + + case RADIO_FREQUENCY: + rda5802_set_frequency(value); + break; + + case RADIO_SCAN_FREQUENCY: + rda5802_set_frequency(value); + return rda5802_tuned(); + + case RADIO_MUTE: + rda5802_write_masked(POWERCFG, value ? 0 : POWERCFG_DMUTE, + POWERCFG_DMUTE); + rda5802_write_masked(SYSCONFIG1, (3 << 9), (3 << 9)); + rda5802_write_set(SYSCONFIG2, SYSCONFIG2_VOLUME); + rda5802_write_cache(); + break; + + case RADIO_REGION: + rda5802_set_region(value); + break; + + case RADIO_FORCE_MONO: + rda5802_write_masked(POWERCFG, value ? POWERCFG_MONO : 0, + POWERCFG_MONO); + rda5802_write_cache(); + break; + + default: + return -1; + } + + return 1; +} + +/* tuner abstraction layer: read something from the tuner */ +int rda5802_get(int setting) +{ + int val = -1; /* default for unsupported query */ + + switch (setting) { + case RADIO_PRESENT: + val = tuner_present ? 1 : 0; + break; + + case RADIO_TUNED: + val = rda5802_tuned(); + break; + + case RADIO_STEREO: + val = rda5802_st(); + break; + } + + return val; +} + +void rda5802_dbg_info(struct rda5802_dbg_info *nfo) +{ + rda5802_read(6); + memcpy(nfo->regs, cache, sizeof (nfo->regs)); +} + diff --git a/firmware/export/config.h b/firmware/export/config.h index 7f77514116..5be2c99dcb 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h @@ -41,7 +41,7 @@ #define TEA5760 0x10 /* Philips */ #define LV240000 0x20 /* Sanyo */ #define IPOD_REMOTE_TUNER 0x40 /* Apple */ -#define FMCLIPPLUS 0x80 /* Mystery SiLabs FM tuner in some clip+ */ +#define RDA5802 0x80 /* RDA Microelectronics */ /* CONFIG_CODEC */ #define MAS3587F 3587 diff --git a/firmware/export/config/sansaclipplus.h b/firmware/export/config/sansaclipplus.h index 90636b152d..df9fad74c9 100644 --- a/firmware/export/config/sansaclipplus.h +++ b/firmware/export/config/sansaclipplus.h @@ -123,7 +123,7 @@ #define AB_REPEAT_ENABLE 1 /* FM Tuner */ -#define CONFIG_TUNER (SI4700|FMCLIPPLUS) /* in fact SI4702 */ +#define CONFIG_TUNER (SI4700|RDA5802) /* in fact SI4702 */ //#define HAVE_TUNER_PWR_CTRL /* Define this for LCD backlight available */ diff --git a/firmware/export/fmclipplus.h b/firmware/export/fmclipplus.h deleted file mode 100644 index 20961f47be..0000000000 --- a/firmware/export/fmclipplus.h +++ /dev/null @@ -1,54 +0,0 @@ -/*************************************************************************** - * __________ __ ___. - * Open \______ \ ____ ____ | | _\_ |__ _______ ___ - * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / - * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < - * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ - * \/ \/ \/ \/ \/ - * - * $Id$ - * - * Tuner header for the Silicon Labs Mystery radio chip in some Sansa Clip+ - * - * Copyright (C) 2010 Bertrik Sikken - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY - * KIND, either express or implied. - * - ****************************************************************************/ - -#ifndef _FMCLIPPLUS_H_ -#define _FMCLIPPLUS_H_ - -#define HAVE_RADIO_REGION - -struct fmclipplus_region_data -{ - unsigned char deemphasis; /* 0: 75us, 1: 50us */ - unsigned char band; /* 0: us/europe, 1: japan */ -} __attribute__((packed)); - -extern const struct fmclipplus_region_data fmclipplus_region_data[TUNER_NUM_REGIONS]; - -struct fmclipplus_dbg_info -{ - uint16_t regs[32]; /* Read registers */ -}; - -bool fmclipplus_detect(void); -void fmclipplus_init(void); -int fmclipplus_set(int setting, int value); -int fmclipplus_get(int setting); -void fmclipplus_dbg_info(struct fmclipplus_dbg_info *nfo); - -#ifndef CONFIG_TUNER_MULTI -#define tuner_set fmclipplus_set -#define tuner_get fmclipplus_get -#endif - -#endif /* _FMCLIPPLUS_H_ */ diff --git a/firmware/export/rda5802.h b/firmware/export/rda5802.h new file mode 100644 index 0000000000..e61ecb40ae --- /dev/null +++ b/firmware/export/rda5802.h @@ -0,0 +1,54 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * $Id$ + * + * Tuner header for the RDA Microelectronics RDA5802 FM tuner chip + * + * Copyright (C) 2010 Bertrik Sikken + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ + +#ifndef _RDA5802_H_ +#define _RDA5802_H_ + +#define HAVE_RADIO_REGION + +struct rda5802_region_data +{ + unsigned char deemphasis; /* 0: 75us, 1: 50us */ + unsigned char band; /* 0: us/europe, 1: japan */ +} __attribute__((packed)); + +extern const struct rda5802_region_data rda5802_region_data[TUNER_NUM_REGIONS]; + +struct rda5802_dbg_info +{ + uint16_t regs[16]; /* Read registers */ +}; + +bool rda5802_detect(void); +void rda5802_init(void); +int rda5802_set(int setting, int value); +int rda5802_get(int setting); +void rda5802_dbg_info(struct rda5802_dbg_info *nfo); + +#ifndef CONFIG_TUNER_MULTI +#define tuner_set rda5802_set +#define tuner_get rda5802_get +#endif + +#endif /* _RDA5802_H_ */ diff --git a/firmware/export/tuner.h b/firmware/export/tuner.h index 9101bb9241..fa894a4b6c 100644 --- a/firmware/export/tuner.h +++ b/firmware/export/tuner.h @@ -132,9 +132,9 @@ extern int (*tuner_get)(int setting); #include "si4700.h" #endif -/* Silicon Labs mystery radio chip in some Sansa Clip+ */ -#if (CONFIG_TUNER & FMCLIPPLUS) -#include "fmclipplus.h" +/* RDA micro RDA5802 */ +#if (CONFIG_TUNER & RDA5802) +#include "rda5802.h" #endif /* Apple remote tuner */ diff --git a/firmware/target/arm/as3525/sansa-clipplus/tuner-clipplus.c b/firmware/target/arm/as3525/sansa-clipplus/tuner-clipplus.c index 6bc1294eb4..650f68dc8b 100644 --- a/firmware/target/arm/as3525/sansa-clipplus/tuner-clipplus.c +++ b/firmware/target/arm/as3525/sansa-clipplus/tuner-clipplus.c @@ -29,8 +29,8 @@ int tuner_detect_type(void) { if (si4700_detect()) { return SI4700; - } else if (fmclipplus_detect()) { - return FMCLIPPLUS; + } else if (rda5802_detect()) { + return RDA5802; } else { return 0; } diff --git a/firmware/tuner.c b/firmware/tuner.c index 4d3866dc8e..3232147bbb 100644 --- a/firmware/tuner.c +++ b/firmware/tuner.c @@ -89,8 +89,8 @@ const struct si4700_region_data si4700_region_data[TUNER_NUM_REGIONS] = }; #endif /* (CONFIG_TUNER & SI4700) */ -#if (CONFIG_TUNER & FMCLIPPLUS) -const struct fmclipplus_region_data fmclipplus_region_data[TUNER_NUM_REGIONS] = +#if (CONFIG_TUNER & RDA5802) +const struct rda5802_region_data rda5802_region_data[TUNER_NUM_REGIONS] = { [REGION_EUROPE] = { 1, 0 }, /* 50uS, US/Europe band */ [REGION_US_CANADA] = { 0, 0 }, /* 75uS, US/Europe band */ @@ -99,7 +99,7 @@ const struct fmclipplus_region_data fmclipplus_region_data[TUNER_NUM_REGIONS] = [REGION_ITALY] = { 1, 0 }, /* 50uS, US/Europe band */ [REGION_OTHER] = { 1, 0 }, /* 50uS, US/Europe band */ }; -#endif /* (CONFIG_TUNER & FMCLIPPLUS) */ +#endif /* (CONFIG_TUNER & RDA5802) */ #if (CONFIG_TUNER & IPOD_REMOTE_TUNER) const struct rmt_tuner_region_data @@ -163,11 +163,11 @@ void tuner_init(void) si4700_get, si4700_init()) #endif - #if (CONFIG_TUNER & FMCLIPPLUS) - TUNER_TYPE_CASE(FMCLIPPLUS, - fmclipplus_set, - fmclipplus_get, - fmclipplus_init()) + #if (CONFIG_TUNER & RDA5802) + TUNER_TYPE_CASE(RDA5802, + rda5802_set, + rda5802_get, + rda5802_init()) #endif } } -- cgit v1.2.3