2 * ISDB-S driver for VA1J5JF8007
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_get_frontend_algo(struct dvb_frontend
*fe
)
57 va1j5jf8007s_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
59 struct va1j5jf8007s_state
*state
;
61 state
= fe
->demodulator_priv
;
63 switch (state
->tune_state
) {
64 case VA1J5JF8007S_IDLE
:
65 case VA1J5JF8007S_SET_FREQUENCY_1
:
66 case VA1J5JF8007S_SET_FREQUENCY_2
:
67 case VA1J5JF8007S_SET_FREQUENCY_3
:
68 case VA1J5JF8007S_CHECK_FREQUENCY
:
73 case VA1J5JF8007S_SET_MODULATION
:
74 case VA1J5JF8007S_CHECK_MODULATION
:
75 *status
|= FE_HAS_SIGNAL
;
78 case VA1J5JF8007S_SET_TS_ID
:
79 case VA1J5JF8007S_CHECK_TS_ID
:
80 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
83 case VA1J5JF8007S_TRACK
:
84 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
91 struct va1j5jf8007s_cb_map
{
96 static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps
[] = {
107 static u8
va1j5jf8007s_lookup_cb(u32 frequency
)
110 const struct va1j5jf8007s_cb_map
*map
;
112 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007s_cb_maps
); i
++) {
113 map
= &va1j5jf8007s_cb_maps
[i
];
114 if (frequency
< map
->frequency
)
120 static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state
*state
)
127 frequency
= state
->fe
.dtv_property_cache
.frequency
;
129 word
= (frequency
+ 500) / 1000;
130 if (frequency
< 1072000)
131 word
= (word
<< 1 & ~0x1f) | (word
& 0x0f);
135 buf
[2] = 0x40 | word
>> 8;
138 buf
[5] = va1j5jf8007s_lookup_cb(frequency
);
140 msg
.addr
= state
->config
->demod_address
;
142 msg
.len
= sizeof(buf
);
145 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
151 static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state
*state
)
160 msg
.addr
= state
->config
->demod_address
;
162 msg
.len
= sizeof(buf
);
165 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
171 static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state
*state
)
177 frequency
= state
->fe
.dtv_property_cache
.frequency
;
182 buf
[3] = va1j5jf8007s_lookup_cb(frequency
) | 0x4;
184 msg
.addr
= state
->config
->demod_address
;
186 msg
.len
= sizeof(buf
);
189 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
196 va1j5jf8007s_check_frequency(struct va1j5jf8007s_state
*state
, int *lock
)
199 u8 write_buf
[2], read_buf
[1];
200 struct i2c_msg msgs
[2];
202 addr
= state
->config
->demod_address
;
209 msgs
[0].len
= sizeof(write_buf
);
210 msgs
[0].buf
= write_buf
;
213 msgs
[1].flags
= I2C_M_RD
;
214 msgs
[1].len
= sizeof(read_buf
);
215 msgs
[1].buf
= read_buf
;
217 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
220 *lock
= read_buf
[0] & 0x40;
224 static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state
*state
)
232 msg
.addr
= state
->config
->demod_address
;
234 msg
.len
= sizeof(buf
);
237 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
244 va1j5jf8007s_check_modulation(struct va1j5jf8007s_state
*state
, int *lock
)
247 u8 write_buf
[1], read_buf
[1];
248 struct i2c_msg msgs
[2];
250 addr
= state
->config
->demod_address
;
256 msgs
[0].len
= sizeof(write_buf
);
257 msgs
[0].buf
= write_buf
;
260 msgs
[1].flags
= I2C_M_RD
;
261 msgs
[1].len
= sizeof(read_buf
);
262 msgs
[1].buf
= read_buf
;
264 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
267 *lock
= !(read_buf
[0] & 0x10);
272 va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state
*state
)
278 ts_id
= state
->fe
.dtv_property_cache
.isdbs_ts_id
;
286 msg
.addr
= state
->config
->demod_address
;
288 msg
.len
= sizeof(buf
);
291 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
298 va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state
*state
, int *lock
)
301 u8 write_buf
[1], read_buf
[2];
302 struct i2c_msg msgs
[2];
305 ts_id
= state
->fe
.dtv_property_cache
.isdbs_ts_id
;
311 addr
= state
->config
->demod_address
;
317 msgs
[0].len
= sizeof(write_buf
);
318 msgs
[0].buf
= write_buf
;
321 msgs
[1].flags
= I2C_M_RD
;
322 msgs
[1].len
= sizeof(read_buf
);
323 msgs
[1].buf
= read_buf
;
325 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
328 *lock
= (read_buf
[0] << 8 | read_buf
[1]) == ts_id
;
333 va1j5jf8007s_tune(struct dvb_frontend
*fe
,
334 struct dvb_frontend_parameters
*params
,
335 unsigned int mode_flags
, unsigned int *delay
,
338 struct va1j5jf8007s_state
*state
;
342 state
= fe
->demodulator_priv
;
345 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_1
;
347 switch (state
->tune_state
) {
348 case VA1J5JF8007S_IDLE
:
353 case VA1J5JF8007S_SET_FREQUENCY_1
:
354 ret
= va1j5jf8007s_set_frequency_1(state
);
358 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_2
;
363 case VA1J5JF8007S_SET_FREQUENCY_2
:
364 ret
= va1j5jf8007s_set_frequency_2(state
);
368 state
->tune_state
= VA1J5JF8007S_SET_FREQUENCY_3
;
369 *delay
= (HZ
+ 99) / 100;
373 case VA1J5JF8007S_SET_FREQUENCY_3
:
374 ret
= va1j5jf8007s_set_frequency_3(state
);
378 state
->tune_state
= VA1J5JF8007S_CHECK_FREQUENCY
;
383 case VA1J5JF8007S_CHECK_FREQUENCY
:
384 ret
= va1j5jf8007s_check_frequency(state
, &lock
);
389 *delay
= (HZ
+ 999) / 1000;
394 state
->tune_state
= VA1J5JF8007S_SET_MODULATION
;
396 *status
= FE_HAS_SIGNAL
;
399 case VA1J5JF8007S_SET_MODULATION
:
400 ret
= va1j5jf8007s_set_modulation(state
);
404 state
->tune_state
= VA1J5JF8007S_CHECK_MODULATION
;
406 *status
= FE_HAS_SIGNAL
;
409 case VA1J5JF8007S_CHECK_MODULATION
:
410 ret
= va1j5jf8007s_check_modulation(state
, &lock
);
415 *delay
= (HZ
+ 49) / 50;
416 *status
= FE_HAS_SIGNAL
;
420 state
->tune_state
= VA1J5JF8007S_SET_TS_ID
;
422 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
425 case VA1J5JF8007S_SET_TS_ID
:
426 ret
= va1j5jf8007s_set_ts_id(state
);
430 state
->tune_state
= VA1J5JF8007S_CHECK_TS_ID
;
433 case VA1J5JF8007S_CHECK_TS_ID
:
434 ret
= va1j5jf8007s_check_ts_id(state
, &lock
);
439 *delay
= (HZ
+ 99) / 100;
440 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
;
444 state
->tune_state
= VA1J5JF8007S_TRACK
;
447 case VA1J5JF8007S_TRACK
:
449 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
456 static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state
*state
)
466 msg
.addr
= state
->config
->demod_address
;
468 msg
.len
= sizeof(buf
);
471 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
477 static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state
*state
, int sleep
)
483 buf
[1] = sleep
? 0x01 : 0x00;
485 msg
.addr
= state
->config
->demod_address
;
487 msg
.len
= sizeof(buf
);
490 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
496 static int va1j5jf8007s_sleep(struct dvb_frontend
*fe
)
498 struct va1j5jf8007s_state
*state
;
501 state
= fe
->demodulator_priv
;
503 ret
= va1j5jf8007s_init_frequency(state
);
507 return va1j5jf8007s_set_sleep(state
, 1);
510 static int va1j5jf8007s_init(struct dvb_frontend
*fe
)
512 struct va1j5jf8007s_state
*state
;
514 state
= fe
->demodulator_priv
;
515 state
->tune_state
= VA1J5JF8007S_IDLE
;
517 return va1j5jf8007s_set_sleep(state
, 0);
520 static void va1j5jf8007s_release(struct dvb_frontend
*fe
)
522 struct va1j5jf8007s_state
*state
;
523 state
= fe
->demodulator_priv
;
527 static struct dvb_frontend_ops va1j5jf8007s_ops
= {
529 .name
= "VA1J5JF8007 ISDB-S",
531 .frequency_min
= 950000,
532 .frequency_max
= 2150000,
533 .frequency_stepsize
= 1000,
534 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_AUTO
|
535 FE_CAN_QAM_AUTO
| FE_CAN_TRANSMISSION_MODE_AUTO
|
536 FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_HIERARCHY_AUTO
,
539 .get_frontend_algo
= va1j5jf8007s_get_frontend_algo
,
540 .read_status
= va1j5jf8007s_read_status
,
541 .tune
= va1j5jf8007s_tune
,
542 .sleep
= va1j5jf8007s_sleep
,
543 .init
= va1j5jf8007s_init
,
544 .release
= va1j5jf8007s_release
,
547 static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state
*state
)
550 u8 write_buf
[1], read_buf
[1];
551 struct i2c_msg msgs
[2];
553 addr
= state
->config
->demod_address
;
559 msgs
[0].len
= sizeof(write_buf
);
560 msgs
[0].buf
= write_buf
;
563 msgs
[1].flags
= I2C_M_RD
;
564 msgs
[1].len
= sizeof(read_buf
);
565 msgs
[1].buf
= read_buf
;
567 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
570 if (read_buf
[0] != 0x41)
576 static const u8 va1j5jf8007s_prepare_bufs
[][2] = {
577 {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
578 {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
579 {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
580 {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
583 static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state
*state
)
590 addr
= state
->config
->demod_address
;
596 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007s_prepare_bufs
); i
++) {
597 memcpy(buf
, va1j5jf8007s_prepare_bufs
[i
], sizeof(buf
));
598 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
605 /* must be called after va1j5jf8007t_attach */
606 int va1j5jf8007s_prepare(struct dvb_frontend
*fe
)
608 struct va1j5jf8007s_state
*state
;
611 state
= fe
->demodulator_priv
;
613 ret
= va1j5jf8007s_prepare_1(state
);
617 ret
= va1j5jf8007s_prepare_2(state
);
621 return va1j5jf8007s_init_frequency(state
);
624 struct dvb_frontend
*
625 va1j5jf8007s_attach(const struct va1j5jf8007s_config
*config
,
626 struct i2c_adapter
*adap
)
628 struct va1j5jf8007s_state
*state
;
629 struct dvb_frontend
*fe
;
633 state
= kzalloc(sizeof(struct va1j5jf8007s_state
), GFP_KERNEL
);
637 state
->config
= config
;
641 memcpy(&fe
->ops
, &va1j5jf8007s_ops
, sizeof(struct dvb_frontend_ops
));
642 fe
->demodulator_priv
= state
;
647 msg
.addr
= state
->config
->demod_address
;
649 msg
.len
= sizeof(buf
);
652 if (i2c_transfer(state
->adap
, &msg
, 1) != 1) {