Staging: brcm80211: fix usage of roundup in structures
[pandora-kernel.git] / 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/slab.h>
11 #include <linux/delay.h>
12 #include "dvb_frontend.h"
13 #include "lgdt3304.h"
14
15 static  unsigned int debug = 0;
16 module_param(debug, int, 0644);
17 MODULE_PARM_DESC(debug,"lgdt3304 debugging (default off)");
18
19 #define dprintk(fmt, args...) if (debug) do {\
20                         printk("lgdt3304 debug: " fmt, ##args); } while (0)
21
22 struct lgdt3304_state
23 {
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;
30 };
31
32 static int i2c_write_demod_bytes (struct dvb_frontend *fe, __u8 *buf, int len)
33 {
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
40         };
41         int i;
42         int err;
43
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;
51                 }
52                 i2cmsgs.buf += 3;
53         }
54         return 0;
55 }
56
57 static int lgdt3304_i2c_read_reg(struct dvb_frontend *fe, unsigned int reg)
58 {
59         struct lgdt3304_state *state = fe->demodulator_priv;
60         struct i2c_msg i2cmsgs[2];
61         int ret;
62         __u8 buf;
63
64         __u8 regbuf[2] = { reg>>8, reg&0xff };
65
66         i2cmsgs[0].addr = state->addr;
67         i2cmsgs[0].flags = 0;
68         i2cmsgs[0].len = 2;
69         i2cmsgs[0].buf = regbuf;
70
71         i2cmsgs[1].addr = state->addr;
72         i2cmsgs[1].flags = I2C_M_RD;
73         i2cmsgs[1].len = 1;
74         i2cmsgs[1].buf = &buf;
75
76         if((ret = i2c_transfer(state->i2c, i2cmsgs, 2))<0) {
77                 printk("%s i2c_transfer error %d\n", __func__, ret);
78                 return ret;
79         }
80
81         return buf;
82 }
83
84 static int lgdt3304_i2c_write_reg(struct dvb_frontend *fe, int reg, int val)
85 {
86         struct lgdt3304_state *state = fe->demodulator_priv;
87         char buffer[3] = { reg>>8, reg&0xff, val };
88         int ret;
89
90         struct i2c_msg i2cmsgs = {
91                 .addr = state->addr,
92                 .flags = 0,
93                 .len = 3,
94                 .buf=buffer
95         };
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;
100         }
101
102         return 0;
103 }
104
105
106 static int lgdt3304_soft_Reset(struct dvb_frontend *fe)
107 {
108         lgdt3304_i2c_write_reg(fe, 0x0002, 0x9a);
109         lgdt3304_i2c_write_reg(fe, 0x0002, 0x9b);
110         mdelay(200);
111         return 0;
112 }
113
114 static int lgdt3304_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *param) {
115         int err = 0;
116
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,
141         };
142
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,
159         };
160
161
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,
171
172                 0x03, 0x0e, 0x1c,
173                 0x03, 0x08, 0x66,
174                 0x03, 0x09, 0x66,
175                 0x03, 0x0a, 0x08,
176                 0x03, 0x0b, 0x9b,
177
178                 0x03, 0x0d, 0x14,
179                 //0x05, 0x0e, 0x5b,
180                 0x01, 0x06, 0x4a,
181                 0x01, 0x07, 0x3d,
182                 0x01, 0x08, 0x70,
183                 0x01, 0x09, 0xa3,
184
185                 0x05, 0x04, 0xfd,
186
187                 0x00, 0x0d, 0x82,
188
189                 0x05, 0x0e, 0x5b,
190
191                 0x05, 0x0e, 0x5b,
192
193                 0x00, 0x02, 0x9a,
194
195                 0x00, 0x02, 0x9b,
196
197                 0x00, 0x00, 0x01,
198                 0x00, 0x12, 0x2a,
199                 0x00, 0x13, 0x80,
200                 0x00, 0x0d, 0x02,
201                 0x03, 0x14, 0xe3,
202
203                 0x03, 0x0e, 0x1c,
204                 0x03, 0x08, 0x66,
205                 0x03, 0x09, 0x66,
206                 0x03, 0x0a, 0x08,
207                 0x03, 0x0b, 0x9b,
208
209                 0x03, 0x0d, 0x14,
210                 0x01, 0x06, 0x4a,
211                 0x01, 0x07, 0x3d,
212                 0x01, 0x08, 0x70,
213                 0x01, 0x09, 0xa3,
214
215                 0x05, 0x04, 0xfd,
216
217                 0x00, 0x0d, 0x82,
218
219                 0x05, 0x0e, 0x5b,
220         };
221
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;
239                 }
240
241                 if (err) {
242                         printk("%s error setting modulation\n", __func__);
243                 } else {
244                         state->current_modulation = param->u.vsb.modulation;
245                 }
246         }
247         state->current_frequency = param->frequency;
248
249         lgdt3304_soft_Reset(fe);
250
251
252         if (fe->ops.tuner_ops.set_params)
253                 fe->ops.tuner_ops.set_params(fe, param);
254
255         return 0;
256 }
257
258 static int lgdt3304_init(struct dvb_frontend *fe) {
259         return 0;
260 }
261
262 static int lgdt3304_sleep(struct dvb_frontend *fe) {
263         return 0;
264 }
265
266
267 static int lgdt3304_read_status(struct dvb_frontend *fe, fe_status_t *status)
268 {
269         struct lgdt3304_state *state = fe->demodulator_priv;
270         int r011d;
271         int qam_lck;
272
273         *status = 0;
274         dprintk("lgdt read status\n");
275
276         r011d = lgdt3304_i2c_read_reg(fe, 0x011d);
277
278         dprintk("%02x\n", r011d);
279
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;
288                 }
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;
306                 }
307                 break;
308         default:
309                 printk("%s unhandled modulation\n", __func__);
310         }
311
312
313         return 0;
314 }
315
316 static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
317 {
318         dprintk("read ber\n");
319         return 0;
320 }
321
322 static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
323 {
324         dprintk("read snr\n");
325         return 0;
326 }
327
328 static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
329 {
330         dprintk("read ucblocks\n");
331         return 0;
332 }
333
334 static void lgdt3304_release(struct dvb_frontend *fe)
335 {
336         struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
337         kfree(state);
338 }
339
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
350         },
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,
359 };
360
361 struct dvb_frontend* lgdt3304_attach(const struct lgdt3304_config *config,
362                                            struct i2c_adapter *i2c)
363 {
364
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;
371
372         memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
373         state->frontend.demodulator_priv = state;
374         return &state->frontend;
375 }
376
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");