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 	memcpy(&b[4], cmd->msg, cmd->msg_len);
160 
161 	state->config->send_command(fe, 0x72,
162 				    sizeof(b) - (6 - cmd->msg_len), b,
163 				    NULL, NULL);
164 
165 	return 0;
166 }
167 
168 
169 static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
170 {
171 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
172 
173 	state->hi_band = (SEC_TONE_ON == tone);
174 
175 	return 0;
176 }
177 
178 
179 static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
180 {
181 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
182 
183 	switch (voltage) {
184 	case SEC_VOLTAGE_13:
185 		state->voltage = 13;
186 		break;
187 	case SEC_VOLTAGE_18:
188 		state->voltage = 18;
189 		break;
190 	default:
191 		return -EINVAL;
192 	}
193 
194 	return 0;
195 }
196 
197 static void ttusbdecfe_release(struct dvb_frontend* fe)
198 {
199 	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
200 	kfree(state);
201 }
202 
203 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
204 
205 struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
206 {
207 	struct ttusbdecfe_state* state = NULL;
208 
209 	/* allocate memory for the internal state */
210 	state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
211 	if (state == NULL)
212 		return NULL;
213 
214 	/* setup the state */
215 	state->config = config;
216 
217 	/* create dvb_frontend */
218 	memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
219 	state->frontend.demodulator_priv = state;
220 	return &state->frontend;
221 }
222 
223 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
224 
225 struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
226 {
227 	struct ttusbdecfe_state* state = NULL;
228 
229 	/* allocate memory for the internal state */
230 	state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
231 	if (state == NULL)
232 		return NULL;
233 
234 	/* setup the state */
235 	state->config = config;
236 	state->voltage = 0;
237 	state->hi_band = 0;
238 
239 	/* create dvb_frontend */
240 	memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
241 	state->frontend.demodulator_priv = state;
242 	return &state->frontend;
243 }
244 
245 static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
246 	.delsys = { SYS_DVBT },
247 	.info = {
248 		.name			= "TechnoTrend/Hauppauge DEC2000-t Frontend",
249 		.frequency_min		= 51000000,
250 		.frequency_max		= 858000000,
251 		.frequency_stepsize	= 62500,
252 		.caps =	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
253 			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
254 			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
255 			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
256 			FE_CAN_HIERARCHY_AUTO,
257 	},
258 
259 	.release = ttusbdecfe_release,
260 
261 	.set_frontend = ttusbdecfe_dvbt_set_frontend,
262 
263 	.get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
264 
265 	.read_status = ttusbdecfe_dvbt_read_status,
266 };
267 
268 static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
269 	.delsys = { SYS_DVBS },
270 	.info = {
271 		.name			= "TechnoTrend/Hauppauge DEC3000-s Frontend",
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