diff options
author | Laurent Gautier <creposucre@rockbox.org> | 2009-12-01 17:54:40 +0000 |
---|---|---|
committer | Laurent Gautier <creposucre@rockbox.org> | 2009-12-01 17:54:40 +0000 |
commit | 0260852771aef7a6e9045684f0c3d0d7e01909f7 (patch) | |
tree | 6fa4b42230d1289857f84405defad94cc2de86b8 /firmware | |
parent | 63d79148fd07aebd2b425c0414b7b9622b312399 (diff) | |
download | rockbox-0260852771aef7a6e9045684f0c3d0d7e01909f7.tar.gz rockbox-0260852771aef7a6e9045684f0c3d0d7e01909f7.zip |
Add support for the ipod FM remote to the 4G, Color, 5G, nano 1G with RDS
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23805 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/SOURCES | 5 | ||||
-rw-r--r-- | firmware/drivers/tuner/ipod_remote_tuner.c | 444 | ||||
-rw-r--r-- | firmware/export/config-ipod4g.h | 6 | ||||
-rw-r--r-- | firmware/export/config-ipodcolor.h | 6 | ||||
-rw-r--r-- | firmware/export/config-ipodnano.h | 6 | ||||
-rw-r--r-- | firmware/export/config-ipodvideo.h | 6 | ||||
-rw-r--r-- | firmware/export/config.h | 1 | ||||
-rw-r--r-- | firmware/export/iap.h | 5 | ||||
-rw-r--r-- | firmware/export/ipod_remote_tuner.h | 75 | ||||
-rw-r--r-- | firmware/export/tuner.h | 21 | ||||
-rw-r--r-- | firmware/target/arm/audio-pp.c | 7 | ||||
-rw-r--r-- | firmware/tuner.c | 19 |
12 files changed, 593 insertions, 8 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES index 061c6323c8..1a078ada29 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -201,6 +201,7 @@ drivers/rtc/rtc_d2.c | |||
201 | #endif /* (CONFIG_RTC == RTC_) */ | 201 | #endif /* (CONFIG_RTC == RTC_) */ |
202 | #endif /* SIMULATOR */ | 202 | #endif /* SIMULATOR */ |
203 | 203 | ||
204 | #ifndef BOOTLOADER | ||
204 | /* Tuner */ | 205 | /* Tuner */ |
205 | #if CONFIG_TUNER | 206 | #if CONFIG_TUNER |
206 | tuner.c | 207 | tuner.c |
@@ -221,8 +222,12 @@ drivers/tuner/tea5767.c | |||
221 | #if (CONFIG_TUNER & SI4700) | 222 | #if (CONFIG_TUNER & SI4700) |
222 | drivers/tuner/si4700.c | 223 | drivers/tuner/si4700.c |
223 | #endif /* (CONFIG_TUNER & SI4700) */ | 224 | #endif /* (CONFIG_TUNER & SI4700) */ |
225 | #if (CONFIG_TUNER & IPOD_REMOTE_TUNER) | ||
226 | drivers/tuner/ipod_remote_tuner.c | ||
227 | #endif /* (CONFIG_TUNER & IPOD_REMOTE_TUNER) */ | ||
224 | #endif /*SIMULATOR */ | 228 | #endif /*SIMULATOR */ |
225 | #endif /* CONFIG_TUNER */ | 229 | #endif /* CONFIG_TUNER */ |
230 | #endif /* BOOTLOADER */ | ||
226 | 231 | ||
227 | /* Sound */ | 232 | /* Sound */ |
228 | #if CONFIG_CODEC != SWCODEC | 233 | #if CONFIG_CODEC != SWCODEC |
diff --git a/firmware/drivers/tuner/ipod_remote_tuner.c b/firmware/drivers/tuner/ipod_remote_tuner.c new file mode 100644 index 0000000000..07a5eeb9a6 --- /dev/null +++ b/firmware/drivers/tuner/ipod_remote_tuner.c | |||
@@ -0,0 +1,444 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * tuner for the ipod fm remote and other ipod remote tuners | ||
10 | * | ||
11 | * Copyright (C) 2009 Laurent Gautier | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | #include "config.h" | ||
23 | #include <stdio.h> | ||
24 | #include <stdbool.h> | ||
25 | #include <string.h> | ||
26 | #include <stdlib.h> | ||
27 | #include "kernel.h" | ||
28 | #include "iap.h" | ||
29 | #include "tuner.h" /* tuner abstraction interface */ | ||
30 | #include "adc.h" | ||
31 | #include "settings.h" | ||
32 | |||
33 | static bool powered = false; | ||
34 | |||
35 | static unsigned char tuner_param = 0x00, old_tuner_param = 0xFF; | ||
36 | /* temp var for tests to avoid looping execution in submenus settings*/ | ||
37 | int mono_mode = -1, old_region = -1; | ||
38 | |||
39 | int radio_present = 0; | ||
40 | int tuner_frequency = 0; | ||
41 | int tuner_signal_power = 0; | ||
42 | int radio_tuned = 0; | ||
43 | int rds_event = 0; | ||
44 | |||
45 | char rds_radioname[9]; | ||
46 | char rds_radioinfo[70]; /* do we need more? */ | ||
47 | |||
48 | union FRQ { | ||
49 | unsigned long int frequency_radio; | ||
50 | char data_frequency[4]; | ||
51 | }Frequency; | ||
52 | |||
53 | void rmt_tuner_freq(void) | ||
54 | { | ||
55 | char tempdata[4]; | ||
56 | tempdata[0] = serbuf[6]; | ||
57 | tempdata[1] = serbuf[5]; | ||
58 | tempdata[2] = serbuf[4]; | ||
59 | tempdata[3] = serbuf[3]; | ||
60 | |||
61 | memcpy(Frequency.data_frequency,tempdata,4); | ||
62 | tuner_frequency = (Frequency.frequency_radio*1000); | ||
63 | radio_tuned = 1; | ||
64 | rmt_tuner_signal_power(serbuf[7]); | ||
65 | } | ||
66 | |||
67 | void rmt_tuner_set_freq(int curr_freq) | ||
68 | { | ||
69 | if (curr_freq != tuner_frequency) | ||
70 | { | ||
71 | radio_tuned = 0; | ||
72 | tuner_signal_power = 0; | ||
73 | /* clear rds name and info */ | ||
74 | memset(rds_radioname,' ',sizeof(rds_radioname)); | ||
75 | memset(rds_radioinfo,' ',sizeof(rds_radioinfo)); | ||
76 | /* ex: 00 01 63 14 = 90.9MHz */ | ||
77 | unsigned char data[] = {0x07, 0x0B, 0x00, 0x01, 0x63, 0x14}; | ||
78 | |||
79 | if (curr_freq != 0) | ||
80 | { | ||
81 | curr_freq = curr_freq / 1000; | ||
82 | char tempdata[4]; | ||
83 | |||
84 | Frequency.frequency_radio = curr_freq; | ||
85 | tempdata[0] = Frequency.data_frequency[3]; | ||
86 | tempdata[1] = Frequency.data_frequency[2]; | ||
87 | tempdata[2] = Frequency.data_frequency[1]; | ||
88 | tempdata[3] = Frequency.data_frequency[0]; | ||
89 | |||
90 | memcpy(data+2,tempdata,4); | ||
91 | iap_send_pkt(data, sizeof(data)); | ||
92 | } | ||
93 | } | ||
94 | } | ||
95 | |||
96 | void rmt_tuner_signal_power(unsigned char value) | ||
97 | { | ||
98 | tuner_signal_power = (int)(value); | ||
99 | } | ||
100 | |||
101 | void rmt_tuner_sleep(int state) | ||
102 | { | ||
103 | if (state == 0) | ||
104 | { | ||
105 | /* tuner HW on */ | ||
106 | unsigned char data[] = {0x07, 0x05, 0x01}; | ||
107 | iap_send_pkt(data, sizeof(data)); | ||
108 | /* boost gain */ | ||
109 | unsigned char data1[] = {0x07, 0x24, 0x06 }; | ||
110 | iap_send_pkt(data1, sizeof(data1)); | ||
111 | /* set volume */ | ||
112 | unsigned char data2[] = {0x03, 0x09, 0x04, 0x00, 0x77 }; | ||
113 | iap_send_pkt(data2, sizeof(data2)); | ||
114 | /* set rds on */ | ||
115 | unsigned char data3[] = {0x07, 0x20, 0x40, 0x00, 0x00, 0x10 }; | ||
116 | iap_send_pkt(data3, sizeof(data3)); | ||
117 | } | ||
118 | else | ||
119 | { | ||
120 | /* unbooste gain */ | ||
121 | unsigned char data[] = {0x07, 0x24, 0x00}; | ||
122 | iap_send_pkt(data, sizeof(data)); | ||
123 | /* set rds off */ | ||
124 | unsigned char data1[] = {0x07, 0x20, 0x00, 0x00, 0x00, 0x00 }; | ||
125 | iap_send_pkt(data1, sizeof(data1)); | ||
126 | /* stop tuner HW */ | ||
127 | unsigned char data2[] = {0x07, 0x05, 0x00}; | ||
128 | iap_send_pkt(data2, sizeof(data2)); | ||
129 | } | ||
130 | } | ||
131 | |||
132 | void rmt_tuner_scan(int param) | ||
133 | { | ||
134 | unsigned char data[] = {0x07, 0x11, 0x08}; /* RSSI level */ | ||
135 | unsigned char updown = 0x00; | ||
136 | radio_tuned = 0; | ||
137 | iap_send_pkt(data, sizeof(data)); | ||
138 | |||
139 | if (param == 1) | ||
140 | { | ||
141 | updown = 0x07; /* scan up */ | ||
142 | } | ||
143 | else if (param == -1) | ||
144 | { | ||
145 | updown = 0x08; /* scan down */ | ||
146 | } | ||
147 | else if (param == 10) | ||
148 | { | ||
149 | updown = 0x01; /* scan up starting from beginning of the band */ | ||
150 | } | ||
151 | unsigned char data1[] = {0x07, 0x12, updown}; | ||
152 | iap_send_pkt(data1, sizeof(data1)); | ||
153 | } | ||
154 | |||
155 | void rmt_tuner_mute(int value) | ||
156 | { | ||
157 | /* mute flag off (play) */ | ||
158 | unsigned char data[] = {0x03, 0x09, 0x03, 0x01}; | ||
159 | if (value) | ||
160 | { | ||
161 | /* mute flag on (pause) */ | ||
162 | data[3] = 0x02; | ||
163 | } | ||
164 | iap_send_pkt(data, sizeof(data)); | ||
165 | } | ||
166 | |||
167 | void rmt_tuner_region(int region) | ||
168 | { | ||
169 | if (region != old_region) | ||
170 | { | ||
171 | unsigned char data[] = {0x07, 0x08, 0x00}; | ||
172 | if (region == 2) | ||
173 | { | ||
174 | data[2] = 0x02; /* japan band */ | ||
175 | } | ||
176 | else | ||
177 | { | ||
178 | data[2] = 0x01; /* us eur band */ | ||
179 | } | ||
180 | iap_send_pkt(data, sizeof(data)); | ||
181 | sleep(HZ/100); | ||
182 | old_region = region; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | /* set stereo/mono, deemphasis, delta freq... */ | ||
187 | void rmt_tuner_set_param(unsigned char tuner_param) | ||
188 | { | ||
189 | if(tuner_param != old_tuner_param) | ||
190 | { | ||
191 | unsigned char data[] = {0x07, 0x0E, 0x00}; | ||
192 | |||
193 | data[2] = tuner_param; | ||
194 | iap_send_pkt(data, sizeof(data)); | ||
195 | old_tuner_param = tuner_param; | ||
196 | } | ||
197 | } | ||
198 | |||
199 | void set_deltafreq(int delta) | ||
200 | { | ||
201 | tuner_param &= 0xFC; | ||
202 | switch (delta) | ||
203 | { | ||
204 | case 1: | ||
205 | { | ||
206 | /* 100KHz */ | ||
207 | tuner_param |= 0x01; | ||
208 | break; | ||
209 | } | ||
210 | case 2: | ||
211 | { | ||
212 | /* 50KHz */ | ||
213 | tuner_param |= 0x02; | ||
214 | break; | ||
215 | } | ||
216 | |||
217 | default: | ||
218 | { | ||
219 | /* 200KHz */ | ||
220 | tuner_param |= 0x00; | ||
221 | break; | ||
222 | } | ||
223 | } | ||
224 | } | ||
225 | |||
226 | void set_deemphasis(int deemphasis) | ||
227 | { | ||
228 | tuner_param &= 0xBF; | ||
229 | switch (deemphasis) | ||
230 | { | ||
231 | case 1: | ||
232 | { | ||
233 | tuner_param |= 0x40; | ||
234 | break; | ||
235 | } | ||
236 | default: | ||
237 | { | ||
238 | tuner_param |= 0x00; | ||
239 | break; | ||
240 | } | ||
241 | } | ||
242 | } | ||
243 | |||
244 | void set_mono(int value) | ||
245 | { | ||
246 | tuner_param &= 0xEF; | ||
247 | |||
248 | if (value != mono_mode) | ||
249 | { | ||
250 | tuner_param |= 0x10; | ||
251 | rmt_tuner_set_param(tuner_param); | ||
252 | sleep(HZ/100); | ||
253 | mono_mode = value; | ||
254 | } | ||
255 | } | ||
256 | |||
257 | bool reply_timeout(void) | ||
258 | { | ||
259 | int timeout = 0; | ||
260 | |||
261 | sleep(HZ/50); | ||
262 | do | ||
263 | { | ||
264 | iap_handlepkt(); | ||
265 | sleep(HZ/50); | ||
266 | timeout++; | ||
267 | } | ||
268 | while((ipod_rmt_tuner_get(RADIO_TUNED) == 0) && (timeout < TIMEOUT_VALUE)); | ||
269 | |||
270 | if (timeout >= TIMEOUT_VALUE) | ||
271 | return true; | ||
272 | else return false; | ||
273 | } | ||
274 | |||
275 | void rmt_tuner_rds_data(void) | ||
276 | { | ||
277 | if (serbuf[3] == 0x1E) | ||
278 | { | ||
279 | strlcpy(rds_radioname,serbuf+5,8); | ||
280 | } | ||
281 | else if(serbuf[3] == 0x04) | ||
282 | { | ||
283 | strlcpy(rds_radioinfo,serbuf+5,(serbuf[0]-4)); | ||
284 | } | ||
285 | rds_event = 1; | ||
286 | } | ||
287 | |||
288 | /* tuner abstraction layer: set something to the tuner */ | ||
289 | int ipod_rmt_tuner_set(int setting, int value) | ||
290 | { | ||
291 | switch(setting) | ||
292 | { | ||
293 | case RADIO_SLEEP: | ||
294 | { | ||
295 | rmt_tuner_sleep(value); | ||
296 | sleep(HZ/2); | ||
297 | break; | ||
298 | } | ||
299 | |||
300 | case RADIO_FREQUENCY: | ||
301 | { | ||
302 | rmt_tuner_set_freq(value); | ||
303 | if (reply_timeout() == true) | ||
304 | return 0; | ||
305 | break; | ||
306 | } | ||
307 | |||
308 | case RADIO_SCAN_FREQUENCY: | ||
309 | { | ||
310 | const struct fm_region_data * const fmr = | ||
311 | &fm_region_data[global_settings.fm_region]; | ||
312 | |||
313 | /* case: scan for presets, back to beginning of the band */ | ||
314 | if ((radio_tuned == 1) && (value == fmr->freq_min)) | ||
315 | { | ||
316 | tuner_set(RADIO_FREQUENCY,value); | ||
317 | } | ||
318 | |||
319 | /* scan through frequencies */ | ||
320 | if (radio_tuned == 1) | ||
321 | { | ||
322 | /* scan down */ | ||
323 | if(value < tuner_frequency) | ||
324 | rmt_tuner_scan(-1); | ||
325 | /* scan up */ | ||
326 | else | ||
327 | rmt_tuner_scan(1); | ||
328 | |||
329 | if (reply_timeout() == true) | ||
330 | return 0; | ||
331 | radio_tuned = 0; | ||
332 | } | ||
333 | |||
334 | if (tuner_frequency == value) | ||
335 | { | ||
336 | radio_tuned = 1; | ||
337 | return 1; | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | radio_tuned = 0; | ||
342 | return 0; | ||
343 | } | ||
344 | } | ||
345 | |||
346 | case RADIO_MUTE: | ||
347 | { | ||
348 | /* mute flag sent to accessory */ | ||
349 | /* rmt_tuner_mute(value); */ | ||
350 | break; | ||
351 | } | ||
352 | |||
353 | case RADIO_REGION: | ||
354 | { | ||
355 | const struct rmt_tuner_region_data *rd = | ||
356 | &rmt_tuner_region_data[value]; | ||
357 | |||
358 | rmt_tuner_region(rd->band); | ||
359 | set_deltafreq(rd->spacing); | ||
360 | set_deemphasis(rd->deemphasis); | ||
361 | rmt_tuner_set_param(tuner_param); | ||
362 | break; | ||
363 | } | ||
364 | |||
365 | case RADIO_FORCE_MONO: | ||
366 | { | ||
367 | set_mono(value); | ||
368 | break; | ||
369 | } | ||
370 | |||
371 | default: | ||
372 | return -1; | ||
373 | } | ||
374 | return 1; | ||
375 | } | ||
376 | |||
377 | /* tuner abstraction layer: read something from the tuner */ | ||
378 | int ipod_rmt_tuner_get(int setting) | ||
379 | { | ||
380 | int val = -1; /* default for unsupported query */ | ||
381 | |||
382 | switch(setting) | ||
383 | { | ||
384 | case RADIO_PRESENT: | ||
385 | val = radio_present; | ||
386 | if (val) | ||
387 | { | ||
388 | /* if accessory disconnected */ | ||
389 | if(adc_read(ADC_ACCESSORY) >= 10) | ||
390 | { | ||
391 | radio_present = 0; | ||
392 | val = 0; | ||
393 | } | ||
394 | } | ||
395 | break; | ||
396 | |||
397 | /* radio tuned: yes no */ | ||
398 | case RADIO_TUNED: | ||
399 | val = 0; | ||
400 | if (radio_tuned == 1) | ||
401 | val = 1; | ||
402 | break; | ||
403 | |||
404 | /* radio is always stereo */ | ||
405 | /* we can't know when it's in mono mode, depending of signal quality */ | ||
406 | /* except if it is forced in mono mode */ | ||
407 | case RADIO_STEREO: | ||
408 | val = true; | ||
409 | break; | ||
410 | |||
411 | case RADIO_EVENT: | ||
412 | if (rds_event) | ||
413 | { | ||
414 | val = 1; | ||
415 | rds_event = 0; | ||
416 | } | ||
417 | break; | ||
418 | } | ||
419 | return val; | ||
420 | } | ||
421 | |||
422 | char* ipod_get_rds_info(int setting) | ||
423 | { | ||
424 | char *text = NULL; | ||
425 | |||
426 | switch(setting) | ||
427 | { | ||
428 | case RADIO_RDS_NAME: | ||
429 | text = rds_radioname; | ||
430 | break; | ||
431 | |||
432 | case RADIO_RDS_TEXT: | ||
433 | text = rds_radioinfo; | ||
434 | break; | ||
435 | } | ||
436 | return text; | ||
437 | } | ||
438 | |||
439 | bool tuner_power(bool status) | ||
440 | { | ||
441 | bool oldstatus = powered; | ||
442 | powered = status; | ||
443 | return oldstatus; | ||
444 | } | ||
diff --git a/firmware/export/config-ipod4g.h b/firmware/export/config-ipod4g.h index c00a6788c6..e6bdc35bd8 100644 --- a/firmware/export/config-ipod4g.h +++ b/firmware/export/config-ipod4g.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | /* Define bitmask of input sources - recordable bitmask can be defined | 19 | /* Define bitmask of input sources - recordable bitmask can be defined |
20 | explicitly if different */ | 20 | explicitly if different */ |
21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) | 21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) |
22 | 22 | ||
23 | /* define the bitmask of hardware sample rates */ | 23 | /* define the bitmask of hardware sample rates */ |
24 | #define HW_SAMPR_CAPS (SAMPR_CAP_44) | 24 | #define HW_SAMPR_CAPS (SAMPR_CAP_44) |
@@ -144,6 +144,10 @@ | |||
144 | #define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ | 144 | #define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ |
145 | #endif | 145 | #endif |
146 | 146 | ||
147 | /* Define Apple remote tuner */ | ||
148 | #define CONFIG_TUNER IPOD_REMOTE_TUNER | ||
149 | #define HAVE_RDS_CAP | ||
150 | |||
147 | /* Define this if you have a PortalPlayer PP5020 */ | 151 | /* Define this if you have a PortalPlayer PP5020 */ |
148 | #define CONFIG_CPU PP5020 | 152 | #define CONFIG_CPU PP5020 |
149 | 153 | ||
diff --git a/firmware/export/config-ipodcolor.h b/firmware/export/config-ipodcolor.h index 751522d47b..0f1de4fdba 100644 --- a/firmware/export/config-ipodcolor.h +++ b/firmware/export/config-ipodcolor.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | /* Define bitmask of input sources - recordable bitmask can be defined | 19 | /* Define bitmask of input sources - recordable bitmask can be defined |
20 | explicitly if different */ | 20 | explicitly if different */ |
21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) | 21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) |
22 | 22 | ||
23 | /* define the bitmask of hardware sample rates */ | 23 | /* define the bitmask of hardware sample rates */ |
24 | #define HW_SAMPR_CAPS (SAMPR_CAP_44) | 24 | #define HW_SAMPR_CAPS (SAMPR_CAP_44) |
@@ -121,6 +121,10 @@ | |||
121 | /* define this if the unit can be powered or charged via USB */ | 121 | /* define this if the unit can be powered or charged via USB */ |
122 | #define HAVE_USB_POWER | 122 | #define HAVE_USB_POWER |
123 | 123 | ||
124 | /* Define Apple remote tuner */ | ||
125 | #define CONFIG_TUNER IPOD_REMOTE_TUNER | ||
126 | #define HAVE_RDS_CAP | ||
127 | |||
124 | /* Define this if you have a PortalPlayer PP5020 */ | 128 | /* Define this if you have a PortalPlayer PP5020 */ |
125 | #define CONFIG_CPU PP5020 | 129 | #define CONFIG_CPU PP5020 |
126 | 130 | ||
diff --git a/firmware/export/config-ipodnano.h b/firmware/export/config-ipodnano.h index 68ed152cda..e1ec1afa86 100644 --- a/firmware/export/config-ipodnano.h +++ b/firmware/export/config-ipodnano.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | /* Define bitmask of input sources - recordable bitmask can be defined | 19 | /* Define bitmask of input sources - recordable bitmask can be defined |
20 | explicitly if different */ | 20 | explicitly if different */ |
21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) | 21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) |
22 | 22 | ||
23 | /* define the bitmask of hardware sample rates */ | 23 | /* define the bitmask of hardware sample rates */ |
24 | #define HW_SAMPR_CAPS (SAMPR_CAP_44) | 24 | #define HW_SAMPR_CAPS (SAMPR_CAP_44) |
@@ -134,6 +134,10 @@ | |||
134 | #define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ | 134 | #define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ |
135 | #endif | 135 | #endif |
136 | 136 | ||
137 | /* Define Apple remote tuner */ | ||
138 | #define CONFIG_TUNER IPOD_REMOTE_TUNER | ||
139 | #define HAVE_RDS_CAP | ||
140 | |||
137 | /* Define this if you have a PortalPlayer PP5022 */ | 141 | /* Define this if you have a PortalPlayer PP5022 */ |
138 | #define CONFIG_CPU PP5022 | 142 | #define CONFIG_CPU PP5022 |
139 | 143 | ||
diff --git a/firmware/export/config-ipodvideo.h b/firmware/export/config-ipodvideo.h index f00de9cbfd..59ac6466e5 100644 --- a/firmware/export/config-ipodvideo.h +++ b/firmware/export/config-ipodvideo.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | /* Define bitmask of input sources - recordable bitmask can be defined | 19 | /* Define bitmask of input sources - recordable bitmask can be defined |
20 | explicitly if different */ | 20 | explicitly if different */ |
21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN) | 21 | #define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO) |
22 | 22 | ||
23 | /* define the bitmask of hardware sample rates */ | 23 | /* define the bitmask of hardware sample rates */ |
24 | #define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ | 24 | #define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \ |
@@ -155,6 +155,10 @@ | |||
155 | #define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ | 155 | #define CURRENT_RECORD 35 /* FIXME: this needs adjusting */ |
156 | #endif | 156 | #endif |
157 | 157 | ||
158 | /* Define Apple remote tuner */ | ||
159 | #define CONFIG_TUNER IPOD_REMOTE_TUNER | ||
160 | #define HAVE_RDS_CAP | ||
161 | |||
158 | /* Define this if you have a PortalPlayer PP5022 */ | 162 | /* Define this if you have a PortalPlayer PP5022 */ |
159 | #define CONFIG_CPU PP5022 | 163 | #define CONFIG_CPU PP5022 |
160 | 164 | ||
diff --git a/firmware/export/config.h b/firmware/export/config.h index 9c7beca2bd..088cab7212 100644 --- a/firmware/export/config.h +++ b/firmware/export/config.h | |||
@@ -40,6 +40,7 @@ | |||
40 | #define SI4700 0x08 /* Silicon Labs */ | 40 | #define SI4700 0x08 /* Silicon Labs */ |
41 | #define TEA5760 0x10 /* Philips */ | 41 | #define TEA5760 0x10 /* Philips */ |
42 | #define LV240000 0x20 /* Sanyo */ | 42 | #define LV240000 0x20 /* Sanyo */ |
43 | #define IPOD_REMOTE_TUNER 0x40 /* Apple */ | ||
43 | 44 | ||
44 | /* CONFIG_CODEC */ | 45 | /* CONFIG_CODEC */ |
45 | #define MAS3587F 3587 | 46 | #define MAS3587F 3587 |
diff --git a/firmware/export/iap.h b/firmware/export/iap.h index e945d0c979..d00e5f398a 100644 --- a/firmware/export/iap.h +++ b/firmware/export/iap.h | |||
@@ -20,6 +20,9 @@ | |||
20 | #ifndef __IAP_H__ | 20 | #ifndef __IAP_H__ |
21 | #define __IAP_H__ | 21 | #define __IAP_H__ |
22 | 22 | ||
23 | #define RX_BUFLEN 260 | ||
24 | #define TX_BUFLEN 128 | ||
25 | |||
23 | extern int iap_getc(unsigned char x); | 26 | extern int iap_getc(unsigned char x); |
24 | extern void iap_write_pkt(unsigned char data, int len); | 27 | extern void iap_write_pkt(unsigned char data, int len); |
25 | extern void iap_setup(int ratenum); | 28 | extern void iap_setup(int ratenum); |
@@ -27,5 +30,7 @@ extern void iap_bitrate_set(int ratenum); | |||
27 | extern void iap_periodic(void); | 30 | extern void iap_periodic(void); |
28 | extern void iap_handlepkt(void); | 31 | extern void iap_handlepkt(void); |
29 | extern void iap_track_changed(void *ignored); | 32 | extern void iap_track_changed(void *ignored); |
33 | extern void iap_send_pkt(const unsigned char * data, int len); | ||
34 | extern unsigned char serbuf[RX_BUFLEN]; | ||
30 | 35 | ||
31 | #endif | 36 | #endif |
diff --git a/firmware/export/ipod_remote_tuner.h b/firmware/export/ipod_remote_tuner.h new file mode 100644 index 0000000000..28fcfe1e93 --- /dev/null +++ b/firmware/export/ipod_remote_tuner.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id: ipod_remote_tuner.h | ||
9 | * Tuner header for the ipod remote tuner and others remote tuners | ||
10 | * | ||
11 | * Copyright (C) 2009 Laurent Gautier | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or | ||
14 | * modify it under the terms of the GNU General Public License | ||
15 | * as published by the Free Software Foundation; either version 2 | ||
16 | * of the License, or (at your option) any later version. | ||
17 | * | ||
18 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
19 | * KIND, either express or implied. | ||
20 | * | ||
21 | ****************************************************************************/ | ||
22 | |||
23 | #ifndef _IPOD_REMOTE_TUNER_H_ | ||
24 | #define _IPOD_REMOTE_TUNER_H_ | ||
25 | |||
26 | #define HAVE_RADIO_REGION | ||
27 | #define TIMEOUT_VALUE 20 | ||
28 | |||
29 | extern int radio_present; | ||
30 | extern int tuner_frequency; | ||
31 | extern int tuner_signal_power; | ||
32 | extern int radio_tuned; | ||
33 | |||
34 | /* update tuner state: plugged or unplugged when in radio mode */ | ||
35 | extern void rmt_tuner_region(int region); | ||
36 | extern void rmt_tuner_set_freq(int curr_freq); | ||
37 | extern void rmt_tuner_freq(void); | ||
38 | extern void rmt_tuner_scan(int direction); | ||
39 | |||
40 | /* tuner mode state: ON or OFF */ | ||
41 | extern void rmt_tuner_sleep(int state); | ||
42 | |||
43 | /* parameters are stereo/mono, deemphasis, delta freq... */ | ||
44 | extern void rmt_tuner_set_param(unsigned char tuner_param); | ||
45 | |||
46 | extern void rmt_tuner_mute(int value); | ||
47 | extern void rmt_tuner_signal_power(unsigned char value); | ||
48 | |||
49 | extern void rmt_tuner_rds_data(void); | ||
50 | |||
51 | struct rmt_tuner_region_data | ||
52 | { | ||
53 | /* 0: 50us, 1: 75us */ | ||
54 | unsigned char deemphasis; | ||
55 | /* 0: europe, 1: japan (BL in TEA spec)*/ | ||
56 | unsigned char band; | ||
57 | /* 0: us/australia (200kHz), 1: europe/japan (100kHz), 2: (50kHz) */ | ||
58 | unsigned char spacing; | ||
59 | } __attribute__((packed)); | ||
60 | |||
61 | extern const struct rmt_tuner_region_data | ||
62 | rmt_tuner_region_data[TUNER_NUM_REGIONS]; | ||
63 | |||
64 | int ipod_rmt_tuner_set(int setting, int value); | ||
65 | int ipod_rmt_tuner_get(int setting); | ||
66 | char* ipod_get_rds_info(int setting); | ||
67 | |||
68 | |||
69 | #ifndef CONFIG_TUNER_MULTI | ||
70 | #define tuner_set ipod_rmt_tuner_set | ||
71 | #define tuner_get ipod_rmt_tuner_get | ||
72 | #define tuner_get_rds_info ipod_get_rds_info | ||
73 | #endif | ||
74 | |||
75 | #endif /* _IPOD_REMOTE_TUNER_H_ */ | ||
diff --git a/firmware/export/tuner.h b/firmware/export/tuner.h index b27e660667..63392160e5 100644 --- a/firmware/export/tuner.h +++ b/firmware/export/tuner.h | |||
@@ -33,7 +33,7 @@ enum | |||
33 | RADIO_MUTE, | 33 | RADIO_MUTE, |
34 | RADIO_FORCE_MONO, | 34 | RADIO_FORCE_MONO, |
35 | RADIO_SCAN_FREQUENCY, | 35 | RADIO_SCAN_FREQUENCY, |
36 | 36 | ||
37 | /* Put new general-purpose settings above this line */ | 37 | /* Put new general-purpose settings above this line */ |
38 | __RADIO_SET_STANDARD_LAST | 38 | __RADIO_SET_STANDARD_LAST |
39 | }; | 39 | }; |
@@ -44,11 +44,25 @@ enum | |||
44 | RADIO_PRESENT = 0, | 44 | RADIO_PRESENT = 0, |
45 | RADIO_TUNED, | 45 | RADIO_TUNED, |
46 | RADIO_STEREO, | 46 | RADIO_STEREO, |
47 | /* RADIO_EVENT is an event that requests a screen update */ | ||
48 | RADIO_EVENT, | ||
47 | 49 | ||
48 | /* Put new general-purpose readback values above this line */ | 50 | /* Put new general-purpose readback values above this line */ |
49 | __RADIO_GET_STANDARD_LAST | 51 | __RADIO_GET_STANDARD_LAST |
50 | }; | 52 | }; |
51 | 53 | ||
54 | #ifdef HAVE_RDS_CAP | ||
55 | /** Readback from the tuner RDS layer **/ | ||
56 | enum | ||
57 | { | ||
58 | RADIO_RDS_NAME, | ||
59 | RADIO_RDS_TEXT, | ||
60 | |||
61 | /* Put new general-purpose readback values above this line */ | ||
62 | __RADIO_GET_RDS_INFO_STANDARD_LAST | ||
63 | }; | ||
64 | #endif | ||
65 | |||
52 | /** Tuner regions **/ | 66 | /** Tuner regions **/ |
53 | 67 | ||
54 | /* Basic region information */ | 68 | /* Basic region information */ |
@@ -114,6 +128,11 @@ extern int (*tuner_get)(int setting); | |||
114 | #include "si4700.h" | 128 | #include "si4700.h" |
115 | #endif | 129 | #endif |
116 | 130 | ||
131 | /* Apple remote tuner */ | ||
132 | #if (CONFIG_TUNER & IPOD_REMOTE_TUNER) | ||
133 | #include "ipod_remote_tuner.h" | ||
134 | #endif | ||
135 | |||
117 | #endif /* SIMULATOR */ | 136 | #endif /* SIMULATOR */ |
118 | 137 | ||
119 | /* Additional messages that get enumerated after tuner driver headers */ | 138 | /* Additional messages that get enumerated after tuner driver headers */ |
diff --git a/firmware/target/arm/audio-pp.c b/firmware/target/arm/audio-pp.c index 1a4952fcc3..8f22bab765 100644 --- a/firmware/target/arm/audio-pp.c +++ b/firmware/target/arm/audio-pp.c | |||
@@ -104,11 +104,17 @@ void audio_input_mux(int source, unsigned flags) | |||
104 | if (!recording) | 104 | if (!recording) |
105 | audiohw_set_recvol(0x17, 0x17, AUDIO_GAIN_LINEIN); | 105 | audiohw_set_recvol(0x17, 0x17, AUDIO_GAIN_LINEIN); |
106 | #endif | 106 | #endif |
107 | |||
107 | if (source == last_source && recording == last_recording) | 108 | if (source == last_source && recording == last_recording) |
108 | break; | 109 | break; |
109 | 110 | ||
110 | last_recording = recording; | 111 | last_recording = recording; |
111 | 112 | ||
113 | #if defined(IPOD_REMOTE_TUNER) | ||
114 | /* Ipod FM tuner is in the remote connected to line-in */ | ||
115 | audiohw_enable_recording(false); /* source line */ | ||
116 | audiohw_set_monitor(true); /* enable bypass mode */ | ||
117 | #else | ||
112 | if (recording) | 118 | if (recording) |
113 | { | 119 | { |
114 | audiohw_set_monitor(false); /* disable bypass mode */ | 120 | audiohw_set_monitor(false); /* disable bypass mode */ |
@@ -119,6 +125,7 @@ void audio_input_mux(int source, unsigned flags) | |||
119 | audiohw_disable_recording(); | 125 | audiohw_disable_recording(); |
120 | audiohw_set_monitor(true); /* enable bypass mode */ | 126 | audiohw_set_monitor(true); /* enable bypass mode */ |
121 | } | 127 | } |
128 | #endif | ||
122 | break; | 129 | break; |
123 | #endif | 130 | #endif |
124 | } /* end switch */ | 131 | } /* end switch */ |
diff --git a/firmware/tuner.c b/firmware/tuner.c index 5fd7fa1f38..cca5cf2491 100644 --- a/firmware/tuner.c +++ b/firmware/tuner.c | |||
@@ -89,17 +89,31 @@ const struct si4700_region_data si4700_region_data[TUNER_NUM_REGIONS] = | |||
89 | }; | 89 | }; |
90 | #endif /* (CONFIG_TUNER & SI4700) */ | 90 | #endif /* (CONFIG_TUNER & SI4700) */ |
91 | 91 | ||
92 | #if (CONFIG_TUNER & IPOD_REMOTE_TUNER) | ||
93 | const struct rmt_tuner_region_data | ||
94 | rmt_tuner_region_data[TUNER_NUM_REGIONS] = | ||
95 | { | ||
96 | [REGION_EUROPE] = { 1, 0, 1 }, /* 50uS, US/Europe band, 100kHz spacing */ | ||
97 | [REGION_US_CANADA] = { 0, 0, 0 }, /* 75uS, US/Europe band, 200kHz spacing */ | ||
98 | [REGION_JAPAN] = { 1, 2, 1 }, /* 50uS, Japanese band, 100kHz spacing */ | ||
99 | [REGION_KOREA] = { 1, 0, 0 }, /* 50uS, US/Europe band, 200kHz spacing */ | ||
100 | [REGION_ITALY] = { 1, 0, 2 }, /* 50uS, US/Europe band, 50kHz spacing */ | ||
101 | [REGION_OTHER] = { 1, 0, 2 }, /* 50uS, US/Europe band, 50kHz spacing */ | ||
102 | }; | ||
103 | #endif /* (CONFIG_TUNER & IPOD_REMOTE_TUNER) */ | ||
104 | |||
92 | #ifdef CONFIG_TUNER_MULTI | 105 | #ifdef CONFIG_TUNER_MULTI |
93 | int (*tuner_set)(int setting, int value); | 106 | int (*tuner_set)(int setting, int value); |
94 | int (*tuner_get)(int setting); | 107 | int (*tuner_get)(int setting); |
95 | #define TUNER_TYPE_CASE(type, set, get, ...) \ | 108 | |
109 | #define TUNER_TYPE_CASE(type, set, get, ...) \ | ||
96 | case type: \ | 110 | case type: \ |
97 | tuner_set = set; \ | 111 | tuner_set = set; \ |
98 | tuner_get = get; \ | 112 | tuner_get = get; \ |
99 | __VA_ARGS__; \ | 113 | __VA_ARGS__; \ |
100 | break; | 114 | break; |
101 | #else | 115 | #else |
102 | #define TUNER_TYPE_CASE(type, set, get, ...) \ | 116 | #define TUNER_TYPE_CASE(type, set, get, ...) \ |
103 | __VA_ARGS__; | 117 | __VA_ARGS__; |
104 | #endif /* CONFIG_TUNER_MULTI */ | 118 | #endif /* CONFIG_TUNER_MULTI */ |
105 | 119 | ||
@@ -139,5 +153,4 @@ void tuner_init(void) | |||
139 | #endif | 153 | #endif |
140 | } | 154 | } |
141 | } | 155 | } |
142 | |||
143 | #endif /* SIMULATOR */ | 156 | #endif /* SIMULATOR */ |