diff -Nur rockbox.git/apps/iap/iap-core.c rockbox/apps/iap/iap-core.c --- rockbox.git/apps/iap/iap-core.c 2018-08-03 14:51:26.000000000 +0100 +++ rockbox/apps/iap/iap-core.c 2018-08-03 17:26:11.448039401 +0100 @@ -164,7 +164,9 @@ {1, 5}, /* Display remote lingo, 0x03 */ {1, 12}, /* Extended Interface lingo, 0x04 */ {1, 1}, /* RF/BT Transmitter lingo, 0x05 */ - {} /* All others are unsupported */ + {0, 0}, /* USB Host lingo, 0x06, disabled */ + {1, 0}, /* RF Receiver lingo, 0x07 */ + {} /* every other lingo, disabled */ }; /* states of the iap de-framing state machine */ @@ -308,6 +310,17 @@ return MS_TO_TICKS(100); } + +void iap_set_remote_volume(void) +{ + IAP_TX_INIT(0x03, 0x0D); + IAP_TX_PUT(0x04); + IAP_TX_PUT(0x00); + IAP_TX_PUT(0xFF &((global_settings.volume+58) * 4)); + iap_send_tx(); +} + + /* This thread is waiting for events posted to iap_queue and calls * the appropriate subroutines in response */ @@ -1212,43 +1225,6 @@ } } -#if 0 -static void iap_handlepkt_mode7(const unsigned int len, const unsigned char *buf) -{ - unsigned int cmd = buf[1]; - switch (cmd) - { - /* RetTunerCaps */ - case 0x02: - { - /* do nothing */ - - /* GetAccessoryInfo */ - unsigned char data[] = {0x00, 0x27, 0x00}; - iap_send_pkt(data, sizeof(data)); - break; - } - - /* RetTunerFreq */ - case 0x0A: - /* fall through */ - /* TunerSeekDone */ - case 0x13: - { - rmt_tuner_freq(len, buf); - break; - } - - /* RdsReadyNotify, RDS station name 0x21 1E 00 + ASCII text*/ - case 0x21: - { - rmt_tuner_rds_data(len, buf); - break; - } - } -} -#endif - void iap_handlepkt(void) { int level; @@ -1271,17 +1247,19 @@ logf("R: %s", hexstring(iap_rxstart+2, (length))); #endif - unsigned char mode = *(iap_rxstart+2); - switch (mode) { - case 0: iap_handlepkt_mode0(length, iap_rxstart+2); break; + if (length != 0) { + unsigned char mode = *(iap_rxstart+2); + switch (mode) { + case 0: iap_handlepkt_mode0(length, iap_rxstart+2); break; #ifdef HAVE_LINE_REC - case 1: iap_handlepkt_mode1(length, iap_rxstart+2); break; + case 1: iap_handlepkt_mode1(length, iap_rxstart+2); break; #endif - case 2: iap_handlepkt_mode2(length, iap_rxstart+2); break; - case 3: iap_handlepkt_mode3(length, iap_rxstart+2); break; - case 4: iap_handlepkt_mode4(length, iap_rxstart+2); break; - case 5: iap_handlepkt_mode5(length, iap_rxstart+2); break; - /* case 7: iap_handlepkt_mode7(length, iap_rxstart+2); break; */ + case 2: iap_handlepkt_mode2(length, iap_rxstart+2); break; + case 3: iap_handlepkt_mode3(length, iap_rxstart+2); break; + case 4: iap_handlepkt_mode4(length, iap_rxstart+2); break; + case 5: iap_handlepkt_mode5(length, iap_rxstart+2); break; + case 7: iap_handlepkt_mode7(length, iap_rxstart+2); break; + } } /* Remove the handled packet from the RX buffer diff -Nur rockbox.git/apps/iap/iap-core.h rockbox/apps/iap/iap-core.h --- rockbox.git/apps/iap/iap-core.h 2018-08-03 14:51:28.000000000 +0100 +++ rockbox/apps/iap/iap-core.h 2018-08-03 16:17:58.000000000 +0100 @@ -73,14 +73,15 @@ /* States of the authentication state machine */ enum authen_state { - AUST_NONE, /* Initial state, no message sent */ - AUST_INIT, /* Remote side has requested authentication */ - AUST_CERTREQ, /* Remote certificate requested */ - AUST_CERTBEG, /* Certificate is being received */ - AUST_CERTDONE, /* Certificate received */ - AUST_CHASENT, /* Challenge sent */ - AUST_CHADONE, /* Challenge response received */ - AUST_AUTH, /* Authentication complete */ + AUST_NONE, /* Initial state, no message sent */ + AUST_INIT, /* Remote side has requested authentication */ + AUST_CERTREQ, /* Remote certificate requested */ + AUST_CERTBEG, /* Certificate is being received */ + AUST_CERTALLRECEIVED, /* Certificate all Received */ + AUST_CERTDONE, /* Certificate all Done */ + AUST_CHASENT, /* Challenge sent */ + AUST_CHADONE, /* Challenge response received */ + AUST_AUTH, /* Authentication complete */ }; /* State of authentication */ @@ -237,6 +238,7 @@ void iap_fill_power_state(void); void iap_send_tx(void); +void iap_set_remote_volume(void); extern enum interface_state interface_state; void iap_interface_state_change(const enum interface_state new); diff -Nur rockbox.git/apps/iap/iap-lingo0.c rockbox/apps/iap/iap-lingo0.c --- rockbox.git/apps/iap/iap-lingo0.c 2018-08-03 14:51:38.000000000 +0100 +++ rockbox/apps/iap/iap-lingo0.c 2018-08-03 17:19:45.444039401 +0100 @@ -21,6 +21,8 @@ #include "iap-lingo.h" #include "kernel.h" #include "system.h" +#include "tuner.h" +#include "ipod_remote_tuner.h" /* * This macro is meant to be used inside an IAP mode message handler. @@ -45,10 +47,13 @@ static void cmd_ack(const unsigned char cmd, const unsigned char status) { - IAP_TX_INIT(0x00, 0x02); - IAP_TX_PUT(status); - IAP_TX_PUT(cmd); - iap_send_tx(); + if (cmd != 0){ + IAP_TX_INIT(0x00, 0x02); + IAP_TX_PUT(status); + IAP_TX_PUT(cmd); + + iap_send_tx(); + } } #define cmd_ok(cmd) cmd_ack((cmd), IAP_ACK_OK) @@ -59,6 +64,7 @@ IAP_TX_PUT(0x06); IAP_TX_PUT(cmd); IAP_TX_PUT_U32(msdelay); + iap_send_tx(); } @@ -531,33 +537,47 @@ cmd_ok(cmd); + /* Bit 0: Must be set by all devices. See above*/ + /* Bit 1: Microphone Lingo */ + /* Bit 2: Simple Remote */ + /* Bit 3: Display Remote */ + /* Bit 4: Extended Remote */ /* Bit 5: RF Transmitter lingo */ if (lingoes & (1 << 5)) { /* FM transmitter sends this: */ /* FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (??)*/ - + /* 0x00000035 = 00000000 00000000 00000000 00110101 */ + /* 1<<5 1 */ /* GetAccessoryInfo */ - unsigned char data2[] = {0x00, 0x27, 0x00}; - iap_send_pkt(data2, sizeof(data2)); - /* RF Transmitter: Begin transmission */ - unsigned char data3[] = {0x05, 0x02}; - iap_send_pkt(data3, sizeof(data3)); - } + IAP_TX_INIT(0x00, 0x27); + IAP_TX_PUT(0x00); + + iap_send_tx(); + /* RF Transmitter: Begin transmission */ + IAP_TX_INIT(0x05, 0x02); -#if 0 + iap_send_tx(); + } + /* Bit 6: USB Host Control */ /* Bit 7: RF Tuner lingo */ if (lingoes & (1 << 7)) { /* ipod fm remote sends this: */ - /* FF 55 0E 00 13 00 00 00 8D 00 00 00 0E 00 00 00 03 41 */ + /* FF 55 0E 00 13 00 00 00 8D 00 00 00 0E 00 00 00 03 */ + /* 0x0000008D = 00000000 00000000 00000000 00011101 */ + /* 1<<7 */ radio_present = 1; - /* GetDevAuthenticationInfo */ - unsigned char data4[] = {0x00, 0x14}; - iap_send_pkt(data4, sizeof(data4)); } -#endif + /* Bit 8: Accessory Equalizer Lingo */ + /* Bit 9: Reserved */ + /* Bit 10: Digial Audio Lingo */ + /* Bit 11: Reserved */ + /* Bit 12: Storage Lingo */ + /* Bit 13: Reserved */ + /* .................*/ + /* Bit 31: Reserved */ break; } @@ -594,7 +614,8 @@ { /* There are two formats of this packet. One with only * the version information bytes (for Auth version 1.0) - * and the long form shown above + * and the long form shown above but it must be at least 4 + * bytes long */ CHECKLEN(4); @@ -605,25 +626,8 @@ device.auth.version = (buf[2] << 8) | buf[3]; - /* We support authentication versions 1.0 and 2.0 */ - if (device.auth.version == 0x100) { - /* If we could really do authentication we'd have to - * check the certificate here. Since we can't, just acknowledge - * the packet with an "everything OK" AckDevAuthenticationInfo - * - * Skip GetAccessoryInfo process, this command together with - * authentication level 2 were added in iAP release 24, it is - * not be supported by devices authenticating at level 1. - */ - IAP_TX_INIT(0x00, 0x16); - IAP_TX_PUT(0x00); - - iap_send_tx(); - device.auth.state = AUST_CERTDONE; - break; - } - - if (device.auth.version != 0x200) { + /* We only support authentication versions 1.0 and 2.0 */ + if ((device.auth.version != 0x100) && (device.auth.version != 0x200)) { /* Version mismatches are signalled by AckDevAuthenticationInfo * with the status set to Authentication Information unsupported */ @@ -635,61 +639,77 @@ iap_send_tx(); break; } - - /* There must be at least one byte of certificate data - * in the packet - */ - CHECKLEN(7); - - switch (device.auth.state) - { - /* This is the first packet. Note the maximum section number - * so we can check it later. + if (device.auth.version == 0x100) { + /* If we could really do authentication we'd have to + * check the certificate here. Since we can't, just acknowledge + * the packet later with an "everything OK" AckDevAuthenticationInfo + * and change device.auth.state to AuthenticateState_CertificateDone + */ + device.auth.state = AUST_CERTALLRECEIVED; + } else { + /* Version 2.00 requires at least one byte of certificate data + * in the packet */ - case AUST_CERTREQ: + CHECKLEN(7); + switch (device.auth.state) { - device.auth.max_section = buf[5]; - device.auth.state = AUST_CERTBEG; + /* This is the first packet. Note the maximum section number + * so we can check it later. + */ + case AUST_CERTREQ: + { + device.auth.max_section = buf[5]; + device.auth.state = AUST_CERTBEG; - /* Intentional fall-through */ - } - /* All following packets */ - case AUST_CERTBEG: - { - /* Check if this is the expected section */ - if (buf[4] != device.auth.next_section) { - cmd_ack(cmd, IAP_ACK_BAD_PARAM); + /* Intentional fall-through */ + } + /* All following packets */ + case AUST_CERTBEG: + { + /* Check if this is the expected section */ + if (buf[4] != device.auth.next_section) { + cmd_ack(cmd, IAP_ACK_BAD_PARAM); + break; + } + + /* Is this the last section? */ + if (device.auth.next_section == device.auth.max_section) { + /* If we could really do authentication we'd have to + * check the certificate here. Since we can't, just acknowledge + * the packet later with an "everything OK" AckDevAuthenticationInfo + * and change device.auth.state to AuthenticateState_CertificateDone + */ + device.auth.state = AUST_CERTALLRECEIVED; + } else { + device.auth.next_section++; + cmd_ok(cmd); + } break; } - - /* Is this the last section? */ - if (device.auth.next_section == device.auth.max_section) { - /* If we could really do authentication we'd have to - * check the certificate here. Since we can't, just acknowledge - * the packet with an "everything OK" AckDevAuthenticationInfo - * - * Also, start GetAccessoryInfo process - */ - IAP_TX_INIT(0x00, 0x16); - IAP_TX_PUT(0x00); - - iap_send_tx(); - device.auth.state = AUST_CERTDONE; - device.accinfo = ACCST_INIT; - } else { - device.auth.next_section++; - cmd_ok(cmd); + default: + { + cmd_ack(cmd, IAP_ACK_BAD_PARAM); + break; } - break; - } - - default: - { - cmd_ack(cmd, IAP_ACK_BAD_PARAM); - break; } } + if (device.auth.state == AUST_CERTALLRECEIVED) { + /* We've received all the certificate data so just + *Acknowledge everything OK + */ + IAP_TX_INIT(0x00, 0x16); + IAP_TX_PUT(0x00); + + iap_send_tx(); + + /* GetAccessoryInfo*/ + IAP_TX_INIT(0x00, 0x27); + IAP_TX_PUT(0x00); + + iap_send_tx(); + device.auth.state = AUST_CERTDONE; + } break; } @@ -744,6 +764,15 @@ iap_send_tx(); device.auth.state = AUST_AUTH; + if (radio_present == 1) + { + /* GetTunerCaps */ + IAP_TX_INIT(0x07, 0x01); + + iap_send_tx(); + } + iap_set_remote_volume(); + break; } diff -Nur rockbox.git/apps/iap/iap-lingo7.c rockbox/apps/iap/iap-lingo7.c --- rockbox.git/apps/iap/iap-lingo7.c 1970-01-01 01:00:00.000000000 +0100 +++ rockbox/apps/iap/iap-lingo7.c 2018-08-03 17:05:00.020039401 +0100 @@ -0,0 +1,474 @@ +/*************************************************************************** + * __________ __ ___. + * 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" +#include "ipod_remote_tuner.h" + +/* + * 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*/ + 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 */ + 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 */ + 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 */ + 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 + */ + 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"); +#else + cmd_ack(cmd, IAP_ACK_BAD_PARAM); +#endif + break; + } + } +} diff -Nur rockbox.git/apps/iap/iap-lingo.h rockbox/apps/iap/iap-lingo.h --- rockbox.git/apps/iap/iap-lingo.h 2018-08-03 14:51:34.000000000 +0100 +++ rockbox/apps/iap/iap-lingo.h 2018-08-03 16:17:58.000000000 +0100 @@ -24,3 +24,4 @@ void iap_handlepkt_mode2(const unsigned int len, const unsigned char *buf); void iap_handlepkt_mode3(const unsigned int len, const unsigned char *buf); void iap_handlepkt_mode4(const unsigned int len, const unsigned char *buf); +void iap_handlepkt_mode7(const unsigned int len, const unsigned char *buf); diff -Nur rockbox.git/apps/SOURCES rockbox/apps/SOURCES --- rockbox.git/apps/SOURCES 2018-08-03 14:53:33.000000000 +0100 +++ rockbox/apps/SOURCES 2018-08-03 16:17:58.000000000 +0100 @@ -70,6 +70,7 @@ iap/iap-lingo2.c iap/iap-lingo3.c iap/iap-lingo4.c +iap/iap-lingo7.c #endif screen_access.c @@ -317,6 +318,4 @@ keymaps/keymap-dx50.c #elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD keymaps/keymap-agptekrocker.c -#elif CONFIG_KEYPAD == XDUOO_X3_PAD -keymaps/keymap-xduoox3.c #endif diff -Nur rockbox.git/firmware/drivers/tuner/ipod_remote_tuner.c rockbox/firmware/drivers/tuner/ipod_remote_tuner.c --- rockbox.git/firmware/drivers/tuner/ipod_remote_tuner.c 2018-08-03 14:52:08.000000000 +0100 +++ rockbox/firmware/drivers/tuner/ipod_remote_tuner.c 2018-08-03 17:10:53.800039401 +0100 @@ -69,7 +69,7 @@ rds_reset(); /* ex: 00 01 63 14 = 90.9MHz */ unsigned char data[] = {0x07, 0x0B, 0x00, 0x01, 0x63, 0x14}; - + if (curr_freq != 0) { unsigned int khz = curr_freq / 1000; @@ -93,7 +93,7 @@ old_region = -1; tuner_frequency = 0; radio_tuned = false; - + /* tuner HW on */ const unsigned char data[] = {0x07, 0x05, 0x01}; iap_send_pkt(data, sizeof(data)); @@ -253,16 +253,16 @@ static bool reply_timeout(void) { int timeout = 0; - + sleep(HZ/50); do { - iap_handlepkt(); +/* iap_handlepkt(); */ sleep(HZ/50); timeout++; } while((ipod_rmt_tuner_get(RADIO_TUNED) == 0) && (timeout < TIMEOUT_VALUE)); - + return (timeout >= TIMEOUT_VALUE); } @@ -277,7 +277,7 @@ rds_push_info(RDS_INFO_RT, (uintptr_t)(buf+4), len-4); } } - + /* tuner abstraction layer: set something to the tuner */ int ipod_rmt_tuner_set(int setting, int value) { @@ -327,7 +327,7 @@ /* scan up */ else rmt_tuner_scan(1); - + sleep(HZ/10); if (reply_timeout()) { @@ -337,7 +337,7 @@ return 0; } radio_tuned = false; - } + } if (tuner_frequency == value) { Binary files rockbox.git/.git/index and rockbox/.git/index differ Binary files rockbox.git/tools/scramble and rockbox/tools/scramble differ