summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c
diff options
context:
space:
mode:
authorWolfram Sang <wsa@the-dreams.de>2021-12-10 16:13:49 +0100
committerWolfram Sang <wsa@the-dreams.de>2022-02-07 22:01:20 +0100
commit5b8873bf333add9ec7208901c62bbd30ad7ea8c3 (patch)
treef17916b7dcf0fb8059354094858a9f691c703b9f /firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c
parent8d453ae9c3beef82bd61401af6216f74a400cbd0 (diff)
downloadrockbox-5b8873bf333add9ec7208901c62bbd30ad7ea8c3.tar.gz
rockbox-5b8873bf333add9ec7208901c62bbd30ad7ea8c3.zip
RFT: convert Gigabeat RDS to thread
This kind of reverts 7b596416bf ("Gigabeat S: Update RDS processing to use asynchronous I2C rather than thread."). However, requiring RDS to run in thread context will a) allow more upcoming features and b) remove quite some complexity from the codebase (see the diffstat here) because Gigabeat is the only user. iMX31 should be able to handle one more thread, as it can even run Linux. Change-Id: I46130034595ba66392c5417c275d036f4bd26943
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c')
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c49
1 files changed, 14 insertions, 35 deletions
diff --git a/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c
index 5b0c71110d..c84f1cf41c 100644
--- a/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c
@@ -125,53 +125,30 @@ bool si4700_st(void)
125 return (GPIO1_DR & (1 << 28)) >> 28; 125 return (GPIO1_DR & (1 << 28)) >> 28;
126} 126}
127 127
128
129/* Low-level RDS Support */ 128/* Low-level RDS Support */
130static bool int_restore; 129static struct semaphore rds_sema;
131 130static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)];
132/* Called after I2C read cycle completes */
133static void si4700_rds_read_raw_async_callback(struct i2c_transfer_desc *xfer)
134{
135 if (xfer->rxcount == 0)
136 si4700_rds_process();
137 /* else read didn't finish */
138
139 if (int_restore)
140 gpio_int_enable(SI4700_EVENT_ID);
141}
142
143/* Called to read registers from ISR context */
144void si4700_rds_read_raw_async(unsigned char *buf, int count)
145{
146 /* transfer descriptor for RDS async operations */
147 static struct i2c_transfer_desc xfer = { .node = &si4700_i2c_node };
148
149 xfer.txdata = NULL;
150 xfer.txcount = 0;
151 xfer.rxdata = buf;
152 xfer.rxcount = count;
153 xfer.callback = si4700_rds_read_raw_async_callback;
154 xfer.next = NULL;
155
156 i2c_transfer(&xfer);
157}
158 131
159/* RDS GPIO interrupt handler - start RDS data read */ 132/* RDS GPIO interrupt handler - start RDS data read */
160void INT_SI4700_RDS(void) 133void INT_SI4700_RDS(void)
161{ 134{
162 /* mask and clear the interrupt until we're done */
163 gpio_int_disable(SI4700_EVENT_ID);
164 gpio_int_clear(SI4700_EVENT_ID); 135 gpio_int_clear(SI4700_EVENT_ID);
136 semaphore_release(&rds_sema);
137}
165 138
166 /* tell radio driver about it */ 139/* Captures RDS data and processes it */
167 si4700_rds_interrupt(); 140static void NORETURN_ATTR rds_thread(void)
141{
142 while (true) {
143 semaphore_wait(&rds_sema, TIMEOUT_BLOCK);
144 si4700_rds_process();
145 }
168} 146}
169 147
170/* Called with on=true after full radio power up, and with on=false before 148/* Called with on=true after full radio power up, and with on=false before
171 powering down */ 149 powering down */
172void si4700_rds_powerup(bool on) 150void si4700_rds_powerup(bool on)
173{ 151{
174 int_restore = on;
175 gpio_int_disable(SI4700_EVENT_ID); 152 gpio_int_disable(SI4700_EVENT_ID);
176 gpio_int_clear(SI4700_EVENT_ID); 153 gpio_int_clear(SI4700_EVENT_ID);
177 gpio_enable_event(SI4700_EVENT_ID, on); 154 gpio_enable_event(SI4700_EVENT_ID, on);
@@ -180,5 +157,7 @@ void si4700_rds_powerup(bool on)
180/* One-time RDS init at startup */ 157/* One-time RDS init at startup */
181void si4700_rds_init(void) 158void si4700_rds_init(void)
182{ 159{
183 /* nothing to do */ 160 semaphore_init(&rds_sema, 1, 0);
161 create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds"
162 IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU));
184} 163}