1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22#include "dvb_frontend.h"
23#include "ec100_priv.h"
24#include "ec100.h"
25
26int ec100_debug;
27module_param_named(debug, ec100_debug, int, 0644);
28MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
29
30struct ec100_state {
31 struct i2c_adapter *i2c;
32 struct dvb_frontend frontend;
33 struct ec100_config config;
34
35 u16 ber;
36};
37
38
39static int ec100_write_reg(struct ec100_state *state, u8 reg, u8 val)
40{
41 u8 buf[2] = {reg, val};
42 struct i2c_msg msg = {
43 .addr = state->config.demod_address,
44 .flags = 0,
45 .len = 2,
46 .buf = buf};
47
48 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
49 warn("I2C write failed reg:%02x", reg);
50 return -EREMOTEIO;
51 }
52 return 0;
53}
54
55
56static int ec100_read_reg(struct ec100_state *state, u8 reg, u8 *val)
57{
58 struct i2c_msg msg[2] = {
59 {
60 .addr = state->config.demod_address,
61 .flags = 0,
62 .len = 1,
63 .buf = ®
64 }, {
65 .addr = state->config.demod_address,
66 .flags = I2C_M_RD,
67 .len = 1,
68 .buf = val
69 }
70 };
71
72 if (i2c_transfer(state->i2c, msg, 2) != 2) {
73 warn("I2C read failed reg:%02x", reg);
74 return -EREMOTEIO;
75 }
76 return 0;
77}
78
79static int ec100_set_frontend(struct dvb_frontend *fe)
80{
81 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
82 struct ec100_state *state = fe->demodulator_priv;
83 int ret;
84 u8 tmp, tmp2;
85
86 deb_info("%s: freq:%d bw:%d\n", __func__, c->frequency,
87 c->bandwidth_hz);
88
89
90 if (fe->ops.tuner_ops.set_params)
91 fe->ops.tuner_ops.set_params(fe);
92
93 ret = ec100_write_reg(state, 0x04, 0x06);
94 if (ret)
95 goto error;
96 ret = ec100_write_reg(state, 0x67, 0x58);
97 if (ret)
98 goto error;
99 ret = ec100_write_reg(state, 0x05, 0x18);
100 if (ret)
101 goto error;
102
103
104
105
106
107
108
109
110
111 switch (c->bandwidth_hz) {
112 case 6000000:
113 tmp = 0xb7;
114 tmp2 = 0x55;
115 break;
116 case 7000000:
117 tmp = 0x00;
118 tmp2 = 0x64;
119 break;
120 case 8000000:
121 default:
122 tmp = 0x49;
123 tmp2 = 0x72;
124 }
125
126 ret = ec100_write_reg(state, 0x1b, tmp);
127 if (ret)
128 goto error;
129 ret = ec100_write_reg(state, 0x1c, tmp2);
130 if (ret)
131 goto error;
132
133 ret = ec100_write_reg(state, 0x0c, 0xbb);
134 if (ret)
135 goto error;
136 ret = ec100_write_reg(state, 0x0d, 0x31);
137 if (ret)
138 goto error;
139
140 ret = ec100_write_reg(state, 0x08, 0x24);
141 if (ret)
142 goto error;
143
144 ret = ec100_write_reg(state, 0x00, 0x00);
145 if (ret)
146 goto error;
147 ret = ec100_write_reg(state, 0x00, 0x20);
148 if (ret)
149 goto error;
150
151 return ret;
152error:
153 deb_info("%s: failed:%d\n", __func__, ret);
154 return ret;
155}
156
157static int ec100_get_tune_settings(struct dvb_frontend *fe,
158 struct dvb_frontend_tune_settings *fesettings)
159{
160 fesettings->min_delay_ms = 300;
161 fesettings->step_size = 0;
162 fesettings->max_drift = 0;
163
164 return 0;
165}
166
167static int ec100_read_status(struct dvb_frontend *fe, fe_status_t *status)
168{
169 struct ec100_state *state = fe->demodulator_priv;
170 int ret;
171 u8 tmp;
172 *status = 0;
173
174 ret = ec100_read_reg(state, 0x42, &tmp);
175 if (ret)
176 goto error;
177
178 if (tmp & 0x80) {
179
180 *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI |
181 FE_HAS_SYNC | FE_HAS_LOCK;
182 } else {
183 ret = ec100_read_reg(state, 0x01, &tmp);
184 if (ret)
185 goto error;
186
187 if (tmp & 0x10) {
188
189 *status |= FE_HAS_SIGNAL;
190 if (!(tmp & 0x01)) {
191
192 *status |= FE_HAS_CARRIER | FE_HAS_VITERBI;
193 }
194 }
195 }
196
197 return ret;
198error:
199 deb_info("%s: failed:%d\n", __func__, ret);
200 return ret;
201}
202
203static int ec100_read_ber(struct dvb_frontend *fe, u32 *ber)
204{
205 struct ec100_state *state = fe->demodulator_priv;
206 int ret;
207 u8 tmp, tmp2;
208 u16 ber2;
209
210 *ber = 0;
211
212 ret = ec100_read_reg(state, 0x65, &tmp);
213 if (ret)
214 goto error;
215 ret = ec100_read_reg(state, 0x66, &tmp2);
216 if (ret)
217 goto error;
218
219 ber2 = (tmp2 << 8) | tmp;
220
221
222 if (ber2 < state->ber)
223 *ber = ber2;
224 else
225 *ber = ber2 - state->ber;
226
227 state->ber = ber2;
228
229 return ret;
230error:
231 deb_info("%s: failed:%d\n", __func__, ret);
232 return ret;
233}
234
235static int ec100_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
236{
237 struct ec100_state *state = fe->demodulator_priv;
238 int ret;
239 u8 tmp;
240
241 ret = ec100_read_reg(state, 0x24, &tmp);
242 if (ret) {
243 *strength = 0;
244 goto error;
245 }
246
247 *strength = ((tmp << 8) | tmp);
248
249 return ret;
250error:
251 deb_info("%s: failed:%d\n", __func__, ret);
252 return ret;
253}
254
255static int ec100_read_snr(struct dvb_frontend *fe, u16 *snr)
256{
257 *snr = 0;
258 return 0;
259}
260
261static int ec100_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
262{
263 *ucblocks = 0;
264 return 0;
265}
266
267static void ec100_release(struct dvb_frontend *fe)
268{
269 struct ec100_state *state = fe->demodulator_priv;
270 kfree(state);
271}
272
273static struct dvb_frontend_ops ec100_ops;
274
275struct dvb_frontend *ec100_attach(const struct ec100_config *config,
276 struct i2c_adapter *i2c)
277{
278 int ret;
279 struct ec100_state *state = NULL;
280 u8 tmp;
281
282
283 state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
284 if (state == NULL)
285 goto error;
286
287
288 state->i2c = i2c;
289 memcpy(&state->config, config, sizeof(struct ec100_config));
290
291
292 ret = ec100_read_reg(state, 0x33, &tmp);
293 if (ret || tmp != 0x0b)
294 goto error;
295
296
297 memcpy(&state->frontend.ops, &ec100_ops,
298 sizeof(struct dvb_frontend_ops));
299 state->frontend.demodulator_priv = state;
300
301 return &state->frontend;
302error:
303 kfree(state);
304 return NULL;
305}
306EXPORT_SYMBOL(ec100_attach);
307
308static struct dvb_frontend_ops ec100_ops = {
309 .delsys = { SYS_DVBT },
310 .info = {
311 .name = "E3C EC100 DVB-T",
312 .caps =
313 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
314 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
315 FE_CAN_QPSK | FE_CAN_QAM_16 |
316 FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
317 FE_CAN_TRANSMISSION_MODE_AUTO |
318 FE_CAN_GUARD_INTERVAL_AUTO |
319 FE_CAN_HIERARCHY_AUTO |
320 FE_CAN_MUTE_TS
321 },
322
323 .release = ec100_release,
324 .set_frontend = ec100_set_frontend,
325 .get_tune_settings = ec100_get_tune_settings,
326 .read_status = ec100_read_status,
327 .read_ber = ec100_read_ber,
328 .read_signal_strength = ec100_read_signal_strength,
329 .read_snr = ec100_read_snr,
330 .read_ucblocks = ec100_read_ucblocks,
331};
332
333MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
334MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
335MODULE_LICENSE("GPL");
336