예제 #1
0
static void si4700_sleep(int snooze)
{
    if (snooze)
    {
        /** power down **/
        /* ENABLE high, DISABLE high */
        si4700_write_set(POWERCFG,
                         POWERCFG_DISABLE | POWERCFG_ENABLE);
        /* Bits self-clear once placed in powerdown. */
        cache[POWERCFG] &= ~(POWERCFG_DISABLE | POWERCFG_ENABLE);
    }
    else
    {
        /** power up **/
        /* ENABLE high, DISABLE low */
        si4700_write_masked(POWERCFG, POWERCFG_ENABLE,
                            POWERCFG_DISABLE | POWERCFG_ENABLE);
        sleep(110 * HZ / 1000);

        /* init register cache */
        si4700_read(16);

#if SI4700_GPIO_SETUP != 0
        si4700_write_masked(SYSCONFIG1, SI4700_GPIO_SETUP, 
                            SYSCONFIG1_GPIO1 | SYSCONFIG1_GPIO2 |
                            SYSCONFIG1_GPIO3);
#endif
        si4700_write_masked(SYSCONFIG2,
                            SYSCONFIG2_SKEETHw(SEEK_THRESHOLD) |
                            SYSCONFIG2_VOLUMEw(0xF),
                            SYSCONFIG2_VOLUME | SYSCONFIG2_SEEKTH);
    }
}
예제 #2
0
파일: si4700.c 프로젝트: kugel-/rockbox
/* tuner abstraction layer: set something to the tuner */
int si4700_set(int setting, int value)
{
    int val = 1;

    if(!tuner_powered() && setting != RADIO_SLEEP)
        return -1;

    mutex_lock(&fmr_mutex);

    switch(setting)
    {
        case RADIO_SLEEP:
            if (value != 2)
                si4700_sleep(value);
            /* else actually it's 'pause' */
            break;

        case RADIO_FREQUENCY:
#ifdef HAVE_RDS_CAP
            rds_reset();
#endif
            si4700_set_frequency(value);
            break;

        case RADIO_SCAN_FREQUENCY:
#ifdef HAVE_RDS_CAP
            rds_reset();
#endif
            si4700_set_frequency(value);
            val = si4700_tuned();
            break;

        case RADIO_MUTE:
            si4700_write_masked(POWERCFG, value ? 0 : POWERCFG_DMUTE,
                                POWERCFG_DMUTE);
            break;

        case RADIO_REGION:
            si4700_set_region(value);
            break;

        case RADIO_FORCE_MONO:
            si4700_write_masked(POWERCFG, value ? POWERCFG_MONO : 0,
                                POWERCFG_MONO);
            break;
            
        default:
            val = -1;
            break;
    }

    mutex_unlock(&fmr_mutex);

    return val;
}
예제 #3
0
파일: si4700.c 프로젝트: kugel-/rockbox
static void si4700_set_region(int region)
{
    const struct fm_region_data *rd = &fm_region_data[region];

    int band = (rd->freq_min == 76000000) ? 2 : 0;
    int spacing = (100000 / rd->freq_step);
    int deemphasis = (rd->deemphasis == 50) ? SYSCONFIG1_DE : 0;

    uint16_t bandspacing = SYSCONFIG2_BANDw(band) |
                           SYSCONFIG2_SPACEw(spacing);
    si4700_write_masked(SYSCONFIG1, deemphasis, SYSCONFIG1_DE);
    si4700_write_masked(SYSCONFIG2, bandspacing,
                        SYSCONFIG2_BAND | SYSCONFIG2_SPACE);
}
예제 #4
0
static void si4700_set_region(int region)
{
    const struct fm_region_data *rd = &fm_region_data[region];

    int band = (rd->freq_min == 76000000) ? 2 : 0;
    int spacing = (100000 / rd->freq_step);
    int deemphasis = (rd->deemphasis == 50) ? SYSCONFIG1_DE : 0;

    uint16_t bandspacing = SYSCONFIG2_BANDw(band) |
                           SYSCONFIG2_SPACEw(spacing);
    uint16_t oldbs = cache[SYSCONFIG2] & (SYSCONFIG2_BAND | SYSCONFIG2_SPACE);

    si4700_write_masked(SYSCONFIG1, deemphasis, SYSCONFIG1_DE);
    si4700_write_masked(SYSCONFIG2, bandspacing,
                        SYSCONFIG2_BAND | SYSCONFIG2_SPACE);

    /* Retune if this region change would change the channel number. */
    if (oldbs != bandspacing)
        si4700_set_frequency(curr_frequency);
}
예제 #5
0
/* tuner abstraction layer: set something to the tuner */
int si4700_set(int setting, int value)
{
    switch(setting)
    {
        case RADIO_SLEEP:
            if (value != 2)
                si4700_sleep(value);
            /* else actually it's 'pause' */
            break;

        case RADIO_FREQUENCY:
            si4700_set_frequency(value);
            break;

        case RADIO_SCAN_FREQUENCY:
            si4700_set_frequency(value);
            return si4700_tuned();

        case RADIO_MUTE:
            si4700_write_masked(POWERCFG, value ? 0 : POWERCFG_DMUTE,
                                POWERCFG_DMUTE);
            break;

        case RADIO_REGION:
            si4700_set_region(value);
            break;

        case RADIO_FORCE_MONO:
            si4700_write_masked(POWERCFG, value ? POWERCFG_MONO : 0,
                                POWERCFG_MONO);
            break;

        default:
            return -1;
    }

    return 1;
}
예제 #6
0
파일: si4700.c 프로젝트: kugel-/rockbox
static void si4700_sleep(int snooze)
{
    if (snooze)
    {
        /** power down **/
#ifdef HAVE_RDS_CAP        
        if (cache[CHIPID] & CHIPID_DEV_0) {
            si4700_rds_powerup(false);
            si4700_write_clear(SYSCONFIG1, SYSCONFIG1_RDS | SYSCONFIG1_RDSIEN);
        }
#endif

        /* ENABLE high, DISABLE high */
        si4700_write_set(POWERCFG,
                         POWERCFG_DISABLE | POWERCFG_ENABLE);
        /* Bits self-clear once placed in powerdown. */
        cache[POWERCFG] &= ~(POWERCFG_DISABLE | POWERCFG_ENABLE);

        tuner_power(false);
    }
    else
    {
        tuner_power(true);
        /* read all registers */
        si4700_read(16);
#ifdef SI4700_USE_INTERNAL_OSCILLATOR
        /* Enable the internal oscillator
          (Si4702-16 needs this register to be initialised to 0x100) */
        si4700_write_set(TEST1, TEST1_XOSCEN | 0x100);
        sleep(HZ/2);
#endif
        /** power up **/
        /* ENABLE high, DISABLE low */
        si4700_write_masked(POWERCFG, POWERCFG_ENABLE,
                            POWERCFG_DISABLE | POWERCFG_ENABLE);
        sleep(110 * HZ / 1000);

        /* init register cache */
        si4700_read(16);

#ifdef SI4700_USE_MO_ST_I
        si4700_write_masked(SYSCONFIG1, SYSCONFIG1_GPIO3_MO_ST_I,
                            SYSCONFIG1_GPIO3);
#endif
        /* set mono->stereo switching RSSI range to lowest setting */
        si4700_write_masked(SYSCONFIG1, SYSCONFIG1_BLNDADJ_19_37_RSSI, 
                            SYSCONFIG1_BLNDADJ);

        si4700_write_masked(SYSCONFIG2,
                            SYSCONFIG2_SKEETHw(SEEK_THRESHOLD) |
                            SYSCONFIG2_VOLUMEw(0xF),
                            SYSCONFIG2_VOLUME | SYSCONFIG2_SEEKTH);

#ifdef HAVE_RDS_CAP
        /* enable RDS and RDS interrupt if supported (bit 9 of CHIPID) */
        if (cache[CHIPID] & CHIPID_DEV_0) {
            /* Is Si4701/2/3 - Enable RDS and interrupt */
            si4700_write_set(SYSCONFIG1, SYSCONFIG1_RDS | SYSCONFIG1_RDSIEN);
            si4700_write_masked(SYSCONFIG1, SYSCONFIG1_GPIO2_STC_RDS_I,
                                            SYSCONFIG1_GPIO2);
            si4700_rds_powerup(true);
        }
#endif
    }
}