2 * ISDB-T 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"
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_get_frontend_algo(struct dvb_frontend
*fe
)
55 va1j5jf8007t_read_status(struct dvb_frontend
*fe
, fe_status_t
*status
)
57 struct va1j5jf8007t_state
*state
;
59 state
= fe
->demodulator_priv
;
61 switch (state
->tune_state
) {
62 case VA1J5JF8007T_IDLE
:
63 case VA1J5JF8007T_SET_FREQUENCY
:
64 case VA1J5JF8007T_CHECK_FREQUENCY
:
69 case VA1J5JF8007T_SET_MODULATION
:
70 case VA1J5JF8007T_CHECK_MODULATION
:
71 case VA1J5JF8007T_ABORT
:
72 *status
|= FE_HAS_SIGNAL
;
75 case VA1J5JF8007T_TRACK
:
76 *status
|= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
83 struct va1j5jf8007t_cb_map
{
88 static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps
[] = {
101 static u8
va1j5jf8007t_lookup_cb(u32 frequency
)
104 const struct va1j5jf8007t_cb_map
*map
;
106 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007t_cb_maps
); i
++) {
107 map
= &va1j5jf8007t_cb_maps
[i
];
108 if (frequency
< map
->frequency
)
114 static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state
*state
)
121 frequency
= state
->fe
.dtv_property_cache
.frequency
;
123 word
= (frequency
+ 71428) / 142857 + 399;
129 buf
[5] = va1j5jf8007t_lookup_cb(frequency
);
131 msg
.addr
= state
->config
->demod_address
;
133 msg
.len
= sizeof(buf
);
136 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
143 va1j5jf8007t_check_frequency(struct va1j5jf8007t_state
*state
, int *lock
)
146 u8 write_buf
[2], read_buf
[1];
147 struct i2c_msg msgs
[2];
149 addr
= state
->config
->demod_address
;
156 msgs
[0].len
= sizeof(write_buf
);
157 msgs
[0].buf
= write_buf
;
160 msgs
[1].flags
= I2C_M_RD
;
161 msgs
[1].len
= sizeof(read_buf
);
162 msgs
[1].buf
= read_buf
;
164 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
167 *lock
= read_buf
[0] & 0x40;
171 static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state
*state
)
179 msg
.addr
= state
->config
->demod_address
;
181 msg
.len
= sizeof(buf
);
184 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
190 static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state
*state
,
191 int *lock
, int *retry
)
194 u8 write_buf
[1], read_buf
[1];
195 struct i2c_msg msgs
[2];
197 addr
= state
->config
->demod_address
;
203 msgs
[0].len
= sizeof(write_buf
);
204 msgs
[0].buf
= write_buf
;
207 msgs
[1].flags
= I2C_M_RD
;
208 msgs
[1].len
= sizeof(read_buf
);
209 msgs
[1].buf
= read_buf
;
211 if (i2c_transfer(state
->adap
, msgs
, 2) != 2)
214 *lock
= !(read_buf
[0] & 0x10);
215 *retry
= read_buf
[0] & 0x80;
220 va1j5jf8007t_tune(struct dvb_frontend
*fe
,
221 struct dvb_frontend_parameters
*params
,
222 unsigned int mode_flags
, unsigned int *delay
,
225 struct va1j5jf8007t_state
*state
;
229 state
= fe
->demodulator_priv
;
232 state
->tune_state
= VA1J5JF8007T_SET_FREQUENCY
;
234 switch (state
->tune_state
) {
235 case VA1J5JF8007T_IDLE
:
240 case VA1J5JF8007T_SET_FREQUENCY
:
241 ret
= va1j5jf8007t_set_frequency(state
);
245 state
->tune_state
= VA1J5JF8007T_CHECK_FREQUENCY
;
250 case VA1J5JF8007T_CHECK_FREQUENCY
:
251 ret
= va1j5jf8007t_check_frequency(state
, &lock
);
256 *delay
= (HZ
+ 999) / 1000;
261 state
->tune_state
= VA1J5JF8007T_SET_MODULATION
;
263 *status
= FE_HAS_SIGNAL
;
266 case VA1J5JF8007T_SET_MODULATION
:
267 ret
= va1j5jf8007t_set_modulation(state
);
271 state
->tune_state
= VA1J5JF8007T_CHECK_MODULATION
;
273 *status
= FE_HAS_SIGNAL
;
276 case VA1J5JF8007T_CHECK_MODULATION
:
277 ret
= va1j5jf8007t_check_modulation(state
, &lock
, &retry
);
283 state
->tune_state
= VA1J5JF8007T_ABORT
;
285 *status
= FE_HAS_SIGNAL
;
288 *delay
= (HZ
+ 999) / 1000;
289 *status
= FE_HAS_SIGNAL
;
293 state
->tune_state
= VA1J5JF8007T_TRACK
;
296 case VA1J5JF8007T_TRACK
:
298 *status
= FE_HAS_SIGNAL
| FE_HAS_CARRIER
| FE_HAS_LOCK
;
301 case VA1J5JF8007T_ABORT
:
303 *status
= FE_HAS_SIGNAL
;
310 static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state
*state
)
323 msg
.addr
= state
->config
->demod_address
;
325 msg
.len
= sizeof(buf
);
328 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
334 static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state
*state
, int sleep
)
340 buf
[1] = sleep
? 0x90 : 0x80;
342 msg
.addr
= state
->config
->demod_address
;
344 msg
.len
= sizeof(buf
);
347 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
353 static int va1j5jf8007t_sleep(struct dvb_frontend
*fe
)
355 struct va1j5jf8007t_state
*state
;
358 state
= fe
->demodulator_priv
;
360 ret
= va1j5jf8007t_init_frequency(state
);
364 return va1j5jf8007t_set_sleep(state
, 1);
367 static int va1j5jf8007t_init(struct dvb_frontend
*fe
)
369 struct va1j5jf8007t_state
*state
;
371 state
= fe
->demodulator_priv
;
372 state
->tune_state
= VA1J5JF8007T_IDLE
;
374 return va1j5jf8007t_set_sleep(state
, 0);
377 static void va1j5jf8007t_release(struct dvb_frontend
*fe
)
379 struct va1j5jf8007t_state
*state
;
380 state
= fe
->demodulator_priv
;
384 static struct dvb_frontend_ops va1j5jf8007t_ops
= {
386 .name
= "VA1J5JF8007 ISDB-T",
388 .frequency_min
= 90000000,
389 .frequency_max
= 770000000,
390 .frequency_stepsize
= 142857,
391 .caps
= FE_CAN_INVERSION_AUTO
| FE_CAN_FEC_AUTO
|
392 FE_CAN_QAM_AUTO
| FE_CAN_TRANSMISSION_MODE_AUTO
|
393 FE_CAN_GUARD_INTERVAL_AUTO
| FE_CAN_HIERARCHY_AUTO
,
396 .get_frontend_algo
= va1j5jf8007t_get_frontend_algo
,
397 .read_status
= va1j5jf8007t_read_status
,
398 .tune
= va1j5jf8007t_tune
,
399 .sleep
= va1j5jf8007t_sleep
,
400 .init
= va1j5jf8007t_init
,
401 .release
= va1j5jf8007t_release
,
404 static const u8 va1j5jf8007t_prepare_bufs
[][2] = {
405 {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
406 {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
407 {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
411 int va1j5jf8007t_prepare(struct dvb_frontend
*fe
)
413 struct va1j5jf8007t_state
*state
;
418 state
= fe
->demodulator_priv
;
420 msg
.addr
= state
->config
->demod_address
;
422 msg
.len
= sizeof(buf
);
425 for (i
= 0; i
< ARRAY_SIZE(va1j5jf8007t_prepare_bufs
); i
++) {
426 memcpy(buf
, va1j5jf8007t_prepare_bufs
[i
], sizeof(buf
));
427 if (i2c_transfer(state
->adap
, &msg
, 1) != 1)
431 return va1j5jf8007t_init_frequency(state
);
434 struct dvb_frontend
*
435 va1j5jf8007t_attach(const struct va1j5jf8007t_config
*config
,
436 struct i2c_adapter
*adap
)
438 struct va1j5jf8007t_state
*state
;
439 struct dvb_frontend
*fe
;
443 state
= kzalloc(sizeof(struct va1j5jf8007t_state
), GFP_KERNEL
);
447 state
->config
= config
;
451 memcpy(&fe
->ops
, &va1j5jf8007t_ops
, sizeof(struct dvb_frontend_ops
));
452 fe
->demodulator_priv
= state
;
457 msg
.addr
= state
->config
->demod_address
;
459 msg
.len
= sizeof(buf
);
462 if (i2c_transfer(state
->adap
, &msg
, 1) != 1) {