summaryrefslogtreecommitdiff
path: root/firmware/drivers/tuner/ipod_remote_tuner.c
diff options
context:
space:
mode:
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);