diff options
Diffstat (limited to 'firmware/target/arm/imx31/gigabeat-s')
3 files changed, 72 insertions, 3 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 39a2cdab04..e0457e367a 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 | |||
@@ -23,8 +23,12 @@ | |||
23 | #include "system.h" | 23 | #include "system.h" |
24 | #include "mc13783.h" | 24 | #include "mc13783.h" |
25 | #include "iomuxc-imx31.h" | 25 | #include "iomuxc-imx31.h" |
26 | #include "gpio-imx31.h" | ||
26 | #include "i2c-imx31.h" | 27 | #include "i2c-imx31.h" |
27 | #include "fmradio_i2c.h" | 28 | #include "fmradio_i2c.h" |
29 | #include "thread.h" | ||
30 | #include "rds.h" | ||
31 | #include "tuner.h" | ||
28 | 32 | ||
29 | static struct i2c_node si4700_i2c_node = | 33 | static struct i2c_node si4700_i2c_node = |
30 | { | 34 | { |
@@ -117,7 +121,57 @@ int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) | |||
117 | return 0; | 121 | return 0; |
118 | } | 122 | } |
119 | 123 | ||
120 | int si4700_st(void) | 124 | bool si4700_st(void) |
121 | { | 125 | { |
122 | return (GPIO1_DR & (1 << 28)) >> 28; | 126 | return (GPIO1_DR & (1 << 28)) >> 28; |
123 | } | 127 | } |
128 | |||
129 | |||
130 | /* Low-level RDS Support */ | ||
131 | static struct semaphore rds_sema; | ||
132 | static uint32_t rds_stack[DEFAULT_STACK_SIZE/sizeof(uint32_t)]; | ||
133 | |||
134 | /* RDS GPIO interrupt handler */ | ||
135 | void si4700_stc_rds_event(void) | ||
136 | { | ||
137 | /* read and clear the interrupt */ | ||
138 | SI4700_GPIO_STC_RDS_ISR = (1ul << SI4700_GPIO_STC_RDS_LINE); | ||
139 | semaphore_release(&rds_sema); | ||
140 | } | ||
141 | |||
142 | /* Called with on=true after full radio power up, and with on=false before | ||
143 | powering down */ | ||
144 | void si4700_rds_powerup(bool on) | ||
145 | { | ||
146 | gpio_disable_event(SI4700_STC_RDS_EVENT_ID); | ||
147 | |||
148 | if (on) | ||
149 | { | ||
150 | SI4700_GPIO_STC_RDS_ISR = (1ul << SI4700_GPIO_STC_RDS_LINE); | ||
151 | gpio_enable_event(SI4700_STC_RDS_EVENT_ID); | ||
152 | } | ||
153 | } | ||
154 | |||
155 | /* Captures RDS data and processes it */ | ||
156 | /* Use of a thread here is likely temporary */ | ||
157 | static void NORETURN_ATTR rds_thread(void) | ||
158 | { | ||
159 | uint16_t rds_data[4]; | ||
160 | |||
161 | while (1) | ||
162 | { | ||
163 | semaphore_wait(&rds_sema, TIMEOUT_BLOCK); | ||
164 | |||
165 | if (si4700_rds_read_raw(rds_data) && rds_process(rds_data)) | ||
166 | si4700_rds_set_event(); | ||
167 | } | ||
168 | } | ||
169 | |||
170 | /* One-time RDS init at startup */ | ||
171 | void si4700_rds_init(void) | ||
172 | { | ||
173 | semaphore_init(&rds_sema, 1, 0); | ||
174 | rds_init(); | ||
175 | create_thread(rds_thread, rds_stack, sizeof(rds_stack), 0, "rds" | ||
176 | IF_PRIO(, PRIORITY_REALTIME) IF_COP(, CPU)); | ||
177 | } | ||
diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c index f4402d5617..e6bbb2345d 100644 --- a/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c +++ b/firmware/target/arm/imx31/gigabeat-s/gpio-gigabeat-s.c | |||
@@ -39,5 +39,12 @@ const struct gpio_event gpio1_events[] = | |||
39 | .mask = 1 << MC13783_GPIO_LINE, | 39 | .mask = 1 << MC13783_GPIO_LINE, |
40 | .sense = GPIO_SENSE_HIGH_LEVEL, | 40 | .sense = GPIO_SENSE_HIGH_LEVEL, |
41 | .callback = mc13783_event, | 41 | .callback = mc13783_event, |
42 | } | 42 | }, |
43 | /* Generates a 5ms low pulse on the line - detect the falling edge */ | ||
44 | [SI4700_STC_RDS_EVENT_ID] = | ||
45 | { | ||
46 | .mask = 1 << SI4700_GPIO_STC_RDS_LINE, | ||
47 | .sense = GPIO_SENSE_FALLING, | ||
48 | .callback = si4700_stc_rds_event, | ||
49 | }, | ||
43 | }; | 50 | }; |
diff --git a/firmware/target/arm/imx31/gigabeat-s/gpio-target.h b/firmware/target/arm/imx31/gigabeat-s/gpio-target.h index 2eea27c3be..4903d0f631 100644 --- a/firmware/target/arm/imx31/gigabeat-s/gpio-target.h +++ b/firmware/target/arm/imx31/gigabeat-s/gpio-target.h | |||
@@ -29,6 +29,12 @@ | |||
29 | #define MC13783_GPIO_ISR GPIO1_ISR | 29 | #define MC13783_GPIO_ISR GPIO1_ISR |
30 | #define MC13783_GPIO_LINE 31 | 30 | #define MC13783_GPIO_LINE 31 |
31 | 31 | ||
32 | /* SI4700 GPIO STC/RDS pin info for this target */ | ||
33 | #define SI4700_GPIO_STC_RDS_IMR GPIO1_IMR | ||
34 | #define SI4700_GPIO_STC_RDS_NUM GPIO1_NUM | ||
35 | #define SI4700_GPIO_STC_RDS_ISR GPIO1_ISR | ||
36 | #define SI4700_GPIO_STC_RDS_LINE 27 | ||
37 | |||
32 | #define GPIO1_INT_PRIO INT_PRIO_DEFAULT | 38 | #define GPIO1_INT_PRIO INT_PRIO_DEFAULT |
33 | 39 | ||
34 | /* Declare event indexes in priority order in a packed array */ | 40 | /* Declare event indexes in priority order in a packed array */ |
@@ -36,7 +42,8 @@ enum gpio_event_ids | |||
36 | { | 42 | { |
37 | /* GPIO1 event IDs */ | 43 | /* GPIO1 event IDs */ |
38 | MC13783_EVENT_ID = GPIO1_EVENT_FIRST, | 44 | MC13783_EVENT_ID = GPIO1_EVENT_FIRST, |
39 | GPIO1_NUM_EVENTS = 1, | 45 | SI4700_STC_RDS_EVENT_ID, |
46 | GPIO1_NUM_EVENTS = 2, | ||
40 | /* GPIO2 event IDs */ | 47 | /* GPIO2 event IDs */ |
41 | /* none defined */ | 48 | /* none defined */ |
42 | /* GPIO3 event IDs */ | 49 | /* GPIO3 event IDs */ |
@@ -44,5 +51,6 @@ enum gpio_event_ids | |||
44 | }; | 51 | }; |
45 | 52 | ||
46 | void mc13783_event(void); | 53 | void mc13783_event(void); |
54 | void si4700_stc_rds_event(void); | ||
47 | 55 | ||
48 | #endif /* GPIO_TARGET_H */ | 56 | #endif /* GPIO_TARGET_H */ |