Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes...
[linux-2.6] / drivers / media / dvb / frontends / lgdt3304.c
1 /*
2  * Driver for LG ATSC lgdt3304 driver
3  *
4  * Copyright (C) 2008 Markus Rechberger <mrechberger@sundtek.de>
5  *
6  */
7
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/delay.h>
11 #include "dvb_frontend.h"
12 #include "lgdt3304.h"
13
14 static  unsigned int debug = 0;
15 module_param(debug, int, 0644);
16 MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)");
17
18 #define dprintk(fmt, args...) if (debug) do {\
19                         printk("lgdt3304 debug: " fmt, ##args); } while (0)
20
21 struct lgdt3304_state
22 {
23         struct dvb_frontend frontend;
24         fe_modulation_t current_modulation;
25         __u32 snr;
26         __u32 current_frequency;
27         __u8 addr;
28         struct i2c_adapter *i2c;
29 };
30
31 static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len)
32 {
33         struct lgdt3304_state *state = fe->demodulator_priv;
34         struct i2c_msg i2cmsgs = {
35                 .addr = state->addr,
36                 .flags = 0,
37                 .len = 3,
38                 .buf = buf
39         };
40         int i;
41         int err;
42
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);
46                         if (err < 0)
47                                 return err;
48                         else
49                                 return -EREMOTEIO;
50                 }
51                 i2cmsgs.buf += 3;
52         }
53         return 0;
54 }
55
56 static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg)
57 {
58         struct lgdt3304_state *state = fe->demodulator_priv;
59         struct i2c_msg i2cmsgs[2];
60         int ret;
61         __u8 buf;
62
63         __u8 regbuf[2] = { reg>>8, reg&0xff };
64
65         i2cmsgs[0].addr = state->addr;
66         i2cmsgs[0].flags = 0;
67         i2cmsgs[0].len = 2;
68         i2cmsgs[0].buf = regbuf;
69
70         i2cmsgs[1].addr = state->addr;
71         i2cmsgs[1].flags = I2C_M_RD;
72         i2cmsgs[1].len = 1;
73         i2cmsgs[1].buf = &buf;
74
75         if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) {
76                 printk("%s i2c_transfer error %d\n", __func__, ret);
77                 return ret;
78         }
79
80         return buf;
81 }
82
83 static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val)
84 {
85         struct lgdt3304_state *state = fe->demodulator_priv;
86         char buffer[3] = { reg>>8, reg&0xff, val };
87         int ret;
88
89         struct i2c_msg i2cmsgs = {
90                 .addr = state->addr,
91                 .flags = 0,
92                 .len = 3,
93                 .buf=buffer
94         };
95         ret = i2c_transfer(state->i2c, &i2cmsgs, 1);
96         if (ret != 1) {
97                 printk("%s i2c_transfer error %d\n", __func__, ret);
98                 return ret;
99         }
100
101         return 0;
102 }
103
104
105 static int lgdt3304_soft_Reset(struct dvb_frontend *fe)
106 {
107         lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a);
108         lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b);
109         mdelay(200);
110         return 0;
111 }
112
113 static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
114         int err = 0;
115
116         static __u8 lgdt3304_vsb8_data[] = {
117                 /* 16bit  , 8bit */
118                 /* regs   , val  */
119                 0x00, 0x00, 0x02,
120                 0x00, 0x00, 0x13,
121                 0x00, 0x0d, 0x02,
122                 0x00, 0x0e, 0x02,
123                 0x00, 0x12, 0x32,
124                 0x00, 0x13, 0xc4,
125                 0x01, 0x12, 0x17,
126                 0x01, 0x13, 0x15,
127                 0x01, 0x14, 0x18,
128                 0x01, 0x15, 0xff,
129                 0x01, 0x16, 0x2c,
130                 0x02, 0x14, 0x67,
131                 0x02, 0x24, 0x8d,
132                 0x04, 0x27, 0x12,
133                 0x04, 0x28, 0x4f,
134                 0x03, 0x08, 0x80,
135                 0x03, 0x09, 0x00,
136                 0x03, 0x0d, 0x00,
137                 0x03, 0x0e, 0x1c,
138                 0x03, 0x14, 0xe1,
139                 0x05, 0x0e, 0x5b,
140         };
141
142         /* not yet tested .. */
143         static __u8 lgdt3304_qam64_data[] = {
144                 /* 16bit  , 8bit */
145                 /* regs   , val  */
146                 0x00, 0x00, 0x18,
147                 0x00, 0x0d, 0x02,
148                 //0x00, 0x0e, 0x02,
149                 0x00, 0x12, 0x2a,
150                 0x00, 0x13, 0x00,
151                 0x03, 0x14, 0xe3,
152                 0x03, 0x0e, 0x1c,
153                 0x03, 0x08, 0x66,
154                 0x03, 0x09, 0x66,
155                 0x03, 0x0a, 0x08,
156                 0x03, 0x0b, 0x9b,
157                 0x05, 0x0e, 0x5b,
158         };
159
160
161         /* tested with KWorld a340 */
162         static __u8 lgdt3304_qam256_data[] = {
163                 /* 16bit  , 8bit */
164                 /* regs   , val  */
165                 0x00, 0x00, 0x01,  //0x19,
166                 0x00, 0x12, 0x2a,
167                 0x00, 0x13, 0x80,
168                 0x00, 0x0d, 0x02,
169                 0x03, 0x14, 0xe3,
170
171                 0x03, 0x0e, 0x1c,
172                 0x03, 0x08, 0x66,
173                 0x03, 0x09, 0x66,
174                 0x03, 0x0a, 0x08,
175                 0x03, 0x0b, 0x9b,
176
177                 0x03, 0x0d, 0x14,
178                 //0x05, 0x0e, 0x5b,
179                 0x01, 0x06, 0x4a,
180                 0x01, 0x07, 0x3d,
181                 0x01, 0x08, 0x70,
182                 0x01, 0x09, 0xa3,
183
184                 0x05, 0x04, 0xfd,
185
186                 0x00, 0x0d, 0x82,
187
188                 0x05, 0x0e, 0x5b,
189
190                 0x05, 0x0e, 0x5b,
191
192                 0x00, 0x02, 0x9a,
193
194                 0x00, 0x02, 0x9b,
195
196                 0x00, 0x00, 0x01,
197                 0x00, 0x12, 0x2a,
198                 0x00, 0x13, 0x80,
199                 0x00, 0x0d, 0x02,
200                 0x03, 0x14, 0xe3,
201
202                 0x03, 0x0e, 0x1c,
203                 0x03, 0x08, 0x66,
204                 0x03, 0x09, 0x66,
205                 0x03, 0x0a, 0x08,
206                 0x03, 0x0b, 0x9b,
207
208                 0x03, 0x0d, 0x14,
209                 0x01, 0x06, 0x4a,
210                 0x01, 0x07, 0x3d,
211                 0x01, 0x08, 0x70,
212                 0x01, 0x09, 0xa3,
213
214                 0x05, 0x04, 0xfd,
215
216                 0x00, 0x0d, 0x82,
217
218                 0x05, 0x0e, 0x5b,
219         };
220
221         struct lgdt3304_state *state = fe->demodulator_priv;
222         if (state->current_modulation != param->u.vsb.modulation) {
223                 switch(param->u.vsb.modulation) {
224                 case VSB_8:
225                         err = i2c_write_demod_bytes(fe, lgdt3304_vsb8_data,
226                                         sizeof(lgdt3304_vsb8_data));
227                         break;
228                 case QAM_64:
229                         err = i2c_write_demod_bytes(fe, lgdt3304_qam64_data,
230                                         sizeof(lgdt3304_qam64_data));
231                         break;
232                 case QAM_256:
233                         err = i2c_write_demod_bytes(fe, lgdt3304_qam256_data,
234                                         sizeof(lgdt3304_qam256_data));
235                         break;
236                 default:
237                         break;
238                 }
239
240                 if (err) {
241                         printk("%s error setting modulation\n", __func__);
242                 } else {
243                         state->current_modulation = param->u.vsb.modulation;
244                 }
245         }
246         state->current_frequency = param->frequency;
247
248         lgdt3304_soft_Reset(fe);
249
250
251         if (fe->ops.tuner_ops.set_params)
252                 fe->ops.tuner_ops.set_params(fe, param);
253
254         return 0;
255 }
256
257 static int lgdt3304_init(struct dvb_frontend *fe) {
258         return 0;
259 }
260
261 static int lgdt3304_sleep(struct dvb_frontend *fe) {
262         return 0;
263 }
264
265
266 static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status)
267 {
268         struct lgdt3304_state *state = fe->demodulator_priv;
269         int r011d;
270         int qam_lck;
271
272         *status = 0;
273         dprintk("lgdt read status\n");
274
275         r011d = lgdt3304_i2c_read_reg(fe, 0x011d);
276
277         dprintk("%02x\n", r011d);
278
279         switch(state->current_modulation) {
280         case VSB_8:
281                 if (r011d & 0x80) {
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;
287                 }
288                 break;
289         case QAM_64:
290         case QAM_256:
291                 qam_lck = r011d & 0x7;
292                 switch(qam_lck) {
293                         case 0x0: dprintk("Unlock\n");
294                                   break;
295                         case 0x4: dprintk("1st Lock in acquisition state\n");
296                                   break;
297                         case 0x6: dprintk("2nd Lock in acquisition state\n");
298                                   break;
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;
304                                   break;
305                 }
306                 break;
307         default:
308                 printk("%s unhandled modulation\n", __func__);
309         }
310
311
312         return 0;
313 }
314
315 static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
316 {
317         dprintk("read ber\n");
318         return 0;
319 }
320
321 static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
322 {
323         dprintk("read snr\n");
324         return 0;
325 }
326
327 static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
328 {
329         dprintk("read ucblocks\n");
330         return 0;
331 }
332
333 static void lgdt3304_release(struct dvb_frontend *fe)
334 {
335         struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
336         kfree(state);
337 }
338
339 static struct dvb_frontend_ops demod_lgdt3304={
340         .info = {
341                 .name = "LG 3304",
342                 .type = FE_ATSC,
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
349         },
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,
358 };
359
360 struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
361                                            struct i2c_adapter *i2c)
362 {
363
364         struct lgdt3304_state *state;
365         state = kzalloc(sizeof(struct lgdt3304_state), GFP_KERNEL);
366         state->addr = config->i2c_address;
367         state->i2c = i2c;
368
369         memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
370         state->frontend.demodulator_priv = state;
371         return &state->frontend;
372 }
373
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");