diff options
Diffstat (limited to 'apps/iap/iap-lingo7.c')
-rw-r--r-- | apps/iap/iap-lingo7.c | 491 |
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 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2002 by Alan Korr & Nick Robinson + * + * All files in this archive are subject to the GNU General Public License. + * See the file COPYING in the source tree root for full license agreement. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ +#include "iap-core.h" +#include "iap-lingo.h" +#include "kernel.h" +#include "system.h" +#include "tuner.h" +#if CONFIG_TUNER +#include "ipod_remote_tuner.h" +#endif + +/* + * This macro is meant to be used inside an IAP mode message handler. + * It is passed the expected minimum length of the message inbufferfer. + * If the inbufferfer does not have the required lenght an ACK + * packet with a Bad Parameter error is generated. + */ +#define CHECKLEN(x) do { \ + if (len < (x)) { \ + cmd_ack(cmd, IAP_ACK_BAD_PARAM); \ + return; \ + }} while(0) + +/* Check for authenticated state, and return an ACK Not + * Authenticated on failure. + */ +#define CHECKAUTH do { \ + if (!DEVICE_AUTHENTICATED) { \ + cmd_ack(cmd, IAP_ACK_NO_AUTHEN); \ + return; \ + }} while(0) + + +static void cmd_ack(const unsigned char cmd, const unsigned char status) +{ + IAP_TX_INIT(0x07, 0x00); + IAP_TX_PUT(status); + IAP_TX_PUT(cmd); + + iap_send_tx(); +} + +#define cmd_ok(cmd) cmd_ack((cmd), IAP_ACK_OK) + +void iap_handlepkt_mode7(const unsigned int len, const unsigned char *inbuffer) +{ + /* Note that some of the Lingo Mode 7 commands are handled by + * ../firmware/drivers/tuner/ipod_remote_tuner.c as some of the + * commands are sourced with the remote as the master with the ipod acting + * as the slave. + */ + unsigned char cmd = inbuffer[1]; + unsigned char statusnotifymaskbyte = 0; + + /* We expect at least two bytes in the inbuffer, one for the + * lingo and one for the command + */ + CHECKLEN(2); + + /* Lingo 0x07 must have been negotiated */ + if (!DEVICE_LINGO_SUPPORTED(0x07)) { + cmd_ack(cmd, IAP_ACK_BAD_PARAM); + return; + } + + switch (cmd) + { + /* case 00 ToIpod Ack 2/6 bytes*/ + case 0x00: + { + /* 0x00 OK + * 0x01 Unknown Track Category + * 0x02 Command Failed. Command is valid but did not succeed + * 0x03 Out Of Resources + * 0x04 Bad Parameter + * 0x05 Unknown Track ID + * 0x06 Command Pending. + * 0x07 Not Authenticated + * + * byte 1 is ID of command being acknowledged + * bytes 2-5 only if status byte is pending. timeout in ms. + */ + break; + } + + /* case 0x01 ToAccessory GetTunerCaps + * This is sent by iap-lingo0.c through case 0x15 after device + * has been authenticated FF55020701F6 + */ + + /* case 02 ToIpod RetTunerCaps 8 bytes */ + case 0x02: + { + /* Capabilities are stored as bits in first 4 bytes, + * inbuffer[2] byte is bits 31:24 + * inbuffer[3] byte is bits 23:16 + * inbuffer[4] byte is bits 15:08 + * inbuffer[5] byte is bits 07:00 + * inbuffer[6] and inbuffer[7] are all reserved bits + * Bit 0 = AM Band 520-1710 Khz + * Bit 1 = FM Europe/US 87.5 - 108.0 Mhz + * Bit 2 = FM Japan 76.0 - 90.0 Mhz + * Bit 3 = FM Wide 76.0 - 108.0 Mhz + * Bit 4 = HD Radio Capable + * Bit 5:7 Reserved + * Bit 8 = Tuner Power On/Off Control Capable + * Bit 9 = Status Change Notification Capable + * Bit 10:15 Reserved + * Bit 17:16 Minimum FM Resolution ID Bits + * 00 = 200Khz, 01 = 100Khz, 10 = 50Khz, 11 = reserved + * Bit 18 = Tuner Seek Up/Down Capable + * Bit 19 = Tuner Seek RSSI Threshold. Only if 18=1 + * Bit 20 = Force Monophonic mode capable + * Bit 21 = Stero Blend Capable + * Bit 22 = FM Tuner deemphasis select capable + * Bit 23 = AM Tuner Resolution 9Khz (0=10Khz Only) capable + * Bit 24 = Radio Data System (RDS/RBDS) data capable + * Bit 25 = Tuner Channel RSSI indicator capable + * Bit 26 = Stero Source Indicator capable + * Bit 27 = RDS/RBDS Raw mode capable + * Bit 31:28 Reserved + * + * ipod Tuner returns 07 5E 07 0E 10 4B + * Bytes 6,7 Reserved + * ???????? ???????? + * ???????? ???????? + * 00010000 01001011 + * + * Byte 5 - 0E + * 00000000 + * 76543210 + * 00001110 + * AM + * FM Europe/US + * FM Japan + * FM Wide + * + * Byte 4 - 07 + * 11111100 + * 54321098 + * 00000111 + * Tuner Power On/Off + * Status Change Notification + * ?? Should be reserved + * + * Byte 3 - 5E + * 22221111 + * 32109876 + * 01011110 + * Tuner Seek Up/Down + * Tuner Seek RSSI Threshold + * Force Mono Mode Capable + * Stereo Blend Capable + * FM Tuner deemphasis select capable + * + * Byte 2 - 07 + * 33222222 + * 10987654 + * 00000111 + * RDS/RBDS Capable + * Tuner Channel RSSI Indicator + * Stereo Source + * + * Just need to see what we can use this data for + * Make a selection for the tuner mode to select + * Preference is + * 1st - 76 to 108 FM + * 2nd - 87.5 to 108 Fm + * 3rd - 76 to 90 Fm + * 4th - AM + * + */ + + if ((inbuffer[4] & 0x03) >0) { + statusnotifymaskbyte = 0; + if ((inbuffer[4] >> 0) & 0x01) { + /* Supports Tuner Power On/Off, so set ON */ + statusnotifymaskbyte = 1; + } + if ((inbuffer[4] >> 1) & 0x01) { + /* Supports Status Change Notification so set ON */ + /* Apple 5/6/7G firmware does NOT enable this bit */ + /* statusnotifymaskbyte += 2; */ + } + IAP_TX_INIT(0x07, 0x05); + IAP_TX_PUT(statusnotifymaskbyte); + iap_send_tx(); + } + if ((inbuffer[5] >> 1) & 0x01) { + /* Supports FM Europe/US Tuner 87.5 - 108.0 Mhz */ + /* Apple firmware sends this before setting region */ + IAP_TX_INIT(0x07, 0x0E); + IAP_TX_PUT(0x00); + iap_send_tx(); + /* Apple firmware then sends region */ + IAP_TX_INIT(0x07, 0x08); + IAP_TX_PUT(0x02); + iap_send_tx(); + } else if ((inbuffer[5] >> 3) & 0x01) { + /* Supports FM Wide Tuner 76 - 108.0 Mhz */ + /* apple firmware send this before setting region */ + IAP_TX_INIT(0x07, 0x0E); + IAP_TX_PUT(0x00); + iap_send_tx(); + /* Apple firmware then send region */ + IAP_TX_INIT(0x07, 0x08); + IAP_TX_PUT(0x08); + iap_send_tx(); + } else if ((inbuffer[5] >> 2) & 0x01) { + /* Supports FM Japan Tuner 76 - 90.0 Mhz */ + /* apple firmware send this before setting region */ + IAP_TX_INIT(0x07, 0x0E); + IAP_TX_PUT(0x41); + iap_send_tx(); + /* Apple firmware then send region */ + IAP_TX_INIT(0x07, 0x08); + IAP_TX_PUT(0x04); + iap_send_tx(); + } else if ((inbuffer[5] >> 0) & 0x01) { + /* Supports AM Tuner */ + IAP_TX_INIT(0x07, 0x08); + IAP_TX_PUT(0x01); + iap_send_tx(); + } + + if ((inbuffer[2] & 0x03) > 0) { + statusnotifymaskbyte = 0; + if ((inbuffer[2] >> 0) & 0x01) { + /* Supports RDS/RBDS Capable so set + *StatusChangeNotify for RDS/RBDS Data + */ + statusnotifymaskbyte = 1; + } + if ((inbuffer[2] >> 1) & 0x01) { + /* Supports Tuner Channel RSSi Indicator Capable so set */ + /* StatusChangeNotify for RSSI */ + /* Apple 5G firmware does NOT enable this bit so we wont */ + /* statusnotifymaskbyte += 2; */ + } + IAP_TX_INIT(0x07, 0x18); + IAP_TX_PUT(statusnotifymaskbyte); + iap_send_tx(); + } + + if ((inbuffer[4] >> 2) & 0x01) { + /* Reserved */ + } + if ((inbuffer[4] >> 3) & 0x01) { + /* Reserved */ + } + if ((inbuffer[3] >> 1) & 0x01) { + /* Tuner Seek Up/Down` */ + } + if ((inbuffer[3] >> 2) & 0x01) { + /* Tuner Seek RSSI Threshold */ + } + if ((inbuffer[3] >> 3) & 0x01) { + /* Force Mono Mode */ + } + if ((inbuffer[3] >> 4) & 0x01) { + /* Stereo Blend */ + } + if ((inbuffer[3] >> 6) & 0x01) { + /* FM Tuner deemphasis */ + } + if ((inbuffer[2] >> 2) & 0x01) { + /* Stereo Source */ + } + break; + } + /* case 03 ToAccessory GetTunerCtrl 2 bytes */ + + /* case 04 ToIpod RetTunerCtrl 3 bytes + * Bit 0 power is on (1) or Off (0) + * Bit 1 StatusChangeNotify is enabled (1) or disabled (0) + * Bit 3 RDS/RBDS Raw mode enabled + * + * Should/Can we do something with these? + */ + + /* case 05 ToAccessory SetTunerCtrl 3 bytes + * Bits as per 0x04 above + * Bit 0/1 set through Lingo7 Cmd02 */ + + /* case 06 ToAccessory GetTunerBand 2 bytes */ + + /* case 07 ToIpod RetTunerBand 3 bytes + * Returns current band for Tuner. See 0x08 below + * + * Should/Can we do something with these? + */ + + /* case 08 ToAccessory SetTuneBand + * Set Bit 0 for AM + * Set Bit 1 for FM Europe/U S 87.5-108Mhz + * Set Bit 2 for FM JApan 76.0-90.0Mhz + * Set Bit 3 for FM Wide 76.0-108Mhz + * Currently we send this after receiving capabilities + * on 0x02 above + */ + + /* case 09 ToAccessory GetTunerFreq 2 bytes */ + + /* case 0A ToIpod RetTunerFreq 7 bytes */ + case 0x0A: + { + /* Returns Frequency set and RSSI Power Levels + * These are sent as is to rmt_tuner_freq() in + * ../firmware/drivers/tuner/ipod_remote_tuner.c */ + rmt_tuner_freq(len, inbuffer); + break; + } + + /* case 0B ToAccessory SetTunerFreq 6 bytes */ + + /* case 0C ToAccessory GetTunerMode 2 bytes */ + + /* case 0D ToIpod RetTunerMode 3 bytes + * Returns Tuner Mode Status in 8 bits as follows + * Bit 1:0 - FM Tuner Resolution + * Bit 2 Tuner is seeking up or down + * Bit 3 Tuner is seeking with RSSI min theshold enabled + * Bit 4 Force Mono Mode (1) or allow stereo (0) + * Bit 5 Stereo Blend enabled. Valid only if Bit 4 is 0 + * Bit 6 FM Tuner Deemphasis 50uS (1) or 75uS (0) + * Bit 7 Reserved 0 + */ + + /* case 0E ToAccessory SetTunerMode 3 bytes + * See 0x0D for Bit Descriptions + * Bits set by Cmd 02 + */ + + /* case 0F ToAccessory GetTunerSeekRssi 2 bytes */ + + /* case 10 ToIpod RetTunerSeekRssi 3 bytes + * Returns RSSI Value for seek operations + * value is 0 (min) - 255 (max) + */ + + /* case 11 ToAccessory SetTunerSeekRssi 3 bytes */ + + /* case 12 ToAccessory TunerSeekStart 3 bytes */ + + /* case 13 ToIpod TunerSeekDone 7 bytes */ + case 0x13: + { + rmt_tuner_freq(len, inbuffer); + break; + } + + /* case 14 ToAccessory GetTunerStatus 2 bytes */ + + /* case 15 ToIpod RetTunerStatus 3 bytes */ + + /* case 16 ToAccessory GetStatusNotifyMask 2 bytes */ + + /* case 17 ToIpod RetStatusNotifyMask 3 bytes */ + + /* case 18 ToAccessory SetStatusNotifyMask 3 bytes + * This is set by Cmd 02 + */ + + /* case 19 ToIpod StatusChangeNotify 3 bytes */ + case 0x19: + { + /* Returns StatusChangeNotify bits to ipod. + * Bit 0 set for RDS/RBDS data ready + * Bit 1 set for Tuner RSSI level change + * Bit 2 for Stereo Indicator changed + * If any of these are set we will request the data + * need to look at using these + */ + break; + } + + /* case 1A ToAccessory GetRdsReadyStatus 2 bytes */ + + /* case 1B ToIpod RetRdsReadyStatus 6 bytes */ + case 0x1B: + { + break; + } + /* case 1C ToAccessory GetRdsData 3 bytes */ + + /* case 1D ToIpod RetRdsData NN bytes */ + case 0x1D: + { + rmt_tuner_rds_data(len, inbuffer); + break; + } + + /* case 1E ToAccessory GetRdsNotifyMask 2 bytes*/ + + /* case 1F ToIpod RetRdsNotifyMask 6 Bytes*/ + case 0x1F: + { + break; + } + + /* case 20 ToAccessory SetRdsNotifyMask 6 bytes */ + + /* case 21 ToIpod RdsReadyNotify NN bytes */ + case 0x21: + { + rmt_tuner_rds_data(len, inbuffer); + break; + } + /* case 22 Reserved */ + + /* case 23 Reserved */ + + /* case 24 Reserved */ + + /* case 25 ToAccessory GetHDProgramServiceCount 0 bytes */ + + /* case 26 ToIpod RetHDProgramServiceCount 1 bytes */ + case 0x26: + { + break; + } + + /* case 27 ToAccessory GetHDProgramService 0 bytes */ + + /* case 28 ToIpod RetHDProgramService 1 bytes */ + case 0x28: + { + break; + } + + /* case 29 ToAccessory SetHDProgramService 1 bytes */ + + /* case 2A ToAccessory GetHDDataReadyStatus 0 bytes */ + + /* case 2B ToIpod RetHDDataReadyStatus 4 bytes */ + case 0x2B: + { + break; + } + + /* case 2C ToAccessory GetHDData 1 bytes */ + + /* case 2D ToIpod RetHDData NN bytes */ + case 0x2D: + { + break; + } + + /* case 2E ToAccessory GetHDDataNotifyMask 0 bytes */ + + /* case 2F ToIpod RetHDDataNotifyMask 4 bytes */ + case 0x2F: + { + break; + } + + /* case 30 ToAccessory SetHDDataNotifyMask 4 bytes */ + + /* case 31 ToIpod HDDataReadyNotify NN bytes */ + case 0x31: + { + break; + } + + /* The default response is IAP_ACK_BAD_PARAM */ + default: + { +#ifdef LOGF_ENABLE + logf("iap: Unsupported Mode07 Command"); +#endif + cmd_ack(cmd, IAP_ACK_BAD_PARAM); + break; + } + } +} |