diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2012-05-10 18:29:43 +0200 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2012-05-12 13:09:06 +0200 |
commit | 1d21e54fc4f586bbdfb765c90c9a64c060eeecc4 (patch) | |
tree | b6eb135bd7136781bda7c5d2d9ce08b3d74d78eb /firmware/target | |
parent | 2202ed35351c30af6ce157002e5cb072b0b66a69 (diff) |
fuze+: add RDS support
I successfully identified the STC/RDS pin as B2P27.
Strangely the OF uses polling instead of interrupts
but since they routed it, let's use it! On the fuze+
the fmradio i2c uses bit toggling so we can't read
the RDS data in the interrupt context. Instead we
defer the work to a thread.
Change-Id: Iedfa425320e6c91b4351b72e97c732696bdb2b73
Reviewed-on: http://gerrit.rockbox.org/236
Reviewed-by: Bertrik Sikken <bertrik@sikken.nl>
Reviewed-by: Amaury Pouly <amaury.pouly@gmail.com>
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c index ee63cd35f6..7988c4cb28 100644 --- a/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c +++ b/firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c @@ -24,12 +24,15 @@ #include "fmradio_i2c.h" #include "pinctrl-imx233.h" #include "generic_i2c.h" +#include "rds.h" +#include "si4700.h" /** * Sansa Fuze+ fmradio uses the following pins: * - B0P29 as CE apparently (active high) * - B1P24 as SDA * - B1P22 as SCL + * - B2P27 as STC/RDS */ static int fmradio_i2c_bus = -1; @@ -103,3 +106,60 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) { return i2c_read_data(fmradio_i2c_bus, address, -1, buf, count); } + +#ifdef HAVE_RDS_CAP +/* Low-level RDS Support */ +static struct semaphore rds_sema; +static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; + +/* RDS GPIO interrupt handler */ +static void stc_rds_callback(int bank, int pin) +{ + (void) bank; + (void) pin; + + semaphore_release(&rds_sema); +} + +/* Captures RDS data and processes it */ +static void NORETURN_ATTR rds_thread(void) +{ + uint16_t rds_data[4]; + + while(true) + { + semaphore_wait(&rds_sema, TIMEOUT_BLOCK); + if(si4700_rds_read_raw(rds_data) && rds_process(rds_data)) + si4700_rds_set_event(); + /* renable callback */ + imx233_setup_pin_irq(2, 27, true, true, false, &stc_rds_callback); + } +} + +/* true after full radio power up, and false before powering down */ +void si4700_rds_powerup(bool on) +{ + if(on) + { + imx233_pinctrl_acquire_pin(2, 27, "tuner stc/rds"); + imx233_set_pin_function(2, 27, PINCTRL_FUNCTION_GPIO); + imx233_enable_gpio_output(2, 27, false); + /* pin is set to 0 when an RDS packet has arrived */ + imx233_setup_pin_irq(2, 27, true, true, false, &stc_rds_callback); + } + else + { + imx233_setup_pin_irq(2, 27, false, false, false, NULL); + imx233_pinctrl_release_pin(2, 27, "tuner stc/rds"); + } +} + +/* One-time RDS init at startup */ +void si4700_rds_init(void) +{ + semaphore_init(&rds_sema, 1, 0); + rds_init(); + create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" + IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); +} +#endif /* HAVE_RDS_CAP */ |