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/delay.h>
11 #include "dvb_frontend.h"
14 static unsigned int debug
= 0;
15 module_param(debug
, int, 0644);
16 MODULE_PARM_DESC(debug
,"lgdt3304 debugging (default off)");
18 #define dprintk(fmt, args...) if (debug) do {\
19 printk("lgdt3304 debug: " fmt, ##args); } while (0)
23 struct dvb_frontend frontend
;
24 fe_modulation_t current_modulation
;
26 __u32 current_frequency
;
28 struct i2c_adapter
*i2c
;
31 static int i2c_write_demod_bytes (struct dvb_frontend
*fe
, __u8
*buf
, int len
)
33 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
34 struct i2c_msg i2cmsgs
= {
43 for (i
=0; i
<len
-1; i
+=3){
44 if((err
= i2c_transfer(state
->i2c
, &i2cmsgs
, 1))<0) {
45 printk("%s i2c_transfer error %d\n", __func__
, err
);
56 static int lgdt3304_i2c_read_reg(struct dvb_frontend
*fe
, unsigned int reg
)
58 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
59 struct i2c_msg i2cmsgs
[2];
63 __u8 regbuf
[2] = { reg
>>8, reg
&0xff };
65 i2cmsgs
[0].addr
= state
->addr
;
68 i2cmsgs
[0].buf
= regbuf
;
70 i2cmsgs
[1].addr
= state
->addr
;
71 i2cmsgs
[1].flags
= I2C_M_RD
;
73 i2cmsgs
[1].buf
= &buf
;
75 if((ret
= i2c_transfer(state
->i2c
, i2cmsgs
, 2))<0) {
76 printk("%s i2c_transfer error %d\n", __func__
, ret
);
83 static int lgdt3304_i2c_write_reg(struct dvb_frontend
*fe
, int reg
, int val
)
85 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
86 char buffer
[3] = { reg
>>8, reg
&0xff, val
};
89 struct i2c_msg i2cmsgs
= {
95 ret
= i2c_transfer(state
->i2c
, &i2cmsgs
, 1);
97 printk("%s i2c_transfer error %d\n", __func__
, ret
);
105 static int lgdt3304_soft_Reset(struct dvb_frontend
*fe
)
107 lgdt3304_i2c_write_reg(fe
, 0x0002, 0x9a);
108 lgdt3304_i2c_write_reg(fe
, 0x0002, 0x9b);
113 static int lgdt3304_set_parameters(struct dvb_frontend
*fe
, struct dvb_frontend_parameters
*param
) {
116 static __u8 lgdt3304_vsb8_data
[] = {
142 /* not yet tested .. */
143 static __u8 lgdt3304_qam64_data
[] = {
161 /* tested with KWorld a340 */
162 static __u8 lgdt3304_qam256_data
[] = {
165 0x00, 0x00, 0x01, //0x19,
221 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
222 if (state
->current_modulation
!= param
->u
.vsb
.modulation
) {
223 switch(param
->u
.vsb
.modulation
) {
225 err
= i2c_write_demod_bytes(fe
, lgdt3304_vsb8_data
,
226 sizeof(lgdt3304_vsb8_data
));
229 err
= i2c_write_demod_bytes(fe
, lgdt3304_qam64_data
,
230 sizeof(lgdt3304_qam64_data
));
233 err
= i2c_write_demod_bytes(fe
, lgdt3304_qam256_data
,
234 sizeof(lgdt3304_qam256_data
));
241 printk("%s error setting modulation\n", __func__
);
243 state
->current_modulation
= param
->u
.vsb
.modulation
;
246 state
->current_frequency
= param
->frequency
;
248 lgdt3304_soft_Reset(fe
);
251 if (fe
->ops
.tuner_ops
.set_params
)
252 fe
->ops
.tuner_ops
.set_params(fe
, param
);
257 static int lgdt3304_init(struct dvb_frontend
*fe
) {
261 static int lgdt3304_sleep(struct dvb_frontend
*fe
) {
266 static int lgdt3304_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
268 struct lgdt3304_state
*state
= fe
->demodulator_priv
;
273 dprintk("lgdt read status\n");
275 r011d
= lgdt3304_i2c_read_reg(fe
, 0x011d);
277 dprintk("%02x\n", r011d
);
279 switch(state
->current_modulation
) {
282 dprintk("VSB Locked\n");
283 *status
|= FE_HAS_CARRIER
;
284 *status
|= FE_HAS_LOCK
;
285 *status
|= FE_HAS_SYNC
;
286 *status
|= FE_HAS_SIGNAL
;
291 qam_lck
= r011d
& 0x7;
293 case 0x0: dprintk("Unlock\n");
295 case 0x4: dprintk("1st Lock in acquisition state\n");
297 case 0x6: dprintk("2nd Lock in acquisition state\n");
299 case 0x7: dprintk("Final Lock in good reception state\n");
300 *status
|= FE_HAS_CARRIER
;
301 *status
|= FE_HAS_LOCK
;
302 *status
|= FE_HAS_SYNC
;
303 *status
|= FE_HAS_SIGNAL
;
308 printk("%s unhandled modulation\n", __func__
);
315 static int lgdt3304_read_ber(struct dvb_frontend
*fe
, __u32
*ber
)
317 dprintk("read ber\n");
321 static int lgdt3304_read_snr(struct dvb_frontend
*fe
, __u16
*snr
)
323 dprintk("read snr\n");
327 static int lgdt3304_read_ucblocks(struct dvb_frontend
*fe
, __u32
*ucblocks
)
329 dprintk("read ucblocks\n");
333 static void lgdt3304_release(struct dvb_frontend
*fe
)
335 struct lgdt3304_state
*state
= (struct lgdt3304_state
*)fe
->demodulator_priv
;
339 static struct dvb_frontend_ops demod_lgdt3304
={
343 .frequency_min
= 54000000,
344 .frequency_max
= 858000000,
345 .frequency_stepsize
= 62500,
346 .symbol_rate_min
= 5056941,
347 .symbol_rate_max
= 10762000,
348 .caps
= FE_CAN_QAM_64
| FE_CAN_QAM_256
| FE_CAN_8VSB
350 .init
= lgdt3304_init
,
351 .sleep
= lgdt3304_sleep
,
352 .set_frontend
= lgdt3304_set_parameters
,
353 .read_snr
= lgdt3304_read_snr
,
354 .read_ber
= lgdt3304_read_ber
,
355 .read_status
= lgdt3304_read_status
,
356 .read_ucblocks
= lgdt3304_read_ucblocks
,
357 .release
= lgdt3304_release
,
360 struct dvb_frontend
* lgdt3304_attach(const struct lgdt3304_config
*config
,
361 struct i2c_adapter
*i2c
)
364 struct lgdt3304_state
*state
;
365 state
= kzalloc(sizeof(struct lgdt3304_state
), GFP_KERNEL
);
368 state
->addr
= config
->i2c_address
;
371 memcpy(&state
->frontend
.ops
, &demod_lgdt3304
, sizeof(struct dvb_frontend_ops
));
372 state
->frontend
.demodulator_priv
= state
;
373 return &state
->frontend
;
376 EXPORT_SYMBOL_GPL(lgdt3304_attach
);
377 MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
378 MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
379 MODULE_LICENSE("GPL");