summaryrefslogtreecommitdiff
path: root/firmware/drivers/tuner/ipod_remote_tuner.c
diff options
context:
space:
mode:
authorLiveboxAndy <liveboxandy@gmail.com>2018-08-04 18:02:21 +0100
committerSolomon Peachy <pizza@shaftnet.org>2020-07-09 18:02:07 +0000
commit77f8c9c9f12f1a520467868047574fe0af7a1556 (patch)
tree2ae699fbdeca5aed4e28a1d5bc69915d5f6f5838 /firmware/drivers/tuner/ipod_remote_tuner.c
parentdcdf2713f610cb3cfaa615ab9b8d4b9412e7a8b6 (diff)
downloadrockbox-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/tuner/ipod_remote_tuner.c')
-rw-r--r--firmware/drivers/tuner/ipod_remote_tuner.c76
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
125static void rmt_tuner_scan(int param) 128void 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)
148static void rmt_tuner_mute(int value) 151static 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
160static void rmt_tuner_region(int region) 173static 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)
253static bool reply_timeout(void) 275static 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 */
282int ipod_rmt_tuner_set(int setting, int value) 303int 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);