diff --git a/apps/audio_path.c b/apps/audio_path.c index dab43ebf42..9ef748382f 100644 --- a/apps/audio_path.c +++ b/apps/audio_path.c @@ -42,7 +42,7 @@ #endif #endif -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0)) #ifdef AUDIO_CPU_BOOST static void audio_cpu_boost(bool state) diff --git a/apps/debug_menu.c b/apps/debug_menu.c index e611694b5b..aec0a9a1a6 100644 --- a/apps/debug_menu.c +++ b/apps/debug_menu.c @@ -78,6 +78,11 @@ #endif #include "power.h" +#if defined(SAMSUNG_YPR0) && defined(CONFIG_TUNER) +#include "tuner.h" +#include "radio.h" +#endif + #ifdef HAVE_LCD_BITMAP #include "scrollbar.h" #include "peakmeter.h" diff --git a/apps/keymaps/keymap-ypr0.c b/apps/keymaps/keymap-ypr0.c index b5706760ba..306fd91e34 100644 --- a/apps/keymaps/keymap-ypr0.c +++ b/apps/keymaps/keymap-ypr0.c @@ -212,7 +212,24 @@ static const struct button_mapping button_context_keyboard[] = { }; /* button_context_keyboard */ static const struct button_mapping button_context_radio[] = { - LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) + { ACTION_FM_MENU, BUTTON_SELECT | BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_FM_PRESET, BUTTON_MENU | BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_FM_STOP, BUTTON_POWER | BUTTON_REL, BUTTON_POWER }, + { ACTION_FM_MODE, BUTTON_MENU | BUTTON_REL, BUTTON_MENU }, + { ACTION_FM_EXIT, BUTTON_BACK | BUTTON_REL, BUTTON_BACK }, + { ACTION_FM_PLAY, BUTTON_SELECT | BUTTON_REL, BUTTON_SELECT }, + { ACTION_FM_NEXT_PRESET, BUTTON_USER | BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_FM_PREV_PRESET, BUTTON_USER | BUTTON_LEFT, BUTTON_NONE }, + /* Volume */ + { ACTION_SETTINGS_INC, BUTTON_UP | BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_INCREPEAT, BUTTON_UP, BUTTON_NONE }, + { ACTION_SETTINGS_DEC, BUTTON_DOWN | BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_SETTINGS_DECREPEAT, BUTTON_DOWN, BUTTON_NONE }, + /* Tuning */ + { ACTION_STD_PREV, BUTTON_LEFT, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_LEFT | BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_RIGHT, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_RIGHT | BUTTON_REPEAT, BUTTON_NONE }, }; /* button_context_radio */ const struct button_mapping* get_context_mapping(int context) diff --git a/apps/radio/radio.c b/apps/radio/radio.c index 9f139f49a6..326e6a3bb0 100644 --- a/apps/radio/radio.c +++ b/apps/radio/radio.c @@ -127,6 +127,16 @@ #define FM_MODE #define FM_STOP +#elif (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD) +#define FM_MENU +#define FM_PRESET +#define FM_STOP +#define FM_MODE +#define FM_EXIT +#define FM_PLAY +#define FM_PREV_PRESET +#define FM_NEXT_PRESET + #endif /* presets.c needs these so keep unstatic or redo the whole thing! */ diff --git a/firmware/SOURCES b/firmware/SOURCES index eb49e3e581..54fde546dc 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -92,6 +92,10 @@ target/hosted/ypr0/backlight-ypr0.c target/hosted/ypr0/ascodec-ypr0.c target/hosted/ypr0/powermgmt-ypr0.c target/hosted/ypr0/gpio_ypr0.c +target/hosted/ypr0/audio-ypr0.c +#if CONFIG_TUNER +target/hosted/ypr0/radio-ypr0.c +#endif #endif /* Maemo specific files */ @@ -309,7 +313,7 @@ drivers/rtc/rtc_imx233.c /* Tuner */ #if CONFIG_TUNER tuner.c -#if (CONFIG_PLATFORM & PLATFORM_NATIVE) +#if ((CONFIG_PLATFORM & PLATFORM_NATIVE) || defined(SAMSUNG_YPR0)) #if (CONFIG_TUNER & LV24020LP) drivers/tuner/lv24020lp.c #endif /* (CONFIG_TUNER & LV24020LP) */ diff --git a/firmware/drivers/audio/as3514.c b/firmware/drivers/audio/as3514.c index 22609621df..5f18bc6ec1 100644 --- a/firmware/drivers/audio/as3514.c +++ b/firmware/drivers/audio/as3514.c @@ -156,8 +156,13 @@ void audiohw_preinit(void) as3514_write(AS3514_AUDIOSET3, AUDIOSET3_HPCM_on | AUDIOSET3_HP_LONGSTART); as3514_write(AS3543_DAC_IF, AS3543_DAC_INT_PLL); +#ifdef SAMSUNG_YPR0 + /* Select Line 1 for FM radio */ + as3514_clear(AS3514_LINE_IN1_R, LINE_IN_R_LINE_SELECT); +#else /* Select Line 2 for FM radio */ as3514_set(AS3514_LINE_IN1_R, LINE_IN_R_LINE_SELECT); +#endif /* Output SUM of microphone/line/DAC */ as3514_write(AS3514_HPH_OUT_R, HPH_OUT_R_HEADPHONES | HPH_OUT_R_HP_OUT_SUM); diff --git a/firmware/export/config/samsungypr0.h b/firmware/export/config/samsungypr0.h index 48e98e5b46..10d7aaecb8 100644 --- a/firmware/export/config/samsungypr0.h +++ b/firmware/export/config/samsungypr0.h @@ -75,7 +75,6 @@ //#define HAVE_RTC_RAM /* define this if you have a real-time clock */ -//#define CONFIG_RTC APPLICATION #define CONFIG_RTC RTC_AS3514 #define HAVE_RTC_ALARM @@ -103,9 +102,17 @@ #define HAVE_SW_TONE_CONTROLS -/* TODO: Make use of the si4703 tuner hardware */ -/* #define CONFIG_TUNER SI4700 */ -/* #define HAVE_TUNER_PWR_CTRL*/ +#define CONFIG_TUNER SI4700 +#define HAVE_TUNER_PWR_CTRL + +/* TODO: next step: enable RDS +#define HAVE_RDS_CAP +#define RDS_ISR_PROCESSING +*/ + +/* Define this for FM radio input available */ +#define HAVE_FMRADIO_IN +#define INPUT_SRC_CAPS SRC_CAP_FMRADIO /* We have a GPIO that detects it */ #define HAVE_HEADPHONE_DETECTION diff --git a/firmware/target/hosted/ypr0/audio-ypr0.c b/firmware/target/hosted/ypr0/audio-ypr0.c new file mode 100644 index 0000000000..dfd63ef5cd --- /dev/null +++ b/firmware/target/hosted/ypr0/audio-ypr0.c @@ -0,0 +1,69 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Bertrik Sikken + * + * 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 "system.h" +#include "cpu.h" +#include "audio.h" +#include "audiohw.h" +#include "sound.h" + +int audio_channels = 2; +int audio_output_source = AUDIO_SRC_PLAYBACK; + +void audio_set_output_source(int source) +{ + if ((unsigned)source >= AUDIO_NUM_SOURCES) + source = AUDIO_SRC_PLAYBACK; + + audio_output_source = source; +} /* audio_set_output_source */ + +void audio_input_mux(int source, unsigned flags) +{ + static int last_source = AUDIO_SRC_PLAYBACK; + + (void)flags; + + switch (source) + { + default: /* playback - no recording */ + source = AUDIO_SRC_PLAYBACK; + case AUDIO_SRC_PLAYBACK: + audio_channels = 2; + if (source != last_source) + { + audiohw_set_monitor(false); + + } + break; + + case AUDIO_SRC_FMRADIO: /* recording and playback */ + audio_channels = 2; + if (source == last_source) + break; + + audiohw_set_monitor(true); + break; + } /* end switch */ + + last_source = source; +} /* audio_input_mux */ + diff --git a/firmware/target/hosted/ypr0/powermgmt-ypr0.c b/firmware/target/hosted/ypr0/powermgmt-ypr0.c index 45ff2ae737..347e5fa146 100644 --- a/firmware/target/hosted/ypr0/powermgmt-ypr0.c +++ b/firmware/target/hosted/ypr0/powermgmt-ypr0.c @@ -24,6 +24,7 @@ #include "file.h" #include "adc.h" #include "sc900776.h" +#include "radio-ypr0.h" const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] = { @@ -37,7 +38,6 @@ const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] = }; /* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */ -/* FIXME: This is guessed. Make proper curve using battery_bench */ const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = { { 3450, 3502, 3550, 3587, 3623, 3669, 3742, 3836, 3926, 4026, 4200 } @@ -45,7 +45,6 @@ const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] = #if CONFIG_CHARGING /* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */ -/* FIXME: This is guessed. Make proper curve using battery_bench */ const unsigned short const percent_to_volt_charge[11] = { 3450, 3670, 3721, 3751, 3782, 3821, 3876, 3941, 4034, 4125, 4200 @@ -81,3 +80,29 @@ bool charging_state(void) /* dont indicate for > ~95% */ return ret && (_battery_voltage() <= charged_thres); } + +#if CONFIG_TUNER +static bool tuner_on = false; + +bool tuner_power(bool status) +{ + if (status != tuner_on) + { + tuner_on = status; + status = !status; + if (tuner_on) { + radiodev_open(); + } + else { + radiodev_close(); + } + } + + return status; +} + +bool tuner_powered(void) +{ + return tuner_on; +} +#endif /* #if CONFIG_TUNER */ \ No newline at end of file diff --git a/firmware/target/hosted/ypr0/radio-ypr0.c b/firmware/target/hosted/ypr0/radio-ypr0.c new file mode 100644 index 0000000000..c3597bd18c --- /dev/null +++ b/firmware/target/hosted/ypr0/radio-ypr0.c @@ -0,0 +1,66 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module wrapper for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) of Samsung YP-R0 + * + * Copyright (c) 2012 Lorenzo Miori + * + * 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 +#include +#include +#include "stdint.h" +#include "string.h" + +#include "radio-ypr0.h" + +static int radio_dev = -1; + +void radiodev_open(void) { + radio_dev = open("/dev/si470x", O_RDWR); +} + +void radiodev_close(void) { + close(radio_dev); +} + +/* High-level registers access */ +void si4709_write_reg(int addr, uint16_t value) { + sSi4709_t r = { .addr = addr, .value = value }; + ioctl(radio_dev, IOCTL_SI4709_WRITE_BYTE, &r); +} + +uint16_t si4709_read_reg(int addr) { + sSi4709_t r = { .addr = addr, .value = 0 }; + ioctl(radio_dev, IOCTL_SI4709_READ_BYTE, &r); + return r.value; +} + +/* Low-level i2c channel access */ +int fmradio_i2c_write(unsigned char address, unsigned char* buf, int count) +{ + (void)address; + sSi4709_i2c_t r = { .size = count, .buf = buf }; + return ioctl(radio_dev, IOCTL_SI4709_I2C_WRITE, &r); +} + +int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) +{ + (void)address; + sSi4709_i2c_t r = { .size = count, .buf = buf }; + return ioctl(radio_dev, IOCTL_SI4709_I2C_READ, &r); +} \ No newline at end of file diff --git a/firmware/target/hosted/ypr0/radio-ypr0.h b/firmware/target/hosted/ypr0/radio-ypr0.h new file mode 100644 index 0000000000..13bcb6dc72 --- /dev/null +++ b/firmware/target/hosted/ypr0/radio-ypr0.h @@ -0,0 +1,36 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module wrapper for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) of Samsung YP-R0 + * + * Copyright (c) 2012 Lorenzo Miori + * + * 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 __RADIO_YPR0_H__ +#define __RADIO_YPR0_H__ + +#include "si4709.h" +#include "stdint.h" +#include "rds.h" +#include "si4700.h" + +void radiodev_open(void); +void radiodev_close(void); +void si4709_write_reg(int addr, uint16_t value); +uint16_t si4709_read_reg(int addr); + +#endif /*__RADIO-YPR0_H__*/ \ No newline at end of file diff --git a/firmware/target/hosted/ypr0/si4709.h b/firmware/target/hosted/ypr0/si4709.h new file mode 100644 index 0000000000..c27472e856 --- /dev/null +++ b/firmware/target/hosted/ypr0/si4709.h @@ -0,0 +1,82 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * + * Module header for SI4709 FM Radio Chip, using /dev/si470x (si4709.ko) of Samsung YP-R0 + * + * Copyright (c) 2012 Lorenzo Miori + * + * 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 __SI4709_H__ +#define __SI4709_H__ + +#include "stdint.h" + +/* 7bits I2C address */ +#define SI4709_I2C_SLAVE_ADDR 0x10 + +#define SI4702_DEVICEID 0x00 +#define SI4702_CHIPID 0x01 +#define SI4702_POWERCFG 0x02 +#define SI4702_CHANNEL 0x03 +#define SI4702_SYSCONFIG1 0x04 +#define SI4702_SYSCONFIG2 0x05 +#define SI4702_SYSCONFIG3 0x06 +#define SI4702_TEST1 0x07 +#define SI4702_TEST2 0x08 +#define SI4702_B00TCONFIG 0x09 +#define SI4702_STATUSRSSI 0x0A +#define SI4702_READCHAN 0x0B +#define SI4709_REG_NUM 0x10 +#define SI4702_REG_BYTE (SI4709_REG_NUM * 2) +#define SI4702_DEVICE_ID 0x1242 +#define SI4702_RW_REG_NUM (SI4702_STATUSRSSI - SI4702_POWERCFG) +#define SI4702_RW_OFFSET \ + (SI4709_REG_NUM - SI4702_STATUSRSSI + SI4702_POWERCFG) +#define BYTE_TO_WORD(hi, lo) (((hi) << 8) & 0xFF00) | ((lo) & 0x00FF) + +typedef struct { + int addr; + uint16_t value; +}__attribute__((packed)) sSi4709_t; + +typedef struct { + int size; + unsigned char *buf; +}__attribute__((packed)) sSi4709_i2c_t; + +typedef enum +{ + IOCTL_SI4709_INIT = 0, + IOCTL_SI4709_CLOSE, + IOCTL_SI4709_WRITE_BYTE, + IOCTL_SI4709_READ_BYTE, + IOCTL_SI4709_I2C_WRITE, + IOCTL_SI4709_I2C_READ, + + E_IOCTL_SI4709_MAX +} eSi4709_ioctl_t; + +#define DRV_IOCTL_SI4709_MAGIC 'S' + +#define IOCTL_SI4709_INIT _IO(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_INIT) +#define IOCTL_SI4709_CLOSE _IO(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_CLOSE) +#define IOCTL_SI4709_WRITE_BYTE _IOW(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_WRITE_BYTE, sSi4709_t) +#define IOCTL_SI4709_READ_BYTE _IOR(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_READ_BYTE, sSi4709_t) +#define IOCTL_SI4709_I2C_WRITE _IOW(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_I2C_WRITE, sSi4709_i2c_t) +#define IOCTL_SI4709_I2C_READ _IOR(DRV_IOCTL_SI4709_MAGIC, IOCTL_SI4709_I2C_READ, sSi4709_i2c_t) + +#endif /* __SI4709_H__ */ \ No newline at end of file