• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
3  *
4  * Copyright (C) 2009 HIRANO Takahito <hiranotaka@zng.info>
5  *
6  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7  * 	by Tomoaki Ishikawa <tomy@users.sourceforge.jp>
8  *
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.
13  *
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.
18  *
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.
22  */
23 
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 "dvb_math.h"
30 #include "va1j5jf8007t.h"
31 
32 enum va1j5jf8007t_tune_state {
33 	VA1J5JF8007T_IDLE,
34 	VA1J5JF8007T_SET_FREQUENCY,
35 	VA1J5JF8007T_CHECK_FREQUENCY,
36 	VA1J5JF8007T_SET_MODULATION,
37 	VA1J5JF8007T_CHECK_MODULATION,
38 	VA1J5JF8007T_TRACK,
39 	VA1J5JF8007T_ABORT,
40 };
41 
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;
47 };
48 
va1j5jf8007t_read_snr(struct dvb_frontend * fe,u16 * snr)49 static int va1j5jf8007t_read_snr(struct dvb_frontend *fe, u16 *snr)
50 {
51 	struct va1j5jf8007t_state *state;
52 	u8 addr;
53 	int i;
54 	u8 write_buf[1], read_buf[1];
55 	struct i2c_msg msgs[2];
56 	s32 word, x, y;
57 
58 	state = fe->demodulator_priv;
59 	addr = state->config->demod_address;
60 
61 	word = 0;
62 	for (i = 0; i < 3; i++) {
63 		write_buf[0] = 0x8b + i;
64 
65 		msgs[0].addr = addr;
66 		msgs[0].flags = 0;
67 		msgs[0].len = sizeof(write_buf);
68 		msgs[0].buf = write_buf;
69 
70 		msgs[1].addr = addr;
71 		msgs[1].flags = I2C_M_RD;
72 		msgs[1].len = sizeof(read_buf);
73 		msgs[1].buf = read_buf;
74 
75 		if (i2c_transfer(state->adap, msgs, 2) != 2)
76 			return -EREMOTEIO;
77 
78 		word <<= 8;
79 		word |= read_buf[0];
80 	}
81 
82 	if (!word)
83 		return -EIO;
84 
85 	x = 10 * (intlog10(0x540000 * 100 / word) - (2 << 24));
86 	y = (24ll << 46) / 1000000;
87 	y = ((s64)y * x >> 30) - (16ll << 40) / 10000;
88 	y = ((s64)y * x >> 29) + (398ll << 35) / 10000;
89 	y = ((s64)y * x >> 30) + (5491ll << 29) / 10000;
90 	y = ((s64)y * x >> 30) + (30965ll << 23) / 10000;
91 	*snr = y >> 15;
92 	return 0;
93 }
94 
va1j5jf8007t_get_frontend_algo(struct dvb_frontend * fe)95 static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
96 {
97 	return DVBFE_ALGO_HW;
98 }
99 
100 static int
va1j5jf8007t_read_status(struct dvb_frontend * fe,fe_status_t * status)101 va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
102 {
103 	struct va1j5jf8007t_state *state;
104 
105 	state = fe->demodulator_priv;
106 
107 	switch (state->tune_state) {
108 	case VA1J5JF8007T_IDLE:
109 	case VA1J5JF8007T_SET_FREQUENCY:
110 	case VA1J5JF8007T_CHECK_FREQUENCY:
111 		*status = 0;
112 		return 0;
113 
114 
115 	case VA1J5JF8007T_SET_MODULATION:
116 	case VA1J5JF8007T_CHECK_MODULATION:
117 	case VA1J5JF8007T_ABORT:
118 		*status |= FE_HAS_SIGNAL;
119 		return 0;
120 
121 	case VA1J5JF8007T_TRACK:
122 		*status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
123 		return 0;
124 	}
125 
126 	BUG();
127 }
128 
129 struct va1j5jf8007t_cb_map {
130 	u32 frequency;
131 	u8 cb;
132 };
133 
134 static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
135 	{  90000000, 0x80 },
136 	{ 140000000, 0x81 },
137 	{ 170000000, 0xa1 },
138 	{ 220000000, 0x62 },
139 	{ 330000000, 0xa2 },
140 	{ 402000000, 0xe2 },
141 	{ 450000000, 0x64 },
142 	{ 550000000, 0x84 },
143 	{ 600000000, 0xa4 },
144 	{ 700000000, 0xc4 },
145 };
146 
va1j5jf8007t_lookup_cb(u32 frequency)147 static u8 va1j5jf8007t_lookup_cb(u32 frequency)
148 {
149 	int i;
150 	const struct va1j5jf8007t_cb_map *map;
151 
152 	for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
153 		map = &va1j5jf8007t_cb_maps[i];
154 		if (frequency < map->frequency)
155 			return map->cb;
156 	}
157 	return 0xe4;
158 }
159 
va1j5jf8007t_set_frequency(struct va1j5jf8007t_state * state)160 static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
161 {
162 	u32 frequency;
163 	u16 word;
164 	u8 buf[6];
165 	struct i2c_msg msg;
166 
167 	frequency = state->fe.dtv_property_cache.frequency;
168 
169 	word = (frequency + 71428) / 142857 + 399;
170 	buf[0] = 0xfe;
171 	buf[1] = 0xc2;
172 	buf[2] = word >> 8;
173 	buf[3] = word;
174 	buf[4] = 0x80;
175 	buf[5] = va1j5jf8007t_lookup_cb(frequency);
176 
177 	msg.addr = state->config->demod_address;
178 	msg.flags = 0;
179 	msg.len = sizeof(buf);
180 	msg.buf = buf;
181 
182 	if (i2c_transfer(state->adap, &msg, 1) != 1)
183 		return -EREMOTEIO;
184 
185 	return 0;
186 }
187 
188 static int
va1j5jf8007t_check_frequency(struct va1j5jf8007t_state * state,int * lock)189 va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
190 {
191 	u8 addr;
192 	u8 write_buf[2], read_buf[1];
193 	struct i2c_msg msgs[2];
194 
195 	addr = state->config->demod_address;
196 
197 	write_buf[0] = 0xfe;
198 	write_buf[1] = 0xc3;
199 
200 	msgs[0].addr = addr;
201 	msgs[0].flags = 0;
202 	msgs[0].len = sizeof(write_buf);
203 	msgs[0].buf = write_buf;
204 
205 	msgs[1].addr = addr;
206 	msgs[1].flags = I2C_M_RD;
207 	msgs[1].len = sizeof(read_buf);
208 	msgs[1].buf = read_buf;
209 
210 	if (i2c_transfer(state->adap, msgs, 2) != 2)
211 		return -EREMOTEIO;
212 
213 	*lock = read_buf[0] & 0x40;
214 	return 0;
215 }
216 
va1j5jf8007t_set_modulation(struct va1j5jf8007t_state * state)217 static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
218 {
219 	u8 buf[2];
220 	struct i2c_msg msg;
221 
222 	buf[0] = 0x01;
223 	buf[1] = 0x40;
224 
225 	msg.addr = state->config->demod_address;
226 	msg.flags = 0;
227 	msg.len = sizeof(buf);
228 	msg.buf = buf;
229 
230 	if (i2c_transfer(state->adap, &msg, 1) != 1)
231 		return -EREMOTEIO;
232 
233 	return 0;
234 }
235 
va1j5jf8007t_check_modulation(struct va1j5jf8007t_state * state,int * lock,int * retry)236 static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
237 					 int *lock, int *retry)
238 {
239 	u8 addr;
240 	u8 write_buf[1], read_buf[1];
241 	struct i2c_msg msgs[2];
242 
243 	addr = state->config->demod_address;
244 
245 	write_buf[0] = 0x80;
246 
247 	msgs[0].addr = addr;
248 	msgs[0].flags = 0;
249 	msgs[0].len = sizeof(write_buf);
250 	msgs[0].buf = write_buf;
251 
252 	msgs[1].addr = addr;
253 	msgs[1].flags = I2C_M_RD;
254 	msgs[1].len = sizeof(read_buf);
255 	msgs[1].buf = read_buf;
256 
257 	if (i2c_transfer(state->adap, msgs, 2) != 2)
258 		return -EREMOTEIO;
259 
260 	*lock = !(read_buf[0] & 0x10);
261 	*retry = read_buf[0] & 0x80;
262 	return 0;
263 }
264 
265 static int
va1j5jf8007t_tune(struct dvb_frontend * fe,bool re_tune,unsigned int mode_flags,unsigned int * delay,fe_status_t * status)266 va1j5jf8007t_tune(struct dvb_frontend *fe,
267 		  bool re_tune,
268 		  unsigned int mode_flags,  unsigned int *delay,
269 		  fe_status_t *status)
270 {
271 	struct va1j5jf8007t_state *state;
272 	int ret;
273 	int lock = 0, retry = 0;
274 
275 	state = fe->demodulator_priv;
276 
277 	if (re_tune)
278 		state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
279 
280 	switch (state->tune_state) {
281 	case VA1J5JF8007T_IDLE:
282 		*delay = 3 * HZ;
283 		*status = 0;
284 		return 0;
285 
286 	case VA1J5JF8007T_SET_FREQUENCY:
287 		ret = va1j5jf8007t_set_frequency(state);
288 		if (ret < 0)
289 			return ret;
290 
291 		state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
292 		*delay = 0;
293 		*status = 0;
294 		return 0;
295 
296 	case VA1J5JF8007T_CHECK_FREQUENCY:
297 		ret = va1j5jf8007t_check_frequency(state, &lock);
298 		if (ret < 0)
299 			return ret;
300 
301 		if (!lock)  {
302 			*delay = (HZ + 999) / 1000;
303 			*status = 0;
304 			return 0;
305 		}
306 
307 		state->tune_state = VA1J5JF8007T_SET_MODULATION;
308 		*delay = 0;
309 		*status = FE_HAS_SIGNAL;
310 		return 0;
311 
312 	case VA1J5JF8007T_SET_MODULATION:
313 		ret = va1j5jf8007t_set_modulation(state);
314 		if (ret < 0)
315 			return ret;
316 
317 		state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
318 		*delay = 0;
319 		*status = FE_HAS_SIGNAL;
320 		return 0;
321 
322 	case VA1J5JF8007T_CHECK_MODULATION:
323 		ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
324 		if (ret < 0)
325 			return ret;
326 
327 		if (!lock)  {
328 			if (!retry)  {
329 				state->tune_state = VA1J5JF8007T_ABORT;
330 				*delay = 3 * HZ;
331 				*status = FE_HAS_SIGNAL;
332 				return 0;
333 			}
334 			*delay = (HZ + 999) / 1000;
335 			*status = FE_HAS_SIGNAL;
336 			return 0;
337 		}
338 
339 		state->tune_state = VA1J5JF8007T_TRACK;
340 		/* fall through */
341 
342 	case VA1J5JF8007T_TRACK:
343 		*delay = 3 * HZ;
344 		*status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
345 		return 0;
346 
347 	case VA1J5JF8007T_ABORT:
348 		*delay = 3 * HZ;
349 		*status = FE_HAS_SIGNAL;
350 		return 0;
351 	}
352 
353 	BUG();
354 }
355 
va1j5jf8007t_init_frequency(struct va1j5jf8007t_state * state)356 static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
357 {
358 	u8 buf[7];
359 	struct i2c_msg msg;
360 
361 	buf[0] = 0xfe;
362 	buf[1] = 0xc2;
363 	buf[2] = 0x01;
364 	buf[3] = 0x8f;
365 	buf[4] = 0xc1;
366 	buf[5] = 0x80;
367 	buf[6] = 0x80;
368 
369 	msg.addr = state->config->demod_address;
370 	msg.flags = 0;
371 	msg.len = sizeof(buf);
372 	msg.buf = buf;
373 
374 	if (i2c_transfer(state->adap, &msg, 1) != 1)
375 		return -EREMOTEIO;
376 
377 	return 0;
378 }
379 
va1j5jf8007t_set_sleep(struct va1j5jf8007t_state * state,int sleep)380 static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
381 {
382 	u8 buf[2];
383 	struct i2c_msg msg;
384 
385 	buf[0] = 0x03;
386 	buf[1] = sleep ? 0x90 : 0x80;
387 
388 	msg.addr = state->config->demod_address;
389 	msg.flags = 0;
390 	msg.len = sizeof(buf);
391 	msg.buf = buf;
392 
393 	if (i2c_transfer(state->adap, &msg, 1) != 1)
394 		return -EREMOTEIO;
395 
396 	return 0;
397 }
398 
va1j5jf8007t_sleep(struct dvb_frontend * fe)399 static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
400 {
401 	struct va1j5jf8007t_state *state;
402 	int ret;
403 
404 	state = fe->demodulator_priv;
405 
406 	ret = va1j5jf8007t_init_frequency(state);
407 	if (ret < 0)
408 		return ret;
409 
410 	return va1j5jf8007t_set_sleep(state, 1);
411 }
412 
va1j5jf8007t_init(struct dvb_frontend * fe)413 static int va1j5jf8007t_init(struct dvb_frontend *fe)
414 {
415 	struct va1j5jf8007t_state *state;
416 
417 	state = fe->demodulator_priv;
418 	state->tune_state = VA1J5JF8007T_IDLE;
419 
420 	return va1j5jf8007t_set_sleep(state, 0);
421 }
422 
va1j5jf8007t_release(struct dvb_frontend * fe)423 static void va1j5jf8007t_release(struct dvb_frontend *fe)
424 {
425 	struct va1j5jf8007t_state *state;
426 	state = fe->demodulator_priv;
427 	kfree(state);
428 }
429 
430 static struct dvb_frontend_ops va1j5jf8007t_ops = {
431 	.delsys = { SYS_ISDBT },
432 	.info = {
433 		.name = "VA1J5JF8007/VA1J5JF8011 ISDB-T",
434 		.frequency_min = 90000000,
435 		.frequency_max = 770000000,
436 		.frequency_stepsize = 142857,
437 		.caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
438 			FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
439 			FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
440 	},
441 
442 	.read_snr = va1j5jf8007t_read_snr,
443 	.get_frontend_algo = va1j5jf8007t_get_frontend_algo,
444 	.read_status = va1j5jf8007t_read_status,
445 	.tune = va1j5jf8007t_tune,
446 	.sleep = va1j5jf8007t_sleep,
447 	.init = va1j5jf8007t_init,
448 	.release = va1j5jf8007t_release,
449 };
450 
451 static const u8 va1j5jf8007t_20mhz_prepare_bufs[][2] = {
452 	{0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
453 	{0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
454 	{0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
455 	{0xef, 0x01}
456 };
457 
458 static const u8 va1j5jf8007t_25mhz_prepare_bufs[][2] = {
459 	{0x03, 0x90}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2}, {0x22, 0x83},
460 	{0x3a, 0x00}, {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x0a}, {0x76, 0x4c},
461 	{0x77, 0x03}, {0xef, 0x01}
462 };
463 
va1j5jf8007t_prepare(struct dvb_frontend * fe)464 int va1j5jf8007t_prepare(struct dvb_frontend *fe)
465 {
466 	struct va1j5jf8007t_state *state;
467 	const u8 (*bufs)[2];
468 	int size;
469 	u8 buf[2];
470 	struct i2c_msg msg;
471 	int i;
472 
473 	state = fe->demodulator_priv;
474 
475 	switch (state->config->frequency) {
476 	case VA1J5JF8007T_20MHZ:
477 		bufs = va1j5jf8007t_20mhz_prepare_bufs;
478 		size = ARRAY_SIZE(va1j5jf8007t_20mhz_prepare_bufs);
479 		break;
480 	case VA1J5JF8007T_25MHZ:
481 		bufs = va1j5jf8007t_25mhz_prepare_bufs;
482 		size = ARRAY_SIZE(va1j5jf8007t_25mhz_prepare_bufs);
483 		break;
484 	default:
485 		return -EINVAL;
486 	}
487 
488 	msg.addr = state->config->demod_address;
489 	msg.flags = 0;
490 	msg.len = sizeof(buf);
491 	msg.buf = buf;
492 
493 	for (i = 0; i < size; i++) {
494 		memcpy(buf, bufs[i], sizeof(buf));
495 		if (i2c_transfer(state->adap, &msg, 1) != 1)
496 			return -EREMOTEIO;
497 	}
498 
499 	return va1j5jf8007t_init_frequency(state);
500 }
501 
502 struct dvb_frontend *
va1j5jf8007t_attach(const struct va1j5jf8007t_config * config,struct i2c_adapter * adap)503 va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
504 		    struct i2c_adapter *adap)
505 {
506 	struct va1j5jf8007t_state *state;
507 	struct dvb_frontend *fe;
508 	u8 buf[2];
509 	struct i2c_msg msg;
510 
511 	state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
512 	if (!state)
513 		return NULL;
514 
515 	state->config = config;
516 	state->adap = adap;
517 
518 	fe = &state->fe;
519 	memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
520 	fe->demodulator_priv = state;
521 
522 	buf[0] = 0x01;
523 	buf[1] = 0x80;
524 
525 	msg.addr = state->config->demod_address;
526 	msg.flags = 0;
527 	msg.len = sizeof(buf);
528 	msg.buf = buf;
529 
530 	if (i2c_transfer(state->adap, &msg, 1) != 1) {
531 		kfree(state);
532 		return NULL;
533 	}
534 
535 	return fe;
536 }
537