PageRenderTime 22ms CodeModel.GetById 6ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/media/dvb/frontends/ec100.c

https://bitbucket.org/abioy/linux
C | 335 lines | 247 code | 50 blank | 38 comment | 31 complexity | 24815c4c20221a46923cbe8ee066d79e MD5 | raw file
Possible License(s): CC-BY-SA-3.0, GPL-2.0, LGPL-2.0, AGPL-1.0
  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 *    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 "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/* write single register */
 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/* read single register */
 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 = &reg
 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	struct dvb_frontend_parameters *params)
 81{
 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__, params->frequency,
 87		params->u.ofdm.bandwidth);
 88
 89	/* program tuner */
 90	if (fe->ops.tuner_ops.set_params)
 91		fe->ops.tuner_ops.set_params(fe, params);
 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	/* reg/bw |   6  |   7  |   8
104	   -------+------+------+------
105	   A 0x1b | 0xa1 | 0xe7 | 0x2c
106	   A 0x1c | 0x55 | 0x63 | 0x72
107	   -------+------+------+------
108	   B 0x1b | 0xb7 | 0x00 | 0x49
109	   B 0x1c | 0x55 | 0x64 | 0x72 */
110
111	switch (params->u.ofdm.bandwidth) {
112	case BANDWIDTH_6_MHZ:
113		tmp = 0xb7;
114		tmp2 = 0x55;
115		break;
116	case BANDWIDTH_7_MHZ:
117		tmp = 0x00;
118		tmp2 = 0x64;
119		break;
120	case BANDWIDTH_8_MHZ:
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); /* if freq */
134	if (ret)
135		goto error;
136	ret = ec100_write_reg(state, 0x0d, 0x31); /* if freq */
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); /* go */
145	if (ret)
146		goto error;
147	ret = ec100_write_reg(state, 0x00, 0x20); /* go */
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		/* bit7 set - have lock */
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			/* bit4 set - have signal */
189			*status |= FE_HAS_SIGNAL;
190			if (!(tmp & 0x01)) {
191				/* bit0 clear - have ~valid signal */
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	/* if counter overflow or clear */
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	/* allocate memory for the internal state */
283	state = kzalloc(sizeof(struct ec100_state), GFP_KERNEL);
284	if (state == NULL)
285		goto error;
286
287	/* setup the state */
288	state->i2c = i2c;
289	memcpy(&state->config, config, sizeof(struct ec100_config));
290
291	/* check if the demod is there */
292	ret = ec100_read_reg(state, 0x33, &tmp);
293	if (ret || tmp != 0x0b)
294		goto error;
295
296	/* create dvb_frontend */
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	.info = {
310		.name = "E3C EC100 DVB-T",
311		.type = FE_OFDM,
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");