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); } }
/* 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; }
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); }
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); }
/* 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; }
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 } }