diff options
author | LiveboxAndy <liveboxandy@gmail.com> | 2018-08-04 18:02:21 +0100 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2020-07-09 18:02:07 +0000 |
commit | 77f8c9c9f12f1a520467868047574fe0af7a1556 (patch) | |
tree | 2ae699fbdeca5aed4e28a1d5bc69915d5f6f5838 /firmware/drivers | |
parent | dcdf2713f610cb3cfaa615ab9b8d4b9412e7a8b6 (diff) | |
download | rockbox-77f8c9c9f12f1a520467868047574fe0af7a1556.tar.gz rockbox-77f8c9c9f12f1a520467868047574fe0af7a1556.zip |
Update to allow the Apple Radio Remote to function on iPod Video 5G.
This was broken when the major update to iap was comitted.
ia-lingo7.c created and various iap related files modified.
On 4G, 6G and Nano 1/2Gen iPods the remote will function
even though the radio won't.
Tested on 4G Greyscale, 4G Color, 4G Photo, 4G Mini 1st Gen,
4G Mini 2Gen, Nano 1G, Nano 2G, Video 5G, Video 5.5G
Change-Id: Ia74e3d07d9ab5edc6da8eafa96801ede722be331
Diffstat (limited to 'firmware/drivers')
-rw-r--r-- | firmware/drivers/tuner/ipod_remote_tuner.c | 76 |
1 files changed, 59 insertions, 17 deletions
diff --git a/firmware/drivers/tuner/ipod_remote_tuner.c b/firmware/drivers/tuner/ipod_remote_tuner.c index 9595939f1d..5539b09721 100644 --- a/firmware/drivers/tuner/ipod_remote_tuner.c +++ b/firmware/drivers/tuner/ipod_remote_tuner.c | |||
@@ -69,7 +69,7 @@ static void rmt_tuner_set_freq(int curr_freq) | |||
69 | rds_reset(); | 69 | rds_reset(); |
70 | /* ex: 00 01 63 14 = 90.9MHz */ | 70 | /* ex: 00 01 63 14 = 90.9MHz */ |
71 | unsigned char data[] = {0x07, 0x0B, 0x00, 0x01, 0x63, 0x14}; | 71 | unsigned char data[] = {0x07, 0x0B, 0x00, 0x01, 0x63, 0x14}; |
72 | 72 | ||
73 | if (curr_freq != 0) | 73 | if (curr_freq != 0) |
74 | { | 74 | { |
75 | unsigned int khz = curr_freq / 1000; | 75 | unsigned int khz = curr_freq / 1000; |
@@ -93,20 +93,23 @@ static void rmt_tuner_sleep(int state) | |||
93 | old_region = -1; | 93 | old_region = -1; |
94 | tuner_frequency = 0; | 94 | tuner_frequency = 0; |
95 | radio_tuned = false; | 95 | radio_tuned = false; |
96 | 96 | ||
97 | /* tuner HW on */ | 97 | /* tuner HW on */ |
98 | const unsigned char data[] = {0x07, 0x05, 0x01}; | 98 | const unsigned char data[] = {0x07, 0x05, 0x01}; |
99 | iap_send_pkt(data, sizeof(data)); | 99 | iap_send_pkt(data, sizeof(data)); |
100 | /* set rds on */ | ||
101 | const unsigned char data3[] = {0x07, 0x20, 0x40, 0x00, 0x00, 0x10 }; | ||
102 | iap_send_pkt(data3, sizeof(data3)); | ||
100 | /* boost gain */ | 103 | /* boost gain */ |
101 | const unsigned char data1[] = {0x07, 0x24, 0x06 }; | 104 | const unsigned char data1[] = {0x07, 0x24, 0x06 }; |
102 | iap_send_pkt(data1, sizeof(data1)); | 105 | iap_send_pkt(data1, sizeof(data1)); |
106 | /* tuner mode */ | ||
107 | const unsigned char data4[] = {0x07, 0x0E, 0x00 }; | ||
108 | iap_send_pkt(data4, sizeof(data3)); | ||
103 | /* set volume */ | 109 | /* set volume */ |
104 | unsigned char data2[] = {0x03, 0x09, 0x04, 0x00, 0x00 }; | 110 | unsigned char data2[] = {0x03, 0x09, 0x04, 0x00, 0x00 }; |
105 | data2[4] = (char)((global_settings.volume+58) * 4); | 111 | data2[4] = (char)((global_settings.volume+58) * 4); |
106 | iap_send_pkt(data2, sizeof(data2)); | 112 | iap_send_pkt(data2, sizeof(data2)); |
107 | /* set rds on */ | ||
108 | const unsigned char data3[] = {0x07, 0x20, 0x40, 0x00, 0x00, 0x10 }; | ||
109 | iap_send_pkt(data3, sizeof(data3)); | ||
110 | } | 113 | } |
111 | else | 114 | else |
112 | { | 115 | { |
@@ -115,14 +118,14 @@ static void rmt_tuner_sleep(int state) | |||
115 | iap_send_pkt(data, sizeof(data)); | 118 | iap_send_pkt(data, sizeof(data)); |
116 | /* set rds off */ | 119 | /* set rds off */ |
117 | const unsigned char data1[] = {0x07, 0x20, 0x00, 0x00, 0x00, 0x00 }; | 120 | const unsigned char data1[] = {0x07, 0x20, 0x00, 0x00, 0x00, 0x00 }; |
118 | iap_send_pkt(data1, sizeof(data1)); | 121 | iap_send_pkt(data1, sizeof(data1)); |
119 | /* stop tuner HW */ | 122 | /* stop tuner HW */ |
120 | const unsigned char data2[] = {0x07, 0x05, 0x00}; | 123 | const unsigned char data2[] = {0x07, 0x05, 0x00}; |
121 | iap_send_pkt(data2, sizeof(data2)); | 124 | iap_send_pkt(data2, sizeof(data2)); |
122 | } | 125 | } |
123 | } | 126 | } |
124 | 127 | ||
125 | static void rmt_tuner_scan(int param) | 128 | void rmt_tuner_scan(int param) |
126 | { | 129 | { |
127 | const unsigned char data[] = {0x07, 0x11, 0x08}; /* RSSI level */ | 130 | const unsigned char data[] = {0x07, 0x11, 0x08}; /* RSSI level */ |
128 | unsigned char updown = 0x00; | 131 | unsigned char updown = 0x00; |
@@ -148,13 +151,23 @@ static void rmt_tuner_scan(int param) | |||
148 | static void rmt_tuner_mute(int value) | 151 | static void rmt_tuner_mute(int value) |
149 | { | 152 | { |
150 | /* mute flag off (play) */ | 153 | /* mute flag off (play) */ |
151 | unsigned char data[] = {0x03, 0x09, 0x03, 0x01}; | 154 | /* The Apple Tuner does NOT appear to support muting. The Apple |
155 | * firmware turns the power off when pressing pause on the iPod | ||
156 | * or on the Tuner Remote. | ||
157 | */ | ||
152 | if (value) | 158 | if (value) |
153 | { | 159 | { |
154 | /* mute flag on (pause) */ | 160 | /* mute flag on (pause) */ |
155 | data[3] = 0x02; | 161 | unsigned char data[] = {0x03, 0x09, 0x03, 0x02}; |
162 | iap_send_pkt(data, sizeof(data)); | ||
163 | rmt_tuner_sleep(1); | ||
164 | } | ||
165 | else | ||
166 | { | ||
167 | unsigned char data[] = {0x03, 0x09, 0x03, 0x01}; | ||
168 | iap_send_pkt(data, sizeof(data)); | ||
169 | rmt_tuner_sleep(0); | ||
156 | } | 170 | } |
157 | iap_send_pkt(data, sizeof(data)); | ||
158 | } | 171 | } |
159 | 172 | ||
160 | static void rmt_tuner_region(int region) | 173 | static void rmt_tuner_region(int region) |
@@ -163,13 +176,20 @@ static void rmt_tuner_region(int region) | |||
163 | { | 176 | { |
164 | const struct fm_region_data *rd = &fm_region_data[region]; | 177 | const struct fm_region_data *rd = &fm_region_data[region]; |
165 | unsigned char data[] = {0x07, 0x08, 0x00}; | 178 | unsigned char data[] = {0x07, 0x08, 0x00}; |
179 | /* Apple MFi Accessory Firmware Spec R46 now lists | ||
180 | * the following bands | ||
181 | * ID00 AM 520-1710Khz Not Supported | ||
182 | * ID02 Japan 76-90Mkz 100Khz 50/75uS | ||
183 | * ID01 87.5-108Mhz US 200Khz 75uS, EU 100Kz 50uS | ||
184 | * ID03 76-108Mhz Wideband. Not Supported | ||
185 | */ | ||
166 | if (rd->freq_min == 76000000) | 186 | if (rd->freq_min == 76000000) |
167 | { | 187 | { |
168 | data[2] = 0x02; /* japan band */ | 188 | data[2] = 0x02; /* japan band */ |
169 | } | 189 | } |
170 | else | 190 | else |
171 | { | 191 | { |
172 | data[2] = 0x01; /* us eur band */ | 192 | data[2] = 0x01; /* us/europe band */ |
173 | } | 193 | } |
174 | iap_send_pkt(data, sizeof(data)); | 194 | iap_send_pkt(data, sizeof(data)); |
175 | sleep(HZ/100); | 195 | sleep(HZ/100); |
@@ -225,11 +245,13 @@ static void set_deemphasis(int deemphasis) | |||
225 | case 1: | 245 | case 1: |
226 | { | 246 | { |
227 | tuner_param |= 0x40; | 247 | tuner_param |= 0x40; |
248 | /* 50uS */ | ||
228 | break; | 249 | break; |
229 | } | 250 | } |
230 | default: | 251 | default: |
231 | { | 252 | { |
232 | tuner_param |= 0x00; | 253 | tuner_param |= 0x00; |
254 | /* 75uS */ | ||
233 | break; | 255 | break; |
234 | } | 256 | } |
235 | } | 257 | } |
@@ -253,16 +275,15 @@ static void set_mono(int value) | |||
253 | static bool reply_timeout(void) | 275 | static bool reply_timeout(void) |
254 | { | 276 | { |
255 | int timeout = 0; | 277 | int timeout = 0; |
256 | 278 | ||
257 | sleep(HZ/50); | 279 | sleep(HZ/50); |
258 | do | 280 | do |
259 | { | 281 | { |
260 | iap_handlepkt(); | ||
261 | sleep(HZ/50); | 282 | sleep(HZ/50); |
262 | timeout++; | 283 | timeout++; |
263 | } | 284 | } |
264 | while((ipod_rmt_tuner_get(RADIO_TUNED) == 0) && (timeout < TIMEOUT_VALUE)); | 285 | while((ipod_rmt_tuner_get(RADIO_TUNED) == 0) && (timeout < TIMEOUT_VALUE)); |
265 | 286 | ||
266 | return (timeout >= TIMEOUT_VALUE); | 287 | return (timeout >= TIMEOUT_VALUE); |
267 | } | 288 | } |
268 | 289 | ||
@@ -277,7 +298,7 @@ void rmt_tuner_rds_data(unsigned int len, const unsigned char *buf) | |||
277 | rds_push_info(RDS_INFO_RT, (uintptr_t)(buf+4), len-4); | 298 | rds_push_info(RDS_INFO_RT, (uintptr_t)(buf+4), len-4); |
278 | } | 299 | } |
279 | } | 300 | } |
280 | 301 | ||
281 | /* tuner abstraction layer: set something to the tuner */ | 302 | /* tuner abstraction layer: set something to the tuner */ |
282 | int ipod_rmt_tuner_set(int setting, int value) | 303 | int ipod_rmt_tuner_set(int setting, int value) |
283 | { | 304 | { |
@@ -327,7 +348,7 @@ int ipod_rmt_tuner_set(int setting, int value) | |||
327 | /* scan up */ | 348 | /* scan up */ |
328 | else | 349 | else |
329 | rmt_tuner_scan(1); | 350 | rmt_tuner_scan(1); |
330 | 351 | ||
331 | sleep(HZ/10); | 352 | sleep(HZ/10); |
332 | if (reply_timeout()) | 353 | if (reply_timeout()) |
333 | { | 354 | { |
@@ -337,7 +358,7 @@ int ipod_rmt_tuner_set(int setting, int value) | |||
337 | return 0; | 358 | return 0; |
338 | } | 359 | } |
339 | radio_tuned = false; | 360 | radio_tuned = false; |
340 | } | 361 | } |
341 | 362 | ||
342 | if (tuner_frequency == value) | 363 | if (tuner_frequency == value) |
343 | { | 364 | { |
@@ -360,6 +381,27 @@ int ipod_rmt_tuner_set(int setting, int value) | |||
360 | 381 | ||
361 | case RADIO_REGION: | 382 | case RADIO_REGION: |
362 | { | 383 | { |
384 | /* The latest MFi Accessory Firmware Document I have lists the | ||
385 | * following regions | ||
386 | * US 87.5-108Mhz 200Khz 75uS | ||
387 | * US/EU 87.5-108Mhz 100Khz 75/50uS | ||
388 | * JP 76.0-90Mhz 100Mhz 50/75uS | ||
389 | * | ||
390 | * with the following bands | ||
391 | * 0x00 AM WordlWide 520-1710Khz | ||
392 | * 0x01 FM EU 87.5-108.0Mhz | ||
393 | * 0x02 FM JP 76.0-90.0Mhz | ||
394 | * 0x03 FM Wide 76.0-108.0Mhz | ||
395 | * | ||
396 | * | ||
397 | * A 7G Classic with the latest Apple Firmware returns the following | ||
398 | * regions with the settings listed | ||
399 | * Americas 87.5-108 200Khz 75uS | ||
400 | * Asia 87.5-108 100Khz 75uS | ||
401 | * Australia 87.5-108 200Khz 75uS | ||
402 | * Europe 87.5-108 100Khz 75uS | ||
403 | * Japan 76.0-90. 100Kz 75uS | ||
404 | */ | ||
363 | const struct fm_region_data *rd = &fm_region_data[value]; | 405 | const struct fm_region_data *rd = &fm_region_data[value]; |
364 | int band = (rd->freq_min == 76000000) ? 2 : 0; | 406 | int band = (rd->freq_min == 76000000) ? 2 : 0; |
365 | int spacing = (100000 / rd->freq_step); | 407 | int spacing = (100000 / rd->freq_step); |