From fd11471a3f9bfbb5f5bdf22866e861bae56ad8ea Mon Sep 17 00:00:00 2001 From: Maurus Cuelenaere Date: Mon, 1 Jun 2009 21:00:31 +0000 Subject: [PATCH] Onda VX747: try at implementing FM tuner support git-svn-id: svn://svn.rockbox.org/rockbox/trunk@21160 a1c6a512-1295-4272-9138-f99709370657 --- apps/keymaps/keymap-ondavx747.c | 16 +++++ firmware/SOURCES | 1 + firmware/export/config-ondavx747.h | 8 +++ .../target/mips/ingenic_jz47xx/codec-jz4740.c | 66 ++++++++++++++++++- .../mips/ingenic_jz47xx/fmradio-i2c-jz4740.c | 37 +++++++++++ .../target/mips/ingenic_jz47xx/i2c-jz4740.c | 40 ++++++----- 6 files changed, 149 insertions(+), 19 deletions(-) create mode 100644 firmware/target/mips/ingenic_jz47xx/fmradio-i2c-jz4740.c diff --git a/apps/keymaps/keymap-ondavx747.c b/apps/keymaps/keymap-ondavx747.c index 0b7f1b3870..0b0339acac 100644 --- a/apps/keymaps/keymap-ondavx747.c +++ b/apps/keymaps/keymap-ondavx747.c @@ -101,6 +101,7 @@ static const struct button_mapping button_context_settings_right_is_inc[] = { }; /* button_context_settingsgraphical */ static const struct button_mapping button_context_yesno[] = { + { ACTION_YESNO_ACCEPT, BUTTON_MENU, BUTTON_NONE }, LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_settings_yesno */ @@ -142,6 +143,19 @@ static const struct button_mapping button_context_pitchscreen[] = { LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_STD) }; /* button_context_pitchcreen */ +/** FM Radio Screen **/ +static const struct button_mapping button_context_radio[] = { + { ACTION_STD_PREV, BUTTON_VOL_DOWN, BUTTON_NONE }, + { ACTION_STD_PREVREPEAT, BUTTON_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_STD_NEXT, BUTTON_VOL_UP, BUTTON_NONE }, + { ACTION_STD_NEXTREPEAT, BUTTON_VOL_UP|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_FM_MENU, BUTTON_MENU|BUTTON_REPEAT, BUTTON_NONE }, + { ACTION_FM_PRESET, BUTTON_MENU|BUTTON_REL, BUTTON_NONE }, + { ACTION_FM_MODE, BUTTON_POWER|BUTTON_REL, BUTTON_POWER }, + { ACTION_FM_EXIT, BUTTON_POWER|BUTTON_REPEAT, BUTTON_NONE }, + LAST_ITEM_IN_LIST__NEXTLIST(CONTEXT_SETTINGS) +}; /* button_context_radio */ + static const struct button_mapping button_context_keyboard[] = { { ACTION_KBD_PAGE_FLIP, BUTTON_MENU, BUTTON_NONE }, { ACTION_KBD_CURSOR_LEFT, BUTTON_VOL_DOWN, BUTTON_NONE }, @@ -201,6 +215,8 @@ const struct button_mapping* target_get_context_mapping(int context) case CONTEXT_YESNOSCREEN: return button_context_yesno; + case CONTEXT_FM: + return button_context_radio; case CONTEXT_BOOKMARKSCREEN: return button_context_bmark; case CONTEXT_QUICKSCREEN: diff --git a/firmware/SOURCES b/firmware/SOURCES index 8ebdcb79bd..3ee805eedd 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -1244,6 +1244,7 @@ drivers/qt1106.c target/mips/ingenic_jz47xx/ata-nand-jz4740.c target/mips/ingenic_jz47xx/ata-sd-jz4740.c target/mips/ingenic_jz47xx/debug-jz4740.c +target/mips/ingenic_jz47xx/fmradio-i2c-jz4740.c target/mips/ingenic_jz47xx/kernel-jz4740.c target/mips/ingenic_jz47xx/i2c-jz4740.c target/mips/ingenic_jz47xx/lcd-jz4740.c diff --git a/firmware/export/config-ondavx747.h b/firmware/export/config-ondavx747.h index b603e02c2b..d735c045e2 100644 --- a/firmware/export/config-ondavx747.h +++ b/firmware/export/config-ondavx747.h @@ -94,6 +94,10 @@ /* define this if you have a real-time clock */ #define CONFIG_RTC RTC_JZ47XX +/* Tuner config */ +#define CONFIG_TUNER TEA5767 +#define CONFIG_TUNER_XTAL 32768 + /* Define this for LCD backlight available */ #define HAVE_BACKLIGHT #define HAVE_BACKLIGHT_BRIGHTNESS @@ -122,6 +126,10 @@ /* Define this if you have the Jz4740 internal codec */ #define HAVE_JZ4740_CODEC +/* Define bitmask of input sources - recordable bitmask can be defined + explicitly if different */ +#define INPUT_SRC_CAPS (SRC_CAP_MIC | SRC_CAP_FMRADIO) + /* has no tone controls, so we use the software ones */ #define HAVE_SW_TONE_CONTROLS diff --git a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c index 6a0b6ae340..325a3734d8 100644 --- a/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/codec-jz4740.c @@ -20,9 +20,10 @@ ****************************************************************************/ #include "config.h" +#include "audio.h" +#include "audiohw.h" #include "jz4740.h" #include "system.h" -#include "audiohw.h" /* TODO */ const struct sound_settings_info audiohw_settings[] = { @@ -330,3 +331,66 @@ void audiohw_set_frequency(int freq) REG_ICDC_CDCCR2 = (REG_ICDC_CDCCR2 & ~ICDC_CDCCR2_SMPR(0xF)) | speed; } + +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; + static bool last_recording = false; + bool recording = flags & SRCF_RECORDING; + + switch (source) + { + default: /* playback - no recording */ + source = AUDIO_SRC_PLAYBACK; + case AUDIO_SRC_PLAYBACK: + audio_channels = 2; + if(source != last_source) + { + REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_HPMUTE)) + | (ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON); + } + break; + + case AUDIO_SRC_MIC: /* recording only */ + audio_channels = 1; + if(source != last_source) + { + REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_ELININ | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) + | (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_EMIC); + } + break; + + case AUDIO_SRC_FMRADIO: /* recording and playback */ + audio_channels = 2; + + if(source == last_source && recording == last_recording) + break; + + last_recording = recording; + + if(recording) + { + REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) + | (ICDC_CDCCR1_EADC | ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ); + } + else + { + REG_ICDC_CDCCR1 = (REG_ICDC_CDCCR1 & ~(ICDC_CDCCR1_EMIC | ICDC_CDCCR1_EDAC | ICDC_CDCCR1_EADC | + ICDC_CDCCR1_SW2ON | ICDC_CDCCR1_HPMUTE)) | (ICDC_CDCCR1_SW1ON | ICDC_CDCCR1_ELININ); + } + break; + } /* end switch */ + + last_source = source; +} /* audio_input_mux */ diff --git a/firmware/target/mips/ingenic_jz47xx/fmradio-i2c-jz4740.c b/firmware/target/mips/ingenic_jz47xx/fmradio-i2c-jz4740.c new file mode 100644 index 0000000000..995e3ae875 --- /dev/null +++ b/firmware/target/mips/ingenic_jz47xx/fmradio-i2c-jz4740.c @@ -0,0 +1,37 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2009 by Maurus Cuelenaere + * + * 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 "fmradio_i2c.h" +#include "i2c.h" + +/* fmradio i2c wrappers */ +void fmradio_i2c_init(void) +{ +} + +int fmradio_i2c_write(unsigned char address, const unsigned char* buf, int count) +{ + return i2c_write(address, buf, count); +} + +int fmradio_i2c_read(unsigned char address, unsigned char* buf, int count) +{ + return i2c_read(address, buf, count); +} diff --git a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c index 5df0e90683..79968889b9 100644 --- a/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c +++ b/firmware/target/mips/ingenic_jz47xx/i2c-jz4740.c @@ -20,6 +20,10 @@ * KIND, either express or implied. * ****************************************************************************/ +#include "config.h" +#include "system.h" +#include "jz4740.h" +#include "logf.h" /* * Jz4740 I2C routines. @@ -42,15 +46,9 @@ * */ -#include "config.h" -#include "system.h" -#include "jz4740.h" -#include "logf.h" - - /* I2C protocol */ #define I2C_READ 1 -#define I2C_WRITE 0 +#define I2C_WRITE 0 #define TIMEOUT 1000 @@ -84,7 +82,7 @@ static int i2c_put_data_nack(unsigned char data) while (__i2c_check_drf() != 0); while (!__i2c_transmit_ended()); while (timeout--); - + return 0; } #endif @@ -121,13 +119,13 @@ void i2c_setclk(unsigned int i2cclk) /* * I2C interface */ -void i2c_open(void) +static void i2c_open(void) { i2c_setclk(10000); /* default 10 KHz */ __i2c_enable(); } -void i2c_close(void) +static void i2c_close(void) { udelay(300); /* wait for STOP goes over. */ __i2c_disable(); @@ -137,21 +135,23 @@ int i2c_read(int device, unsigned char *buf, int count) { int cnt = count; int timeout = 5; - + device &= 0xFF; + i2c_open(); + L_try_again: if (timeout < 0) goto L_timeout; __i2c_send_nack(); /* Master does not send ACK, slave sends it */ - + __i2c_send_start(); if (i2c_put_data( (device << 1) | I2C_READ ) < 0) goto device_err; - + __i2c_send_ack(); /* Master sends ACK for continue reading */ - + while (cnt) { if (cnt == 1) @@ -170,7 +170,7 @@ L_try_again: __i2c_send_stop(); return count - cnt; - + device_err: timeout--; __i2c_send_stop(); @@ -179,6 +179,7 @@ device_err: L_timeout: __i2c_send_stop(); logf("Read I2C device 0x%2x failed.", device); + i2c_close(); return -1; } @@ -186,9 +187,11 @@ int i2c_write(int device, unsigned char *buf, int count) { int cnt = count; int timeout = 5; - + device &= 0xFF; + i2c_open(); + __i2c_send_nack(); /* Master does not send ACK, slave sends it */ W_try_again: @@ -200,7 +203,7 @@ W_try_again: __i2c_send_start(); if (i2c_put_data( (device << 1) | I2C_WRITE ) < 0) goto device_err; - + #if 0 //CONFIG_JZ_TPANEL_ATA2508 if (address == 0xff) { @@ -226,7 +229,7 @@ W_try_again: __i2c_send_stop(); return count - cnt; - + device_err: timeout--; __i2c_send_stop(); @@ -235,6 +238,7 @@ device_err: W_timeout: logf("Write I2C device 0x%2x failed.", device); __i2c_send_stop(); + i2c_close(); return -1; }