]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/dvb/frontends/lgdt3304.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / drivers / media / dvb / frontends / lgdt3304.c
CommitLineData
67ea14f2
MR
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>
5a0e3ad6 10#include <linux/slab.h>
67ea14f2
MR
11#include <linux/delay.h>
12#include "dvb_frontend.h"
13#include "lgdt3304.h"
14
15static unsigned int debug = 0;
16module_param(debug, int, 0644);
17MODULE_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
22struct lgdt3304_state
23{
f71f11ed
MCC
24 struct dvb_frontend frontend;
25 fe_modulation_t current_modulation;
26 __u32 snr;
27 __u32 current_frequency;
67ea14f2
MR
28 __u8 addr;
29 struct i2c_adapter *i2c;
30};
31
32static 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 };
f71f11ed
MCC
41 int i;
42 int err;
67ea14f2 43
f71f11ed 44 for (i=0; i<len-1; i+=3){
67ea14f2 45 if((err = i2c_transfer(state->i2c, &i2cmsgs, 1))<0) {
9b4778f6 46 printk("%s i2c_transfer error %d\n", __func__, err);
f71f11ed
MCC
47 if (err < 0)
48 return err;
49 else
50 return -EREMOTEIO;
51 }
52 i2cmsgs.buf += 3;
53 }
54 return 0;
67ea14f2
MR
55}
56
57static 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) {
9b4778f6 77 printk("%s i2c_transfer error %d\n", __func__, ret);
67ea14f2
MR
78 return ret;
79 }
80
81 return buf;
82}
83
84static 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) {
9b4778f6 98 printk("%s i2c_transfer error %d\n", __func__, ret);
67ea14f2
MR
99 return ret;
100 }
101
102 return 0;
103}
104
105
106static 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
114static 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) {
9b4778f6 242 printk("%s error setting modulation\n", __func__);
67ea14f2
MR
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
f71f11ed
MCC
252 if (fe->ops.tuner_ops.set_params)
253 fe->ops.tuner_ops.set_params(fe, param);
67ea14f2
MR
254
255 return 0;
256}
257
258static int lgdt3304_init(struct dvb_frontend *fe) {
f71f11ed 259 return 0;
67ea14f2
MR
260}
261
262static int lgdt3304_sleep(struct dvb_frontend *fe) {
263 return 0;
264}
265
266
267static 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:
9b4778f6 309 printk("%s unhandled modulation\n", __func__);
67ea14f2
MR
310 }
311
312
313 return 0;
314}
315
316static int lgdt3304_read_ber(struct dvb_frontend *fe, __u32 *ber)
317{
318 dprintk("read ber\n");
319 return 0;
320}
321
322static int lgdt3304_read_snr(struct dvb_frontend *fe, __u16 *snr)
323{
324 dprintk("read snr\n");
325 return 0;
326}
327
328static int lgdt3304_read_ucblocks(struct dvb_frontend *fe, __u32 *ucblocks)
329{
330 dprintk("read ucblocks\n");
331 return 0;
332}
333
334static void lgdt3304_release(struct dvb_frontend *fe)
335{
336 struct lgdt3304_state *state = (struct lgdt3304_state *)fe->demodulator_priv;
337 kfree(state);
338}
339
340static 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
361struct 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);
8d04df49
RK
367 if (state == NULL)
368 return NULL;
67ea14f2
MR
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
377EXPORT_SYMBOL_GPL(lgdt3304_attach);
378MODULE_AUTHOR("Markus Rechberger <mrechberger@empiatech.com>");
379MODULE_DESCRIPTION("LGE LGDT3304 DVB-T demodulator driver");
380MODULE_LICENSE("GPL");