2 * ISDB-S 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 "dvb_frontend.h"
25 #include "va1j5jf8007s.h"
27 enum va1j5jf8007s_tune_state
{
29 VA1J5JF8007S_SET_FREQUENCY_1
,
30 VA1J5JF8007S_SET_FREQUENCY_2
,
31 VA1J5JF8007S_SET_FREQUENCY_3
,
32 VA1J5JF8007S_CHECK_FREQUENCY
,
33 VA1J5JF8007S_SET_MODULATION
,
34 VA1J5JF8007S_CHECK_MODULATION
,
35 VA1J5JF8007S_SET_TS_ID
,
36 VA1J5JF8007S_CHECK_TS_ID
,
40 struct va1j5jf8007s_state
{
41 const struct va1j5jf8007s_config
*config
;
42 struct i2c_adapter
*adap
;
43 struct dvb_frontend fe
;
44 enum va1j5jf8007s_tune_state tune_state
;
47 static int va1j5jf8007s_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
49 struct va1j5jf8007s_state
*state
;
52 u8 write_buf
[1], read_buf
[1];
53 struct i2c_msg msgs
[2];
54 s32 word
, x1
, x2
, x3
, x4
, x5
, y
;
56 state
= fe
->demodulator_priv
;
57 addr
= state
->config
->demod_address
;
60 for (i
= 0; i
< 2; i
++) {
61 write_buf
[0] = 0xbc + i
;
65 msgs
[0].len
= sizeof(write_buf
);
66 msgs
[0].buf
= write_buf
;
69 msgs
[1].flags
= I2C_M_RD
;
70 msgs
[1].len
= sizeof(read_buf
);
71 msgs
[1].buf
= read_buf
;
73 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
84 x1
= int_sqrt(word
<< 16) * ((15625ll << 21) / 1000000);
85 x2
= (s64
)x1
* x1
>> 31;
86 x3
= (s64
)x2
* x1
>> 31;
87 x4
= (s64
)x2
* x2
>> 31;
88 x5
= (s64
)x4
* x1
>> 31;
90 y
= (58857ll << 23) / 1000;
91 y
-= (s64
)x1
* ((89565ll << 24) / 1000) >> 30;
92 y
+= (s64
)x2
* ((88977ll << 24) / 1000) >> 28;
93 y
-= (s64
)x3
* ((50259ll << 25) / 1000) >> 27;
94 y
+= (s64
)x4
* ((14341ll << 27) / 1000) >> 27;
95 y
-= (s64
)x5
* ((16346ll << 30) / 10000) >> 28;
97 *snr
= y
< 0 ? 0 : y
>> 15;
101 static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend
*fe
)
103 return DVBFE_ALGO_HW
;
107 va1j5jf8007s_read_status(struct dvb_frontend
*fe
, enum fe_status
*status
)
109 struct va1j5jf8007s_state
*state
;
111 state
= fe
->demodulator_priv
;
113 switch (state
->tune_state
) {
114 case VA1J5JF8007S_IDLE
:
115 case VA1J5JF8007S_SET_FREQUENCY_1
:
116 case VA1J5JF8007S_SET_FREQUENCY_2
:
117 case VA1J5JF8007S_SET_FREQUENCY_3
:
118 case VA1J5JF8007S_CHECK_FREQUENCY
:
123 case VA1J5JF8007S_SET_MODULATION
:
124 case VA1J5JF8007S_CHECK_MODULATION
:
125 *status
|= FE_HAS_SIGNAL
;
128 case VA1J5JF8007S_SET_TS_ID
:
129 case VA1J5JF8007S_CHECK_TS_ID
:
130 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
133 case VA1J5JF8007S_TRACK
:
134 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
141 struct va1j5jf8007s_cb_map
{
146 static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps
[] = {
157 static u8
va1j5jf8007s_lookup_cb(u32 frequency
)
160 const struct va1j5jf8007s_cb_map
*map
;
162 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007s_cb_maps
); i
++) {
163 map
= &va1j5jf8007s_cb_maps
[i
];
164 if (frequency
< map
->frequency
)
170 static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state
*state
)
177 frequency
= state
->fe
.dtv_property_cache
.frequency
;
179 word
= (frequency
+ 500) / 1000;
180 if (frequency
< 1072000)
181 word
= (word
<< 1 & ~0x1f) | (word
& 0x0f);
185 buf
[2] = 0x40 | word
>> 8;
188 buf
[5] = va1j5jf8007s_lookup_cb(frequency
);
190 msg
.addr
= state
->config
->demod_address
;
192 msg
.len
= sizeof(buf
);
195 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
201 static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state
*state
)
210 msg
.addr
= state
->config
->demod_address
;
212 msg
.len
= sizeof(buf
);
215 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
221 static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state
*state
)
227 frequency
= state
->fe
.dtv_property_cache
.frequency
;
232 buf
[3] = va1j5jf8007s_lookup_cb(frequency
) | 0x4;
234 msg
.addr
= state
->config
->demod_address
;
236 msg
.len
= sizeof(buf
);
239 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
246 va1j5jf8007s_check_frequency(struct va1j5jf8007s_state
*state
, int *lock
)
249 u8 write_buf
[2], read_buf
[1];
250 struct i2c_msg msgs
[2];
252 addr
= state
->config
->demod_address
;
259 msgs
[0].len
= sizeof(write_buf
);
260 msgs
[0].buf
= write_buf
;
263 msgs
[1].flags
= I2C_M_RD
;
264 msgs
[1].len
= sizeof(read_buf
);
265 msgs
[1].buf
= read_buf
;
267 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
270 *lock
= read_buf
[0] & 0x40;
274 static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state
*state
)
282 msg
.addr
= state
->config
->demod_address
;
284 msg
.len
= sizeof(buf
);
287 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
294 va1j5jf8007s_check_modulation(struct va1j5jf8007s_state
*state
, int *lock
)
297 u8 write_buf
[1], read_buf
[1];
298 struct i2c_msg msgs
[2];
300 addr
= state
->config
->demod_address
;
306 msgs
[0].len
= sizeof(write_buf
);
307 msgs
[0].buf
= write_buf
;
310 msgs
[1].flags
= I2C_M_RD
;
311 msgs
[1].len
= sizeof(read_buf
);
312 msgs
[1].buf
= read_buf
;
314 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
317 *lock
= !(read_buf
[0] & 0x10);
322 va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state
*state
)
328 ts_id
= state
->fe
.dtv_property_cache
.stream_id
;
329 if (!ts_id
|| ts_id
== NO_STREAM_ID_FILTER
)
336 msg
.addr
= state
->config
->demod_address
;
338 msg
.len
= sizeof(buf
);
341 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
348 va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state
*state
, int *lock
)
351 u8 write_buf
[1], read_buf
[2];
352 struct i2c_msg msgs
[2];
355 ts_id
= state
->fe
.dtv_property_cache
.stream_id
;
356 if (!ts_id
|| ts_id
== NO_STREAM_ID_FILTER
) {
361 addr
= state
->config
->demod_address
;
367 msgs
[0].len
= sizeof(write_buf
);
368 msgs
[0].buf
= write_buf
;
371 msgs
[1].flags
= I2C_M_RD
;
372 msgs
[1].len
= sizeof(read_buf
);
373 msgs
[1].buf
= read_buf
;
375 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
378 *lock
= (read_buf
[0] << 8 | read_buf
[1]) == ts_id
;
383 va1j5jf8007s_tune(struct dvb_frontend
*fe
,
385 unsigned int mode_flags
, unsigned int *delay
,
386 enum fe_status
*status
)
388 struct va1j5jf8007s_state
*state
;
392 state
= fe
->demodulator_priv
;
395 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_1
;
397 switch (state
->tune_state
) {
398 case VA1J5JF8007S_IDLE
:
403 case VA1J5JF8007S_SET_FREQUENCY_1
:
404 ret
= va1j5jf8007s_set_frequency_1(state
);
408 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_2
;
413 case VA1J5JF8007S_SET_FREQUENCY_2
:
414 ret
= va1j5jf8007s_set_frequency_2(state
);
418 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_3
;
419 *delay
= (HZ
+ 99) / 100;
423 case VA1J5JF8007S_SET_FREQUENCY_3
:
424 ret
= va1j5jf8007s_set_frequency_3(state
);
428 state
->tune_state
= VA1J5JF8007S_CHECK_FREQUENCY
;
433 case VA1J5JF8007S_CHECK_FREQUENCY
:
434 ret
= va1j5jf8007s_check_frequency(state
, &lock
);
439 *delay
= (HZ
+ 999) / 1000;
444 state
->tune_state
= VA1J5JF8007S_SET_MODULATION
;
446 *status
= FE_HAS_SIGNAL
;
449 case VA1J5JF8007S_SET_MODULATION
:
450 ret
= va1j5jf8007s_set_modulation(state
);
454 state
->tune_state
= VA1J5JF8007S_CHECK_MODULATION
;
456 *status
= FE_HAS_SIGNAL
;
459 case VA1J5JF8007S_CHECK_MODULATION
:
460 ret
= va1j5jf8007s_check_modulation(state
, &lock
);
465 *delay
= (HZ
+ 49) / 50;
466 *status
= FE_HAS_SIGNAL
;
470 state
->tune_state
= VA1J5JF8007S_SET_TS_ID
;
472 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
475 case VA1J5JF8007S_SET_TS_ID
:
476 ret
= va1j5jf8007s_set_ts_id(state
);
480 state
->tune_state
= VA1J5JF8007S_CHECK_TS_ID
;
483 case VA1J5JF8007S_CHECK_TS_ID
:
484 ret
= va1j5jf8007s_check_ts_id(state
, &lock
);
489 *delay
= (HZ
+ 99) / 100;
490 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
494 state
->tune_state
= VA1J5JF8007S_TRACK
;
497 case VA1J5JF8007S_TRACK
:
499 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
506 static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state
*state
)
516 msg
.addr
= state
->config
->demod_address
;
518 msg
.len
= sizeof(buf
);
521 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
527 static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state
*state
, int sleep
)
533 buf
[1] = sleep
? 0x01 : 0x00;
535 msg
.addr
= state
->config
->demod_address
;
537 msg
.len
= sizeof(buf
);
540 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
546 static int va1j5jf8007s_sleep(struct dvb_frontend
*fe
)
548 struct va1j5jf8007s_state
*state
;
551 state
= fe
->demodulator_priv
;
553 ret
= va1j5jf8007s_init_frequency(state
);
557 return va1j5jf8007s_set_sleep(state
, 1);
560 static int va1j5jf8007s_init(struct dvb_frontend
*fe
)
562 struct va1j5jf8007s_state
*state
;
564 state
= fe
->demodulator_priv
;
565 state
->tune_state
= VA1J5JF8007S_IDLE
;
567 return va1j5jf8007s_set_sleep(state
, 0);
570 static void va1j5jf8007s_release(struct dvb_frontend
*fe
)
572 struct va1j5jf8007s_state
*state
;
573 state
= fe
->demodulator_priv
;
577 static const struct dvb_frontend_ops va1j5jf8007s_ops
= {
578 .delsys
= { SYS_ISDBS
},
580 .name
= "VA1J5JF8007/VA1J5JF8011 ISDB-S",
581 .frequency_min
= 950000,
582 .frequency_max
= 2150000,
583 .frequency_stepsize
= 1000,
584 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_AUTO
|
585 FE_CAN_QAM_AUTO
| FE_CAN_TRANSMISSION_MODE_AUTO
|
586 FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_HIERARCHY_AUTO
|
590 .read_snr
= va1j5jf8007s_read_snr
,
591 .get_frontend_algo
= va1j5jf8007s_get_frontend_algo
,
592 .read_status
= va1j5jf8007s_read_status
,
593 .tune
= va1j5jf8007s_tune
,
594 .sleep
= va1j5jf8007s_sleep
,
595 .init
= va1j5jf8007s_init
,
596 .release
= va1j5jf8007s_release
,
599 static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state
*state
)
602 u8 write_buf
[1], read_buf
[1];
603 struct i2c_msg msgs
[2];
605 addr
= state
->config
->demod_address
;
611 msgs
[0].len
= sizeof(write_buf
);
612 msgs
[0].buf
= write_buf
;
615 msgs
[1].flags
= I2C_M_RD
;
616 msgs
[1].len
= sizeof(read_buf
);
617 msgs
[1].buf
= read_buf
;
619 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
622 if (read_buf
[0] != 0x41)
628 static const u8 va1j5jf8007s_20mhz_prepare_bufs
[][2] = {
629 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
630 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
631 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
632 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
635 static const u8 va1j5jf8007s_25mhz_prepare_bufs
[][2] = {
636 {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
637 {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
638 {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
639 {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
642 static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state
*state
)
651 switch (state
->config
->frequency
) {
652 case VA1J5JF8007S_20MHZ
:
653 bufs
= va1j5jf8007s_20mhz_prepare_bufs
;
654 size
= ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs
);
656 case VA1J5JF8007S_25MHZ
:
657 bufs
= va1j5jf8007s_25mhz_prepare_bufs
;
658 size
= ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs
);
664 addr
= state
->config
->demod_address
;
670 for (i
= 0; i
< size
; i
++) {
671 memcpy(buf
, bufs
[i
], sizeof(buf
));
672 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
679 /* must be called after va1j5jf8007t_attach */
680 int va1j5jf8007s_prepare(struct dvb_frontend
*fe
)
682 struct va1j5jf8007s_state
*state
;
685 state
= fe
->demodulator_priv
;
687 ret
= va1j5jf8007s_prepare_1(state
);
691 ret
= va1j5jf8007s_prepare_2(state
);
695 return va1j5jf8007s_init_frequency(state
);
698 struct dvb_frontend
*
699 va1j5jf8007s_attach(const struct va1j5jf8007s_config
*config
,
700 struct i2c_adapter
*adap
)
702 struct va1j5jf8007s_state
*state
;
703 struct dvb_frontend
*fe
;
707 state
= kzalloc(sizeof(struct va1j5jf8007s_state
), GFP_KERNEL
);
711 state
->config
= config
;
715 memcpy(&fe
->ops
, &va1j5jf8007s_ops
, sizeof(struct dvb_frontend_ops
));
716 fe
->demodulator_priv
= state
;
721 msg
.addr
= state
->config
->demod_address
;
723 msg
.len
= sizeof(buf
);
726 if (i2c_transfer(state
->adap
, &msg
, 1) != 1) {