0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/errno.h>
0012 #include <linux/i2c.h>
0013 #include <linux/init.h>
0014 #include <linux/kernel.h>
0015 #include <linux/module.h>
0016 #include <linux/printk.h>
0017 #include <linux/random.h>
0018 #include <linux/ratelimit.h>
0019 #include <linux/slab.h>
0020 #include <linux/string.h>
0021 #include <linux/workqueue.h>
0022
0023 #include <media/dvb_frontend.h>
0024
0025 #include "vidtv_demod.h"
0026
0027 #define POLL_THRD_TIME 2000
0028
0029 static const struct vidtv_demod_cnr_to_qual_s vidtv_demod_c_cnr_2_qual[] = {
0030
0031 { QAM_256, FEC_NONE, 34000, 38000},
0032 { QAM_64, FEC_NONE, 30000, 34000},
0033 };
0034
0035 static const struct vidtv_demod_cnr_to_qual_s vidtv_demod_s_cnr_2_qual[] = {
0036
0037 { QPSK, FEC_1_2, 7000, 10000},
0038 { QPSK, FEC_2_3, 9000, 12000},
0039 { QPSK, FEC_3_4, 10000, 13000},
0040 { QPSK, FEC_5_6, 11000, 14000},
0041 { QPSK, FEC_7_8, 12000, 15000},
0042 };
0043
0044 static const struct vidtv_demod_cnr_to_qual_s vidtv_demod_s2_cnr_2_qual[] = {
0045
0046 { QPSK, FEC_1_2, 9000, 12000},
0047 { QPSK, FEC_2_3, 11000, 14000},
0048 { QPSK, FEC_3_4, 12000, 15000},
0049 { QPSK, FEC_5_6, 12000, 15000},
0050 { QPSK, FEC_8_9, 13000, 16000},
0051 { QPSK, FEC_9_10, 13500, 16500},
0052 { PSK_8, FEC_2_3, 14500, 17500},
0053 { PSK_8, FEC_3_4, 16000, 19000},
0054 { PSK_8, FEC_5_6, 17500, 20500},
0055 { PSK_8, FEC_8_9, 19000, 22000},
0056 };
0057
0058 static const struct vidtv_demod_cnr_to_qual_s vidtv_demod_t_cnr_2_qual[] = {
0059
0060 { QPSK, FEC_1_2, 4100, 5900},
0061 { QPSK, FEC_2_3, 6100, 9600},
0062 { QPSK, FEC_3_4, 7200, 12400},
0063 { QPSK, FEC_5_6, 8500, 15600},
0064 { QPSK, FEC_7_8, 9200, 17500},
0065 { QAM_16, FEC_1_2, 9800, 11800},
0066 { QAM_16, FEC_2_3, 12100, 15300},
0067 { QAM_16, FEC_3_4, 13400, 18100},
0068 { QAM_16, FEC_5_6, 14800, 21300},
0069 { QAM_16, FEC_7_8, 15700, 23600},
0070 { QAM_64, FEC_1_2, 14000, 16000},
0071 { QAM_64, FEC_2_3, 19900, 25400},
0072 { QAM_64, FEC_3_4, 24900, 27900},
0073 { QAM_64, FEC_5_6, 21300, 23300},
0074 { QAM_64, FEC_7_8, 22000, 24000},
0075 };
0076
0077 static const struct vidtv_demod_cnr_to_qual_s *vidtv_match_cnr_s(struct dvb_frontend *fe)
0078 {
0079 const struct vidtv_demod_cnr_to_qual_s *cnr2qual = NULL;
0080 struct device *dev = fe->dvb->device;
0081 struct dtv_frontend_properties *c;
0082 u32 array_size = 0;
0083 u32 i;
0084
0085 c = &fe->dtv_property_cache;
0086
0087 switch (c->delivery_system) {
0088 case SYS_DVBT:
0089 case SYS_DVBT2:
0090 cnr2qual = vidtv_demod_t_cnr_2_qual;
0091 array_size = ARRAY_SIZE(vidtv_demod_t_cnr_2_qual);
0092 break;
0093
0094 case SYS_DVBS:
0095 cnr2qual = vidtv_demod_s_cnr_2_qual;
0096 array_size = ARRAY_SIZE(vidtv_demod_s_cnr_2_qual);
0097 break;
0098
0099 case SYS_DVBS2:
0100 cnr2qual = vidtv_demod_s2_cnr_2_qual;
0101 array_size = ARRAY_SIZE(vidtv_demod_s2_cnr_2_qual);
0102 break;
0103
0104 case SYS_DVBC_ANNEX_A:
0105 cnr2qual = vidtv_demod_c_cnr_2_qual;
0106 array_size = ARRAY_SIZE(vidtv_demod_c_cnr_2_qual);
0107 break;
0108
0109 default:
0110 dev_warn_ratelimited(dev,
0111 "%s: unsupported delivery system: %u\n",
0112 __func__,
0113 c->delivery_system);
0114 break;
0115 }
0116
0117 for (i = 0; i < array_size; i++)
0118 if (cnr2qual[i].modulation == c->modulation &&
0119 cnr2qual[i].fec == c->fec_inner)
0120 return &cnr2qual[i];
0121
0122 return NULL;
0123 }
0124
0125 static void vidtv_clean_stats(struct dvb_frontend *fe)
0126 {
0127 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0128
0129
0130
0131
0132 c->strength.len = 1;
0133 c->strength.stat[0].scale = FE_SCALE_DECIBEL;
0134 c->strength.stat[0].svalue = 0;
0135
0136
0137 c->cnr.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0138 c->cnr.stat[0].svalue = 0;
0139 c->cnr.len = 1;
0140
0141
0142 c->pre_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0143 c->pre_bit_error.stat[0].uvalue = 0;
0144 c->pre_bit_error.len = 1;
0145 c->pre_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0146 c->pre_bit_count.stat[0].uvalue = 0;
0147 c->pre_bit_count.len = 1;
0148 c->post_bit_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0149 c->post_bit_error.stat[0].uvalue = 0;
0150 c->post_bit_error.len = 1;
0151 c->post_bit_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0152 c->post_bit_count.stat[0].uvalue = 0;
0153 c->post_bit_count.len = 1;
0154 c->block_error.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0155 c->block_error.stat[0].uvalue = 0;
0156 c->block_error.len = 1;
0157 c->block_count.stat[0].scale = FE_SCALE_NOT_AVAILABLE;
0158 c->block_count.stat[0].uvalue = 0;
0159 c->block_count.len = 1;
0160 }
0161
0162 static void vidtv_demod_update_stats(struct dvb_frontend *fe)
0163 {
0164 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0165 struct vidtv_demod_state *state = fe->demodulator_priv;
0166 u32 scale;
0167
0168 if (state->status & FE_HAS_LOCK) {
0169 scale = FE_SCALE_COUNTER;
0170 c->cnr.stat[0].scale = FE_SCALE_DECIBEL;
0171 } else {
0172 scale = FE_SCALE_NOT_AVAILABLE;
0173 c->cnr.stat[0].scale = scale;
0174 }
0175
0176 c->pre_bit_error.stat[0].scale = scale;
0177 c->pre_bit_count.stat[0].scale = scale;
0178 c->post_bit_error.stat[0].scale = scale;
0179 c->post_bit_count.stat[0].scale = scale;
0180 c->block_error.stat[0].scale = scale;
0181 c->block_count.stat[0].scale = scale;
0182
0183
0184
0185
0186
0187
0188
0189
0190 c->strength.stat[0].svalue = state->tuner_cnr;
0191 c->strength.stat[0].svalue -= prandom_u32_max(state->tuner_cnr / 50);
0192 c->strength.stat[0].svalue -= 68000;
0193
0194 c->cnr.stat[0].svalue = state->tuner_cnr;
0195 c->cnr.stat[0].svalue -= prandom_u32_max(state->tuner_cnr / 50);
0196 }
0197
0198 static int vidtv_demod_read_status(struct dvb_frontend *fe,
0199 enum fe_status *status)
0200 {
0201 struct vidtv_demod_state *state = fe->demodulator_priv;
0202 const struct vidtv_demod_cnr_to_qual_s *cnr2qual = NULL;
0203 struct vidtv_demod_config *config = &state->config;
0204 u16 snr = 0;
0205
0206
0207 cnr2qual = vidtv_match_cnr_s(&state->frontend);
0208
0209 if (cnr2qual && state->tuner_cnr < cnr2qual->cnr_good &&
0210 state->frontend.ops.tuner_ops.get_rf_strength) {
0211 state->frontend.ops.tuner_ops.get_rf_strength(&state->frontend,
0212 &snr);
0213
0214 if (snr < cnr2qual->cnr_ok) {
0215
0216 if (prandom_u32_max(100) < config->drop_tslock_prob_on_low_snr)
0217 state->status = 0;
0218 } else {
0219
0220 if (prandom_u32_max(100) <
0221 config->recover_tslock_prob_on_good_snr)
0222 state->status = FE_HAS_SIGNAL |
0223 FE_HAS_CARRIER |
0224 FE_HAS_VITERBI |
0225 FE_HAS_SYNC |
0226 FE_HAS_LOCK;
0227 }
0228 }
0229
0230 vidtv_demod_update_stats(&state->frontend);
0231
0232 *status = state->status;
0233
0234 return 0;
0235 }
0236
0237 static int vidtv_demod_read_signal_strength(struct dvb_frontend *fe,
0238 u16 *strength)
0239 {
0240 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
0241
0242 *strength = c->strength.stat[0].uvalue;
0243
0244 return 0;
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256 static int vidtv_demod_get_frontend(struct dvb_frontend *fe,
0257 struct dtv_frontend_properties *p)
0258 {
0259 return 0;
0260 }
0261
0262 static int vidtv_demod_set_frontend(struct dvb_frontend *fe)
0263 {
0264 struct vidtv_demod_state *state = fe->demodulator_priv;
0265 u32 tuner_status = 0;
0266 int ret;
0267
0268 if (!fe->ops.tuner_ops.set_params)
0269 return 0;
0270
0271 fe->ops.tuner_ops.set_params(fe);
0272
0273
0274 ret = fe->ops.tuner_ops.get_rf_strength(fe, &state->tuner_cnr);
0275 if (ret < 0)
0276 return ret;
0277
0278 fe->ops.tuner_ops.get_status(fe, &tuner_status);
0279 state->status = (state->tuner_cnr > 0) ? FE_HAS_SIGNAL |
0280 FE_HAS_CARRIER |
0281 FE_HAS_VITERBI |
0282 FE_HAS_SYNC |
0283 FE_HAS_LOCK :
0284 0;
0285
0286 vidtv_demod_update_stats(fe);
0287
0288 if (fe->ops.i2c_gate_ctrl)
0289 fe->ops.i2c_gate_ctrl(fe, 0);
0290
0291 return 0;
0292 }
0293
0294
0295
0296
0297
0298
0299
0300
0301 static int vidtv_demod_set_tone(struct dvb_frontend *fe,
0302 enum fe_sec_tone_mode tone)
0303 {
0304 return 0;
0305 }
0306
0307
0308
0309
0310
0311
0312
0313
0314 static int vidtv_demod_set_voltage(struct dvb_frontend *fe,
0315 enum fe_sec_voltage voltage)
0316 {
0317 return 0;
0318 }
0319
0320
0321
0322
0323
0324
0325
0326
0327 static int vidtv_send_diseqc_msg(struct dvb_frontend *fe,
0328 struct dvb_diseqc_master_cmd *cmd)
0329 {
0330 return 0;
0331 }
0332
0333
0334
0335
0336
0337
0338
0339
0340 static int vidtv_diseqc_send_burst(struct dvb_frontend *fe,
0341 enum fe_sec_mini_cmd burst)
0342 {
0343 return 0;
0344 }
0345
0346 static void vidtv_demod_release(struct dvb_frontend *fe)
0347 {
0348 struct vidtv_demod_state *state = fe->demodulator_priv;
0349
0350 kfree(state);
0351 }
0352
0353 static const struct dvb_frontend_ops vidtv_demod_ops = {
0354 .delsys = {
0355 SYS_DVBT,
0356 SYS_DVBT2,
0357 SYS_DVBC_ANNEX_A,
0358 SYS_DVBS,
0359 SYS_DVBS2,
0360 },
0361
0362 .info = {
0363 .name = "Dummy demod for DVB-T/T2/C/S/S2",
0364 .frequency_min_hz = 51 * MHz,
0365 .frequency_max_hz = 2150 * MHz,
0366 .frequency_stepsize_hz = 62500,
0367 .frequency_tolerance_hz = 29500 * kHz,
0368 .symbol_rate_min = 1000000,
0369 .symbol_rate_max = 45000000,
0370
0371 .caps = FE_CAN_FEC_1_2 |
0372 FE_CAN_FEC_2_3 |
0373 FE_CAN_FEC_3_4 |
0374 FE_CAN_FEC_4_5 |
0375 FE_CAN_FEC_5_6 |
0376 FE_CAN_FEC_6_7 |
0377 FE_CAN_FEC_7_8 |
0378 FE_CAN_FEC_8_9 |
0379 FE_CAN_QAM_16 |
0380 FE_CAN_QAM_64 |
0381 FE_CAN_QAM_32 |
0382 FE_CAN_QAM_128 |
0383 FE_CAN_QAM_256 |
0384 FE_CAN_QAM_AUTO |
0385 FE_CAN_QPSK |
0386 FE_CAN_FEC_AUTO |
0387 FE_CAN_INVERSION_AUTO |
0388 FE_CAN_TRANSMISSION_MODE_AUTO |
0389 FE_CAN_GUARD_INTERVAL_AUTO |
0390 FE_CAN_HIERARCHY_AUTO,
0391 },
0392
0393 .release = vidtv_demod_release,
0394
0395 .set_frontend = vidtv_demod_set_frontend,
0396 .get_frontend = vidtv_demod_get_frontend,
0397
0398 .read_status = vidtv_demod_read_status,
0399 .read_signal_strength = vidtv_demod_read_signal_strength,
0400
0401
0402 .set_voltage = vidtv_demod_set_voltage,
0403 .set_tone = vidtv_demod_set_tone,
0404 .diseqc_send_master_cmd = vidtv_send_diseqc_msg,
0405 .diseqc_send_burst = vidtv_diseqc_send_burst,
0406
0407 };
0408
0409 static const struct i2c_device_id vidtv_demod_i2c_id_table[] = {
0410 {"dvb_vidtv_demod", 0},
0411 {}
0412 };
0413 MODULE_DEVICE_TABLE(i2c, vidtv_demod_i2c_id_table);
0414
0415 static int vidtv_demod_i2c_probe(struct i2c_client *client,
0416 const struct i2c_device_id *id)
0417 {
0418 struct vidtv_tuner_config *config = client->dev.platform_data;
0419 struct vidtv_demod_state *state;
0420
0421
0422 state = kzalloc(sizeof(*state), GFP_KERNEL);
0423 if (!state)
0424 return -ENOMEM;
0425
0426
0427 memcpy(&state->frontend.ops,
0428 &vidtv_demod_ops,
0429 sizeof(struct dvb_frontend_ops));
0430
0431 memcpy(&state->config, config, sizeof(state->config));
0432
0433 state->frontend.demodulator_priv = state;
0434 i2c_set_clientdata(client, state);
0435
0436 vidtv_clean_stats(&state->frontend);
0437
0438 return 0;
0439 }
0440
0441 static int vidtv_demod_i2c_remove(struct i2c_client *client)
0442 {
0443 struct vidtv_demod_state *state = i2c_get_clientdata(client);
0444
0445 kfree(state);
0446
0447 return 0;
0448 }
0449
0450 static struct i2c_driver vidtv_demod_i2c_driver = {
0451 .driver = {
0452 .name = "dvb_vidtv_demod",
0453 .suppress_bind_attrs = true,
0454 },
0455 .probe = vidtv_demod_i2c_probe,
0456 .remove = vidtv_demod_i2c_remove,
0457 .id_table = vidtv_demod_i2c_id_table,
0458 };
0459
0460 module_i2c_driver(vidtv_demod_i2c_driver);
0461
0462 MODULE_DESCRIPTION("Virtual DVB Demodulator Driver");
0463 MODULE_AUTHOR("Daniel W. S. Almeida");
0464 MODULE_LICENSE("GPL");