0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/init.h>
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/string.h>
0019 #include <linux/slab.h>
0020 #include <linux/jiffies.h>
0021 #include <media/dvb_frontend.h>
0022 #include "tda8083.h"
0023
0024
0025 struct tda8083_state {
0026 struct i2c_adapter* i2c;
0027
0028 const struct tda8083_config* config;
0029 struct dvb_frontend frontend;
0030 };
0031
0032 static int debug;
0033 #define dprintk(args...) \
0034 do { \
0035 if (debug) printk(KERN_DEBUG "tda8083: " args); \
0036 } while (0)
0037
0038
0039 static u8 tda8083_init_tab [] = {
0040 0x04, 0x00, 0x4a, 0x79, 0x04, 0x00, 0xff, 0xea,
0041 0x48, 0x42, 0x79, 0x60, 0x70, 0x52, 0x9a, 0x10,
0042 0x0e, 0x10, 0xf2, 0xa7, 0x93, 0x0b, 0x05, 0xc8,
0043 0x9d, 0x00, 0x42, 0x80, 0x00, 0x60, 0x40, 0x00,
0044 0x00, 0x75, 0x00, 0xe0, 0x00, 0x00, 0x00, 0x00,
0045 0x00, 0x00, 0x00, 0x00
0046 };
0047
0048
0049 static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
0050 {
0051 int ret;
0052 u8 buf [] = { reg, data };
0053 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
0054
0055 ret = i2c_transfer(state->i2c, &msg, 1);
0056
0057 if (ret != 1)
0058 dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
0059 __func__, reg, ret);
0060
0061 return (ret != 1) ? -1 : 0;
0062 }
0063
0064 static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len)
0065 {
0066 int ret;
0067 struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = ®1, .len = 1 },
0068 { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = len } };
0069
0070 ret = i2c_transfer(state->i2c, msg, 2);
0071
0072 if (ret != 2)
0073 dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
0074 __func__, reg1, ret);
0075
0076 return ret == 2 ? 0 : -1;
0077 }
0078
0079 static inline u8 tda8083_readreg (struct tda8083_state* state, u8 reg)
0080 {
0081 u8 val;
0082
0083 tda8083_readregs (state, reg, &val, 1);
0084
0085 return val;
0086 }
0087
0088 static int tda8083_set_inversion(struct tda8083_state *state,
0089 enum fe_spectral_inversion inversion)
0090 {
0091
0092 if (inversion == INVERSION_AUTO)
0093 return 0;
0094
0095 return -EINVAL;
0096 }
0097
0098 static int tda8083_set_fec(struct tda8083_state *state, enum fe_code_rate fec)
0099 {
0100 if (fec == FEC_AUTO)
0101 return tda8083_writereg (state, 0x07, 0xff);
0102
0103 if (fec >= FEC_1_2 && fec <= FEC_8_9)
0104 return tda8083_writereg (state, 0x07, 1 << (FEC_8_9 - fec));
0105
0106 return -EINVAL;
0107 }
0108
0109 static enum fe_code_rate tda8083_get_fec(struct tda8083_state *state)
0110 {
0111 u8 index;
0112 static enum fe_code_rate fec_tab[] = {
0113 FEC_8_9, FEC_1_2, FEC_2_3, FEC_3_4,
0114 FEC_4_5, FEC_5_6, FEC_6_7, FEC_7_8
0115 };
0116
0117 index = tda8083_readreg(state, 0x0e) & 0x07;
0118
0119 return fec_tab [index];
0120 }
0121
0122 static int tda8083_set_symbolrate (struct tda8083_state* state, u32 srate)
0123 {
0124 u32 ratio;
0125 u32 tmp;
0126 u8 filter;
0127
0128 if (srate > 32000000)
0129 srate = 32000000;
0130 if (srate < 500000)
0131 srate = 500000;
0132
0133 filter = 0;
0134 if (srate < 24000000)
0135 filter = 2;
0136 if (srate < 16000000)
0137 filter = 3;
0138
0139 tmp = 31250 << 16;
0140 ratio = tmp / srate;
0141
0142 tmp = (tmp % srate) << 8;
0143 ratio = (ratio << 8) + tmp / srate;
0144
0145 tmp = (tmp % srate) << 8;
0146 ratio = (ratio << 8) + tmp / srate;
0147
0148 dprintk("tda8083: ratio == %08x\n", (unsigned int) ratio);
0149
0150 tda8083_writereg (state, 0x05, filter);
0151 tda8083_writereg (state, 0x02, (ratio >> 16) & 0xff);
0152 tda8083_writereg (state, 0x03, (ratio >> 8) & 0xff);
0153 tda8083_writereg (state, 0x04, (ratio ) & 0xff);
0154
0155 tda8083_writereg (state, 0x00, 0x3c);
0156 tda8083_writereg (state, 0x00, 0x04);
0157
0158 return 1;
0159 }
0160
0161 static void tda8083_wait_diseqc_fifo (struct tda8083_state* state, int timeout)
0162 {
0163 unsigned long start = jiffies;
0164
0165 while (time_is_after_jiffies(start + timeout) &&
0166 !(tda8083_readreg(state, 0x02) & 0x80))
0167 {
0168 msleep(50);
0169 }
0170 }
0171
0172 static int tda8083_set_tone(struct tda8083_state *state,
0173 enum fe_sec_tone_mode tone)
0174 {
0175 tda8083_writereg (state, 0x26, 0xf1);
0176
0177 switch (tone) {
0178 case SEC_TONE_OFF:
0179 return tda8083_writereg (state, 0x29, 0x00);
0180 case SEC_TONE_ON:
0181 return tda8083_writereg (state, 0x29, 0x80);
0182 default:
0183 return -EINVAL;
0184 }
0185 }
0186
0187 static int tda8083_set_voltage(struct tda8083_state *state,
0188 enum fe_sec_voltage voltage)
0189 {
0190 switch (voltage) {
0191 case SEC_VOLTAGE_13:
0192 return tda8083_writereg (state, 0x20, 0x00);
0193 case SEC_VOLTAGE_18:
0194 return tda8083_writereg (state, 0x20, 0x11);
0195 default:
0196 return -EINVAL;
0197 }
0198 }
0199
0200 static int tda8083_send_diseqc_burst(struct tda8083_state *state,
0201 enum fe_sec_mini_cmd burst)
0202 {
0203 switch (burst) {
0204 case SEC_MINI_A:
0205 tda8083_writereg (state, 0x29, (5 << 2));
0206 break;
0207 case SEC_MINI_B:
0208 tda8083_writereg (state, 0x29, (7 << 2));
0209 break;
0210 default:
0211 return -EINVAL;
0212 }
0213
0214 tda8083_wait_diseqc_fifo (state, 100);
0215
0216 return 0;
0217 }
0218
0219 static int tda8083_send_diseqc_msg(struct dvb_frontend *fe,
0220 struct dvb_diseqc_master_cmd *m)
0221 {
0222 struct tda8083_state* state = fe->demodulator_priv;
0223 int i;
0224
0225 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (1 << 2));
0226
0227 for (i=0; i<m->msg_len; i++)
0228 tda8083_writereg (state, 0x23 + i, m->msg[i]);
0229
0230 tda8083_writereg (state, 0x29, (m->msg_len - 3) | (3 << 2));
0231
0232 tda8083_wait_diseqc_fifo (state, 100);
0233
0234 return 0;
0235 }
0236
0237 static int tda8083_read_status(struct dvb_frontend *fe,
0238 enum fe_status *status)
0239 {
0240 struct tda8083_state* state = fe->demodulator_priv;
0241
0242 u8 signal = ~tda8083_readreg (state, 0x01);
0243 u8 sync = tda8083_readreg (state, 0x02);
0244
0245 *status = 0;
0246
0247 if (signal > 10)
0248 *status |= FE_HAS_SIGNAL;
0249
0250 if (sync & 0x01)
0251 *status |= FE_HAS_CARRIER;
0252
0253 if (sync & 0x02)
0254 *status |= FE_HAS_VITERBI;
0255
0256 if (sync & 0x10)
0257 *status |= FE_HAS_SYNC;
0258
0259 if (sync & 0x20)
0260 *status |= FE_TIMEDOUT;
0261
0262 if ((sync & 0x1f) == 0x1f)
0263 *status |= FE_HAS_LOCK;
0264
0265 return 0;
0266 }
0267
0268 static int tda8083_read_ber(struct dvb_frontend* fe, u32* ber)
0269 {
0270 struct tda8083_state* state = fe->demodulator_priv;
0271 int ret;
0272 u8 buf[3];
0273
0274 if ((ret = tda8083_readregs(state, 0x0b, buf, sizeof(buf))))
0275 return ret;
0276
0277 *ber = ((buf[0] & 0x1f) << 16) | (buf[1] << 8) | buf[2];
0278
0279 return 0;
0280 }
0281
0282 static int tda8083_read_signal_strength(struct dvb_frontend* fe, u16* strength)
0283 {
0284 struct tda8083_state* state = fe->demodulator_priv;
0285
0286 u8 signal = ~tda8083_readreg (state, 0x01);
0287 *strength = (signal << 8) | signal;
0288
0289 return 0;
0290 }
0291
0292 static int tda8083_read_snr(struct dvb_frontend* fe, u16* snr)
0293 {
0294 struct tda8083_state* state = fe->demodulator_priv;
0295
0296 u8 _snr = tda8083_readreg (state, 0x08);
0297 *snr = (_snr << 8) | _snr;
0298
0299 return 0;
0300 }
0301
0302 static int tda8083_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
0303 {
0304 struct tda8083_state* state = fe->demodulator_priv;
0305
0306 *ucblocks = tda8083_readreg(state, 0x0f);
0307 if (*ucblocks == 0xff)
0308 *ucblocks = 0xffffffff;
0309
0310 return 0;
0311 }
0312
0313 static int tda8083_set_frontend(struct dvb_frontend *fe)
0314 {
0315 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0316 struct tda8083_state* state = fe->demodulator_priv;
0317
0318 if (fe->ops.tuner_ops.set_params) {
0319 fe->ops.tuner_ops.set_params(fe);
0320 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
0321 }
0322
0323 tda8083_set_inversion (state, p->inversion);
0324 tda8083_set_fec(state, p->fec_inner);
0325 tda8083_set_symbolrate(state, p->symbol_rate);
0326
0327 tda8083_writereg (state, 0x00, 0x3c);
0328 tda8083_writereg (state, 0x00, 0x04);
0329
0330 return 0;
0331 }
0332
0333 static int tda8083_get_frontend(struct dvb_frontend *fe,
0334 struct dtv_frontend_properties *p)
0335 {
0336 struct tda8083_state* state = fe->demodulator_priv;
0337
0338
0339
0340 p->inversion = (tda8083_readreg (state, 0x0e) & 0x80) ?
0341 INVERSION_ON : INVERSION_OFF;
0342 p->fec_inner = tda8083_get_fec(state);
0343
0344
0345 return 0;
0346 }
0347
0348 static int tda8083_sleep(struct dvb_frontend* fe)
0349 {
0350 struct tda8083_state* state = fe->demodulator_priv;
0351
0352 tda8083_writereg (state, 0x00, 0x02);
0353 return 0;
0354 }
0355
0356 static int tda8083_init(struct dvb_frontend* fe)
0357 {
0358 struct tda8083_state* state = fe->demodulator_priv;
0359 int i;
0360
0361 for (i=0; i<44; i++)
0362 tda8083_writereg (state, i, tda8083_init_tab[i]);
0363
0364 tda8083_writereg (state, 0x00, 0x3c);
0365 tda8083_writereg (state, 0x00, 0x04);
0366
0367 return 0;
0368 }
0369
0370 static int tda8083_diseqc_send_burst(struct dvb_frontend *fe,
0371 enum fe_sec_mini_cmd burst)
0372 {
0373 struct tda8083_state* state = fe->demodulator_priv;
0374
0375 tda8083_send_diseqc_burst (state, burst);
0376 tda8083_writereg (state, 0x00, 0x3c);
0377 tda8083_writereg (state, 0x00, 0x04);
0378
0379 return 0;
0380 }
0381
0382 static int tda8083_diseqc_set_tone(struct dvb_frontend *fe,
0383 enum fe_sec_tone_mode tone)
0384 {
0385 struct tda8083_state* state = fe->demodulator_priv;
0386
0387 tda8083_set_tone (state, tone);
0388 tda8083_writereg (state, 0x00, 0x3c);
0389 tda8083_writereg (state, 0x00, 0x04);
0390
0391 return 0;
0392 }
0393
0394 static int tda8083_diseqc_set_voltage(struct dvb_frontend *fe,
0395 enum fe_sec_voltage voltage)
0396 {
0397 struct tda8083_state* state = fe->demodulator_priv;
0398
0399 tda8083_set_voltage (state, voltage);
0400 tda8083_writereg (state, 0x00, 0x3c);
0401 tda8083_writereg (state, 0x00, 0x04);
0402
0403 return 0;
0404 }
0405
0406 static void tda8083_release(struct dvb_frontend* fe)
0407 {
0408 struct tda8083_state* state = fe->demodulator_priv;
0409 kfree(state);
0410 }
0411
0412 static const struct dvb_frontend_ops tda8083_ops;
0413
0414 struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
0415 struct i2c_adapter* i2c)
0416 {
0417 struct tda8083_state* state = NULL;
0418
0419
0420 state = kzalloc(sizeof(struct tda8083_state), GFP_KERNEL);
0421 if (state == NULL) goto error;
0422
0423
0424 state->config = config;
0425 state->i2c = i2c;
0426
0427
0428 if ((tda8083_readreg(state, 0x00)) != 0x05) goto error;
0429
0430
0431 memcpy(&state->frontend.ops, &tda8083_ops, sizeof(struct dvb_frontend_ops));
0432 state->frontend.demodulator_priv = state;
0433 return &state->frontend;
0434
0435 error:
0436 kfree(state);
0437 return NULL;
0438 }
0439
0440 static const struct dvb_frontend_ops tda8083_ops = {
0441 .delsys = { SYS_DVBS },
0442 .info = {
0443 .name = "Philips TDA8083 DVB-S",
0444 .frequency_min_hz = 920 * MHz,
0445 .frequency_max_hz = 2200 * MHz,
0446 .frequency_stepsize_hz = 125 * kHz,
0447 .symbol_rate_min = 12000000,
0448 .symbol_rate_max = 30000000,
0449
0450 .caps = FE_CAN_INVERSION_AUTO |
0451 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0452 FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
0453 FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
0454 FE_CAN_QPSK | FE_CAN_MUTE_TS
0455 },
0456
0457 .release = tda8083_release,
0458
0459 .init = tda8083_init,
0460 .sleep = tda8083_sleep,
0461
0462 .set_frontend = tda8083_set_frontend,
0463 .get_frontend = tda8083_get_frontend,
0464
0465 .read_status = tda8083_read_status,
0466 .read_signal_strength = tda8083_read_signal_strength,
0467 .read_snr = tda8083_read_snr,
0468 .read_ber = tda8083_read_ber,
0469 .read_ucblocks = tda8083_read_ucblocks,
0470
0471 .diseqc_send_master_cmd = tda8083_send_diseqc_msg,
0472 .diseqc_send_burst = tda8083_diseqc_send_burst,
0473 .set_tone = tda8083_diseqc_set_tone,
0474 .set_voltage = tda8083_diseqc_set_voltage,
0475 };
0476
0477 module_param(debug, int, 0644);
0478 MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
0479
0480 MODULE_DESCRIPTION("Philips TDA8083 DVB-S Demodulator");
0481 MODULE_AUTHOR("Ralph Metzler, Holger Waechtler");
0482 MODULE_LICENSE("GPL");
0483
0484 EXPORT_SYMBOL(tda8083_attach);