1 /* 2 * TTUSB DEC Frontend Driver 3 * 4 * Copyright (C) 2003-2004 Alex Woods <linux-dvb@giblets.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published by 8 * the Free Software Foundation; either version 2 of the License, or 9 * (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 19 * 20 */ 21 22 #include "dvb_frontend.h" 23 #include "ttusbdecfe.h" 24 25 26 #define LOF_HI 10600000 27 #define LOF_LO 9750000 28 29 struct ttusbdecfe_state { 30 31 /* configuration settings */ 32 const struct ttusbdecfe_config* config; 33 34 struct dvb_frontend frontend; 35 36 u8 hi_band; 37 u8 voltage; 38 }; 39 40 41 static int ttusbdecfe_dvbs_read_status(struct dvb_frontend *fe, 42 fe_status_t *status) 43 { 44 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | 45 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; 46 return 0; 47 } 48 49 50 static int ttusbdecfe_dvbt_read_status(struct dvb_frontend *fe, 51 fe_status_t *status) 52 { 53 struct ttusbdecfe_state* state = fe->demodulator_priv; 54 u8 b[] = { 0x00, 0x00, 0x00, 0x00, 55 0x00, 0x00, 0x00, 0x00 }; 56 u8 result[4]; 57 int len, ret; 58 59 *status=0; 60 61 ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result); 62 if(ret) 63 return ret; 64 65 if(len != 4) { 66 printk(KERN_ERR "%s: unexpected reply\n", __func__); 67 return -EIO; 68 } 69 70 switch(result[3]) { 71 case 1: /* not tuned yet */ 72 case 2: /* no signal/no lock*/ 73 break; 74 case 3: /* signal found and locked*/ 75 *status = FE_HAS_SIGNAL | FE_HAS_VITERBI | 76 FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK; 77 break; 78 case 4: 79 *status = FE_TIMEDOUT; 80 break; 81 default: 82 pr_info("%s: returned unknown value: %d\n", 83 __func__, result[3]); 84 return -EIO; 85 } 86 87 return 0; 88 } 89 90 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend *fe) 91 { 92 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 93 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 94 u8 b[] = { 0x00, 0x00, 0x00, 0x03, 95 0x00, 0x00, 0x00, 0x00, 96 0x00, 0x00, 0x00, 0x01, 97 0x00, 0x00, 0x00, 0xff, 98 0x00, 0x00, 0x00, 0xff }; 99 100 __be32 freq = htonl(p->frequency / 1000); 101 memcpy(&b[4], &freq, sizeof (u32)); 102 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); 103 104 return 0; 105 } 106 107 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe, 108 struct dvb_frontend_tune_settings* fesettings) 109 { 110 fesettings->min_delay_ms = 1500; 111 /* Drift compensation makes no sense for DVB-T */ 112 fesettings->step_size = 0; 113 fesettings->max_drift = 0; 114 return 0; 115 } 116 117 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend *fe) 118 { 119 struct dtv_frontend_properties *p = &fe->dtv_property_cache; 120 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 121 122 u8 b[] = { 0x00, 0x00, 0x00, 0x01, 123 0x00, 0x00, 0x00, 0x00, 124 0x00, 0x00, 0x00, 0x01, 125 0x00, 0x00, 0x00, 0x00, 126 0x00, 0x00, 0x00, 0x00, 127 0x00, 0x00, 0x00, 0x00, 128 0x00, 0x00, 0x00, 0x00, 129 0x00, 0x00, 0x00, 0x00, 130 0x00, 0x00, 0x00, 0x00, 131 0x00, 0x00, 0x00, 0x00 }; 132 __be32 freq; 133 __be32 sym_rate; 134 __be32 band; 135 __be32 lnb_voltage; 136 137 freq = htonl(p->frequency + 138 (state->hi_band ? LOF_HI : LOF_LO)); 139 memcpy(&b[4], &freq, sizeof(u32)); 140 sym_rate = htonl(p->symbol_rate); 141 memcpy(&b[12], &sym_rate, sizeof(u32)); 142 band = htonl(state->hi_band ? LOF_HI : LOF_LO); 143 memcpy(&b[24], &band, sizeof(u32)); 144 lnb_voltage = htonl(state->voltage); 145 memcpy(&b[28], &lnb_voltage, sizeof(u32)); 146 147 state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL); 148 149 return 0; 150 } 151 152 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd) 153 { 154 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 155 u8 b[] = { 0x00, 0xff, 0x00, 0x00, 156 0x00, 0x00, 0x00, 0x00, 157 0x00, 0x00 }; 158 159 if (cmd->msg_len > sizeof(b) - 4) 160 return -EINVAL; 161 162 memcpy(&b[4], cmd->msg, cmd->msg_len); 163 164 state->config->send_command(fe, 0x72, 165 sizeof(b) - (6 - cmd->msg_len), b, 166 NULL, NULL); 167 168 return 0; 169 } 170 171 172 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) 173 { 174 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 175 176 state->hi_band = (SEC_TONE_ON == tone); 177 178 return 0; 179 } 180 181 182 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage) 183 { 184 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 185 186 switch (voltage) { 187 case SEC_VOLTAGE_13: 188 state->voltage = 13; 189 break; 190 case SEC_VOLTAGE_18: 191 state->voltage = 18; 192 break; 193 default: 194 return -EINVAL; 195 } 196 197 return 0; 198 } 199 200 static void ttusbdecfe_release(struct dvb_frontend* fe) 201 { 202 struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv; 203 kfree(state); 204 } 205 206 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops; 207 208 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config) 209 { 210 struct ttusbdecfe_state* state = NULL; 211 212 /* allocate memory for the internal state */ 213 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); 214 if (state == NULL) 215 return NULL; 216 217 /* setup the state */ 218 state->config = config; 219 220 /* create dvb_frontend */ 221 memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops)); 222 state->frontend.demodulator_priv = state; 223 return &state->frontend; 224 } 225 226 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops; 227 228 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config) 229 { 230 struct ttusbdecfe_state* state = NULL; 231 232 /* allocate memory for the internal state */ 233 state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL); 234 if (state == NULL) 235 return NULL; 236 237 /* setup the state */ 238 state->config = config; 239 state->voltage = 0; 240 state->hi_band = 0; 241 242 /* create dvb_frontend */ 243 memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops)); 244 state->frontend.demodulator_priv = state; 245 return &state->frontend; 246 } 247 248 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = { 249 .delsys = { SYS_DVBT }, 250 .info = { 251 .name = "TechnoTrend/Hauppauge DEC2000-t Frontend", 252 .frequency_min = 51000000, 253 .frequency_max = 858000000, 254 .frequency_stepsize = 62500, 255 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 256 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 257 FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 258 FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO | 259 FE_CAN_HIERARCHY_AUTO, 260 }, 261 262 .release = ttusbdecfe_release, 263 264 .set_frontend = ttusbdecfe_dvbt_set_frontend, 265 266 .get_tune_settings = ttusbdecfe_dvbt_get_tune_settings, 267 268 .read_status = ttusbdecfe_dvbt_read_status, 269 }; 270 271 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = { 272 .delsys = { SYS_DVBS }, 273 .info = { 274 .name = "TechnoTrend/Hauppauge DEC3000-s Frontend", 275 .frequency_min = 950000, 276 .frequency_max = 2150000, 277 .frequency_stepsize = 125, 278 .symbol_rate_min = 1000000, /* guessed */ 279 .symbol_rate_max = 45000000, /* guessed */ 280 .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 281 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 282 FE_CAN_QPSK 283 }, 284 285 .release = ttusbdecfe_release, 286 287 .set_frontend = ttusbdecfe_dvbs_set_frontend, 288 289 .read_status = ttusbdecfe_dvbs_read_status, 290 291 .diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd, 292 .set_voltage = ttusbdecfe_dvbs_set_voltage, 293 .set_tone = ttusbdecfe_dvbs_set_tone, 294 }; 295 296 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver"); 297 MODULE_AUTHOR("Alex Woods/Andrew de Quincey"); 298 MODULE_LICENSE("GPL"); 299 300 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach); 301 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach); 302