/* tuner abstraction layer: read something from the tuner */ int s1a0903x01_get(int setting) { int val = -1; switch(setting) { case RADIO_PRESENT: if (fm_present == -1) { #ifdef HAVE_TUNER_PWR_CTRL bool fmstatus = tuner_power(true); #endif /* 5kHz, 7.2MHz crystal, test mode 1 */ fmradio_set(2, 0x140885); fm_present = (fmradio_read(0) == 0x140885); #ifdef HAVE_TUNER_PWR_CTRL if (!fmstatus) tuner_power(false); #endif } val = fm_present; break; case RADIO_TUNED: val = fmradio_read(3); val = abs(10700 - ((val & 0x7ffff) / 8)) < 50; /* convert to kHz */ break; case RADIO_STEREO: val = fmradio_read(3); val = ((val & 0x100000) ? true : false); break; } return val; }
int lv24020lp_get(int setting) { int val = -1; const unsigned char fst[7] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f}; unsigned char fst_ndx, fs; mutex_lock(&tuner_mtx); switch(setting) { case RADIO_TUNED: /* TODO: really implement this */ val = lp24020lp_tuned(); break; case RADIO_STEREO: val = (lv24020lp_read(RADIO_STAT) & RSS_MS) != 0; break; case RADIO_PRESENT: { bool fmstatus = true; if (!(tuner_status & TUNER_PRESENCE_CHECKED)) fmstatus = tuner_power(true); val = (tuner_status & TUNER_PRESENT) != 0; if (!fmstatus) tuner_power(false); break; } case RADIO_RSSI: fs = RSS_FS(lv24020lp_read(RADIO_STAT)); for(fst_ndx=0; fst_ndx<7; fst_ndx++) if(fs == fst[fst_ndx]) break; val = 75 - 10*fst_ndx; break; case RADIO_RSSI_MIN: val = RSSI_MIN; break; case RADIO_RSSI_MAX: val = RSSI_MAX; break; default: val = lv24020lp_debug_info(setting); } mutex_unlock(&tuner_mtx); return val; }
bool si4700_detect(void) { if (!tuner_present) { tuner_power(true); tuner_present = (si4700_read_reg(DEVICEID) == 0x1242); tuner_power(false); } return tuner_present; }
bool si4700_detect(void) { bool detected; tuner_power(true); detected = (si4700_read_reg(DEVICEID) == 0x1242); tuner_power(false); return detected; }
static void radio_off(void) { tuner_set(RADIO_MUTE, 1); tuner_set(RADIO_SLEEP, 1); /* low power mode, if available */ radio_status = FMRADIO_OFF; tuner_power(false); /* status update, power off if avail. */ }
void radio_start(void) { const struct fm_region_data *fmr; bool start_paused; if(radio_status == FMRADIO_PLAYING) return; fmr = &fm_region_data[global_settings.fm_region]; start_paused = radio_status & FMRADIO_START_PAUSED; /* clear flag before any yielding */ radio_status &= ~FMRADIO_START_PAUSED; if(radio_status == FMRADIO_OFF) tuner_power(true); curr_freq = global_status.last_frequency * fmr->freq_step + fmr->freq_min; tuner_set(RADIO_SLEEP, 0); /* wake up the tuner */ if(radio_status == FMRADIO_OFF) { #ifdef HAVE_RADIO_REGION tuner_set(RADIO_REGION, global_settings.fm_region); #endif tuner_set(RADIO_FORCE_MONO, global_settings.fm_force_mono); } tuner_set(RADIO_FREQUENCY, curr_freq); #ifdef HAVE_RADIO_MUTE_TIMEOUT { unsigned long mute_timeout = current_tick + HZ; if (radio_status != FMRADIO_OFF) { /* paused */ mute_timeout += HZ; } while(!tuner_get(RADIO_STEREO) && !tuner_get(RADIO_TUNED)) { if(TIME_AFTER(current_tick, mute_timeout)) break; yield(); } } #endif /* keep radio from sounding initially */ if(!start_paused) tuner_set(RADIO_MUTE, 0); radio_status = FMRADIO_PLAYING; } /* radio_start */
void si4700_init(void) { /* check device id */ if (si4700_detect()) { tuner_present = true; tuner_power(true); /* read all registers */ si4700_read(16); si4700_sleep(0); #ifdef 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 si4700_sleep(1); tuner_power(false); } }
static void set_sleep(bool sleep) { tuner_power(!sleep); if (sleep || tuner_awake()) return; if ((tuner_status & (TUNER_PRESENT | TUNER_POWERED)) != (TUNER_PRESENT | TUNER_POWERED)) return; enable_afc(false); /* 2. Calibrate the IF frequency at 110 kHz: */ lv24020lp_write_clear(RADIO_CTRL2, IF_PM_L); fine_step_tune(if_setcmp, 0x80, 8); lv24020lp_write_set(RADIO_CTRL2, IF_PM_L); /* 3. Calibrate the stereo decoder clock at 38.3 kHz: */ lv24020lp_write_set(STEREO_CTRL, SD_PM); fine_step_tune(sd_setcmp, 0x80, 8); lv24020lp_write_clear(STEREO_CTRL, SD_PM); /* calculate FM tuning coefficients */ lv24020lp_write(FM_CAP, sw_cap_low); lv24020lp_write(FM_OSC, sw_osc_low); coef_00 = calculate_coef(tuner_measure(MSS_FM, 1, 64)); lv24020lp_write(FM_CAP, sw_cap_high); coef_01 = calculate_coef(tuner_measure(MSS_FM, 1, 64)); lv24020lp_write(FM_CAP, sw_cap_low); lv24020lp_write(FM_OSC, sw_osc_high); coef_10 = calculate_coef(tuner_measure(MSS_FM, 1, 64)); lv24020lp_write(FM_CAP, sw_cap_high); coef_11 = calculate_coef(tuner_measure(MSS_FM, 1, 64)); /* set various audio level settings */ lv24020lp_write(AUDIO_CTRL1, TONE_LVL_SET(0) | VOL_LVL_SET(0)); lv24020lp_write_set(RADIO_CTRL2, AGCSP); lv24020lp_write_set(RADIO_CTRL3, VOLSH); 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 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 } }