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.
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"
29 #include "va1j5jf8007s.h"
31 enum va1j5jf8007s_tune_state
{
33 VA1J5JF8007S_SET_FREQUENCY_1
,
34 VA1J5JF8007S_SET_FREQUENCY_2
,
35 VA1J5JF8007S_SET_FREQUENCY_3
,
36 VA1J5JF8007S_CHECK_FREQUENCY
,
37 VA1J5JF8007S_SET_MODULATION
,
38 VA1J5JF8007S_CHECK_MODULATION
,
39 VA1J5JF8007S_SET_TS_ID
,
40 VA1J5JF8007S_CHECK_TS_ID
,
44 struct va1j5jf8007s_state
{
45 const struct va1j5jf8007s_config
*config
;
46 struct i2c_adapter
*adap
;
47 struct dvb_frontend fe
;
48 enum va1j5jf8007s_tune_state tune_state
;
51 static int va1j5jf8007s_read_snr(struct dvb_frontend
*fe
, u16
*snr
)
53 struct va1j5jf8007s_state
*state
;
56 u8 write_buf
[1], read_buf
[1];
57 struct i2c_msg msgs
[2];
58 s32 word
, x1
, x2
, x3
, x4
, x5
, y
;
60 state
= fe
->demodulator_priv
;
61 addr
= state
->config
->demod_address
;
64 for (i
= 0; i
< 2; i
++) {
65 write_buf
[0] = 0xbc + i
;
69 msgs
[0].len
= sizeof(write_buf
);
70 msgs
[0].buf
= write_buf
;
73 msgs
[1].flags
= I2C_M_RD
;
74 msgs
[1].len
= sizeof(read_buf
);
75 msgs
[1].buf
= read_buf
;
77 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
88 x1
= int_sqrt(word
<< 16) * ((15625ll << 21) / 1000000);
89 x2
= (s64
)x1
* x1
>> 31;
90 x3
= (s64
)x2
* x1
>> 31;
91 x4
= (s64
)x2
* x2
>> 31;
92 x5
= (s64
)x4
* x1
>> 31;
94 y
= (58857ll << 23) / 1000;
95 y
-= (s64
)x1
* ((89565ll << 24) / 1000) >> 30;
96 y
+= (s64
)x2
* ((88977ll << 24) / 1000) >> 28;
97 y
-= (s64
)x3
* ((50259ll << 25) / 1000) >> 27;
98 y
+= (s64
)x4
* ((14341ll << 27) / 1000) >> 27;
99 y
-= (s64
)x5
* ((16346ll << 30) / 10000) >> 28;
101 *snr
= y
< 0 ? 0 : y
>> 15;
105 static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend
*fe
)
107 return DVBFE_ALGO_HW
;
111 va1j5jf8007s_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
113 struct va1j5jf8007s_state
*state
;
115 state
= fe
->demodulator_priv
;
117 switch (state
->tune_state
) {
118 case VA1J5JF8007S_IDLE
:
119 case VA1J5JF8007S_SET_FREQUENCY_1
:
120 case VA1J5JF8007S_SET_FREQUENCY_2
:
121 case VA1J5JF8007S_SET_FREQUENCY_3
:
122 case VA1J5JF8007S_CHECK_FREQUENCY
:
127 case VA1J5JF8007S_SET_MODULATION
:
128 case VA1J5JF8007S_CHECK_MODULATION
:
129 *status
|= FE_HAS_SIGNAL
;
132 case VA1J5JF8007S_SET_TS_ID
:
133 case VA1J5JF8007S_CHECK_TS_ID
:
134 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
137 case VA1J5JF8007S_TRACK
:
138 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
145 struct va1j5jf8007s_cb_map
{
150 static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps
[] = {
161 static u8
va1j5jf8007s_lookup_cb(u32 frequency
)
164 const struct va1j5jf8007s_cb_map
*map
;
166 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007s_cb_maps
); i
++) {
167 map
= &va1j5jf8007s_cb_maps
[i
];
168 if (frequency
< map
->frequency
)
174 static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state
*state
)
181 frequency
= state
->fe
.dtv_property_cache
.frequency
;
183 word
= (frequency
+ 500) / 1000;
184 if (frequency
< 1072000)
185 word
= (word
<< 1 & ~0x1f) | (word
& 0x0f);
189 buf
[2] = 0x40 | word
>> 8;
192 buf
[5] = va1j5jf8007s_lookup_cb(frequency
);
194 msg
.addr
= state
->config
->demod_address
;
196 msg
.len
= sizeof(buf
);
199 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
205 static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state
*state
)
214 msg
.addr
= state
->config
->demod_address
;
216 msg
.len
= sizeof(buf
);
219 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
225 static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state
*state
)
231 frequency
= state
->fe
.dtv_property_cache
.frequency
;
236 buf
[3] = va1j5jf8007s_lookup_cb(frequency
) | 0x4;
238 msg
.addr
= state
->config
->demod_address
;
240 msg
.len
= sizeof(buf
);
243 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
250 va1j5jf8007s_check_frequency(struct va1j5jf8007s_state
*state
, int *lock
)
253 u8 write_buf
[2], read_buf
[1];
254 struct i2c_msg msgs
[2];
256 addr
= state
->config
->demod_address
;
263 msgs
[0].len
= sizeof(write_buf
);
264 msgs
[0].buf
= write_buf
;
267 msgs
[1].flags
= I2C_M_RD
;
268 msgs
[1].len
= sizeof(read_buf
);
269 msgs
[1].buf
= read_buf
;
271 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
274 *lock
= read_buf
[0] & 0x40;
278 static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state
*state
)
286 msg
.addr
= state
->config
->demod_address
;
288 msg
.len
= sizeof(buf
);
291 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
298 va1j5jf8007s_check_modulation(struct va1j5jf8007s_state
*state
, int *lock
)
301 u8 write_buf
[1], read_buf
[1];
302 struct i2c_msg msgs
[2];
304 addr
= state
->config
->demod_address
;
310 msgs
[0].len
= sizeof(write_buf
);
311 msgs
[0].buf
= write_buf
;
314 msgs
[1].flags
= I2C_M_RD
;
315 msgs
[1].len
= sizeof(read_buf
);
316 msgs
[1].buf
= read_buf
;
318 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
321 *lock
= !(read_buf
[0] & 0x10);
326 va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state
*state
)
332 ts_id
= state
->fe
.dtv_property_cache
.stream_id
;
333 if (!ts_id
|| ts_id
== NO_STREAM_ID_FILTER
)
340 msg
.addr
= state
->config
->demod_address
;
342 msg
.len
= sizeof(buf
);
345 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
352 va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state
*state
, int *lock
)
355 u8 write_buf
[1], read_buf
[2];
356 struct i2c_msg msgs
[2];
359 ts_id
= state
->fe
.dtv_property_cache
.stream_id
;
360 if (!ts_id
|| ts_id
== NO_STREAM_ID_FILTER
) {
365 addr
= state
->config
->demod_address
;
371 msgs
[0].len
= sizeof(write_buf
);
372 msgs
[0].buf
= write_buf
;
375 msgs
[1].flags
= I2C_M_RD
;
376 msgs
[1].len
= sizeof(read_buf
);
377 msgs
[1].buf
= read_buf
;
379 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
382 *lock
= (read_buf
[0] << 8 | read_buf
[1]) == ts_id
;
387 va1j5jf8007s_tune(struct dvb_frontend
*fe
,
389 unsigned int mode_flags
, unsigned int *delay
,
392 struct va1j5jf8007s_state
*state
;
396 state
= fe
->demodulator_priv
;
399 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_1
;
401 switch (state
->tune_state
) {
402 case VA1J5JF8007S_IDLE
:
407 case VA1J5JF8007S_SET_FREQUENCY_1
:
408 ret
= va1j5jf8007s_set_frequency_1(state
);
412 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_2
;
417 case VA1J5JF8007S_SET_FREQUENCY_2
:
418 ret
= va1j5jf8007s_set_frequency_2(state
);
422 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_3
;
423 *delay
= (HZ
+ 99) / 100;
427 case VA1J5JF8007S_SET_FREQUENCY_3
:
428 ret
= va1j5jf8007s_set_frequency_3(state
);
432 state
->tune_state
= VA1J5JF8007S_CHECK_FREQUENCY
;
437 case VA1J5JF8007S_CHECK_FREQUENCY
:
438 ret
= va1j5jf8007s_check_frequency(state
, &lock
);
443 *delay
= (HZ
+ 999) / 1000;
448 state
->tune_state
= VA1J5JF8007S_SET_MODULATION
;
450 *status
= FE_HAS_SIGNAL
;
453 case VA1J5JF8007S_SET_MODULATION
:
454 ret
= va1j5jf8007s_set_modulation(state
);
458 state
->tune_state
= VA1J5JF8007S_CHECK_MODULATION
;
460 *status
= FE_HAS_SIGNAL
;
463 case VA1J5JF8007S_CHECK_MODULATION
:
464 ret
= va1j5jf8007s_check_modulation(state
, &lock
);
469 *delay
= (HZ
+ 49) / 50;
470 *status
= FE_HAS_SIGNAL
;
474 state
->tune_state
= VA1J5JF8007S_SET_TS_ID
;
476 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
479 case VA1J5JF8007S_SET_TS_ID
:
480 ret
= va1j5jf8007s_set_ts_id(state
);
484 state
->tune_state
= VA1J5JF8007S_CHECK_TS_ID
;
487 case VA1J5JF8007S_CHECK_TS_ID
:
488 ret
= va1j5jf8007s_check_ts_id(state
, &lock
);
493 *delay
= (HZ
+ 99) / 100;
494 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
498 state
->tune_state
= VA1J5JF8007S_TRACK
;
501 case VA1J5JF8007S_TRACK
:
503 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
510 static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state
*state
)
520 msg
.addr
= state
->config
->demod_address
;
522 msg
.len
= sizeof(buf
);
525 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
531 static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state
*state
, int sleep
)
537 buf
[1] = sleep
? 0x01 : 0x00;
539 msg
.addr
= state
->config
->demod_address
;
541 msg
.len
= sizeof(buf
);
544 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
550 static int va1j5jf8007s_sleep(struct dvb_frontend
*fe
)
552 struct va1j5jf8007s_state
*state
;
555 state
= fe
->demodulator_priv
;
557 ret
= va1j5jf8007s_init_frequency(state
);
561 return va1j5jf8007s_set_sleep(state
, 1);
564 static int va1j5jf8007s_init(struct dvb_frontend
*fe
)
566 struct va1j5jf8007s_state
*state
;
568 state
= fe
->demodulator_priv
;
569 state
->tune_state
= VA1J5JF8007S_IDLE
;
571 return va1j5jf8007s_set_sleep(state
, 0);
574 static void va1j5jf8007s_release(struct dvb_frontend
*fe
)
576 struct va1j5jf8007s_state
*state
;
577 state
= fe
->demodulator_priv
;
581 static struct dvb_frontend_ops va1j5jf8007s_ops
= {
582 .delsys
= { SYS_ISDBS
},
584 .name
= "VA1J5JF8007/VA1J5JF8011 ISDB-S",
585 .frequency_min
= 950000,
586 .frequency_max
= 2150000,
587 .frequency_stepsize
= 1000,
588 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_AUTO
|
589 FE_CAN_QAM_AUTO
| FE_CAN_TRANSMISSION_MODE_AUTO
|
590 FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_HIERARCHY_AUTO
|
594 .read_snr
= va1j5jf8007s_read_snr
,
595 .get_frontend_algo
= va1j5jf8007s_get_frontend_algo
,
596 .read_status
= va1j5jf8007s_read_status
,
597 .tune
= va1j5jf8007s_tune
,
598 .sleep
= va1j5jf8007s_sleep
,
599 .init
= va1j5jf8007s_init
,
600 .release
= va1j5jf8007s_release
,
603 static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state
*state
)
606 u8 write_buf
[1], read_buf
[1];
607 struct i2c_msg msgs
[2];
609 addr
= state
->config
->demod_address
;
615 msgs
[0].len
= sizeof(write_buf
);
616 msgs
[0].buf
= write_buf
;
619 msgs
[1].flags
= I2C_M_RD
;
620 msgs
[1].len
= sizeof(read_buf
);
621 msgs
[1].buf
= read_buf
;
623 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
626 if (read_buf
[0] != 0x41)
632 static const u8 va1j5jf8007s_20mhz_prepare_bufs
[][2] = {
633 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
634 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
635 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
636 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
639 static const u8 va1j5jf8007s_25mhz_prepare_bufs
[][2] = {
640 {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
641 {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
642 {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
643 {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
646 static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state
*state
)
655 switch (state
->config
->frequency
) {
656 case VA1J5JF8007S_20MHZ
:
657 bufs
= va1j5jf8007s_20mhz_prepare_bufs
;
658 size
= ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs
);
660 case VA1J5JF8007S_25MHZ
:
661 bufs
= va1j5jf8007s_25mhz_prepare_bufs
;
662 size
= ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs
);
668 addr
= state
->config
->demod_address
;
674 for (i
= 0; i
< size
; i
++) {
675 memcpy(buf
, bufs
[i
], sizeof(buf
));
676 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
683 /* must be called after va1j5jf8007t_attach */
684 int va1j5jf8007s_prepare(struct dvb_frontend
*fe
)
686 struct va1j5jf8007s_state
*state
;
689 state
= fe
->demodulator_priv
;
691 ret
= va1j5jf8007s_prepare_1(state
);
695 ret
= va1j5jf8007s_prepare_2(state
);
699 return va1j5jf8007s_init_frequency(state
);
702 struct dvb_frontend
*
703 va1j5jf8007s_attach(const struct va1j5jf8007s_config
*config
,
704 struct i2c_adapter
*adap
)
706 struct va1j5jf8007s_state
*state
;
707 struct dvb_frontend
*fe
;
711 state
= kzalloc(sizeof(struct va1j5jf8007s_state
), GFP_KERNEL
);
715 state
->config
= config
;
719 memcpy(&fe
->ops
, &va1j5jf8007s_ops
, sizeof(struct dvb_frontend_ops
));
720 fe
->demodulator_priv
= state
;
725 msg
.addr
= state
->config
->demod_address
;
727 msg
.len
= sizeof(buf
);
730 if (i2c_transfer(state
->adap
, &msg
, 1) != 1) {