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:
Michael Sevakis 2007-07-14 22:00:50 +00:00
parent a42a346789
commit dc051248be
6 changed files with 149 additions and 62 deletions

View file

@ -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;
}

View file

@ -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 */

View file

@ -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

View file

@ -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

View file

@ -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;

View file

@ -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
}
}