2 * E3C EC100 demodulator driver
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
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.
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.
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.
22 #include "dvb_frontend.h"
26 struct i2c_adapter
*i2c
;
27 struct dvb_frontend frontend
;
28 struct ec100_config config
;
33 /* write single register */
34 static int ec100_write_reg(struct ec100_state
*state
, u8 reg
, u8 val
)
37 u8 buf
[2] = {reg
, val
};
38 struct i2c_msg msg
[1] = {
40 .addr
= state
->config
.demod_address
,
47 ret
= i2c_transfer(state
->i2c
, msg
, 1);
51 dev_warn(&state
->i2c
->dev
, "%s: i2c wr failed=%d reg=%02x\n",
52 KBUILD_MODNAME
, ret
, reg
);
59 /* read single register */
60 static int ec100_read_reg(struct ec100_state
*state
, u8 reg
, u8
*val
)
63 struct i2c_msg msg
[2] = {
65 .addr
= state
->config
.demod_address
,
70 .addr
= state
->config
.demod_address
,
77 ret
= i2c_transfer(state
->i2c
, msg
, 2);
81 dev_warn(&state
->i2c
->dev
, "%s: i2c rd failed=%d reg=%02x\n",
82 KBUILD_MODNAME
, ret
, reg
);
89 static int ec100_set_frontend(struct dvb_frontend
*fe
)
91 struct dtv_frontend_properties
*c
= &fe
->dtv_property_cache
;
92 struct ec100_state
*state
= fe
->demodulator_priv
;
96 dev_dbg(&state
->i2c
->dev
, "%s: frequency=%d bandwidth_hz=%d\n",
97 __func__
, c
->frequency
, c
->bandwidth_hz
);
100 if (fe
->ops
.tuner_ops
.set_params
)
101 fe
->ops
.tuner_ops
.set_params(fe
);
103 ret
= ec100_write_reg(state
, 0x04, 0x06);
106 ret
= ec100_write_reg(state
, 0x67, 0x58);
109 ret
= ec100_write_reg(state
, 0x05, 0x18);
113 /* reg/bw | 6 | 7 | 8
114 -------+------+------+------
115 A 0x1b | 0xa1 | 0xe7 | 0x2c
116 A 0x1c | 0x55 | 0x63 | 0x72
117 -------+------+------+------
118 B 0x1b | 0xb7 | 0x00 | 0x49
119 B 0x1c | 0x55 | 0x64 | 0x72 */
121 switch (c
->bandwidth_hz
) {
136 ret
= ec100_write_reg(state
, 0x1b, tmp
);
139 ret
= ec100_write_reg(state
, 0x1c, tmp2
);
143 ret
= ec100_write_reg(state
, 0x0c, 0xbb); /* if freq */
146 ret
= ec100_write_reg(state
, 0x0d, 0x31); /* if freq */
150 ret
= ec100_write_reg(state
, 0x08, 0x24);
154 ret
= ec100_write_reg(state
, 0x00, 0x00); /* go */
157 ret
= ec100_write_reg(state
, 0x00, 0x20); /* go */
163 dev_dbg(&state
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
167 static int ec100_get_tune_settings(struct dvb_frontend
*fe
,
168 struct dvb_frontend_tune_settings
*fesettings
)
170 fesettings
->min_delay_ms
= 300;
171 fesettings
->step_size
= 0;
172 fesettings
->max_drift
= 0;
177 static int ec100_read_status(struct dvb_frontend
*fe
, enum fe_status
*status
)
179 struct ec100_state
*state
= fe
->demodulator_priv
;
184 ret
= ec100_read_reg(state
, 0x42, &tmp
);
189 /* bit7 set - have lock */
190 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_VITERBI
|
191 FE_HAS_SYNC
| FE_HAS_LOCK
;
193 ret
= ec100_read_reg(state
, 0x01, &tmp
);
198 /* bit4 set - have signal */
199 *status
|= FE_HAS_SIGNAL
;
201 /* bit0 clear - have ~valid signal */
202 *status
|= FE_HAS_CARRIER
| FE_HAS_VITERBI
;
209 dev_dbg(&state
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
213 static int ec100_read_ber(struct dvb_frontend
*fe
, u32
*ber
)
215 struct ec100_state
*state
= fe
->demodulator_priv
;
222 ret
= ec100_read_reg(state
, 0x65, &tmp
);
225 ret
= ec100_read_reg(state
, 0x66, &tmp2
);
229 ber2
= (tmp2
<< 8) | tmp
;
231 /* if counter overflow or clear */
232 if (ber2
< state
->ber
)
235 *ber
= ber2
- state
->ber
;
241 dev_dbg(&state
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
245 static int ec100_read_signal_strength(struct dvb_frontend
*fe
, u16
*strength
)
247 struct ec100_state
*state
= fe
->demodulator_priv
;
251 ret
= ec100_read_reg(state
, 0x24, &tmp
);
257 *strength
= ((tmp
<< 8) | tmp
);
261 dev_dbg(&state
->i2c
->dev
, "%s: failed=%d\n", __func__
, ret
);
265 static int ec100_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
271 static int ec100_read_ucblocks(struct dvb_frontend
*fe
, u32
*ucblocks
)
277 static void ec100_release(struct dvb_frontend
*fe
)
279 struct ec100_state
*state
= fe
->demodulator_priv
;
283 static const struct dvb_frontend_ops ec100_ops
;
285 struct dvb_frontend
*ec100_attach(const struct ec100_config
*config
,
286 struct i2c_adapter
*i2c
)
289 struct ec100_state
*state
= NULL
;
292 /* allocate memory for the internal state */
293 state
= kzalloc(sizeof(struct ec100_state
), GFP_KERNEL
);
297 /* setup the state */
299 memcpy(&state
->config
, config
, sizeof(struct ec100_config
));
301 /* check if the demod is there */
302 ret
= ec100_read_reg(state
, 0x33, &tmp
);
303 if (ret
|| tmp
!= 0x0b)
306 /* create dvb_frontend */
307 memcpy(&state
->frontend
.ops
, &ec100_ops
,
308 sizeof(struct dvb_frontend_ops
));
309 state
->frontend
.demodulator_priv
= state
;
311 return &state
->frontend
;
316 EXPORT_SYMBOL(ec100_attach
);
318 static const struct dvb_frontend_ops ec100_ops
= {
319 .delsys
= { SYS_DVBT
},
321 .name
= "E3C EC100 DVB-T",
323 FE_CAN_FEC_1_2
| FE_CAN_FEC_2_3
| FE_CAN_FEC_3_4
|
324 FE_CAN_FEC_5_6
| FE_CAN_FEC_7_8
| FE_CAN_FEC_AUTO
|
325 FE_CAN_QPSK
| FE_CAN_QAM_16
|
326 FE_CAN_QAM_64
| FE_CAN_QAM_AUTO
|
327 FE_CAN_TRANSMISSION_MODE_AUTO
|
328 FE_CAN_GUARD_INTERVAL_AUTO
|
329 FE_CAN_HIERARCHY_AUTO
|
333 .release
= ec100_release
,
334 .set_frontend
= ec100_set_frontend
,
335 .get_tune_settings
= ec100_get_tune_settings
,
336 .read_status
= ec100_read_status
,
337 .read_ber
= ec100_read_ber
,
338 .read_signal_strength
= ec100_read_signal_strength
,
339 .read_snr
= ec100_read_snr
,
340 .read_ucblocks
= ec100_read_ucblocks
,
343 MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
344 MODULE_DESCRIPTION("E3C EC100 DVB-T demodulator driver");
345 MODULE_LICENSE("GPL");