e200: Tuner driver needs to yield alot and also be mutexed. FM debug screen got broken again and was ignoring cancellation and not drawing the lines.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13896 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
a42a346789
commit
dc051248be
6 changed files with 149 additions and 62 deletions
|
@ -1942,11 +1942,10 @@ static bool dbg_save_roms(void)
|
|||
|
||||
#ifndef SIMULATOR
|
||||
#if CONFIG_TUNER
|
||||
int radio_lines = 0;
|
||||
static int radio_callback(int btn, struct gui_synclist *lists)
|
||||
{
|
||||
(void)btn;(void)lists;
|
||||
radio_lines = 0;
|
||||
int radio_lines = 0;
|
||||
|
||||
if (radio_hardware_present())
|
||||
{
|
||||
snprintf(debug_list_messages[radio_lines++], DEBUG_MSG_LEN,
|
||||
|
@ -1966,10 +1965,14 @@ static int radio_callback(int btn, struct gui_synclist *lists)
|
|||
"if_set: %d Hz", (lv24020lp_get(LV24020LP_IF_SET) ) );
|
||||
snprintf(debug_list_messages[radio_lines++], DEBUG_MSG_LEN,
|
||||
"sd_set: %d Hz", (lv24020lp_get(LV24020LP_SD_SET) ) );
|
||||
|
||||
if (btn != ACTION_STD_CANCEL)
|
||||
btn = ACTION_REDRAW;
|
||||
#endif
|
||||
#if (CONFIG_TUNER & S1A0903X01)
|
||||
snprintf(debug_list_messages[radio_lines++], DEBUG_MSG_LEN,
|
||||
"Samsung regs: %08X", s1a0903x01_get(RADIO_ALL));
|
||||
/* This one doesn't return dynamic data atm */
|
||||
#endif
|
||||
#if (CONFIG_TUNER & TEA5767)
|
||||
struct tea5767_dbg_info info;
|
||||
|
@ -1985,16 +1988,21 @@ static int radio_callback(int btn, struct gui_synclist *lists)
|
|||
(unsigned)info.write_regs[0], (unsigned)info.write_regs[1],
|
||||
(unsigned)info.write_regs[2], (unsigned)info.write_regs[3],
|
||||
(unsigned)info.write_regs[4]);
|
||||
|
||||
if (btn != ACTION_STD_CANCEL)
|
||||
btn = ACTION_REDRAW;
|
||||
#endif
|
||||
btn = ACTION_REDRAW;
|
||||
|
||||
gui_synclist_set_nb_items(lists, radio_lines);
|
||||
}
|
||||
else
|
||||
snprintf(debug_list_messages[radio_lines++], DEBUG_MSG_LEN, "HW detected: no");
|
||||
snprintf(debug_list_messages[0], DEBUG_MSG_LEN, "HW detected: no");
|
||||
|
||||
return btn;
|
||||
}
|
||||
static bool dbg_fm_radio(void)
|
||||
{
|
||||
dbg_list("FM Radio",radio_lines, 1,
|
||||
dbg_list("FM Radio", 1, 1,
|
||||
radio_callback, dbg_listmessage_getname);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "thread.h"
|
||||
#include "kernel.h"
|
||||
#include "tuner.h" /* tuner abstraction interface */
|
||||
#include "power.h"
|
||||
#include "fmradio.h" /* physical interface driver */
|
||||
#include "sound.h"
|
||||
#include "pp5024.h"
|
||||
|
@ -31,6 +32,8 @@
|
|||
|
||||
#ifndef BOOTLOADER
|
||||
|
||||
static struct mutex tuner_mtx;
|
||||
|
||||
#if 0
|
||||
/* define to enable tuner logging */
|
||||
#define SANYO_TUNER_LOG
|
||||
|
@ -338,6 +341,10 @@ static void lv24020lp_write(unsigned int address, unsigned int data)
|
|||
break;
|
||||
}
|
||||
|
||||
/* Check if interface is turned on */
|
||||
if (!(tuner_status & TUNER_POWERED))
|
||||
return;
|
||||
|
||||
address = lv24020lp_begin_write(address);
|
||||
|
||||
/* data first */
|
||||
|
@ -365,6 +372,10 @@ static unsigned int lv24020lp_read(unsigned int address)
|
|||
int i;
|
||||
unsigned int toread;
|
||||
|
||||
/* Check if interface is turned on */
|
||||
if (!(tuner_status & TUNER_POWERED))
|
||||
return 0;
|
||||
|
||||
address = lv24020lp_begin_write(address);
|
||||
|
||||
/* address */
|
||||
|
@ -433,9 +444,6 @@ static int tuner_measure(unsigned char type, int scale, int duration)
|
|||
{
|
||||
int64_t finval;
|
||||
|
||||
if (!tuner_awake())
|
||||
return 0;
|
||||
|
||||
/* enable measuring */
|
||||
lv24020lp_write_or(MSRC_SEL, type);
|
||||
lv24020lp_write_and(CNT_CTRL, ~CNT_SEL);
|
||||
|
@ -463,19 +471,20 @@ static int tuner_measure(unsigned char type, int scale, int duration)
|
|||
else
|
||||
finval = scale*finval / duration;
|
||||
|
||||
/* This function takes a loooong time and other stuff needs
|
||||
running by now */
|
||||
yield();
|
||||
|
||||
return (int)finval;
|
||||
}
|
||||
|
||||
/* set the FM oscillator frequency */
|
||||
static void set_frequency(int freq)
|
||||
static bool set_frequency(int freq)
|
||||
{
|
||||
int coef, cap_value, osc_value;
|
||||
int f1, f2, x1, x2;
|
||||
int count;
|
||||
|
||||
if (!tuner_awake())
|
||||
return;
|
||||
|
||||
TUNER_LOG_OPEN();
|
||||
|
||||
TUNER_LOG("set_frequency(%d)\n", freq);
|
||||
|
@ -579,6 +588,8 @@ static void set_frequency(int freq)
|
|||
TUNER_LOG("\n");
|
||||
|
||||
TUNER_LOG_SYNC();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void fine_step_tune(int (*setcmp)(int regval), int regval, int step)
|
||||
|
@ -639,10 +650,10 @@ static int if_setcmp(int regval)
|
|||
/* This register is bounces around by a few hundred Hz and doesn't seem
|
||||
to be precisely tuneable. Just do 110000 +/- 500 since it's not very
|
||||
critical it seems. */
|
||||
if (abs(if_set - 109500) <= 500)
|
||||
if (abs(if_set - 110000) <= 500)
|
||||
return 0;
|
||||
|
||||
return if_set < 109500 ? -1 : 1;
|
||||
return if_set < 110000 ? -1 : 1;
|
||||
}
|
||||
|
||||
static int sd_setcmp(int regval)
|
||||
|
@ -666,8 +677,6 @@ static void set_sleep(bool sleep)
|
|||
(TUNER_PRESENT | TUNER_POWERED))
|
||||
return;
|
||||
|
||||
tuner_status |= TUNER_AWAKE;
|
||||
|
||||
enable_afc(false);
|
||||
|
||||
/* 2. Calibrate the IF frequency at 110 kHz: */
|
||||
|
@ -702,9 +711,79 @@ static void set_sleep(bool sleep)
|
|||
lv24020lp_write(STEREO_CTRL, FMCS_SET(7) | AUTOSSR);
|
||||
lv24020lp_write(PW_SCTRL, SS_CTRL_SET(3) | SM_CTRL_SET(1) |
|
||||
PW_RAD);
|
||||
|
||||
tuner_status |= TUNER_AWAKE;
|
||||
}
|
||||
|
||||
static int lp24020lp_tuned(void)
|
||||
{
|
||||
return RSS_FS(lv24020lp_read(RADIO_STAT)) < 0x1f;
|
||||
}
|
||||
|
||||
static int lv24020lp_debug_info(int setting)
|
||||
{
|
||||
int val = -1;
|
||||
|
||||
if (setting >= LV24020LP_DEBUG_FIRST && setting <= LV24020LP_DEBUG_LAST)
|
||||
{
|
||||
val = 0;
|
||||
|
||||
if (tuner_awake())
|
||||
{
|
||||
switch (setting)
|
||||
{
|
||||
/* tuner-specific debug info */
|
||||
case LV24020LP_CTRL_STAT:
|
||||
val = lv24020lp_read(CTRL_STAT);
|
||||
break;
|
||||
|
||||
case LV24020LP_REG_STAT:
|
||||
val = lv24020lp_read(RADIO_STAT);
|
||||
break;
|
||||
|
||||
case LV24020LP_MSS_FM:
|
||||
val = tuner_measure(MSS_FM, 1, 16);
|
||||
break;
|
||||
|
||||
case LV24020LP_MSS_IF:
|
||||
val = tuner_measure(MSS_IF, 1000, 16);
|
||||
break;
|
||||
|
||||
case LV24020LP_MSS_SD:
|
||||
val = tuner_measure(MSS_SD, 1000, 16);
|
||||
break;
|
||||
|
||||
case LV24020LP_IF_SET:
|
||||
val = if_set;
|
||||
break;
|
||||
|
||||
case LV24020LP_SD_SET:
|
||||
val = sd_set;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
/** Public interfaces **/
|
||||
void lv24020lp_init(void)
|
||||
{
|
||||
mutex_init(&tuner_mtx);
|
||||
}
|
||||
|
||||
void lv24020lp_lock(void)
|
||||
{
|
||||
mutex_lock(&tuner_mtx);
|
||||
}
|
||||
|
||||
void lv24020lp_unlock(void)
|
||||
{
|
||||
mutex_unlock(&tuner_mtx);
|
||||
}
|
||||
|
||||
/* This function expects the driver to be locked externally */
|
||||
void lv24020lp_power(bool status)
|
||||
{
|
||||
static const unsigned char tuner_defaults[][2] =
|
||||
|
@ -734,7 +813,7 @@ void lv24020lp_power(bool status)
|
|||
|
||||
if (status)
|
||||
{
|
||||
tuner_status |= TUNER_POWERED | TUNER_PRESENCE_CHECKED;
|
||||
tuner_status |= (TUNER_PRESENCE_CHECKED | TUNER_POWERED);
|
||||
|
||||
/* if tuner is present, CHIP ID is 0x09 */
|
||||
if (lv24020lp_read(CHIP_ID) == 0x09)
|
||||
|
@ -750,16 +829,16 @@ void lv24020lp_power(bool status)
|
|||
lv24020lp_write(tuner_defaults[i][0], tuner_defaults[i][1]);
|
||||
|
||||
/* Complete the startup calibration if the tuner is woken */
|
||||
udelay(100000);
|
||||
sleep(HZ/10);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tuner_status &= ~(TUNER_POWERED | TUNER_AWAKE);
|
||||
|
||||
/* Power off */
|
||||
if (tuner_status & TUNER_PRESENT)
|
||||
lv24020lp_write_and(PW_SCTRL, ~PW_RAD);
|
||||
|
||||
tuner_status &= ~(TUNER_POWERED | TUNER_AWAKE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -767,6 +846,8 @@ int lv24020lp_set(int setting, int value)
|
|||
{
|
||||
int val = 1;
|
||||
|
||||
mutex_lock(&tuner_mtx);
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_SLEEP:
|
||||
|
@ -780,7 +861,7 @@ int lv24020lp_set(int setting, int value)
|
|||
case RADIO_SCAN_FREQUENCY:
|
||||
/* TODO: really implement this */
|
||||
set_frequency(value);
|
||||
val = lv24020lp_get(RADIO_TUNED);
|
||||
val = lp24020lp_tuned();
|
||||
break;
|
||||
|
||||
case RADIO_MUTE:
|
||||
|
@ -791,13 +872,11 @@ int lv24020lp_set(int setting, int value)
|
|||
break;
|
||||
|
||||
case RADIO_REGION:
|
||||
{
|
||||
if (lv24020lp_region_data[value])
|
||||
lv24020lp_write_or(AUDIO_CTRL2, DEEMP);
|
||||
else
|
||||
lv24020lp_write_and(AUDIO_CTRL2, ~DEEMP);
|
||||
break;
|
||||
}
|
||||
|
||||
case RADIO_FORCE_MONO:
|
||||
if (value)
|
||||
|
@ -807,9 +886,11 @@ int lv24020lp_set(int setting, int value)
|
|||
break;
|
||||
|
||||
default:
|
||||
val = -1;
|
||||
value = -1;
|
||||
}
|
||||
|
||||
mutex_unlock(&tuner_mtx);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
@ -817,11 +898,13 @@ int lv24020lp_get(int setting)
|
|||
{
|
||||
int val = -1;
|
||||
|
||||
mutex_lock(&tuner_mtx);
|
||||
|
||||
switch(setting)
|
||||
{
|
||||
case RADIO_TUNED:
|
||||
/* TODO: really implement this */
|
||||
val = RSS_FS(lv24020lp_read(RADIO_STAT)) < 0x1f;
|
||||
val = lp24020lp_tuned();
|
||||
break;
|
||||
|
||||
case RADIO_STEREO:
|
||||
|
@ -833,38 +916,21 @@ int lv24020lp_get(int setting)
|
|||
bool fmstatus = true;
|
||||
|
||||
if (!(tuner_status & TUNER_PRESENCE_CHECKED))
|
||||
fmstatus = tuner_power(true);
|
||||
fmstatus = tuner_power_nolock(true);
|
||||
|
||||
val = (tuner_status & TUNER_PRESENT) != 0;
|
||||
|
||||
if (!fmstatus)
|
||||
tuner_power(false);
|
||||
tuner_power_nolock(false);
|
||||
break;
|
||||
}
|
||||
|
||||
/* tuner-specific debug info */
|
||||
case LV24020LP_CTRL_STAT:
|
||||
return lv24020lp_read(CTRL_STAT);
|
||||
|
||||
case LV24020LP_REG_STAT:
|
||||
return lv24020lp_read(RADIO_STAT);
|
||||
|
||||
case LV24020LP_MSS_FM:
|
||||
return tuner_measure(MSS_FM, 1, 16);
|
||||
|
||||
case LV24020LP_MSS_IF:
|
||||
return tuner_measure(MSS_IF, 1000, 16);
|
||||
|
||||
case LV24020LP_MSS_SD:
|
||||
return tuner_measure(MSS_SD, 1000, 16);
|
||||
|
||||
case LV24020LP_IF_SET:
|
||||
return if_set;
|
||||
|
||||
case LV24020LP_SD_SET:
|
||||
return sd_set;
|
||||
default:
|
||||
val = lv24020lp_debug_info(setting);
|
||||
}
|
||||
|
||||
mutex_unlock(&tuner_mtx);
|
||||
|
||||
return val;
|
||||
}
|
||||
#endif /* BOOTLOADER */
|
||||
|
|
|
@ -32,16 +32,17 @@
|
|||
#define LV24020LP_IF_SET (RADIO_GET_CHIP_FIRST+5)
|
||||
#define LV24020LP_SD_SET (RADIO_GET_CHIP_FIRST+6)
|
||||
|
||||
struct lv24020lp_region_data
|
||||
{
|
||||
unsigned char deemphasis;
|
||||
} __attribute__((packed));
|
||||
#define LV24020LP_DEBUG_FIRST LV24020LP_CTRL_STAT
|
||||
#define LV24020LP_DEBUG_LAST LV24020LP_SD_SET
|
||||
|
||||
const unsigned char lv24020lp_region_data[TUNER_NUM_REGIONS];
|
||||
|
||||
int lv24020lp_set(int setting, int value);
|
||||
int lv24020lp_get(int setting);
|
||||
void lv24020lp_power(bool status);
|
||||
void lv24020lp_init(void);
|
||||
void lv24020lp_lock(void);
|
||||
void lv24020lp_unlock(void);
|
||||
|
||||
#ifndef CONFIG_TUNER_MULTI
|
||||
#define tuner_set lv24020lp_set
|
||||
|
|
|
@ -49,6 +49,7 @@ bool spdif_powered(void);
|
|||
|
||||
#if CONFIG_TUNER
|
||||
extern bool tuner_power(bool status);
|
||||
extern bool tuner_power_nolock(bool status);
|
||||
extern bool tuner_powered(void);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -66,9 +66,11 @@ void ide_power_enable(bool on)
|
|||
/** Tuner **/
|
||||
static bool powered = false;
|
||||
|
||||
bool tuner_power(bool status)
|
||||
bool tuner_power_nolock(bool status)
|
||||
{
|
||||
bool old_status = powered;
|
||||
bool old_status;
|
||||
|
||||
old_status = powered;
|
||||
|
||||
if (status != old_status)
|
||||
{
|
||||
|
@ -115,6 +117,15 @@ bool tuner_power(bool status)
|
|||
return old_status;
|
||||
}
|
||||
|
||||
bool tuner_power(bool status)
|
||||
{
|
||||
bool old_status;
|
||||
lv24020lp_lock();
|
||||
old_status = tuner_power_nolock(status);
|
||||
lv24020lp_unlock();
|
||||
return old_status;
|
||||
}
|
||||
|
||||
bool tuner_powered(void)
|
||||
{
|
||||
return powered;
|
||||
|
|
|
@ -60,13 +60,15 @@ const struct tea5767_region_data tea5767_region_data[TUNER_NUM_REGIONS] =
|
|||
#ifdef CONFIG_TUNER_MULTI
|
||||
int (*tuner_set)(int setting, int value);
|
||||
int (*tuner_get)(int setting);
|
||||
#define TUNER_TYPE_CASE(type, set, get, region_data) \
|
||||
#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, region_data)
|
||||
#define TUNER_TYPE_CASE(type, set, get, ...) \
|
||||
__VA_ARGS__;
|
||||
#endif /* CONFIG_TUNER_MULTI */
|
||||
|
||||
void tuner_init(void)
|
||||
|
@ -79,19 +81,17 @@ void tuner_init(void)
|
|||
TUNER_TYPE_CASE(LV24020LP,
|
||||
lv24020lp_set,
|
||||
lv24020lp_get,
|
||||
lv24020lp_region_data)
|
||||
lv24020lp_init())
|
||||
#endif
|
||||
#if (CONFIG_TUNER & TEA5767)
|
||||
TUNER_TYPE_CASE(TEA5767,
|
||||
tea5767_set,
|
||||
tea5767_get,
|
||||
tea5767_region_data)
|
||||
tea5767_get)
|
||||
#endif
|
||||
#if (CONFIG_TUNER & S1A0903X01)
|
||||
TUNER_TYPE_CASE(S1A0903X01,
|
||||
s1a0903x01_set,
|
||||
s1a0903x01_get,
|
||||
NULL)
|
||||
s1a0903x01_get)
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue