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 
ttusbdecfe_dvbs_read_status(struct dvb_frontend * fe,fe_status_t * status)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 
ttusbdecfe_dvbt_read_status(struct dvb_frontend * fe,fe_status_t * status)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 
ttusbdecfe_dvbt_set_frontend(struct dvb_frontend * fe,struct dvb_frontend_parameters * p)90 static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
91 {
92 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
93 	u8 b[] = { 0x00, 0x00, 0x00, 0x03,
94 		   0x00, 0x00, 0x00, 0x00,
95 		   0x00, 0x00, 0x00, 0x01,
96 		   0x00, 0x00, 0x00, 0xff,
97 		   0x00, 0x00, 0x00, 0xff };
98 
99 	__be32 freq = htonl(p->frequency / 1000);
100 	memcpy(&b[4], &freq, sizeof (u32));
101 	state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
102 
103 	return 0;
104 }
105 
ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend * fe,struct dvb_frontend_tune_settings * fesettings)106 static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
107 					struct dvb_frontend_tune_settings* fesettings)
108 {
109 		fesettings->min_delay_ms = 1500;
110 		/* Drift compensation makes no sense for DVB-T */
111 		fesettings->step_size = 0;
112 		fesettings->max_drift = 0;
113 		return 0;
114 }
115 
ttusbdecfe_dvbs_set_frontend(struct dvb_frontend * fe,struct dvb_frontend_parameters * p)116 static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
117 {
118 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
119 
120 	u8 b[] = { 0x00, 0x00, 0x00, 0x01,
121 		   0x00, 0x00, 0x00, 0x00,
122 		   0x00, 0x00, 0x00, 0x01,
123 		   0x00, 0x00, 0x00, 0x00,
124 		   0x00, 0x00, 0x00, 0x00,
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 	__be32 freq;
131 	__be32 sym_rate;
132 	__be32 band;
133 	__be32 lnb_voltage;
134 
135 	freq = htonl(p->frequency +
136 	       (state->hi_band ? LOF_HI : LOF_LO));
137 	memcpy(&b[4], &freq, sizeof(u32));
138 	sym_rate = htonl(p->u.qam.symbol_rate);
139 	memcpy(&b[12], &sym_rate, sizeof(u32));
140 	band = htonl(state->hi_band ? LOF_HI : LOF_LO);
141 	memcpy(&b[24], &band, sizeof(u32));
142 	lnb_voltage = htonl(state->voltage);
143 	memcpy(&b[28], &lnb_voltage, sizeof(u32));
144 
145 	state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
146 
147 	return 0;
148 }
149 
ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend * fe,struct dvb_diseqc_master_cmd * cmd)150 static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
151 {
152 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
153 	u8 b[] = { 0x00, 0xff, 0x00, 0x00,
154 		   0x00, 0x00, 0x00, 0x00,
155 		   0x00, 0x00 };
156 
157 	memcpy(&b[4], cmd->msg, cmd->msg_len);
158 
159 	state->config->send_command(fe, 0x72,
160 				    sizeof(b) - (6 - cmd->msg_len), b,
161 				    NULL, NULL);
162 
163 	return 0;
164 }
165 
166 
ttusbdecfe_dvbs_set_tone(struct dvb_frontend * fe,fe_sec_tone_mode_t tone)167 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
168 {
169 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
170 
171 	state->hi_band = (SEC_TONE_ON == tone);
172 
173 	return 0;
174 }
175 
176 
ttusbdecfe_dvbs_set_voltage(struct dvb_frontend * fe,fe_sec_voltage_t voltage)177 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
178 {
179 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
180 
181 	switch (voltage) {
182 	case SEC_VOLTAGE_13:
183 		state->voltage = 13;
184 		break;
185 	case SEC_VOLTAGE_18:
186 		state->voltage = 18;
187 		break;
188 	default:
189 		return -EINVAL;
190 	}
191 
192 	return 0;
193 }
194 
ttusbdecfe_release(struct dvb_frontend * fe)195 static void ttusbdecfe_release(struct dvb_frontend* fe)
196 {
197 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
198 	kfree(state);
199 }
200 
201 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
202 
ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config * config)203 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
204 {
205 	struct ttusbdecfe_state* state = NULL;
206 
207 	/* allocate memory for the internal state */
208 	state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
209 	if (state == NULL)
210 		return NULL;
211 
212 	/* setup the state */
213 	state->config = config;
214 
215 	/* create dvb_frontend */
216 	memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
217 	state->frontend.demodulator_priv = state;
218 	return &state->frontend;
219 }
220 
221 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
222 
ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config * config)223 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
224 {
225 	struct ttusbdecfe_state* state = NULL;
226 
227 	/* allocate memory for the internal state */
228 	state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
229 	if (state == NULL)
230 		return NULL;
231 
232 	/* setup the state */
233 	state->config = config;
234 	state->voltage = 0;
235 	state->hi_band = 0;
236 
237 	/* create dvb_frontend */
238 	memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
239 	state->frontend.demodulator_priv = state;
240 	return &state->frontend;
241 }
242 
243 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
244 
245 	.info = {
246 		.name			= "TechnoTrend/Hauppauge DEC2000-t Frontend",
247 		.type			= FE_OFDM,
248 		.frequency_min		= 51000000,
249 		.frequency_max		= 858000000,
250 		.frequency_stepsize	= 62500,
251 		.caps =	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
252 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
253 			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
254 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
255 			FE_CAN_HIERARCHY_AUTO,
256 	},
257 
258 	.release = ttusbdecfe_release,
259 
260 	.set_frontend = ttusbdecfe_dvbt_set_frontend,
261 
262 	.get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
263 
264 	.read_status = ttusbdecfe_dvbt_read_status,
265 };
266 
267 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
268 
269 	.info = {
270 		.name			= "TechnoTrend/Hauppauge DEC3000-s Frontend",
271 		.type			= FE_QPSK,
272 		.frequency_min		= 950000,
273 		.frequency_max		= 2150000,
274 		.frequency_stepsize	= 125,
275 		.symbol_rate_min        = 1000000,  /* guessed */
276 		.symbol_rate_max        = 45000000, /* guessed */
277 		.caps =	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
278 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
279 			FE_CAN_QPSK
280 	},
281 
282 	.release = ttusbdecfe_release,
283 
284 	.set_frontend = ttusbdecfe_dvbs_set_frontend,
285 
286 	.read_status = ttusbdecfe_dvbs_read_status,
287 
288 	.diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
289 	.set_voltage = ttusbdecfe_dvbs_set_voltage,
290 	.set_tone = ttusbdecfe_dvbs_set_tone,
291 };
292 
293 MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
294 MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
295 MODULE_LICENSE("GPL");
296 
297 EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
298 EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
299