Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/dvb/ttusb-dec/ttusbdecfe.c
15115 views
1
/*
2
* TTUSB DEC Frontend Driver
3
*
4
* Copyright (C) 2003-2004 Alex Woods <[email protected]>
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, 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
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
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
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
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
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
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
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
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
300