2 * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
4 * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
6 * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7 * by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
20 #include <linux/kernel.h>
21 #include <linux/module.h>
22 #include <linux/slab.h>
23 #include <linux/i2c.h>
24 #include <media/dvb_frontend.h>
25 #include <media/dvb_math.h>
26 #include "va1j5jf8007t.h"
28 enum va1j5jf8007t_tune_state
{
30 VA1J5JF8007T_SET_FREQUENCY
,
31 VA1J5JF8007T_CHECK_FREQUENCY
,
32 VA1J5JF8007T_SET_MODULATION
,
33 VA1J5JF8007T_CHECK_MODULATION
,
38 struct va1j5jf8007t_state
{
39 const struct va1j5jf8007t_config
*config
;
40 struct i2c_adapter
*adap
;
41 struct dvb_frontend fe
;
42 enum va1j5jf8007t_tune_state tune_state
;
45 static int va1j5jf8007t_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
47 struct va1j5jf8007t_state
*state
;
50 u8 write_buf
[1], read_buf
[1];
51 struct i2c_msg msgs
[2];
54 state
= fe
->demodulator_priv
;
55 addr
= state
->config
->demod_address
;
58 for (i
= 0; i
< 3; i
++) {
59 write_buf
[0] = 0x8b + i
;
63 msgs
[0].len
= sizeof(write_buf
);
64 msgs
[0].buf
= write_buf
;
67 msgs
[1].flags
= I2C_M_RD
;
68 msgs
[1].len
= sizeof(read_buf
);
69 msgs
[1].buf
= read_buf
;
71 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
81 x
= 10 * (intlog10(0x540000 * 100 / word
) - (2 << 24));
82 y
= (24ll << 46) / 1000000;
83 y
= ((s64
)y
* x
>> 30) - (16ll << 40) / 10000;
84 y
= ((s64
)y
* x
>> 29) + (398ll << 35) / 10000;
85 y
= ((s64
)y
* x
>> 30) + (5491ll << 29) / 10000;
86 y
= ((s64
)y
* x
>> 30) + (30965ll << 23) / 10000;
91 static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend
*fe
)
97 va1j5jf8007t_read_status(struct dvb_frontend
*fe
, enum fe_status
*status
)
99 struct va1j5jf8007t_state
*state
;
101 state
= fe
->demodulator_priv
;
103 switch (state
->tune_state
) {
104 case VA1J5JF8007T_IDLE
:
105 case VA1J5JF8007T_SET_FREQUENCY
:
106 case VA1J5JF8007T_CHECK_FREQUENCY
:
111 case VA1J5JF8007T_SET_MODULATION
:
112 case VA1J5JF8007T_CHECK_MODULATION
:
113 case VA1J5JF8007T_ABORT
:
114 *status
|= FE_HAS_SIGNAL
;
117 case VA1J5JF8007T_TRACK
:
118 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
125 struct va1j5jf8007t_cb_map
{
130 static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps
[] = {
143 static u8
va1j5jf8007t_lookup_cb(u32 frequency
)
146 const struct va1j5jf8007t_cb_map
*map
;
148 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007t_cb_maps
); i
++) {
149 map
= &va1j5jf8007t_cb_maps
[i
];
150 if (frequency
< map
->frequency
)
156 static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state
*state
)
163 frequency
= state
->fe
.dtv_property_cache
.frequency
;
165 word
= (frequency
+ 71428) / 142857 + 399;
171 buf
[5] = va1j5jf8007t_lookup_cb(frequency
);
173 msg
.addr
= state
->config
->demod_address
;
175 msg
.len
= sizeof(buf
);
178 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
185 va1j5jf8007t_check_frequency(struct va1j5jf8007t_state
*state
, int *lock
)
188 u8 write_buf
[2], read_buf
[1];
189 struct i2c_msg msgs
[2];
191 addr
= state
->config
->demod_address
;
198 msgs
[0].len
= sizeof(write_buf
);
199 msgs
[0].buf
= write_buf
;
202 msgs
[1].flags
= I2C_M_RD
;
203 msgs
[1].len
= sizeof(read_buf
);
204 msgs
[1].buf
= read_buf
;
206 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
209 *lock
= read_buf
[0] & 0x40;
213 static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state
*state
)
221 msg
.addr
= state
->config
->demod_address
;
223 msg
.len
= sizeof(buf
);
226 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
232 static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state
*state
,
233 int *lock
, int *retry
)
236 u8 write_buf
[1], read_buf
[1];
237 struct i2c_msg msgs
[2];
239 addr
= state
->config
->demod_address
;
245 msgs
[0].len
= sizeof(write_buf
);
246 msgs
[0].buf
= write_buf
;
249 msgs
[1].flags
= I2C_M_RD
;
250 msgs
[1].len
= sizeof(read_buf
);
251 msgs
[1].buf
= read_buf
;
253 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
256 *lock
= !(read_buf
[0] & 0x10);
257 *retry
= read_buf
[0] & 0x80;
262 va1j5jf8007t_tune(struct dvb_frontend
*fe
,
264 unsigned int mode_flags
, unsigned int *delay
,
265 enum fe_status
*status
)
267 struct va1j5jf8007t_state
*state
;
269 int lock
= 0, retry
= 0;
271 state
= fe
->demodulator_priv
;
274 state
->tune_state
= VA1J5JF8007T_SET_FREQUENCY
;
276 switch (state
->tune_state
) {
277 case VA1J5JF8007T_IDLE
:
282 case VA1J5JF8007T_SET_FREQUENCY
:
283 ret
= va1j5jf8007t_set_frequency(state
);
287 state
->tune_state
= VA1J5JF8007T_CHECK_FREQUENCY
;
292 case VA1J5JF8007T_CHECK_FREQUENCY
:
293 ret
= va1j5jf8007t_check_frequency(state
, &lock
);
298 *delay
= (HZ
+ 999) / 1000;
303 state
->tune_state
= VA1J5JF8007T_SET_MODULATION
;
305 *status
= FE_HAS_SIGNAL
;
308 case VA1J5JF8007T_SET_MODULATION
:
309 ret
= va1j5jf8007t_set_modulation(state
);
313 state
->tune_state
= VA1J5JF8007T_CHECK_MODULATION
;
315 *status
= FE_HAS_SIGNAL
;
318 case VA1J5JF8007T_CHECK_MODULATION
:
319 ret
= va1j5jf8007t_check_modulation(state
, &lock
, &retry
);
325 state
->tune_state
= VA1J5JF8007T_ABORT
;
327 *status
= FE_HAS_SIGNAL
;
330 *delay
= (HZ
+ 999) / 1000;
331 *status
= FE_HAS_SIGNAL
;
335 state
->tune_state
= VA1J5JF8007T_TRACK
;
338 case VA1J5JF8007T_TRACK
:
340 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
343 case VA1J5JF8007T_ABORT
:
345 *status
= FE_HAS_SIGNAL
;
352 static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state
*state
)
365 msg
.addr
= state
->config
->demod_address
;
367 msg
.len
= sizeof(buf
);
370 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
376 static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state
*state
, int sleep
)
382 buf
[1] = sleep
? 0x90 : 0x80;
384 msg
.addr
= state
->config
->demod_address
;
386 msg
.len
= sizeof(buf
);
389 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
395 static int va1j5jf8007t_sleep(struct dvb_frontend
*fe
)
397 struct va1j5jf8007t_state
*state
;
400 state
= fe
->demodulator_priv
;
402 ret
= va1j5jf8007t_init_frequency(state
);
406 return va1j5jf8007t_set_sleep(state
, 1);
409 static int va1j5jf8007t_init(struct dvb_frontend
*fe
)
411 struct va1j5jf8007t_state
*state
;
413 state
= fe
->demodulator_priv
;
414 state
->tune_state
= VA1J5JF8007T_IDLE
;
416 return va1j5jf8007t_set_sleep(state
, 0);
419 static void va1j5jf8007t_release(struct dvb_frontend
*fe
)
421 struct va1j5jf8007t_state
*state
;
422 state
= fe
->demodulator_priv
;
426 static const struct dvb_frontend_ops va1j5jf8007t_ops
= {
427 .delsys
= { SYS_ISDBT
},
429 .name
= "VA1J5JF8007/VA1J5JF8011 ISDB-T",
430 .frequency_min
= 90000000,
431 .frequency_max
= 770000000,
432 .frequency_stepsize
= 142857,
433 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_AUTO
|
434 FE_CAN_QAM_AUTO
| FE_CAN_TRANSMISSION_MODE_AUTO
|
435 FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_HIERARCHY_AUTO
,
438 .read_snr
= va1j5jf8007t_read_snr
,
439 .get_frontend_algo
= va1j5jf8007t_get_frontend_algo
,
440 .read_status
= va1j5jf8007t_read_status
,
441 .tune
= va1j5jf8007t_tune
,
442 .sleep
= va1j5jf8007t_sleep
,
443 .init
= va1j5jf8007t_init
,
444 .release
= va1j5jf8007t_release
,
447 static const u8 va1j5jf8007t_20mhz_prepare_bufs
[][2] = {
448 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
449 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
450 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
454 static const u8 va1j5jf8007t_25mhz_prepare_bufs
[][2] = {
455 {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83},
456 {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c},
457 {0x77, 0x03}, {0xef, 0x01}
460 int va1j5jf8007t_prepare(struct dvb_frontend
*fe
)
462 struct va1j5jf8007t_state
*state
;
469 state
= fe
->demodulator_priv
;
471 switch (state
->config
->frequency
) {
472 case VA1J5JF8007T_20MHZ
:
473 bufs
= va1j5jf8007t_20mhz_prepare_bufs
;
474 size
= ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs
);
476 case VA1J5JF8007T_25MHZ
:
477 bufs
= va1j5jf8007t_25mhz_prepare_bufs
;
478 size
= ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs
);
484 msg
.addr
= state
->config
->demod_address
;
486 msg
.len
= sizeof(buf
);
489 for (i
= 0; i
< size
; i
++) {
490 memcpy(buf
, bufs
[i
], sizeof(buf
));
491 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
495 return va1j5jf8007t_init_frequency(state
);
498 struct dvb_frontend
*
499 va1j5jf8007t_attach(const struct va1j5jf8007t_config
*config
,
500 struct i2c_adapter
*adap
)
502 struct va1j5jf8007t_state
*state
;
503 struct dvb_frontend
*fe
;
507 state
= kzalloc(sizeof(struct va1j5jf8007t_state
), GFP_KERNEL
);
511 state
->config
= config
;
515 memcpy(&fe
->ops
, &va1j5jf8007t_ops
, sizeof(struct dvb_frontend_ops
));
516 fe
->demodulator_priv
= state
;
521 msg
.addr
= state
->config
->demod_address
;
523 msg
.len
= sizeof(buf
);
526 if (i2c_transfer(state
->adap
, &msg
, 1) != 1) {