diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx31/gigabeat-s/fmradio-i2c-gigabeat-s.c | 49 |
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 */ |
130 | static bool int_restore; | 129 | static struct semaphore rds_sema; |
131 | 130 | static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)]; | |
132 | /* Called after I2C read cycle completes */ | ||
133 | static 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 */ | ||
144 | void 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 */ |
160 | void INT_SI4700_RDS(void) | 133 | void 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(); | 140 | static 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 */ |
172 | void si4700_rds_powerup(bool on) | 150 | void 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 */ |
181 | void si4700_rds_init(void) | 158 | void 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 | } |