Merge branch 'timers-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[GitHub/mt8127/android_kernel_alcatel_ttab.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/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 if (state == NULL)
367 return NULL;
368 state->addr = config->i2c_address;
369 state->i2c = i2c;
370
371 memcpy(&state->frontend.ops, &demod_lgdt3304, sizeof(struct dvb_frontend_ops));
372 state->frontend.demodulator_priv = state;
373 return &state->frontend;
374 }
375
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");