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
32enum 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
42struct 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
49static 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
95static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
96{
97	return DVBFE_ALGO_HW;
98}
99
100static int
101va1j5jf8007t_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
129struct va1j5jf8007t_cb_map {
130	u32 frequency;
131	u8 cb;
132};
133
134static 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
147static 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
160static 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
188static int
189va1j5jf8007t_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
217static 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
236static 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
265static int
266va1j5jf8007t_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
356static 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
380static 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
399static 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
413static 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
423static void va1j5jf8007t_release(struct dvb_frontend *fe)
424{
425	struct va1j5jf8007t_state *state;
426	state = fe->demodulator_priv;
427	kfree(state);
428}
429
430static 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
451static 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
458static 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
464int 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
502struct dvb_frontend *
503va1j5jf8007t_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