• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-WNDR4500v2-V1.0.0.60_1.0.38/src/linux/linux-2.6/drivers/media/dvb/ttusb-dec/
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
29struct 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
41static int ttusbdecfe_read_status(struct dvb_frontend* fe, fe_status_t* status)
42{
43	struct ttusbdecfe_state* state = fe->demodulator_priv;
44	u8 b[] = { 0x00, 0x00, 0x00, 0x00,
45		   0x00, 0x00, 0x00, 0x00 };
46	u8 result[4];
47	int len, ret;
48
49	*status=0;
50
51	ret=state->config->send_command(fe, 0x73, sizeof(b), b, &len, result);
52	if(ret)
53		return ret;
54
55	if(len != 4) {
56		printk(KERN_ERR "%s: unexpected reply\n", __FUNCTION__);
57		return -EIO;
58	}
59
60	switch(result[3]) {
61		case 1:  /* not tuned yet */
62		case 2:  /* no signal/no lock*/
63			break;
64		case 3:	 /* signal found and locked*/
65			*status = FE_HAS_SIGNAL | FE_HAS_VITERBI |
66			FE_HAS_SYNC | FE_HAS_CARRIER | FE_HAS_LOCK;
67			break;
68		case 4:
69			*status = FE_TIMEDOUT;
70			break;
71		default:
72			pr_info("%s: returned unknown value: %d\n",
73				__FUNCTION__, result[3]);
74			return -EIO;
75	}
76
77	return 0;
78}
79
80static int ttusbdecfe_dvbt_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
81{
82	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
83	u8 b[] = { 0x00, 0x00, 0x00, 0x03,
84		   0x00, 0x00, 0x00, 0x00,
85		   0x00, 0x00, 0x00, 0x01,
86		   0x00, 0x00, 0x00, 0xff,
87		   0x00, 0x00, 0x00, 0xff };
88
89	u32 freq = htonl(p->frequency / 1000);
90	memcpy(&b[4], &freq, sizeof (u32));
91	state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
92
93	return 0;
94}
95
96static int ttusbdecfe_dvbt_get_tune_settings(struct dvb_frontend* fe,
97					struct dvb_frontend_tune_settings* fesettings)
98{
99		fesettings->min_delay_ms = 1500;
100		/* Drift compensation makes no sense for DVB-T */
101		fesettings->step_size = 0;
102		fesettings->max_drift = 0;
103		return 0;
104}
105
106static int ttusbdecfe_dvbs_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *p)
107{
108	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
109
110	u8 b[] = { 0x00, 0x00, 0x00, 0x01,
111		   0x00, 0x00, 0x00, 0x00,
112		   0x00, 0x00, 0x00, 0x01,
113		   0x00, 0x00, 0x00, 0x00,
114		   0x00, 0x00, 0x00, 0x00,
115		   0x00, 0x00, 0x00, 0x00,
116		   0x00, 0x00, 0x00, 0x00,
117		   0x00, 0x00, 0x00, 0x00,
118		   0x00, 0x00, 0x00, 0x00,
119		   0x00, 0x00, 0x00, 0x00 };
120	u32 freq;
121	u32 sym_rate;
122	u32 band;
123	u32 lnb_voltage;
124
125	freq = htonl(p->frequency +
126	       (state->hi_band ? LOF_HI : LOF_LO));
127	memcpy(&b[4], &freq, sizeof(u32));
128	sym_rate = htonl(p->u.qam.symbol_rate);
129	memcpy(&b[12], &sym_rate, sizeof(u32));
130	band = htonl(state->hi_band ? LOF_HI : LOF_LO);
131	memcpy(&b[24], &band, sizeof(u32));
132	lnb_voltage = htonl(state->voltage);
133	memcpy(&b[28], &lnb_voltage, sizeof(u32));
134
135	state->config->send_command(fe, 0x71, sizeof(b), b, NULL, NULL);
136
137	return 0;
138}
139
140static int ttusbdecfe_dvbs_diseqc_send_master_cmd(struct dvb_frontend* fe, struct dvb_diseqc_master_cmd *cmd)
141{
142	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
143	u8 b[] = { 0x00, 0xff, 0x00, 0x00,
144		   0x00, 0x00, 0x00, 0x00,
145		   0x00, 0x00 };
146
147	memcpy(&b[4], cmd->msg, cmd->msg_len);
148
149	state->config->send_command(fe, 0x72,
150				    sizeof(b) - (6 - cmd->msg_len), b,
151				    NULL, NULL);
152
153	return 0;
154}
155
156
157static int ttusbdecfe_dvbs_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
158{
159	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
160
161	state->hi_band = (SEC_TONE_ON == tone);
162
163	return 0;
164}
165
166
167static int ttusbdecfe_dvbs_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage)
168{
169	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
170
171	switch (voltage) {
172	case SEC_VOLTAGE_13:
173		state->voltage = 13;
174		break;
175	case SEC_VOLTAGE_18:
176		state->voltage = 18;
177		break;
178	default:
179		return -EINVAL;
180	}
181
182	return 0;
183}
184
185static void ttusbdecfe_release(struct dvb_frontend* fe)
186{
187	struct ttusbdecfe_state* state = (struct ttusbdecfe_state*) fe->demodulator_priv;
188	kfree(state);
189}
190
191static struct dvb_frontend_ops ttusbdecfe_dvbt_ops;
192
193struct dvb_frontend* ttusbdecfe_dvbt_attach(const struct ttusbdecfe_config* config)
194{
195	struct ttusbdecfe_state* state = NULL;
196
197	/* allocate memory for the internal state */
198	state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
199	if (state == NULL)
200		return NULL;
201
202	/* setup the state */
203	state->config = config;
204
205	/* create dvb_frontend */
206	memcpy(&state->frontend.ops, &ttusbdecfe_dvbt_ops, sizeof(struct dvb_frontend_ops));
207	state->frontend.demodulator_priv = state;
208	return &state->frontend;
209}
210
211static struct dvb_frontend_ops ttusbdecfe_dvbs_ops;
212
213struct dvb_frontend* ttusbdecfe_dvbs_attach(const struct ttusbdecfe_config* config)
214{
215	struct ttusbdecfe_state* state = NULL;
216
217	/* allocate memory for the internal state */
218	state = kmalloc(sizeof(struct ttusbdecfe_state), GFP_KERNEL);
219	if (state == NULL)
220		return NULL;
221
222	/* setup the state */
223	state->config = config;
224	state->voltage = 0;
225	state->hi_band = 0;
226
227	/* create dvb_frontend */
228	memcpy(&state->frontend.ops, &ttusbdecfe_dvbs_ops, sizeof(struct dvb_frontend_ops));
229	state->frontend.demodulator_priv = state;
230	return &state->frontend;
231}
232
233static struct dvb_frontend_ops ttusbdecfe_dvbt_ops = {
234
235	.info = {
236		.name			= "TechnoTrend/Hauppauge DEC2000-t Frontend",
237		.type			= FE_OFDM,
238		.frequency_min		= 51000000,
239		.frequency_max		= 858000000,
240		.frequency_stepsize	= 62500,
241		.caps =	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
242			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
243			FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
244			FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
245			FE_CAN_HIERARCHY_AUTO,
246	},
247
248	.release = ttusbdecfe_release,
249
250	.set_frontend = ttusbdecfe_dvbt_set_frontend,
251
252	.get_tune_settings = ttusbdecfe_dvbt_get_tune_settings,
253
254	.read_status = ttusbdecfe_read_status,
255};
256
257static struct dvb_frontend_ops ttusbdecfe_dvbs_ops = {
258
259	.info = {
260		.name			= "TechnoTrend/Hauppauge DEC3000-s Frontend",
261		.type			= FE_QPSK,
262		.frequency_min		= 950000,
263		.frequency_max		= 2150000,
264		.frequency_stepsize	= 125,
265		.symbol_rate_min        = 1000000,  /* guessed */
266		.symbol_rate_max        = 45000000, /* guessed */
267		.caps =	FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
268			FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
269			FE_CAN_QPSK
270	},
271
272	.release = ttusbdecfe_release,
273
274	.set_frontend = ttusbdecfe_dvbs_set_frontend,
275
276	.read_status = ttusbdecfe_read_status,
277
278	.diseqc_send_master_cmd = ttusbdecfe_dvbs_diseqc_send_master_cmd,
279	.set_voltage = ttusbdecfe_dvbs_set_voltage,
280	.set_tone = ttusbdecfe_dvbs_set_tone,
281};
282
283MODULE_DESCRIPTION("TTUSB DEC DVB-T/S Demodulator driver");
284MODULE_AUTHOR("Alex Woods/Andrew de Quincey");
285MODULE_LICENSE("GPL");
286
287EXPORT_SYMBOL(ttusbdecfe_dvbt_attach);
288EXPORT_SYMBOL(ttusbdecfe_dvbs_attach);
289