Add support for the ipod FM remote to the 4G, Color, 5G, nano 1G with RDS
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23805 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
63d79148fd
commit
0260852771
16 changed files with 881 additions and 54 deletions
218
apps/iap.c
218
apps/iap.c
|
@ -37,11 +37,12 @@
|
|||
#include "settings.h"
|
||||
#include "metadata.h"
|
||||
#include "wps.h"
|
||||
|
||||
#include "sound.h"
|
||||
#include "action.h"
|
||||
#include "powermgmt.h"
|
||||
|
||||
#define RX_BUFLEN 260
|
||||
#define TX_BUFLEN 128
|
||||
#include "tuner.h"
|
||||
#include "ipod_remote_tuner.h"
|
||||
|
||||
static volatile int iap_pollspeed = 0;
|
||||
static volatile bool iap_remotetick = true;
|
||||
|
@ -115,7 +116,7 @@ void iap_bitrate_set(int ratenum)
|
|||
checksum (length+mode+parameters+checksum == 0)
|
||||
*/
|
||||
|
||||
static void iap_send_pkt(const unsigned char * data, int len)
|
||||
void iap_send_pkt(const unsigned char * data, int len)
|
||||
{
|
||||
int i, chksum;
|
||||
|
||||
|
@ -192,15 +193,15 @@ void iap_periodic(void)
|
|||
unsigned long time_elapsed = audio_current_track()->elapsed;
|
||||
|
||||
time_elapsed += wps_get_ff_rewind_count();
|
||||
|
||||
data[3] = 0x04; // playing
|
||||
|
||||
data[3] = 0x04; /* playing */
|
||||
|
||||
/* If info has changed, don't flag it right away */
|
||||
if(iap_changedctr && iap_changedctr++ >= iap_pollspeed * 2)
|
||||
{
|
||||
{
|
||||
/* track info has changed */
|
||||
iap_changedctr = 0;
|
||||
data[3] = 0x01; // 0x02 has same effect?
|
||||
data[3] = 0x01; /* 0x02 has same effect? */
|
||||
iap_updateflag = true;
|
||||
}
|
||||
|
||||
|
@ -211,12 +212,19 @@ void iap_periodic(void)
|
|||
iap_send_pkt(data, sizeof(data));
|
||||
}
|
||||
|
||||
void iap_set_remote_volume(void)
|
||||
{
|
||||
unsigned char data[] = {0x03, 0x0D, 0x04, 0x00, 0x00};
|
||||
data[4] = (char)((global_settings.volume+58) * 4);
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
}
|
||||
|
||||
void iap_handlepkt(void)
|
||||
{
|
||||
|
||||
|
||||
if(!iap_setupflag) return;
|
||||
if(serbuf[0] == 0) return;
|
||||
|
||||
|
||||
/* if we are waiting for a remote button to go out,
|
||||
delay the handling of the new packet */
|
||||
if(!iap_remotetick)
|
||||
|
@ -224,63 +232,140 @@ void iap_handlepkt(void)
|
|||
queue_post(&button_queue, SYS_IAP_HANDLEPKT, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Handle Mode 0 */
|
||||
if (serbuf[1] == 0x00)
|
||||
{
|
||||
switch (serbuf[2])
|
||||
{
|
||||
/* get model info */
|
||||
case 0x0D:
|
||||
case 0x24:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x0E, 0x00, 0x0B, 0x00, 0x10,
|
||||
'R', 'O', 'C', 'K', 'B', 'O', 'X', 0x00};
|
||||
/* ipod video send this */
|
||||
unsigned char data[] = {0x00, 0x25, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,0x01};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
/* No idea ??? */
|
||||
|
||||
case 0x18:
|
||||
{
|
||||
/* ciphered authentication command */
|
||||
/* Isn't used since we don't send the 0x00 0x17 command */
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x15:
|
||||
{
|
||||
unsigned char data0[] = {0x00, 0x16, 0x00};
|
||||
iap_send_pkt(data0, sizeof(data0));
|
||||
unsigned char data1[] = {0x00, 0x27, 0x00};
|
||||
iap_send_pkt(data1, sizeof(data1));
|
||||
/* authentication ack, mandatory to enable some hardware */
|
||||
unsigned char data2[] = {0x00, 0x19, 0x00};
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
if (radio_present == 1)
|
||||
{
|
||||
/* get tuner capacities */
|
||||
unsigned char data3[] = {0x07, 0x01};
|
||||
iap_send_pkt(data3, sizeof(data3));
|
||||
}
|
||||
iap_set_remote_volume();
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x13:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x02, 0x00, 0x13};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
|
||||
if (serbuf[6] == 0x35)
|
||||
/* FM transmitter sends this: */
|
||||
/* FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (??)*/
|
||||
{
|
||||
unsigned char data2[] = {0x00, 0x27, 0x00};
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
unsigned char data3[] = {0x05, 0x02};
|
||||
iap_send_pkt(data3, sizeof(data3));
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
/* ipod fm remote sends this: */
|
||||
/* FF 55 0E 00 13 00 00 00 8D 00 00 00 0E 00 00 00 03 41 */
|
||||
if (serbuf[6] |= 0x80)
|
||||
radio_present = 1;
|
||||
unsigned char data4[] = {0x00, 0x14};
|
||||
iap_send_pkt(data4, sizeof(data4));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Init */
|
||||
case 0x0F:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x10, 0x00, 0x01, 0x05};
|
||||
data[2] = serbuf[3];
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
/* FM transmitter sends this: FF 55 06 00 01 05 00 02 01 F1 (mode switch) */
|
||||
|
||||
/* get model info */
|
||||
case 0x0D:
|
||||
{
|
||||
/* ipod is supposed to work only with 5G and nano 2G */
|
||||
/*{0x00, 0x0E, 0x00, 0x0B, 0x00, 0x05, 0x50, 0x41, 0x31, 0x34,
|
||||
0x37, 0x4C, 0x4C, 0x00}; PA147LL (IPOD 5G 60 GO) */
|
||||
unsigned char data[] = {0x00, 0x0E, 0x00, 0x0B, 0x00, 0x10,
|
||||
'R', 'O', 'C', 'K', 'B', 'O', 'X', 0x00};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
|
||||
/* Ipod FM remote sends this: FF 55 02 00 09 F5 */
|
||||
case 0x09:
|
||||
{
|
||||
/* ipod5G firmware version */
|
||||
unsigned char data[] = {0x00, 0x0A, 0x01, 0x02, 0x01 };
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
|
||||
/* FM transmitter sends this: */
|
||||
/* FF 55 02 00 05 F9 (mode switch: AiR mode) */
|
||||
case 0x05:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x02, 0x06,
|
||||
0x05, 0x00, 0x00, 0x0B, 0xB8, 0x28};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
unsigned char data2[] = {0x00, 0x02, 0x00, 0x05};
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x01:
|
||||
{
|
||||
if(serbuf[3] == 0x05)
|
||||
/* FM transmitter sends this: */
|
||||
/* FF 55 06 00 01 05 00 02 01 F1 (mode switch) */
|
||||
if(serbuf[3] == 0x05)
|
||||
{
|
||||
sleep(HZ/3);
|
||||
unsigned char data[] = {0x05, 0x02};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
}
|
||||
/* FM remote sends this: */
|
||||
/* FF 55 03 00 01 02 FA (1st thing sent) */
|
||||
else if(serbuf[3] == 0x02)
|
||||
{
|
||||
/* useful only for apple firmware */
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* FM transmitter sends this: FF 55 0E 00 13 00 00 00 35 00 00 00 04 00 00 00 00 A6 (???)*/
|
||||
case 0x13:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x02, 0x00, 0x13};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
unsigned char data2[] = {0x00, 0x27, 0x00};
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
unsigned char data3[] = {0x05, 0x02};
|
||||
iap_send_pkt(data3, sizeof(data3));
|
||||
break;
|
||||
}
|
||||
/* FM transmitter sends this: FF 55 02 00 05 F9 (mode switch: AiR mode) */
|
||||
case 0x05:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x02, 0x06, 0x05, 0x00, 0x00, 0x0B, 0xB8, 0x28};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
unsigned char data2[] = {0x00, 0x02, 0x00, 0x05};
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
break;
|
||||
}
|
||||
|
||||
/* default response is with cmd ok packet */
|
||||
default:
|
||||
{
|
||||
unsigned char data[] = {0x00, 0x02, 0x00, 0x00};
|
||||
data[3] = serbuf[2]; //respond with cmd
|
||||
data[3] = serbuf[2]; /* respond with cmd */
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
|
@ -395,6 +480,30 @@ void iap_handlepkt(void)
|
|||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x08:
|
||||
{
|
||||
/* ACK */
|
||||
unsigned char data[] = {0x03, 0x00, 0x00, 0x08};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x0C:
|
||||
{
|
||||
/* request ipod volume */
|
||||
if (serbuf[3] == 0x04)
|
||||
{
|
||||
iap_set_remote_volume();
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* get volume from accessory */
|
||||
case 0x0E:
|
||||
if (serbuf[3] == 0x04)
|
||||
global_settings.volume = (-58)+((int)serbuf[5]+1)/4;
|
||||
sound_set_volume(global_settings.volume);
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Handle Mode 4 */
|
||||
|
@ -712,6 +821,37 @@ void iap_handlepkt(void)
|
|||
}
|
||||
}
|
||||
}
|
||||
/* Handle Mode 7 */
|
||||
else if (serbuf[1] == 0x07)
|
||||
{
|
||||
switch(serbuf[2])
|
||||
{
|
||||
/* tuner capabilities */
|
||||
case 0x02:
|
||||
{
|
||||
/* do nothing */
|
||||
|
||||
unsigned char data[] = {0x00, 0x27, 0x00};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
break;
|
||||
}
|
||||
/* actual tuner frequency */
|
||||
case 0x0A:
|
||||
/* fall through */
|
||||
/* tuner frequency from scan */
|
||||
case 0x13:
|
||||
{
|
||||
rmt_tuner_freq();
|
||||
break;
|
||||
}
|
||||
/* RDS station name 0x21 1E 00 + ASCII text*/
|
||||
case 0x21:
|
||||
{
|
||||
rmt_tuner_rds_data();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
serbuf[0] = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -193,6 +193,26 @@ const struct button_mapping button_context_recscreen[] = {
|
|||
}; /* button_context_recscreen */
|
||||
#endif
|
||||
|
||||
/** FM Radio Screen **/
|
||||
#if CONFIG_TUNER
|
||||
static const struct button_mapping button_context_radio[] = {
|
||||
{ ACTION_FM_MENU, BUTTON_SELECT | BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_FM_STOP, BUTTON_PLAY | BUTTON_REPEAT, BUTTON_PLAY },
|
||||
{ ACTION_FM_MODE, BUTTON_SELECT, BUTTON_NONE },
|
||||
{ ACTION_FM_EXIT, BUTTON_MENU | BUTTON_REL, BUTTON_NONE },
|
||||
{ ACTION_FM_PLAY, BUTTON_PLAY | BUTTON_REL, BUTTON_PLAY },
|
||||
{ ACTION_SETTINGS_INC, BUTTON_SCROLL_FWD, BUTTON_NONE },
|
||||
{ ACTION_SETTINGS_INCREPEAT,BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_SETTINGS_DEC, BUTTON_SCROLL_BACK, BUTTON_NONE },
|
||||
{ ACTION_SETTINGS_DECREPEAT,BUTTON_SCROLL_BACK|BUTTON_REPEAT,BUTTON_NONE },
|
||||
{ ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE },
|
||||
{ ACTION_STD_NEXTREPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE },
|
||||
{ ACTION_STD_PREVREPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS)
|
||||
}; /* button_context_radio */
|
||||
#endif
|
||||
|
||||
#ifdef USB_ENABLE_HID
|
||||
static const struct button_mapping button_context_usb_hid[] = {
|
||||
{ ACTION_USB_HID_MODE_SWITCH_NEXT, BUTTON_SELECT|BUTTON_RIGHT|BUTTON_REL, BUTTON_SELECT|BUTTON_RIGHT },
|
||||
|
@ -311,6 +331,26 @@ static const struct button_mapping remote_button_context_wps[] = {
|
|||
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
|
||||
}; /* remote_button_context_wps */
|
||||
|
||||
static const struct button_mapping remote_button_context_tree[] = {
|
||||
{ ACTION_TREE_WPS, BUTTON_RC_PLAY|BUTTON_REL, BUTTON_RC_PLAY },
|
||||
{ ACTION_TREE_STOP, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_RC_PLAY },
|
||||
|
||||
LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD)
|
||||
}; /* remote_button_context_tree */
|
||||
|
||||
#if CONFIG_TUNER
|
||||
static const struct button_mapping remote_button_context_radio[] = {
|
||||
{ ACTION_FM_STOP, BUTTON_RC_PLAY | BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_FM_PLAY, BUTTON_RC_PLAY | BUTTON_REL, BUTTON_RC_PLAY },
|
||||
{ ACTION_STD_NEXT, BUTTON_RC_RIGHT|BUTTON_REL, BUTTON_RC_RIGHT },
|
||||
{ ACTION_STD_NEXTREPEAT, BUTTON_RC_RIGHT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
{ ACTION_STD_PREV, BUTTON_RC_LEFT|BUTTON_REL, BUTTON_RC_LEFT },
|
||||
{ ACTION_STD_PREVREPEAT, BUTTON_RC_LEFT|BUTTON_REPEAT, BUTTON_NONE },
|
||||
|
||||
LAST_ITEM_IN_LIST
|
||||
}; /* remote_button_context_radio */
|
||||
#endif
|
||||
|
||||
static const struct button_mapping* get_context_mapping_remote( int context )
|
||||
{
|
||||
context ^= CONTEXT_REMOTE;
|
||||
|
@ -319,6 +359,14 @@ static const struct button_mapping* get_context_mapping_remote( int context )
|
|||
{
|
||||
case CONTEXT_WPS:
|
||||
return remote_button_context_wps;
|
||||
case CONTEXT_TREE:
|
||||
case CONTEXT_CUSTOM|CONTEXT_TREE:
|
||||
return remote_button_context_tree;
|
||||
|
||||
#ifdef CONFIG_TUNER
|
||||
case CONTEXT_FM:
|
||||
return remote_button_context_radio;
|
||||
#endif
|
||||
default:
|
||||
return remote_button_context_standard;
|
||||
}
|
||||
|
@ -371,6 +419,10 @@ const struct button_mapping* get_context_mapping(int context)
|
|||
case CONTEXT_RECSCREEN:
|
||||
return button_context_recscreen;
|
||||
#endif
|
||||
#if CONFIG_TUNER
|
||||
case CONTEXT_FM:
|
||||
return button_context_radio;
|
||||
#endif
|
||||
#ifdef USB_ENABLE_HID
|
||||
case CONTEXT_USB_HID:
|
||||
return button_context_usb_hid;
|
||||
|
|
|
@ -49,6 +49,9 @@
|
|||
#ifdef HAVE_RECORDING
|
||||
#include "recording.h"
|
||||
#endif
|
||||
#ifdef IPOD_ACCESSORY_PROTOCOL
|
||||
#include "iap.h"
|
||||
#endif
|
||||
#include "talk.h"
|
||||
#include "tuner.h"
|
||||
#include "power.h"
|
||||
|
@ -114,6 +117,15 @@
|
|||
#define FM_MODE
|
||||
#define FM_EXIT
|
||||
#define FM_PLAY
|
||||
|
||||
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
||||
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
|
||||
#define FM_MENU
|
||||
#define FM_STOP
|
||||
#define FM_EXIT
|
||||
#define FM_PLAY
|
||||
#define FM_MODE
|
||||
|
||||
#endif
|
||||
|
||||
#define RADIO_SCAN_MODE 0
|
||||
|
@ -586,7 +598,6 @@ int radio_screen(void)
|
|||
end_search();
|
||||
talk = true;
|
||||
}
|
||||
|
||||
trigger_cpu_boost();
|
||||
}
|
||||
|
||||
|
@ -873,6 +884,33 @@ int radio_screen(void)
|
|||
|
||||
default:
|
||||
default_event_handler(button);
|
||||
#ifdef HAVE_RDS_CAP
|
||||
if (tuner_get(RADIO_EVENT))
|
||||
update_screen = true;
|
||||
#endif
|
||||
if (!tuner_get(RADIO_PRESENT))
|
||||
{
|
||||
#if CONFIG_CODEC != SWCODEC && !defined(SIMULATOR)
|
||||
if(audio_status() == AUDIO_STATUS_RECORD)
|
||||
audio_stop();
|
||||
#endif
|
||||
keep_playing = false;
|
||||
done = true;
|
||||
ret_val = GO_TO_ROOT;
|
||||
if(presets_changed)
|
||||
{
|
||||
if(yesno_pop(ID2P(LANG_FM_SAVE_CHANGES)))
|
||||
{
|
||||
if(filepreset[0] == '\0')
|
||||
save_preset_list();
|
||||
else
|
||||
radio_save_presets();
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the preset list on exit. */
|
||||
clear_preset_list();
|
||||
}
|
||||
break;
|
||||
} /*switch(button)*/
|
||||
|
||||
|
@ -895,11 +933,11 @@ int radio_screen(void)
|
|||
{
|
||||
screens[i].set_viewport(&vp[i]);
|
||||
peak_meter_screen(&screens[i],0,
|
||||
STATUSBAR_HEIGHT + fh*(top_of_screen + 4),
|
||||
fh);
|
||||
STATUSBAR_HEIGHT + fh*(top_of_screen + 4),
|
||||
fh);
|
||||
screens[i].update_rect(0,
|
||||
STATUSBAR_HEIGHT + fh*(top_of_screen + 4),
|
||||
screens[i].getwidth(), fh);
|
||||
STATUSBAR_HEIGHT + fh*(top_of_screen + 4),
|
||||
screens[i].getwidth(), fh);
|
||||
screens[i].set_viewport(NULL);
|
||||
}
|
||||
}
|
||||
|
@ -963,7 +1001,18 @@ int radio_screen(void)
|
|||
str(LANG_RADIO_SCAN_MODE));
|
||||
FOR_NB_SCREENS(i)
|
||||
screens[i].puts_scroll(0, top_of_screen + 3, buf);
|
||||
#ifndef SIMULATOR
|
||||
#ifdef HAVE_RDS_CAP
|
||||
snprintf(buf, 128, "%s",tuner_get_rds_info(RADIO_RDS_NAME));
|
||||
FOR_NB_SCREENS(i)
|
||||
screens[i].puts_scroll(0, top_of_screen + 4, buf);
|
||||
|
||||
snprintf(buf, 128, "%s",tuner_get_rds_info(RADIO_RDS_TEXT));
|
||||
FOR_NB_SCREENS(i)
|
||||
screens[i].puts_scroll(0, top_of_screen + 5, buf);
|
||||
#endif
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
#if CONFIG_CODEC != SWCODEC
|
||||
if(audio_status() == AUDIO_STATUS_RECORD)
|
||||
{
|
||||
|
@ -1498,6 +1547,7 @@ static int scan_presets(void *viewports)
|
|||
curr_freq = fmr->freq_min;
|
||||
num_presets = 0;
|
||||
memset(presets, 0, sizeof(presets));
|
||||
|
||||
tuner_set(RADIO_MUTE, 1);
|
||||
|
||||
while(curr_freq <= fmr->freq_max)
|
||||
|
@ -1563,7 +1613,6 @@ static int fm_recording_screen(void)
|
|||
/* switch recording source to FMRADIO for the duration */
|
||||
int rec_source = global_settings.rec_source;
|
||||
global_settings.rec_source = AUDIO_SRC_FMRADIO;
|
||||
|
||||
ret = recording_screen(true);
|
||||
|
||||
/* safe to reset as changing sources is prohibited here */
|
||||
|
@ -1649,7 +1698,7 @@ MAKE_MENU(radio_settings_menu, ID2P(LANG_FM_MENU), NULL,
|
|||
static bool radio_menu(void)
|
||||
{
|
||||
return do_menu(&radio_settings_menu, NULL, NULL, false) ==
|
||||
MENU_ATTACHED_USB;
|
||||
MENU_ATTACHED_USB;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -61,6 +61,7 @@ kjer Kjell Ericson
|
|||
kkurbjun Karl Kurbjun
|
||||
kugel Thomas Martitz
|
||||
lamed Shachar Liberman
|
||||
laurent Gautier
|
||||
learman Magnus Holmgren
|
||||
len0x Anton Oleynikov
|
||||
lenzone10 Alessio Lenzi
|
||||
|
|
|
@ -201,6 +201,7 @@ drivers/rtc/rtc_d2.c
|
|||
#endif /* (CONFIG_RTC == RTC_) */
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
#ifndef BOOTLOADER
|
||||
/* Tuner */
|
||||
#if CONFIG_TUNER
|
||||
tuner.c
|
||||
|
@ -221,8 +222,12 @@ drivers/tuner/tea5767.c
|
|||
#if (CONFIG_TUNER & SI4700)
|
||||
drivers/tuner/si4700.c
|
||||
#endif /* (CONFIG_TUNER & SI4700) */
|
||||
#if (CONFIG_TUNER & IPOD_REMOTE_TUNER)
|
||||
drivers/tuner/ipod_remote_tuner.c
|
||||
#endif /* (CONFIG_TUNER & IPOD_REMOTE_TUNER) */
|
||||
#endif /*SIMULATOR */
|
||||
#endif /* CONFIG_TUNER */
|
||||
#endif /* BOOTLOADER */
|
||||
|
||||
/* Sound */
|
||||
#if CONFIG_CODEC != SWCODEC
|
||||
|
|
444
firmware/drivers/tuner/ipod_remote_tuner.c
Normal file
444
firmware/drivers/tuner/ipod_remote_tuner.c
Normal file
|
@ -0,0 +1,444 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
* tuner for the ipod fm remote and other ipod remote tuners
|
||||
*
|
||||
* Copyright (C) 2009 Laurent Gautier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "kernel.h"
|
||||
#include "iap.h"
|
||||
#include "tuner.h" /* tuner abstraction interface */
|
||||
#include "adc.h"
|
||||
#include "settings.h"
|
||||
|
||||
static bool powered = false;
|
||||
|
||||
static unsigned char tuner_param = 0x00, old_tuner_param = 0xFF;
|
||||
/* temp var for tests to avoid looping execution in submenus settings*/
|
||||
int mono_mode = -1, old_region = -1;
|
||||
|
||||
int radio_present = 0;
|
||||
int tuner_frequency = 0;
|
||||
int tuner_signal_power = 0;
|
||||
int radio_tuned = 0;
|
||||
int rds_event = 0;
|
||||
|
||||
char rds_radioname[9];
|
||||
char rds_radioinfo[70]; /* do we need more? */
|
||||
|
||||
union FRQ {
|
||||
unsigned long int frequency_radio;
|
||||
char data_frequency[4];
|
||||
}Frequency;
|
||||
|
||||
void rmt_tuner_freq(void)
|
||||
{
|
||||
char tempdata[4];
|
||||
tempdata[0] = serbuf[6];
|
||||
tempdata[1] = serbuf[5];
|
||||
tempdata[2] = serbuf[4];
|
||||
tempdata[3] = serbuf[3];
|
||||
|
||||
memcpy(Frequency.data_frequency,tempdata,4);
|
||||
tuner_frequency = (Frequency.frequency_radio*1000);
|
||||
radio_tuned = 1;
|
||||
rmt_tuner_signal_power(serbuf[7]);
|
||||
}
|
||||
|
||||
void rmt_tuner_set_freq(int curr_freq)
|
||||
{
|
||||
if (curr_freq != tuner_frequency)
|
||||
{
|
||||
radio_tuned = 0;
|
||||
tuner_signal_power = 0;
|
||||
/* clear rds name and info */
|
||||
memset(rds_radioname,' ',sizeof(rds_radioname));
|
||||
memset(rds_radioinfo,' ',sizeof(rds_radioinfo));
|
||||
/* ex: 00 01 63 14 = 90.9MHz */
|
||||
unsigned char data[] = {0x07, 0x0B, 0x00, 0x01, 0x63, 0x14};
|
||||
|
||||
if (curr_freq != 0)
|
||||
{
|
||||
curr_freq = curr_freq / 1000;
|
||||
char tempdata[4];
|
||||
|
||||
Frequency.frequency_radio = curr_freq;
|
||||
tempdata[0] = Frequency.data_frequency[3];
|
||||
tempdata[1] = Frequency.data_frequency[2];
|
||||
tempdata[2] = Frequency.data_frequency[1];
|
||||
tempdata[3] = Frequency.data_frequency[0];
|
||||
|
||||
memcpy(data+2,tempdata,4);
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rmt_tuner_signal_power(unsigned char value)
|
||||
{
|
||||
tuner_signal_power = (int)(value);
|
||||
}
|
||||
|
||||
void rmt_tuner_sleep(int state)
|
||||
{
|
||||
if (state == 0)
|
||||
{
|
||||
/* tuner HW on */
|
||||
unsigned char data[] = {0x07, 0x05, 0x01};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
/* boost gain */
|
||||
unsigned char data1[] = {0x07, 0x24, 0x06 };
|
||||
iap_send_pkt(data1, sizeof(data1));
|
||||
/* set volume */
|
||||
unsigned char data2[] = {0x03, 0x09, 0x04, 0x00, 0x77 };
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
/* set rds on */
|
||||
unsigned char data3[] = {0x07, 0x20, 0x40, 0x00, 0x00, 0x10 };
|
||||
iap_send_pkt(data3, sizeof(data3));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* unbooste gain */
|
||||
unsigned char data[] = {0x07, 0x24, 0x00};
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
/* set rds off */
|
||||
unsigned char data1[] = {0x07, 0x20, 0x00, 0x00, 0x00, 0x00 };
|
||||
iap_send_pkt(data1, sizeof(data1));
|
||||
/* stop tuner HW */
|
||||
unsigned char data2[] = {0x07, 0x05, 0x00};
|
||||
iap_send_pkt(data2, sizeof(data2));
|
||||
}
|
||||
}
|
||||
|
||||
void rmt_tuner_scan(int param)
|
||||
{
|
||||
unsigned char data[] = {0x07, 0x11, 0x08}; /* RSSI level */
|
||||
unsigned char updown = 0x00;
|
||||
radio_tuned = 0;
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
|
||||
if (param == 1)
|
||||
{
|
||||
updown = 0x07; /* scan up */
|
||||
}
|
||||
else if (param == -1)
|
||||
{
|
||||
updown = 0x08; /* scan down */
|
||||
}
|
||||
else if (param == 10)
|
||||
{
|
||||
updown = 0x01; /* scan up starting from beginning of the band */
|
||||
}
|
||||
unsigned char data1[] = {0x07, 0x12, updown};
|
||||
iap_send_pkt(data1, sizeof(data1));
|
||||
}
|
||||
|
||||
void rmt_tuner_mute(int value)
|
||||
{
|
||||
/* mute flag off (play) */
|
||||
unsigned char data[] = {0x03, 0x09, 0x03, 0x01};
|
||||
if (value)
|
||||
{
|
||||
/* mute flag on (pause) */
|
||||
data[3] = 0x02;
|
||||
}
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
}
|
||||
|
||||
void rmt_tuner_region(int region)
|
||||
{
|
||||
if (region != old_region)
|
||||
{
|
||||
unsigned char data[] = {0x07, 0x08, 0x00};
|
||||
if (region == 2)
|
||||
{
|
||||
data[2] = 0x02; /* japan band */
|
||||
}
|
||||
else
|
||||
{
|
||||
data[2] = 0x01; /* us eur band */
|
||||
}
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
sleep(HZ/100);
|
||||
old_region = region;
|
||||
}
|
||||
}
|
||||
|
||||
/* set stereo/mono, deemphasis, delta freq... */
|
||||
void rmt_tuner_set_param(unsigned char tuner_param)
|
||||
{
|
||||
if(tuner_param != old_tuner_param)
|
||||
{
|
||||
unsigned char data[] = {0x07, 0x0E, 0x00};
|
||||
|
||||
data[2] = tuner_param;
|
||||
iap_send_pkt(data, sizeof(data));
|
||||
old_tuner_param = tuner_param;
|
||||
}
|
||||
}
|
||||
|
||||
void set_deltafreq(int delta)
|
||||
{
|
||||
tuner_param &= 0xFC;
|
||||
switch (delta)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
/* 100KHz */
|
||||
tuner_param |= 0x01;
|
||||
break;
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
/* 50KHz */
|
||||
tuner_param |= 0x02;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
/* 200KHz */
|
||||
tuner_param |= 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_deemphasis(int deemphasis)
|
||||
{
|
||||
tuner_param &= 0xBF;
|
||||
switch (deemphasis)
|
||||
{
|
||||
case 1:
|
||||
{
|
||||
tuner_param |= 0x40;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
tuner_param |= 0x00;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void set_mono(int value)
|
||||
{
|
||||
tuner_param &= 0xEF;
|
||||
|
||||
if (value != mono_mode)
|
||||
{
|
||||
tuner_param |= 0x10;
|
||||
rmt_tuner_set_param(tuner_param);
|
||||
sleep(HZ/100);
|
||||
mono_mode = value;
|
||||
}
|
||||
}
|
||||
|
||||
bool reply_timeout(void)
|
||||
{
|
||||
int timeout = 0;
|
||||
|
||||
sleep(HZ/50);
|
||||
do
|
||||
{
|
||||
iap_handlepkt();
|
||||
sleep(HZ/50);
|
||||
timeout++;
|
||||
}
|
||||
while((ipod_rmt_tuner_get(RADIO_TUNED) == 0) && (timeout < TIMEOUT_VALUE));
|
||||
|
||||
if (timeout >= TIMEOUT_VALUE)
|
||||
return true;
|
||||
else return false;
|
||||
}
|
||||
|
||||
void rmt_tuner_rds_data(void)
|
||||
{
|
||||
if (serbuf[3] == 0x1E)
|
||||
{
|
||||
strlcpy(rds_radioname,serbuf+5,8);
|
||||
}
|
||||
else if(serbuf[3] == 0x04)
|
||||
{
|
||||
strlcpy(rds_radioinfo,serbuf+5,(serbuf[0]-4));
|
||||
}
|
||||
rds_event = 1;
|
||||
}
|
||||
|
||||
/* tuner abstraction layer: set something to the tuner */
|
||||
int ipod_rmt_tuner_set(int setting, int value)
|
||||
{
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_SLEEP:
|
||||
{
|
||||
rmt_tuner_sleep(value);
|
||||
sleep(HZ/2);
|
||||
break;
|
||||
}
|
||||
|
||||
case RADIO_FREQUENCY:
|
||||
{
|
||||
rmt_tuner_set_freq(value);
|
||||
if (reply_timeout() == true)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case RADIO_SCAN_FREQUENCY:
|
||||
{
|
||||
const struct fm_region_data * const fmr =
|
||||
&fm_region_data[global_settings.fm_region];
|
||||
|
||||
/* case: scan for presets, back to beginning of the band */
|
||||
if ((radio_tuned == 1) && (value == fmr->freq_min))
|
||||
{
|
||||
tuner_set(RADIO_FREQUENCY,value);
|
||||
}
|
||||
|
||||
/* scan through frequencies */
|
||||
if (radio_tuned == 1)
|
||||
{
|
||||
/* scan down */
|
||||
if(value < tuner_frequency)
|
||||
rmt_tuner_scan(-1);
|
||||
/* scan up */
|
||||
else
|
||||
rmt_tuner_scan(1);
|
||||
|
||||
if (reply_timeout() == true)
|
||||
return 0;
|
||||
radio_tuned = 0;
|
||||
}
|
||||
|
||||
if (tuner_frequency == value)
|
||||
{
|
||||
radio_tuned = 1;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
radio_tuned = 0;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
case RADIO_MUTE:
|
||||
{
|
||||
/* mute flag sent to accessory */
|
||||
/* rmt_tuner_mute(value); */
|
||||
break;
|
||||
}
|
||||
|
||||
case RADIO_REGION:
|
||||
{
|
||||
const struct rmt_tuner_region_data *rd =
|
||||
&rmt_tuner_region_data[value];
|
||||
|
||||
rmt_tuner_region(rd->band);
|
||||
set_deltafreq(rd->spacing);
|
||||
set_deemphasis(rd->deemphasis);
|
||||
rmt_tuner_set_param(tuner_param);
|
||||
break;
|
||||
}
|
||||
|
||||
case RADIO_FORCE_MONO:
|
||||
{
|
||||
set_mono(value);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* tuner abstraction layer: read something from the tuner */
|
||||
int ipod_rmt_tuner_get(int setting)
|
||||
{
|
||||
int val = -1; /* default for unsupported query */
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_PRESENT:
|
||||
val = radio_present;
|
||||
if (val)
|
||||
{
|
||||
/* if accessory disconnected */
|
||||
if(adc_read(ADC_ACCESSORY) >= 10)
|
||||
{
|
||||
radio_present = 0;
|
||||
val = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
/* radio tuned: yes no */
|
||||
case RADIO_TUNED:
|
||||
val = 0;
|
||||
if (radio_tuned == 1)
|
||||
val = 1;
|
||||
break;
|
||||
|
||||
/* radio is always stereo */
|
||||
/* we can't know when it's in mono mode, depending of signal quality */
|
||||
/* except if it is forced in mono mode */
|
||||
case RADIO_STEREO:
|
||||
val = true;
|
||||
break;
|
||||
|
||||
case RADIO_EVENT:
|
||||
if (rds_event)
|
||||
{
|
||||
val = 1;
|
||||
rds_event = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
char* ipod_get_rds_info(int setting)
|
||||
{
|
||||
char *text = NULL;
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_RDS_NAME:
|
||||
text = rds_radioname;
|
||||
break;
|
||||
|
||||
case RADIO_RDS_TEXT:
|
||||
text = rds_radioinfo;
|
||||
break;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
bool tuner_power(bool status)
|
||||
{
|
||||
bool oldstatus = powered;
|
||||
powered = status;
|
||||
return oldstatus;
|
||||
}
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||
|
||||
/* define the bitmask of hardware sample rates */
|
||||
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
||||
|
@ -144,6 +144,10 @@
|
|||
#define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
|
||||
/* Define Apple remote tuner */
|
||||
#define CONFIG_TUNER IPOD_REMOTE_TUNER
|
||||
#define HAVE_RDS_CAP
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5020 */
|
||||
#define CONFIG_CPU PP5020
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||
|
||||
/* define the bitmask of hardware sample rates */
|
||||
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
||||
|
@ -121,6 +121,10 @@
|
|||
/* define this if the unit can be powered or charged via USB */
|
||||
#define HAVE_USB_POWER
|
||||
|
||||
/* Define Apple remote tuner */
|
||||
#define CONFIG_TUNER IPOD_REMOTE_TUNER
|
||||
#define HAVE_RDS_CAP
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5020 */
|
||||
#define CONFIG_CPU PP5020
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||
|
||||
/* define the bitmask of hardware sample rates */
|
||||
#define HW_SAMPR_CAPS (SAMPR_CAP_44)
|
||||
|
@ -134,6 +134,10 @@
|
|||
#define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
|
||||
/* Define Apple remote tuner */
|
||||
#define CONFIG_TUNER IPOD_REMOTE_TUNER
|
||||
#define HAVE_RDS_CAP
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5022 */
|
||||
#define CONFIG_CPU PP5022
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
/* Define bitmask of input sources - recordable bitmask can be defined
|
||||
explicitly if different */
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN)
|
||||
#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_LINEIN | SRC_CAP_FMRADIO)
|
||||
|
||||
/* define the bitmask of hardware sample rates */
|
||||
#define HW_SAMPR_CAPS (SAMPR_CAP_48 | SAMPR_CAP_44 | SAMPR_CAP_32 | \
|
||||
|
@ -155,6 +155,10 @@
|
|||
#define CURRENT_RECORD 35 /* FIXME: this needs adjusting */
|
||||
#endif
|
||||
|
||||
/* Define Apple remote tuner */
|
||||
#define CONFIG_TUNER IPOD_REMOTE_TUNER
|
||||
#define HAVE_RDS_CAP
|
||||
|
||||
/* Define this if you have a PortalPlayer PP5022 */
|
||||
#define CONFIG_CPU PP5022
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
#define SI4700 0x08 /* Silicon Labs */
|
||||
#define TEA5760 0x10 /* Philips */
|
||||
#define LV240000 0x20 /* Sanyo */
|
||||
#define IPOD_REMOTE_TUNER 0x40 /* Apple */
|
||||
|
||||
/* CONFIG_CODEC */
|
||||
#define MAS3587F 3587
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
#ifndef __IAP_H__
|
||||
#define __IAP_H__
|
||||
|
||||
#define RX_BUFLEN 260
|
||||
#define TX_BUFLEN 128
|
||||
|
||||
extern int iap_getc(unsigned char x);
|
||||
extern void iap_write_pkt(unsigned char data, int len);
|
||||
extern void iap_setup(int ratenum);
|
||||
|
@ -27,5 +30,7 @@ extern void iap_bitrate_set(int ratenum);
|
|||
extern void iap_periodic(void);
|
||||
extern void iap_handlepkt(void);
|
||||
extern void iap_track_changed(void *ignored);
|
||||
extern void iap_send_pkt(const unsigned char * data, int len);
|
||||
extern unsigned char serbuf[RX_BUFLEN];
|
||||
|
||||
#endif
|
||||
|
|
75
firmware/export/ipod_remote_tuner.h
Normal file
75
firmware/export/ipod_remote_tuner.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: ipod_remote_tuner.h
|
||||
* Tuner header for the ipod remote tuner and others remote tuners
|
||||
*
|
||||
* Copyright (C) 2009 Laurent Gautier
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef _IPOD_REMOTE_TUNER_H_
|
||||
#define _IPOD_REMOTE_TUNER_H_
|
||||
|
||||
#define HAVE_RADIO_REGION
|
||||
#define TIMEOUT_VALUE 20
|
||||
|
||||
extern int radio_present;
|
||||
extern int tuner_frequency;
|
||||
extern int tuner_signal_power;
|
||||
extern int radio_tuned;
|
||||
|
||||
/* update tuner state: plugged or unplugged when in radio mode */
|
||||
extern void rmt_tuner_region(int region);
|
||||
extern void rmt_tuner_set_freq(int curr_freq);
|
||||
extern void rmt_tuner_freq(void);
|
||||
extern void rmt_tuner_scan(int direction);
|
||||
|
||||
/* tuner mode state: ON or OFF */
|
||||
extern void rmt_tuner_sleep(int state);
|
||||
|
||||
/* parameters are stereo/mono, deemphasis, delta freq... */
|
||||
extern void rmt_tuner_set_param(unsigned char tuner_param);
|
||||
|
||||
extern void rmt_tuner_mute(int value);
|
||||
extern void rmt_tuner_signal_power(unsigned char value);
|
||||
|
||||
extern void rmt_tuner_rds_data(void);
|
||||
|
||||
struct rmt_tuner_region_data
|
||||
{
|
||||
/* 0: 50us, 1: 75us */
|
||||
unsigned char deemphasis;
|
||||
/* 0: europe, 1: japan (BL in TEA spec)*/
|
||||
unsigned char band;
|
||||
/* 0: us/australia (200kHz), 1: europe/japan (100kHz), 2: (50kHz) */
|
||||
unsigned char spacing;
|
||||
} __attribute__((packed));
|
||||
|
||||
extern const struct rmt_tuner_region_data
|
||||
rmt_tuner_region_data[TUNER_NUM_REGIONS];
|
||||
|
||||
int ipod_rmt_tuner_set(int setting, int value);
|
||||
int ipod_rmt_tuner_get(int setting);
|
||||
char* ipod_get_rds_info(int setting);
|
||||
|
||||
|
||||
#ifndef CONFIG_TUNER_MULTI
|
||||
#define tuner_set ipod_rmt_tuner_set
|
||||
#define tuner_get ipod_rmt_tuner_get
|
||||
#define tuner_get_rds_info ipod_get_rds_info
|
||||
#endif
|
||||
|
||||
#endif /* _IPOD_REMOTE_TUNER_H_ */
|
|
@ -33,7 +33,7 @@ enum
|
|||
RADIO_MUTE,
|
||||
RADIO_FORCE_MONO,
|
||||
RADIO_SCAN_FREQUENCY,
|
||||
|
||||
|
||||
/* Put new general-purpose settings above this line */
|
||||
__RADIO_SET_STANDARD_LAST
|
||||
};
|
||||
|
@ -44,11 +44,25 @@ enum
|
|||
RADIO_PRESENT = 0,
|
||||
RADIO_TUNED,
|
||||
RADIO_STEREO,
|
||||
/* RADIO_EVENT is an event that requests a screen update */
|
||||
RADIO_EVENT,
|
||||
|
||||
/* Put new general-purpose readback values above this line */
|
||||
__RADIO_GET_STANDARD_LAST
|
||||
};
|
||||
|
||||
#ifdef HAVE_RDS_CAP
|
||||
/** Readback from the tuner RDS layer **/
|
||||
enum
|
||||
{
|
||||
RADIO_RDS_NAME,
|
||||
RADIO_RDS_TEXT,
|
||||
|
||||
/* Put new general-purpose readback values above this line */
|
||||
__RADIO_GET_RDS_INFO_STANDARD_LAST
|
||||
};
|
||||
#endif
|
||||
|
||||
/** Tuner regions **/
|
||||
|
||||
/* Basic region information */
|
||||
|
@ -114,6 +128,11 @@ extern int (*tuner_get)(int setting);
|
|||
#include "si4700.h"
|
||||
#endif
|
||||
|
||||
/* Apple remote tuner */
|
||||
#if (CONFIG_TUNER & IPOD_REMOTE_TUNER)
|
||||
#include "ipod_remote_tuner.h"
|
||||
#endif
|
||||
|
||||
#endif /* SIMULATOR */
|
||||
|
||||
/* Additional messages that get enumerated after tuner driver headers */
|
||||
|
|
|
@ -104,11 +104,17 @@ void audio_input_mux(int source, unsigned flags)
|
|||
if (!recording)
|
||||
audiohw_set_recvol(0x17, 0x17, AUDIO_GAIN_LINEIN);
|
||||
#endif
|
||||
|
||||
if (source == last_source && recording == last_recording)
|
||||
break;
|
||||
|
||||
last_recording = recording;
|
||||
|
||||
#if defined(IPOD_REMOTE_TUNER)
|
||||
/* Ipod FM tuner is in the remote connected to line-in */
|
||||
audiohw_enable_recording(false); /* source line */
|
||||
audiohw_set_monitor(true); /* enable bypass mode */
|
||||
#else
|
||||
if (recording)
|
||||
{
|
||||
audiohw_set_monitor(false); /* disable bypass mode */
|
||||
|
@ -119,6 +125,7 @@ void audio_input_mux(int source, unsigned flags)
|
|||
audiohw_disable_recording();
|
||||
audiohw_set_monitor(true); /* enable bypass mode */
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
#endif
|
||||
} /* end switch */
|
||||
|
|
|
@ -89,17 +89,31 @@ const struct si4700_region_data si4700_region_data[TUNER_NUM_REGIONS] =
|
|||
};
|
||||
#endif /* (CONFIG_TUNER & SI4700) */
|
||||
|
||||
#if (CONFIG_TUNER & IPOD_REMOTE_TUNER)
|
||||
const struct rmt_tuner_region_data
|
||||
rmt_tuner_region_data[TUNER_NUM_REGIONS] =
|
||||
{
|
||||
[REGION_EUROPE] = { 1, 0, 1 }, /* 50uS, US/Europe band, 100kHz spacing */
|
||||
[REGION_US_CANADA] = { 0, 0, 0 }, /* 75uS, US/Europe band, 200kHz spacing */
|
||||
[REGION_JAPAN] = { 1, 2, 1 }, /* 50uS, Japanese band, 100kHz spacing */
|
||||
[REGION_KOREA] = { 1, 0, 0 }, /* 50uS, US/Europe band, 200kHz spacing */
|
||||
[REGION_ITALY] = { 1, 0, 2 }, /* 50uS, US/Europe band, 50kHz spacing */
|
||||
[REGION_OTHER] = { 1, 0, 2 }, /* 50uS, US/Europe band, 50kHz spacing */
|
||||
};
|
||||
#endif /* (CONFIG_TUNER & IPOD_REMOTE_TUNER) */
|
||||
|
||||
#ifdef CONFIG_TUNER_MULTI
|
||||
int (*tuner_set)(int setting, int value);
|
||||
int (*tuner_get)(int setting);
|
||||
#define TUNER_TYPE_CASE(type, set, get, ...) \
|
||||
|
||||
#define TUNER_TYPE_CASE(type, set, get, ...) \
|
||||
case type: \
|
||||
tuner_set = set; \
|
||||
tuner_get = get; \
|
||||
__VA_ARGS__; \
|
||||
break;
|
||||
#else
|
||||
#define TUNER_TYPE_CASE(type, set, get, ...) \
|
||||
#define TUNER_TYPE_CASE(type, set, get, ...) \
|
||||
__VA_ARGS__;
|
||||
#endif /* CONFIG_TUNER_MULTI */
|
||||
|
||||
|
@ -139,5 +153,4 @@ void tuner_init(void)
|
|||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* SIMULATOR */
|
||||
|
|
Loading…
Reference in a new issue