2 * Driver for LG ATSC lgdt3304 driver
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/delay.h>
12 #include "dvb_frontend.h"
15 static unsigned int debug
= 0;
16 module_param(debug
, int, 0644);
17 MODULE_PARM_DESC(debug
,"lgdt3304 debugging (default off)");
19 #define dprintk(fmt, args...) if (debug) do {\
20 printk("lgdt3304 debug: " fmt, ##args); } while (0)
24 struct dvb_frontend frontend
;
25 fe_modulation_t current_modulation
;
27 __u32 current_frequency
;
29 struct i2c_adapter
*i2c
;
32 static int i2c_write_demod_bytes (struct dvb_frontend
*fe
, __u8
*buf
, int len
)
34 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
35 struct i2c_msg i2cmsgs
= {
44 for (i
=0; i
<len
-1; i
+=3){
45 if((err
= i2c_transfer(state
->i2c
, &i2cmsgs
, 1))<0) {
46 printk("%s i2c_transfer error %d\n", __func__
, err
);
57 static int lgdt3304_i2c_read_reg(struct dvb_frontend
*fe
, unsigned int reg
)
59 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
60 struct i2c_msg i2cmsgs
[2];
64 __u8 regbuf
[2] = { reg
>>8, reg
&0xff };
66 i2cmsgs
[0].addr
= state
->addr
;
69 i2cmsgs
[0].buf
= regbuf
;
71 i2cmsgs
[1].addr
= state
->addr
;
72 i2cmsgs
[1].flags
= I2C_M_RD
;
74 i2cmsgs
[1].buf
= &buf
;
76 if((ret
= i2c_transfer(state
->i2c
, i2cmsgs
, 2))<0) {
77 printk("%s i2c_transfer error %d\n", __func__
, ret
);
84 static int lgdt3304_i2c_write_reg(struct dvb_frontend
*fe
, int reg
, int val
)
86 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
87 char buffer
[3] = { reg
>>8, reg
&0xff, val
};
90 struct i2c_msg i2cmsgs
= {
96 ret
= i2c_transfer(state
->i2c
, &i2cmsgs
, 1);
98 printk("%s i2c_transfer error %d\n", __func__
, ret
);
106 static int lgdt3304_soft_Reset(struct dvb_frontend
*fe
)
108 lgdt3304_i2c_write_reg(fe
, 0x0002, 0x9a);
109 lgdt3304_i2c_write_reg(fe
, 0x0002, 0x9b);
114 static int lgdt3304_set_parameters(struct dvb_frontend
*fe
, struct dvb_frontend_parameters
*param
) {
117 static __u8 lgdt3304_vsb8_data
[] = {
143 /* not yet tested .. */
144 static __u8 lgdt3304_qam64_data
[] = {
162 /* tested with KWorld a340 */
163 static __u8 lgdt3304_qam256_data
[] = {
166 0x00, 0x00, 0x01, //0x19,
222 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
223 if (state
->current_modulation
!= param
->u
.vsb
.modulation
) {
224 switch(param
->u
.vsb
.modulation
) {
226 err
= i2c_write_demod_bytes(fe
, lgdt3304_vsb8_data
,
227 sizeof(lgdt3304_vsb8_data
));
230 err
= i2c_write_demod_bytes(fe
, lgdt3304_qam64_data
,
231 sizeof(lgdt3304_qam64_data
));
234 err
= i2c_write_demod_bytes(fe
, lgdt3304_qam256_data
,
235 sizeof(lgdt3304_qam256_data
));
242 printk("%s error setting modulation\n", __func__
);
244 state
->current_modulation
= param
->u
.vsb
.modulation
;
247 state
->current_frequency
= param
->frequency
;
249 lgdt3304_soft_Reset(fe
);
252 if (fe
->ops
.tuner_ops
.set_params
)
253 fe
->ops
.tuner_ops
.set_params(fe
, param
);
258 static int lgdt3304_init(struct dvb_frontend
*fe
) {
262 static int lgdt3304_sleep(struct dvb_frontend
*fe
) {
267 static int lgdt3304_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
269 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
274 dprintk("lgdt read status\n");
276 r011d
= lgdt3304_i2c_read_reg(fe
, 0x011d);
278 dprintk("%02x\n", r011d
);
280 switch(state
->current_modulation
) {
283 dprintk("VSB Locked\n");
284 *status
|= FE_HAS_CARRIER
;
285 *status
|= FE_HAS_LOCK
;
286 *status
|= FE_HAS_SYNC
;
287 *status
|= FE_HAS_SIGNAL
;
292 qam_lck
= r011d
& 0x7;
294 case 0x0: dprintk("Unlock\n");
296 case 0x4: dprintk("1st Lock in acquisition state\n");
298 case 0x6: dprintk("2nd Lock in acquisition state\n");
300 case 0x7: dprintk("Final Lock in good reception state\n");
301 *status
|= FE_HAS_CARRIER
;
302 *status
|= FE_HAS_LOCK
;
303 *status
|= FE_HAS_SYNC
;
304 *status
|= FE_HAS_SIGNAL
;
309 printk("%s unhandled modulation\n", __func__
);
316 static int lgdt3304_read_ber(struct dvb_frontend
*fe
, __u32
*ber
)
318 dprintk("read ber\n");
322 static int lgdt3304_read_snr(struct dvb_frontend
*fe
, __u16
*snr
)
324 dprintk("read snr\n");
328 static int lgdt3304_read_ucblocks(struct dvb_frontend
*fe
, __u32
*ucblocks
)
330 dprintk("read ucblocks\n");
334 static void lgdt3304_release(struct dvb_frontend
*fe
)
336 struct lgdt3304_state
*state
= (struct lgdt3304_state
*)fe
->demodulator_priv
;
340 static struct dvb_frontend_ops demod_lgdt3304
={
344 .frequency_min
= 54000000,
345 .frequency_max
= 858000000,
346 .frequency_stepsize
= 62500,
347 .symbol_rate_min
= 5056941,
348 .symbol_rate_max
= 10762000,
349 .caps
= FE_CAN_QAM_64
| FE_CAN_QAM_256
| FE_CAN_8VSB
351 .init
= lgdt3304_init
,
352 .sleep
= lgdt3304_sleep
,
353 .set_frontend
= lgdt3304_set_parameters
,
354 .read_snr
= lgdt3304_read_snr
,
355 .read_ber
= lgdt3304_read_ber
,
356 .read_status
= lgdt3304_read_status
,
357 .read_ucblocks
= lgdt3304_read_ucblocks
,
358 .release
= lgdt3304_release
,
361 struct dvb_frontend
* lgdt3304_attach(const struct lgdt3304_config
*config
,
362 struct i2c_adapter
*i2c
)
365 struct lgdt3304_state
*state
;
366 state
= kzalloc(sizeof(struct lgdt3304_state
), GFP_KERNEL
);
369 state
->addr
= config
->i2c_address
;
372 memcpy(&state
->frontend
.ops
, &demod_lgdt3304
, sizeof(struct dvb_frontend_ops
));
373 state
->frontend
.demodulator_priv
= state
;
374 return &state
->frontend
;
377 EXPORT_SYMBOL_GPL(lgdt3304_attach
);
378 MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
379 MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
380 MODULE_LICENSE("GPL");