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 | |
parent | 2202ed35351c30af6ce157002e5cb072b0b66a69 (diff) | |
download | rockbox-1d21e54fc4f586bbdfb765c90c9a64c060eeecc4.tar.gz rockbox-1d21e54fc4f586bbdfb765c90c9a64c060eeecc4.zip |
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>
-rw-r--r-- | firmware/export/config/sansafuzeplus.h | 5 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/fmradio-i2c-fuzeplus.c | 60 |
2 files changed, 63 insertions, 2 deletions
diff --git a/firmware/export/config/sansafuzeplus.h b/firmware/export/config/sansafuzeplus.h index 9d7b9bf756..810cc1d6a1 100644 --- a/firmware/export/config/sansafuzeplus.h +++ b/firmware/export/config/sansafuzeplus.h | |||
@@ -77,6 +77,7 @@ | |||
77 | #define HAVE_IMX233_CODEC | 77 | #define HAVE_IMX233_CODEC |
78 | 78 | ||
79 | #define CONFIG_TUNER SI4700 | 79 | #define CONFIG_TUNER SI4700 |
80 | #define HAVE_RDS_CAP | ||
80 | 81 | ||
81 | /* There is no hardware tone control */ | 82 | /* There is no hardware tone control */ |
82 | #define HAVE_SW_TONE_CONTROLS | 83 | #define HAVE_SW_TONE_CONTROLS |
@@ -129,8 +130,8 @@ | |||
129 | #define NUM_DRIVES 2 | 130 | #define NUM_DRIVES 2 |
130 | #define HAVE_HOTSWAP | 131 | #define HAVE_HOTSWAP |
131 | 132 | ||
132 | /* Extra threads: touchpad */ | 133 | /* Extra threads: touchpad and rds */ |
133 | #define TARGET_EXTRA_THREADS 1 | 134 | #define TARGET_EXTRA_THREADS 2 |
134 | 135 | ||
135 | /* todo */ | 136 | /* todo */ |
136 | #define BATTERY_CAPACITY_DEFAULT 550 /* default battery capacity */ | 137 | #define BATTERY_CAPACITY_DEFAULT 550 /* default battery capacity */ |
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 @@ | |||
24 | #include "fmradio_i2c.h" | 24 | #include "fmradio_i2c.h" |
25 | #include "pinctrl-imx233.h" | 25 | #include "pinctrl-imx233.h" |
26 | #include "generic_i2c.h" | 26 | #include "generic_i2c.h" |
27 | #include "rds.h" | ||
28 | #include "si4700.h" | ||
27 | 29 | ||
28 | /** | 30 | /** |
29 | * Sansa Fuze+ fmradio uses the following pins: | 31 | * Sansa Fuze+ fmradio uses the following pins: |
30 | * - B0P29 as CE apparently (active high) | 32 | * - B0P29 as CE apparently (active high) |
31 | * - B1P24 as SDA | 33 | * - B1P24 as SDA |
32 | * - B1P22 as SCL | 34 | * - B1P22 as SCL |
35 | * - B2P27 as STC/RDS | ||
33 | */ | 36 | */ |
34 | static int fmradio_i2c_bus = -1; | 37 | static int fmradio_i2c_bus = -1; |
35 | 38 | ||
@@ -103,3 +106,60 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | |||
103 | { | 106 | { |
104 | return i2c_read_data(fmradio_i2c_bus, address, -1, buf, count); | 107 | return i2c_read_data(fmradio_i2c_bus, address, -1, buf, count); |
105 | } | 108 | } |
109 | |||
110 | #ifdef HAVE_RDS_CAP | ||
111 | /* Low-level RDS Support */ | ||
112 | static struct semaphore rds_sema; | ||
113 | static uint32_t rds_stack[DEFAULT_STACK_SIZE / sizeof(uint32_t)]; | ||
114 | |||
115 | /* RDS GPIO interrupt handler */ | ||
116 | static void stc_rds_callback(int bank, int pin) | ||
117 | { | ||
118 | (void) bank; | ||
119 | (void) pin; | ||
120 | |||
121 | semaphore_release(&rds_sema); | ||
122 | } | ||
123 | |||
124 | /* Captures RDS data and processes it */ | ||
125 | static void NORETURN_ATTR rds_thread(void) | ||
126 | { | ||
127 | uint16_t rds_data[4]; | ||
128 | |||
129 | while(true) | ||
130 | { | ||
131 | semaphore_wait(&rds_sema, TIMEOUT_BLOCK); | ||
132 | if(si4700_rds_read_raw(rds_data) && rds_process(rds_data)) | ||
133 | si4700_rds_set_event(); | ||
134 | /* renable callback */ | ||
135 | imx233_setup_pin_irq(2, 27, true, true, false, &stc_rds_callback); | ||
136 | } | ||
137 | } | ||
138 | |||
139 | /* true after full radio power up, and false before powering down */ | ||
140 | void si4700_rds_powerup(bool on) | ||
141 | { | ||
142 | if(on) | ||
143 | { | ||
144 | imx233_pinctrl_acquire_pin(2, 27, "tuner stc/rds"); | ||
145 | imx233_set_pin_function(2, 27, PINCTRL_FUNCTION_GPIO); | ||
146 | imx233_enable_gpio_output(2, 27, false); | ||
147 | /* pin is set to 0 when an RDS packet has arrived */ | ||
148 | imx233_setup_pin_irq(2, 27, true, true, false, &stc_rds_callback); | ||
149 | } | ||
150 | else | ||
151 | { | ||
152 | imx233_setup_pin_irq(2, 27, false, false, false, NULL); | ||
153 | imx233_pinctrl_release_pin(2, 27, "tuner stc/rds"); | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /* One-time RDS init at startup */ | ||
158 | void si4700_rds_init(void) | ||
159 | { | ||
160 | semaphore_init(&rds_sema, 1, 0); | ||
161 | rds_init(); | ||
162 | create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" | ||
163 | IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); | ||
164 | } | ||
165 | #endif /* HAVE_RDS_CAP */ | ||