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