Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * TTUSB DEC Frontend Driver
0004  *
0005  * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org>
0006  */
0007 
0008 #include <media/dvb_frontend.h>
0009 #include "ttusbdecfe.h"
0010 
0011 
0012 #define LOF_HI          10600000
0013 #define LOF_LO          9750000
0014 
0015 struct ttusbdecfe_state {
0016 
0017     /* configuration settings */
0018     const struct ttusbdecfe_config* config;
0019 
0020     struct dvb_frontend frontend;
0021 
0022     u8 hi_band;
0023     u8 voltage;
0024 };
0025 
0026 
0027 static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe,
0028                        enum fe_status *status)
0029 {
0030     *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
0031         FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
0032     return 0;
0033 }
0034 
0035 
0036 static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe,
0037                        enum fe_status *status)
0038 {
0039     struct ttusbdecfe_state* state = fe->demodulator_priv;
0040     u8 b[] = { 0x00, 0x00, 0x00, 0x00,
0041            0x00, 0x00, 0x00, 0x00 };
0042     u8 result[4];
0043     int len, ret;
0044 
0045     *status=0;
0046 
0047     ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
0048     if(ret)
0049         return ret;
0050 
0051     if(len != 4) {
0052         printk(KERN_ERR "%s: unexpected reply\n", __func__);
0053         return -EIO;
0054     }
0055 
0056     switch(result[3]) {
0057         case 1:  /* not tuned yet */
0058         case 2:  /* no signal/no lock*/
0059             break;
0060         case 3:  /* signal found and locked*/
0061             *status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
0062             FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
0063             break;
0064         case 4:
0065             *status = FE_TIMEDOUT;
0066             break;
0067         default:
0068             pr_info("%s: returned unknown value: %d\n",
0069                 __func__, result[3]);
0070             return -EIO;
0071     }
0072 
0073     return 0;
0074 }
0075 
0076 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe)
0077 {
0078     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0079     struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
0080     u8 b[] = { 0x00, 0x00, 0x00, 0x03,
0081            0x00, 0x00, 0x00, 0x00,
0082            0x00, 0x00, 0x00, 0x01,
0083            0x00, 0x00, 0x00, 0xff,
0084            0x00, 0x00, 0x00, 0xff };
0085 
0086     __be32 freq = htonl(p->frequency / 1000);
0087     memcpy(&b[4], &freq, sizeof (u32));
0088     state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
0089 
0090     return 0;
0091 }
0092 
0093 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
0094                     struct dvb_frontend_tune_settings* fesettings)
0095 {
0096         fesettings->min_delay_ms = 1500;
0097         /* Drift compensation makes no sense for DVB-T */
0098         fesettings->step_size = 0;
0099         fesettings->max_drift = 0;
0100         return 0;
0101 }
0102 
0103 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe)
0104 {
0105     struct dtv_frontend_properties *p = &fe->dtv_property_cache;
0106     struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
0107 
0108     u8 b[] = { 0x00, 0x00, 0x00, 0x01,
0109            0x00, 0x00, 0x00, 0x00,
0110            0x00, 0x00, 0x00, 0x01,
0111            0x00, 0x00, 0x00, 0x00,
0112            0x00, 0x00, 0x00, 0x00,
0113            0x00, 0x00, 0x00, 0x00,
0114            0x00, 0x00, 0x00, 0x00,
0115            0x00, 0x00, 0x00, 0x00,
0116            0x00, 0x00, 0x00, 0x00,
0117            0x00, 0x00, 0x00, 0x00 };
0118     __be32 freq;
0119     __be32 sym_rate;
0120     __be32 band;
0121     __be32 lnb_voltage;
0122 
0123     freq = htonl(p->frequency +
0124            (state->hi_band ? LOF_HI : LOF_LO));
0125     memcpy(&b[4], &freq, sizeof(u32));
0126     sym_rate = htonl(p->symbol_rate);
0127     memcpy(&b[12], &sym_rate, sizeof(u32));
0128     band = htonl(state->hi_band ? LOF_HI : LOF_LO);
0129     memcpy(&b[24], &band, sizeof(u32));
0130     lnb_voltage = htonl(state->voltage);
0131     memcpy(&b[28], &lnb_voltage, sizeof(u32));
0132 
0133     state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
0134 
0135     return 0;
0136 }
0137 
0138 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
0139 {
0140     struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
0141     u8 b[] = { 0x00, 0xff, 0x00, 0x00,
0142            0x00, 0x00, 0x00, 0x00,
0143            0x00, 0x00 };
0144 
0145     if (cmd->msg_len > sizeof(b) - 4)
0146         return -EINVAL;
0147 
0148     memcpy(&b[4], cmd->msg, cmd->msg_len);
0149 
0150     state->config->send_command(fe, 0x72,
0151                     sizeof(b) - (6 - cmd->msg_len), b,
0152                     NULL, NULL);
0153 
0154     return 0;
0155 }
0156 
0157 
0158 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend *fe,
0159                     enum fe_sec_tone_mode tone)
0160 {
0161     struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
0162 
0163     state->hi_band = (SEC_TONE_ON == tone);
0164 
0165     return 0;
0166 }
0167 
0168 
0169 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend *fe,
0170                        enum fe_sec_voltage voltage)
0171 {
0172     struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
0173 
0174     switch (voltage) {
0175     case SEC_VOLTAGE_13:
0176         state->voltage = 13;
0177         break;
0178     case SEC_VOLTAGE_18:
0179         state->voltage = 18;
0180         break;
0181     default:
0182         return -EINVAL;
0183     }
0184 
0185     return 0;
0186 }
0187 
0188 static void ttusbdecfe_release(struct dvb_frontend* fe)
0189 {
0190     struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
0191     kfree(state);
0192 }
0193 
0194 static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
0195 
0196 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
0197 {
0198     struct ttusbdecfe_state* state = NULL;
0199 
0200     /* allocate memory for the internal state */
0201     state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
0202     if (state == NULL)
0203         return NULL;
0204 
0205     /* setup the state */
0206     state->config = config;
0207 
0208     /* create dvb_frontend */
0209     memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
0210     state->frontend.demodulator_priv = state;
0211     return &state->frontend;
0212 }
0213 
0214 static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
0215 
0216 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
0217 {
0218     struct ttusbdecfe_state* state = NULL;
0219 
0220     /* allocate memory for the internal state */
0221     state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
0222     if (state == NULL)
0223         return NULL;
0224 
0225     /* setup the state */
0226     state->config = config;
0227     state->voltage = 0;
0228     state->hi_band = 0;
0229 
0230     /* create dvb_frontend */
0231     memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
0232     state->frontend.demodulator_priv = state;
0233     return &state->frontend;
0234 }
0235 
0236 static const struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
0237     .delsys = { SYS_DVBT },
0238     .info = {
0239         .name           = "TechnoTrend/Hauppauge DEC2000-t Frontend",
0240         .frequency_min_hz   =  51 * MHz,
0241         .frequency_max_hz   = 858 * MHz,
0242         .frequency_stepsize_hz  = 62500,
0243         .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0244             FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
0245             FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
0246             FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
0247             FE_CAN_HIERARCHY_AUTO,
0248     },
0249 
0250     .release = ttusbdecfe_release,
0251 
0252     .set_frontend = ttusbdecfe_dvbt_set_frontend,
0253 
0254     .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
0255 
0256     .read_status = ttusbdecfe_dvbt_read_status,
0257 };
0258 
0259 static const struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
0260     .delsys = { SYS_DVBS },
0261     .info = {
0262         .name           = "TechnoTrend/Hauppauge DEC3000-s Frontend",
0263         .frequency_min_hz   =  950 * MHz,
0264         .frequency_max_hz   = 2150 * MHz,
0265         .frequency_stepsize_hz  =  125 * kHz,
0266         .symbol_rate_min        = 1000000,  /* guessed */
0267         .symbol_rate_max        = 45000000, /* guessed */
0268         .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
0269             FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
0270             FE_CAN_QPSK
0271     },
0272 
0273     .release = ttusbdecfe_release,
0274 
0275     .set_frontend = ttusbdecfe_dvbs_set_frontend,
0276 
0277     .read_status = ttusbdecfe_dvbs_read_status,
0278 
0279     .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
0280     .set_voltage = ttusbdecfe_dvbs_set_voltage,
0281     .set_tone = ttusbdecfe_dvbs_set_tone,
0282 };
0283 
0284 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
0285 MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
0286 MODULE_LICENSE("GPL");
0287 
0288 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
0289 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);