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);
366 state->addr = config->i2c_address;
369 memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
370 state->frontend.demodulator_priv = state;
371 return &state->frontend;
374 EXPORT_SYMBOL_GPL(lgdt3304_attach);
375 MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
376 MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
377 MODULE_LICENSE("GPL");