summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c
diff options
context:
space:
mode:
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}