GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / drivers / media / dvb / frontends / lgdt3304.c
blob45a529b06b9d31b13531d0181a29259ae54b8f98
1 /*
2 * Driver for LG ATSC lgdt3304 driver
4 * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
6 */
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"
13 #include "lgdt3304.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)
22 struct lgdt3304_state
24 struct dvb_frontend frontend;
25 fe_modulation_t current_modulation;
26 __u32 snr;
27 __u32 current_frequency;
28 __u8 addr;
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 = {
36 .addr = state->addr,
37 .flags = 0,
38 .len = 3,
39 .buf = buf
41 int i;
42 int err;
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);
47 if (err < 0)
48 return err;
49 else
50 return -EREMOTEIO;
52 i2cmsgs.buf += 3;
54 return 0;
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];
61 int ret;
62 __u8 buf;
64 __u8 regbuf[2] = { reg>>8, reg&0xff };
66 i2cmsgs[0].addr = state->addr;
67 i2cmsgs[0].flags = 0;
68 i2cmsgs[0].len = 2;
69 i2cmsgs[0].buf = regbuf;
71 i2cmsgs[1].addr = state->addr;
72 i2cmsgs[1].flags = I2C_M_RD;
73 i2cmsgs[1].len = 1;
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);
78 return ret;
81 return buf;
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 };
88 int ret;
90 struct i2c_msg i2cmsgs = {
91 .addr = state->addr,
92 .flags = 0,
93 .len = 3,
94 .buf=buffer
96 ret = i2c_transfer(state->i2c, &i2cmsgs, 1);
97 if (ret != 1) {
98 printk("%s i2c_transfer error %d\n", __func__, ret);
99 return ret;
102 return 0;
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);
110 mdelay(200);
111 return 0;
114 static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
115 int err = 0;
117 static __u8 lgdt3304_vsb8_data[] = {
118 /* 16bit , 8bit */
119 /* regs , val */
120 0x00, 0x00, 0x02,
121 0x00, 0x00, 0x13,
122 0x00, 0x0d, 0x02,
123 0x00, 0x0e, 0x02,
124 0x00, 0x12, 0x32,
125 0x00, 0x13, 0xc4,
126 0x01, 0x12, 0x17,
127 0x01, 0x13, 0x15,
128 0x01, 0x14, 0x18,
129 0x01, 0x15, 0xff,
130 0x01, 0x16, 0x2c,
131 0x02, 0x14, 0x67,
132 0x02, 0x24, 0x8d,
133 0x04, 0x27, 0x12,
134 0x04, 0x28, 0x4f,
135 0x03, 0x08, 0x80,
136 0x03, 0x09, 0x00,
137 0x03, 0x0d, 0x00,
138 0x03, 0x0e, 0x1c,
139 0x03, 0x14, 0xe1,
140 0x05, 0x0e, 0x5b,
143 /* not yet tested .. */
144 static __u8 lgdt3304_qam64_data[] = {
145 /* 16bit , 8bit */
146 /* regs , val */
147 0x00, 0x00, 0x18,
148 0x00, 0x0d, 0x02,
149 //0x00, 0x0e, 0x02,
150 0x00, 0x12, 0x2a,
151 0x00, 0x13, 0x00,
152 0x03, 0x14, 0xe3,
153 0x03, 0x0e, 0x1c,
154 0x03, 0x08, 0x66,
155 0x03, 0x09, 0x66,
156 0x03, 0x0a, 0x08,
157 0x03, 0x0b, 0x9b,
158 0x05, 0x0e, 0x5b,
162 /* tested with KWorld a340 */
163 static __u8 lgdt3304_qam256_data[] = {
164 /* 16bit , 8bit */
165 /* regs , val */
166 0x00, 0x00, 0x01, //0x19,
167 0x00, 0x12, 0x2a,
168 0x00, 0x13, 0x80,
169 0x00, 0x0d, 0x02,
170 0x03, 0x14, 0xe3,
172 0x03, 0x0e, 0x1c,
173 0x03, 0x08, 0x66,
174 0x03, 0x09, 0x66,
175 0x03, 0x0a, 0x08,
176 0x03, 0x0b, 0x9b,
178 0x03, 0x0d, 0x14,
179 //0x05, 0x0e, 0x5b,
180 0x01, 0x06, 0x4a,
181 0x01, 0x07, 0x3d,
182 0x01, 0x08, 0x70,
183 0x01, 0x09, 0xa3,
185 0x05, 0x04, 0xfd,
187 0x00, 0x0d, 0x82,
189 0x05, 0x0e, 0x5b,
191 0x05, 0x0e, 0x5b,
193 0x00, 0x02, 0x9a,
195 0x00, 0x02, 0x9b,
197 0x00, 0x00, 0x01,
198 0x00, 0x12, 0x2a,
199 0x00, 0x13, 0x80,
200 0x00, 0x0d, 0x02,
201 0x03, 0x14, 0xe3,
203 0x03, 0x0e, 0x1c,
204 0x03, 0x08, 0x66,
205 0x03, 0x09, 0x66,
206 0x03, 0x0a, 0x08,
207 0x03, 0x0b, 0x9b,
209 0x03, 0x0d, 0x14,
210 0x01, 0x06, 0x4a,
211 0x01, 0x07, 0x3d,
212 0x01, 0x08, 0x70,
213 0x01, 0x09, 0xa3,
215 0x05, 0x04, 0xfd,
217 0x00, 0x0d, 0x82,
219 0x05, 0x0e, 0x5b,
222 struct lgdt3304_state *state = fe->demodulator_priv;
223 if (state->current_modulation != param->u.vsb.modulation) {
224 switch(param->u.vsb.modulation) {
225 case VSB_8:
226 err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data,
227 sizeof(lgdt3304_vsb8_data));
228 break;
229 case QAM_64:
230 err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data,
231 sizeof(lgdt3304_qam64_data));
232 break;
233 case QAM_256:
234 err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data,
235 sizeof(lgdt3304_qam256_data));
236 break;
237 default:
238 break;
241 if (err) {
242 printk("%s error setting modulation\n", __func__);
243 } else {
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);
255 return 0;
258 static int lgdt3304_init(struct dvb_frontend *fe) {
259 return 0;
262 static int lgdt3304_sleep(struct dvb_frontend *fe) {
263 return 0;
267 static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status)
269 struct lgdt3304_state *state = fe->demodulator_priv;
270 int r011d;
271 int qam_lck;
273 *status = 0;
274 dprintk("lgdt read status\n");
276 r011d = lgdt3304_i2c_read_reg(fe, 0x011d);
278 dprintk("%02x\n", r011d);
280 switch(state->current_modulation) {
281 case VSB_8:
282 if (r011d & 0x80) {
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;
289 break;
290 case QAM_64:
291 case QAM_256:
292 qam_lck = r011d & 0x7;
293 switch(qam_lck) {
294 case 0x0: dprintk("Unlock\n");
295 break;
296 case 0x4: dprintk("1st Lock in acquisition state\n");
297 break;
298 case 0x6: dprintk("2nd Lock in acquisition state\n");
299 break;
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;
305 break;
307 break;
308 default:
309 printk("%s unhandled modulation\n", __func__);
313 return 0;
316 static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
318 dprintk("read ber\n");
319 return 0;
322 static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
324 dprintk("read snr\n");
325 return 0;
328 static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
330 dprintk("read ucblocks\n");
331 return 0;
334 static void lgdt3304_release(struct dvb_frontend *fe)
336 struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
337 kfree(state);
340 static struct dvb_frontend_ops demod_lgdt3304={
341 .info = {
342 .name = "LG 3304",
343 .type = FE_ATSC,
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);
367 if (state == NULL)
368 return NULL;
369 state->addr = config->i2c_address;
370 state->i2c = i2c;
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");