Skip to content

Commit e251e6c

Browse files
committed
spectrum scan for m88rs6060
1 parent ca99ffe commit e251e6c

File tree

4 files changed

+464
-25
lines changed

4 files changed

+464
-25
lines changed

drivers/media/dvb-frontends/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ drxd-objs := drxd_firm.o drxd_hard.o
2020
cxd2820r-objs := cxd2820r_core.o cxd2820r_c.o cxd2820r_t.o cxd2820r_t2.o
2121
drxk-objs := drxk_hard.o
2222
stv091x-objs := stv091x_chip.o stv091x_drv.o
23-
m88rs6060-objs := m88rs6060_drv.o m88rs6060_si5351.o
23+
m88rs6060-objs := m88rs6060_drv.o m88rs6060_si5351.o m88rs6060_fft.o
2424
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
2525
obj-$(CONFIG_DVB_STV0299) += stv0299.o
2626
obj-$(CONFIG_DVB_STB0899) += stb0899.o

drivers/media/dvb-frontends/m88rs6060_drv.c

Lines changed: 116 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2955,8 +2955,8 @@ static void m88rs6060_spi_write(struct dvb_frontend *fe,
29552955
static int m88rs6060_stop_task(struct dvb_frontend *fe)
29562956
{
29572957
struct m88rs6060_state* state = fe->demodulator_priv;
2958-
struct m88rs6060_spectrum_scan_state* ss = &state->scan_state;
2959-
struct m88rs6060_constellation_scan_state* cs = &state->constellation_scan_state;
2958+
struct spectrum_scan_state* ss = &state->spectrum_scan_state;
2959+
struct constellation_scan_state* cs = &state->constellation_scan_state;
29602960
if(ss->freq)
29612961
kfree(ss->freq);
29622962
if(ss->spectrum)
@@ -3032,6 +3032,116 @@ static enum dvbfe_algo m88rs6060_get_algo(struct dvb_frontend *fe)
30323032
}
30333033

30343034

3035+
static int m88rs6060_get_spectrum_scan_sweep(struct dvb_frontend* fe,
3036+
unsigned int *delay, enum fe_status *status)
3037+
{
3038+
struct m88rs6060_state* state = fe->demodulator_priv;
3039+
struct spectrum_scan_state* ss = &state->spectrum_scan_state;
3040+
struct dtv_frontend_properties* p = &fe->dtv_property_cache;
3041+
s32 pch_rf;
3042+
int i = 0;
3043+
u32 start_frequency = p->scan_start_frequency;
3044+
u32 end_frequency = p->scan_end_frequency;
3045+
//u32 bandwidth = end_frequency-start_frequency; //in kHz
3046+
3047+
uint32_t frequency;
3048+
uint32_t resolution = (p->scan_resolution>0) ? p->scan_resolution : 500; //in kHz
3049+
ss->spectrum_len = (end_frequency - start_frequency + resolution-1)/resolution;
3050+
ss->freq = kzalloc(ss->spectrum_len * (sizeof(ss->freq[0])), GFP_KERNEL);
3051+
ss->spectrum = kzalloc(ss->spectrum_len * (sizeof(ss->spectrum[0])), GFP_KERNEL);
3052+
if (!ss->freq || !ss->spectrum) {
3053+
return -ENOMEM;
3054+
}
3055+
ss->spectrum_present = true;
3056+
dprintk("demod: %d: range=[%d,%d]kHz num_freq=%d resolution=%dkHz\n", state->nr,
3057+
start_frequency, end_frequency, ss->spectrum_len, resolution);
3058+
3059+
//global reset
3060+
regmap_write(state->demod_regmap, 0x7, 0x80);
3061+
regmap_write(state->demod_regmap, 0x7, 0x00);
3062+
msleep(2);
3063+
m88rs6060_clear_stream(state);
3064+
msleep(2);
3065+
3066+
regmap_write(state->demod_regmap, 0xb2, 0x01); //reset microcontroller
3067+
regmap_write(state->demod_regmap, 0x00, 0x00); //chip id
3068+
3069+
3070+
for (i = 0; i < ss->spectrum_len; i++) {
3071+
if ((i% 20==19) && (kthread_should_stop() || dvb_frontend_task_should_stop(fe))) {
3072+
dprintk("exiting on should stop\n");
3073+
break;
3074+
}
3075+
ss->freq[i]= start_frequency +i*resolution;
3076+
frequency = ss->freq[i];
3077+
if(i==0) {
3078+
m88rs6060_set_demod(state, resolution, false);
3079+
}
3080+
rs6060_set_tuner(state, frequency / 1000, 2000, 3000);
3081+
m88rs6060_set_carrier_offset(state, frequency - (frequency/1000)*1000);
3082+
msleep(10);//m88rs6060_wait_for_analog_agc_lock(state);
3083+
m88rs6060_get_rf_level(state, frequency / 1000, &pch_rf);
3084+
ss->spectrum[i] = -10*pch_rf;
3085+
}
3086+
*status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|FE_HAS_SYNC|FE_HAS_LOCK;
3087+
return 0;
3088+
}
3089+
3090+
static int m88rs6060_spectrum_start(struct dvb_frontend* fe,
3091+
struct dtv_fe_spectrum* s,
3092+
unsigned int *delay, enum fe_status *status)
3093+
{
3094+
struct m88rs6060_state* state = fe->demodulator_priv;
3095+
struct spectrum_scan_state* ss = &state->spectrum_scan_state;
3096+
int ret=0;
3097+
m88rs6060_stop_task(fe);
3098+
3099+
s->scale = FE_SCALE_DECIBEL; //in units of 0.001dB
3100+
switch(s->spectrum_method) {
3101+
case SPECTRUM_METHOD_SWEEP:
3102+
default:
3103+
ret = m88rs6060_get_spectrum_scan_sweep(fe, delay, status);
3104+
break;
3105+
case SPECTRUM_METHOD_FFT:
3106+
ret = m88rs6060_get_spectrum_scan_fft(fe, delay, status);
3107+
s->num_freq = ss->spectrum_len;
3108+
break;
3109+
}
3110+
return -1;
3111+
}
3112+
3113+
static int m88rs6060_spectrum_get(struct dvb_frontend* fe, struct dtv_fe_spectrum* user)
3114+
{
3115+
struct m88rs6060_state* state = fe->demodulator_priv;
3116+
int error=0;
3117+
dprintk("num_freq=%d/%d num_cand=%d/%d freq=%p/%p rf=%p/%p\n",
3118+
user->num_freq , state->spectrum_scan_state.spectrum_len,
3119+
user->num_candidates, state->spectrum_scan_state.num_candidates,
3120+
user->freq, state->spectrum_scan_state.freq,
3121+
user->rf_level, state->spectrum_scan_state.spectrum);
3122+
if (user->num_freq> state->spectrum_scan_state.spectrum_len)
3123+
user->num_freq = state->spectrum_scan_state.spectrum_len;
3124+
if (user->num_candidates > state->spectrum_scan_state.num_candidates)
3125+
user->num_candidates = state->spectrum_scan_state.num_candidates;
3126+
if(state->spectrum_scan_state.freq && state->spectrum_scan_state.spectrum) {
3127+
if(user->freq && user->num_freq > 0 &&
3128+
copy_to_user((void __user*) user->freq, state->spectrum_scan_state.freq, user->num_freq * sizeof(__u32))) {
3129+
error = -EFAULT;
3130+
}
3131+
if(user->rf_level && user->num_freq > 0 &&
3132+
copy_to_user((void __user*) user->rf_level, state->spectrum_scan_state.spectrum, user->num_freq * sizeof(__s32))) {
3133+
error = -EFAULT;
3134+
}
3135+
if(user->candidates && user->num_candidates >0 &&
3136+
copy_to_user((void __user*) user->candidates,
3137+
state->spectrum_scan_state.candidates,
3138+
user->num_candidates * sizeof(struct spectral_peak_t))) {
3139+
error = -EFAULT;
3140+
}
3141+
} else
3142+
error = -EFAULT;
3143+
return error;
3144+
}
30353145

30363146
static const struct dvb_frontend_ops m88rs6060_ops = {
30373147
.delsys = {SYS_DVBS, SYS_DVBS2, SYS_AUTO},
@@ -3043,7 +3153,7 @@ static const struct dvb_frontend_ops m88rs6060_ops = {
30433153
.symbol_rate_max = 45000000,
30443154
.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO | FE_CAN_QPSK |
30453155
FE_CAN_RECOVER | FE_CAN_2G_MODULATION | FE_CAN_MULTISTREAM,
3046-
.extended_caps = /*FE_CAN_SPECTRUMSCAN | FE_CAN_IQ | */ FE_CAN_BLINDSEARCH
3156+
.extended_caps = FE_CAN_SPECTRUMSCAN | /* FE_CAN_IQ | */ FE_CAN_BLINDSEARCH
30473157
},
30483158

30493159
.tuner_ops = {
@@ -3069,6 +3179,9 @@ static const struct dvb_frontend_ops m88rs6060_ops = {
30693179
.spi_read = m88rs6060_spi_read,
30703180
.spi_write = m88rs6060_spi_write,
30713181
.stop_task = m88rs6060_stop_task,
3182+
.spectrum_start = m88rs6060_spectrum_start,
3183+
.spectrum_get = m88rs6060_spectrum_get,
3184+
30723185

30733186
};
30743187

0 commit comments

Comments
 (0)