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) {