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.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/slab.h>
27 #include <linux/i2c.h>
28 #include "dvb_frontend.h"
30 #include "va1j5jf8007t.h"
32 enum va1j5jf8007t_tune_state
{
34 VA1J5JF8007T_SET_FREQUENCY
,
35 VA1J5JF8007T_CHECK_FREQUENCY
,
36 VA1J5JF8007T_SET_MODULATION
,
37 VA1J5JF8007T_CHECK_MODULATION
,
42 struct va1j5jf8007t_state
{
43 const struct va1j5jf8007t_config
*config
;
44 struct i2c_adapter
*adap
;
45 struct dvb_frontend fe
;
46 enum va1j5jf8007t_tune_state tune_state
;
49 static int va1j5jf8007t_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
51 struct va1j5jf8007t_state
*state
;
54 u8 write_buf
[1], read_buf
[1];
55 struct i2c_msg msgs
[2];
58 state
= fe
->demodulator_priv
;
59 addr
= state
->config
->demod_address
;
62 for (i
= 0; i
< 3; i
++) {
63 write_buf
[0] = 0x8b + i
;
67 msgs
[0].len
= sizeof(write_buf
);
68 msgs
[0].buf
= write_buf
;
71 msgs
[1].flags
= I2C_M_RD
;
72 msgs
[1].len
= sizeof(read_buf
);
73 msgs
[1].buf
= read_buf
;
75 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
85 x
= 10 * (intlog10(0x540000 * 100 / word
) - (2 << 24));
86 y
= (24ll << 46) / 1000000;
87 y
= ((s64
)y
* x
>> 30) - (16ll << 40) / 10000;
88 y
= ((s64
)y
* x
>> 29) + (398ll << 35) / 10000;
89 y
= ((s64
)y
* x
>> 30) + (5491ll << 29) / 10000;
90 y
= ((s64
)y
* x
>> 30) + (30965ll << 23) / 10000;
95 static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend
*fe
)
101 va1j5jf8007t_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
103 struct va1j5jf8007t_state
*state
;
105 state
= fe
->demodulator_priv
;
107 switch (state
->tune_state
) {
108 case VA1J5JF8007T_IDLE
:
109 case VA1J5JF8007T_SET_FREQUENCY
:
110 case VA1J5JF8007T_CHECK_FREQUENCY
:
115 case VA1J5JF8007T_SET_MODULATION
:
116 case VA1J5JF8007T_CHECK_MODULATION
:
117 case VA1J5JF8007T_ABORT
:
118 *status
|= FE_HAS_SIGNAL
;
121 case VA1J5JF8007T_TRACK
:
122 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
129 struct va1j5jf8007t_cb_map
{
134 static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps
[] = {
147 static u8
va1j5jf8007t_lookup_cb(u32 frequency
)
150 const struct va1j5jf8007t_cb_map
*map
;
152 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007t_cb_maps
); i
++) {
153 map
= &va1j5jf8007t_cb_maps
[i
];
154 if (frequency
< map
->frequency
)
160 static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state
*state
)
167 frequency
= state
->fe
.dtv_property_cache
.frequency
;
169 word
= (frequency
+ 71428) / 142857 + 399;
175 buf
[5] = va1j5jf8007t_lookup_cb(frequency
);
177 msg
.addr
= state
->config
->demod_address
;
179 msg
.len
= sizeof(buf
);
182 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
189 va1j5jf8007t_check_frequency(struct va1j5jf8007t_state
*state
, int *lock
)
192 u8 write_buf
[2], read_buf
[1];
193 struct i2c_msg msgs
[2];
195 addr
= state
->config
->demod_address
;
202 msgs
[0].len
= sizeof(write_buf
);
203 msgs
[0].buf
= write_buf
;
206 msgs
[1].flags
= I2C_M_RD
;
207 msgs
[1].len
= sizeof(read_buf
);
208 msgs
[1].buf
= read_buf
;
210 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
213 *lock
= read_buf
[0] & 0x40;
217 static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state
*state
)
225 msg
.addr
= state
->config
->demod_address
;
227 msg
.len
= sizeof(buf
);
230 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
236 static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state
*state
,
237 int *lock
, int *retry
)
240 u8 write_buf
[1], read_buf
[1];
241 struct i2c_msg msgs
[2];
243 addr
= state
->config
->demod_address
;
249 msgs
[0].len
= sizeof(write_buf
);
250 msgs
[0].buf
= write_buf
;
253 msgs
[1].flags
= I2C_M_RD
;
254 msgs
[1].len
= sizeof(read_buf
);
255 msgs
[1].buf
= read_buf
;
257 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
260 *lock
= !(read_buf
[0] & 0x10);
261 *retry
= read_buf
[0] & 0x80;
266 va1j5jf8007t_tune(struct dvb_frontend
*fe
,
267 struct dvb_frontend_parameters
*params
,
268 unsigned int mode_flags
, unsigned int *delay
,
271 struct va1j5jf8007t_state
*state
;
273 int lock
= 0, retry
= 0;
275 state
= fe
->demodulator_priv
;
278 state
->tune_state
= VA1J5JF8007T_SET_FREQUENCY
;
280 switch (state
->tune_state
) {
281 case VA1J5JF8007T_IDLE
:
286 case VA1J5JF8007T_SET_FREQUENCY
:
287 ret
= va1j5jf8007t_set_frequency(state
);
291 state
->tune_state
= VA1J5JF8007T_CHECK_FREQUENCY
;
296 case VA1J5JF8007T_CHECK_FREQUENCY
:
297 ret
= va1j5jf8007t_check_frequency(state
, &lock
);
302 *delay
= (HZ
+ 999) / 1000;
307 state
->tune_state
= VA1J5JF8007T_SET_MODULATION
;
309 *status
= FE_HAS_SIGNAL
;
312 case VA1J5JF8007T_SET_MODULATION
:
313 ret
= va1j5jf8007t_set_modulation(state
);
317 state
->tune_state
= VA1J5JF8007T_CHECK_MODULATION
;
319 *status
= FE_HAS_SIGNAL
;
322 case VA1J5JF8007T_CHECK_MODULATION
:
323 ret
= va1j5jf8007t_check_modulation(state
, &lock
, &retry
);
329 state
->tune_state
= VA1J5JF8007T_ABORT
;
331 *status
= FE_HAS_SIGNAL
;
334 *delay
= (HZ
+ 999) / 1000;
335 *status
= FE_HAS_SIGNAL
;
339 state
->tune_state
= VA1J5JF8007T_TRACK
;
342 case VA1J5JF8007T_TRACK
:
344 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
347 case VA1J5JF8007T_ABORT
:
349 *status
= FE_HAS_SIGNAL
;
356 static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state
*state
)
369 msg
.addr
= state
->config
->demod_address
;
371 msg
.len
= sizeof(buf
);
374 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
380 static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state
*state
, int sleep
)
386 buf
[1] = sleep
? 0x90 : 0x80;
388 msg
.addr
= state
->config
->demod_address
;
390 msg
.len
= sizeof(buf
);
393 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
399 static int va1j5jf8007t_sleep(struct dvb_frontend
*fe
)
401 struct va1j5jf8007t_state
*state
;
404 state
= fe
->demodulator_priv
;
406 ret
= va1j5jf8007t_init_frequency(state
);
410 return va1j5jf8007t_set_sleep(state
, 1);
413 static int va1j5jf8007t_init(struct dvb_frontend
*fe
)
415 struct va1j5jf8007t_state
*state
;
417 state
= fe
->demodulator_priv
;
418 state
->tune_state
= VA1J5JF8007T_IDLE
;
420 return va1j5jf8007t_set_sleep(state
, 0);
423 static void va1j5jf8007t_release(struct dvb_frontend
*fe
)
425 struct va1j5jf8007t_state
*state
;
426 state
= fe
->demodulator_priv
;
430 static struct dvb_frontend_ops va1j5jf8007t_ops
= {
432 .name
= "VA1J5JF8007/VA1J5JF8011 ISDB-T",
434 .frequency_min
= 90000000,
435 .frequency_max
= 770000000,
436 .frequency_stepsize
= 142857,
437 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_AUTO
|
438 FE_CAN_QAM_AUTO
| FE_CAN_TRANSMISSION_MODE_AUTO
|
439 FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_HIERARCHY_AUTO
,
442 .read_snr
= va1j5jf8007t_read_snr
,
443 .get_frontend_algo
= va1j5jf8007t_get_frontend_algo
,
444 .read_status
= va1j5jf8007t_read_status
,
445 .tune
= va1j5jf8007t_tune
,
446 .sleep
= va1j5jf8007t_sleep
,
447 .init
= va1j5jf8007t_init
,
448 .release
= va1j5jf8007t_release
,
451 static const u8 va1j5jf8007t_20mhz_prepare_bufs
[][2] = {
452 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
453 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
454 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
458 static const u8 va1j5jf8007t_25mhz_prepare_bufs
[][2] = {
459 {0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83},
460 {0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c},
461 {0x77, 0x03}, {0xef, 0x01}
464 int va1j5jf8007t_prepare(struct dvb_frontend
*fe
)
466 struct va1j5jf8007t_state
*state
;
473 state
= fe
->demodulator_priv
;
475 switch (state
->config
->frequency
) {
476 case VA1J5JF8007T_20MHZ
:
477 bufs
= va1j5jf8007t_20mhz_prepare_bufs
;
478 size
= ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs
);
480 case VA1J5JF8007T_25MHZ
:
481 bufs
= va1j5jf8007t_25mhz_prepare_bufs
;
482 size
= ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs
);
488 msg
.addr
= state
->config
->demod_address
;
490 msg
.len
= sizeof(buf
);
493 for (i
= 0; i
< size
; i
++) {
494 memcpy(buf
, bufs
[i
], sizeof(buf
));
495 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
499 return va1j5jf8007t_init_frequency(state
);
502 struct dvb_frontend
*
503 va1j5jf8007t_attach(const struct va1j5jf8007t_config
*config
,
504 struct i2c_adapter
*adap
)
506 struct va1j5jf8007t_state
*state
;
507 struct dvb_frontend
*fe
;
511 state
= kzalloc(sizeof(struct va1j5jf8007t_state
), GFP_KERNEL
);
515 state
->config
= config
;
519 memcpy(&fe
->ops
, &va1j5jf8007t_ops
, sizeof(struct dvb_frontend_ops
));
520 fe
->demodulator_priv
= state
;
525 msg
.addr
= state
->config
->demod_address
;
527 msg
.len
= sizeof(buf
);
530 if (i2c_transfer(state
->adap
, &msg
, 1) != 1) {