summaryrefslogtreecommitdiff
path: root/apps/iap/iap-lingo7.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/iap/iap-lingo7.c')
-rw-r--r--apps/iap/iap-lingo7.c491
1 files changed, 491 insertions, 0 deletions
diff --git a/apps/iap/iap-lingo7.c b/apps/iap/iap-lingo7.c
new file mode 100644
index 0000000000..467a81cc76
--- /dev/null
+++ b/apps/iap/iap-lingo7.c
@@ -0,0 +1,491 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 by Alan Korr & Nick Robinson
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19#include "iap-core.h"
20#include "iap-lingo.h"
21#include "kernel.h"
22#include "system.h"
23#include "tuner.h"
24#if CONFIG_TUNER
25#include "ipod_remote_tuner.h"
26#endif
27
28/*
29 * This macro is meant to be used inside an IAP mode message handler.
30 * It is passed the expected minimum length of the message inbufferfer.
31 * If the inbufferfer does not have the required lenght an ACK
32 * packet with a Bad Parameter error is generated.
33 */
34#define CHECKLEN(x) do { \
35 if (len < (x)) { \
36 cmd_ack(cmd, IAP_ACK_BAD_PARAM); \
37 return; \
38 }} while(0)
39
40/* Check for authenticated state, and return an ACK Not
41 * Authenticated on failure.
42 */
43#define CHECKAUTH do { \
44 if (!DEVICE_AUTHENTICATED) { \
45 cmd_ack(cmd, IAP_ACK_NO_AUTHEN); \
46 return; \
47 }} while(0)
48
49
50static void cmd_ack(const unsigned char cmd, const unsigned char status)
51{
52 IAP_TX_INIT(0x07, 0x00);
53 IAP_TX_PUT(status);
54 IAP_TX_PUT(cmd);
55
56 iap_send_tx();
57}
58
59#define cmd_ok(cmd) cmd_ack((cmd), IAP_ACK_OK)
60
61void iap_handlepkt_mode7(const unsigned int len, const unsigned char *inbuffer)
62{
63 /* Note that some of the Lingo Mode 7 commands are handled by
64 * ../firmware/drivers/tuner/ipod_remote_tuner.c as some of the
65 * commands are sourced with the remote as the master with the ipod acting
66 * as the slave.
67 */
68 unsigned char cmd = inbuffer[1];
69 unsigned char statusnotifymaskbyte = 0;
70
71 /* We expect at least two bytes in the inbuffer, one for the
72 * lingo and one for the command
73 */
74 CHECKLEN(2);
75
76 /* Lingo 0x07 must have been negotiated */
77 if (!DEVICE_LINGO_SUPPORTED(0x07)) {
78 cmd_ack(cmd, IAP_ACK_BAD_PARAM);
79 return;
80 }
81
82 switch (cmd)
83 {
84 /* case 00 ToIpod Ack 2/6 bytes*/
85 case 0x00:
86 {
87 /* 0x00 OK
88 * 0x01 Unknown Track Category
89 * 0x02 Command Failed. Command is valid but did not succeed
90 * 0x03 Out Of Resources
91 * 0x04 Bad Parameter
92 * 0x05 Unknown Track ID
93 * 0x06 Command Pending.
94 * 0x07 Not Authenticated
95 *
96 * byte 1 is ID of command being acknowledged
97 * bytes 2-5 only if status byte is pending. timeout in ms.
98 */
99 break;
100 }
101
102 /* case 0x01 ToAccessory GetTunerCaps
103 * This is sent by iap-lingo0.c through case 0x15 after device
104 * has been authenticated FF55020701F6
105 */
106
107 /* case 02 ToIpod RetTunerCaps 8 bytes */
108 case 0x02:
109 {
110 /* Capabilities are stored as bits in first 4 bytes,
111 * inbuffer[2] byte is bits 31:24
112 * inbuffer[3] byte is bits 23:16
113 * inbuffer[4] byte is bits 15:08
114 * inbuffer[5] byte is bits 07:00
115 * inbuffer[6] and inbuffer[7] are all reserved bits
116 * Bit 0 = AM Band 520-1710 Khz
117 * Bit 1 = FM Europe/US 87.5 - 108.0 Mhz
118 * Bit 2 = FM Japan 76.0 - 90.0 Mhz
119 * Bit 3 = FM Wide 76.0 - 108.0 Mhz
120 * Bit 4 = HD Radio Capable
121 * Bit 5:7 Reserved
122 * Bit 8 = Tuner Power On/Off Control Capable
123 * Bit 9 = Status Change Notification Capable
124 * Bit 10:15 Reserved
125 * Bit 17:16 Minimum FM Resolution ID Bits
126 * 00 = 200Khz, 01 = 100Khz, 10 = 50Khz, 11 = reserved
127 * Bit 18 = Tuner Seek Up/Down Capable
128 * Bit 19 = Tuner Seek RSSI Threshold. Only if 18=1
129 * Bit 20 = Force Monophonic mode capable
130 * Bit 21 = Stero Blend Capable
131 * Bit 22 = FM Tuner deemphasis select capable
132 * Bit 23 = AM Tuner Resolution 9Khz (0=10Khz Only) capable
133 * Bit 24 = Radio Data System (RDS/RBDS) data capable
134 * Bit 25 = Tuner Channel RSSI indicator capable
135 * Bit 26 = Stero Source Indicator capable
136 * Bit 27 = RDS/RBDS Raw mode capable
137 * Bit 31:28 Reserved
138 *
139 * ipod Tuner returns 07 5E 07 0E 10 4B
140 * Bytes 6,7 Reserved
141 * ???????? ????????
142 * ???????? ????????
143 * 00010000 01001011
144 *
145 * Byte 5 - 0E
146 * 00000000
147 * 76543210
148 * 00001110
149 * AM
150 * FM Europe/US
151 * FM Japan
152 * FM Wide
153 *
154 * Byte 4 - 07
155 * 11111100
156 * 54321098
157 * 00000111
158 * Tuner Power On/Off
159 * Status Change Notification
160 * ?? Should be reserved
161 *
162 * Byte 3 - 5E
163 * 22221111
164 * 32109876
165 * 01011110
166 * Tuner Seek Up/Down
167 * Tuner Seek RSSI Threshold
168 * Force Mono Mode Capable
169 * Stereo Blend Capable
170 * FM Tuner deemphasis select capable
171 *
172 * Byte 2 - 07
173 * 33222222
174 * 10987654
175 * 00000111
176 * RDS/RBDS Capable
177 * Tuner Channel RSSI Indicator
178 * Stereo Source
179 *
180 * Just need to see what we can use this data for
181 * Make a selection for the tuner mode to select
182 * Preference is
183 * 1st - 76 to 108 FM
184 * 2nd - 87.5 to 108 Fm
185 * 3rd - 76 to 90 Fm
186 * 4th - AM
187 *
188 */
189
190 if ((inbuffer[4] & 0x03) >0) {
191 statusnotifymaskbyte = 0;
192 if ((inbuffer[4] >> 0) & 0x01) {
193 /* Supports Tuner Power On/Off, so set ON */
194 statusnotifymaskbyte = 1;
195 }
196 if ((inbuffer[4] >> 1) & 0x01) {
197 /* Supports Status Change Notification so set ON */
198 /* Apple 5/6/7G firmware does NOT enable this bit */
199 /* statusnotifymaskbyte += 2; */
200 }
201 IAP_TX_INIT(0x07, 0x05);
202 IAP_TX_PUT(statusnotifymaskbyte);
203 iap_send_tx();
204 }
205 if ((inbuffer[5] >> 1) & 0x01) {
206 /* Supports FM Europe/US Tuner 87.5 - 108.0 Mhz */
207 /* Apple firmware sends this before setting region */
208 IAP_TX_INIT(0x07, 0x0E);
209 IAP_TX_PUT(0x00);
210 iap_send_tx();
211 /* Apple firmware then sends region */
212 IAP_TX_INIT(0x07, 0x08);
213 IAP_TX_PUT(0x02);
214 iap_send_tx();
215 } else if ((inbuffer[5] >> 3) & 0x01) {
216 /* Supports FM Wide Tuner 76 - 108.0 Mhz */
217 /* apple firmware send this before setting region */
218 IAP_TX_INIT(0x07, 0x0E);
219 IAP_TX_PUT(0x00);
220 iap_send_tx();
221 /* Apple firmware then send region */
222 IAP_TX_INIT(0x07, 0x08);
223 IAP_TX_PUT(0x08);
224 iap_send_tx();
225 } else if ((inbuffer[5] >> 2) & 0x01) {
226 /* Supports FM Japan Tuner 76 - 90.0 Mhz */
227 /* apple firmware send this before setting region */
228 IAP_TX_INIT(0x07, 0x0E);
229 IAP_TX_PUT(0x41);
230 iap_send_tx();
231 /* Apple firmware then send region */
232 IAP_TX_INIT(0x07, 0x08);
233 IAP_TX_PUT(0x04);
234 iap_send_tx();
235 } else if ((inbuffer[5] >> 0) & 0x01) {
236 /* Supports AM Tuner */
237 IAP_TX_INIT(0x07, 0x08);
238 IAP_TX_PUT(0x01);
239 iap_send_tx();
240 }
241
242 if ((inbuffer[2] & 0x03) > 0) {
243 statusnotifymaskbyte = 0;
244 if ((inbuffer[2] >> 0) & 0x01) {
245 /* Supports RDS/RBDS Capable so set
246 *StatusChangeNotify for RDS/RBDS Data
247 */
248 statusnotifymaskbyte = 1;
249 }
250 if ((inbuffer[2] >> 1) & 0x01) {
251 /* Supports Tuner Channel RSSi Indicator Capable so set */
252 /* StatusChangeNotify for RSSI */
253 /* Apple 5G firmware does NOT enable this bit so we wont */
254 /* statusnotifymaskbyte += 2; */
255 }
256 IAP_TX_INIT(0x07, 0x18);
257 IAP_TX_PUT(statusnotifymaskbyte);
258 iap_send_tx();
259 }
260
261 if ((inbuffer[4] >> 2) & 0x01) {
262 /* Reserved */
263 }
264 if ((inbuffer[4] >> 3) & 0x01) {
265 /* Reserved */
266 }
267 if ((inbuffer[3] >> 1) & 0x01) {
268 /* Tuner Seek Up/Down` */
269 }
270 if ((inbuffer[3] >> 2) & 0x01) {
271 /* Tuner Seek RSSI Threshold */
272 }
273 if ((inbuffer[3] >> 3) & 0x01) {
274 /* Force Mono Mode */
275 }
276 if ((inbuffer[3] >> 4) & 0x01) {
277 /* Stereo Blend */
278 }
279 if ((inbuffer[3] >> 6) & 0x01) {
280 /* FM Tuner deemphasis */
281 }
282 if ((inbuffer[2] >> 2) & 0x01) {
283 /* Stereo Source */
284 }
285 break;
286 }
287 /* case 03 ToAccessory GetTunerCtrl 2 bytes */
288
289 /* case 04 ToIpod RetTunerCtrl 3 bytes
290 * Bit 0 power is on (1) or Off (0)
291 * Bit 1 StatusChangeNotify is enabled (1) or disabled (0)
292 * Bit 3 RDS/RBDS Raw mode enabled
293 *
294 * Should/Can we do something with these?
295 */
296
297 /* case 05 ToAccessory SetTunerCtrl 3 bytes
298 * Bits as per 0x04 above
299 * Bit 0/1 set through Lingo7 Cmd02 */
300
301 /* case 06 ToAccessory GetTunerBand 2 bytes */
302
303 /* case 07 ToIpod RetTunerBand 3 bytes
304 * Returns current band for Tuner. See 0x08 below
305 *
306 * Should/Can we do something with these?
307 */
308
309 /* case 08 ToAccessory SetTuneBand
310 * Set Bit 0 for AM
311 * Set Bit 1 for FM Europe/U S 87.5-108Mhz
312 * Set Bit 2 for FM JApan 76.0-90.0Mhz
313 * Set Bit 3 for FM Wide 76.0-108Mhz
314 * Currently we send this after receiving capabilities
315 * on 0x02 above
316 */
317
318 /* case 09 ToAccessory GetTunerFreq 2 bytes */
319
320 /* case 0A ToIpod RetTunerFreq 7 bytes */
321 case 0x0A:
322 {
323 /* Returns Frequency set and RSSI Power Levels
324 * These are sent as is to rmt_tuner_freq() in
325 * ../firmware/drivers/tuner/ipod_remote_tuner.c */
326 rmt_tuner_freq(len, inbuffer);
327 break;
328 }
329
330 /* case 0B ToAccessory SetTunerFreq 6 bytes */
331
332 /* case 0C ToAccessory GetTunerMode 2 bytes */
333
334 /* case 0D ToIpod RetTunerMode 3 bytes
335 * Returns Tuner Mode Status in 8 bits as follows
336 * Bit 1:0 - FM Tuner Resolution
337 * Bit 2 Tuner is seeking up or down
338 * Bit 3 Tuner is seeking with RSSI min theshold enabled
339 * Bit 4 Force Mono Mode (1) or allow stereo (0)
340 * Bit 5 Stereo Blend enabled. Valid only if Bit 4 is 0
341 * Bit 6 FM Tuner Deemphasis 50uS (1) or 75uS (0)
342 * Bit 7 Reserved 0
343 */
344
345 /* case 0E ToAccessory SetTunerMode 3 bytes
346 * See 0x0D for Bit Descriptions
347 * Bits set by Cmd 02
348 */
349
350 /* case 0F ToAccessory GetTunerSeekRssi 2 bytes */
351
352 /* case 10 ToIpod RetTunerSeekRssi 3 bytes
353 * Returns RSSI Value for seek operations
354 * value is 0 (min) - 255 (max)
355 */
356
357 /* case 11 ToAccessory SetTunerSeekRssi 3 bytes */
358
359 /* case 12 ToAccessory TunerSeekStart 3 bytes */
360
361 /* case 13 ToIpod TunerSeekDone 7 bytes */
362 case 0x13:
363 {
364 rmt_tuner_freq(len, inbuffer);
365 break;
366 }
367
368 /* case 14 ToAccessory GetTunerStatus 2 bytes */
369
370 /* case 15 ToIpod RetTunerStatus 3 bytes */
371
372 /* case 16 ToAccessory GetStatusNotifyMask 2 bytes */
373
374 /* case 17 ToIpod RetStatusNotifyMask 3 bytes */
375
376 /* case 18 ToAccessory SetStatusNotifyMask 3 bytes
377 * This is set by Cmd 02
378 */
379
380 /* case 19 ToIpod StatusChangeNotify 3 bytes */
381 case 0x19:
382 {
383 /* Returns StatusChangeNotify bits to ipod.
384 * Bit 0 set for RDS/RBDS data ready
385 * Bit 1 set for Tuner RSSI level change
386 * Bit 2 for Stereo Indicator changed
387 * If any of these are set we will request the data
388 * need to look at using these
389 */
390 break;
391 }
392
393 /* case 1A ToAccessory GetRdsReadyStatus 2 bytes */
394
395 /* case 1B ToIpod RetRdsReadyStatus 6 bytes */
396 case 0x1B:
397 {
398 break;
399 }
400 /* case 1C ToAccessory GetRdsData 3 bytes */
401
402 /* case 1D ToIpod RetRdsData NN bytes */
403 case 0x1D:
404 {
405 rmt_tuner_rds_data(len, inbuffer);
406 break;
407 }
408
409 /* case 1E ToAccessory GetRdsNotifyMask 2 bytes*/
410
411 /* case 1F ToIpod RetRdsNotifyMask 6 Bytes*/
412 case 0x1F:
413 {
414 break;
415 }
416
417 /* case 20 ToAccessory SetRdsNotifyMask 6 bytes */
418
419 /* case 21 ToIpod RdsReadyNotify NN bytes */
420 case 0x21:
421 {
422 rmt_tuner_rds_data(len, inbuffer);
423 break;
424 }
425 /* case 22 Reserved */
426
427 /* case 23 Reserved */
428
429 /* case 24 Reserved */
430
431 /* case 25 ToAccessory GetHDProgramServiceCount 0 bytes */
432
433 /* case 26 ToIpod RetHDProgramServiceCount 1 bytes */
434 case 0x26:
435 {
436 break;
437 }
438
439 /* case 27 ToAccessory GetHDProgramService 0 bytes */
440
441 /* case 28 ToIpod RetHDProgramService 1 bytes */
442 case 0x28:
443 {
444 break;
445 }
446
447 /* case 29 ToAccessory SetHDProgramService 1 bytes */
448
449 /* case 2A ToAccessory GetHDDataReadyStatus 0 bytes */
450
451 /* case 2B ToIpod RetHDDataReadyStatus 4 bytes */
452 case 0x2B:
453 {
454 break;
455 }
456
457 /* case 2C ToAccessory GetHDData 1 bytes */
458
459 /* case 2D ToIpod RetHDData NN bytes */
460 case 0x2D:
461 {
462 break;
463 }
464
465 /* case 2E ToAccessory GetHDDataNotifyMask 0 bytes */
466
467 /* case 2F ToIpod RetHDDataNotifyMask 4 bytes */
468 case 0x2F:
469 {
470 break;
471 }
472
473 /* case 30 ToAccessory SetHDDataNotifyMask 4 bytes */
474
475 /* case 31 ToIpod HDDataReadyNotify NN bytes */
476 case 0x31:
477 {
478 break;
479 }
480
481 /* The default response is IAP_ACK_BAD_PARAM */
482 default:
483 {
484#ifdef LOGF_ENABLE
485 logf("iap: Unsupported Mode07 Command");
486#endif
487 cmd_ack(cmd, IAP_ACK_BAD_PARAM);
488 break;
489 }
490 }
491}