Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
va1j5jf8007t.c
Go to the documentation of this file.
1 /*
2  * ISDB-T driver for VA1J5JF8007/VA1J5JF8011
3  *
4  * Copyright (C) 2009 HIRANO Takahito <[email protected]>
5  *
6  * based on pt1dvr - http://pt1dvr.sourceforge.jp/
7  * by Tomoaki Ishikawa <[email protected]>
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 
40 };
41 
43  const struct va1j5jf8007t_config *config;
44  struct i2c_adapter *adap;
45  struct dvb_frontend fe;
47 };
48 
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 
95 static int va1j5jf8007t_get_frontend_algo(struct dvb_frontend *fe)
96 {
97  return DVBFE_ALGO_HW;
98 }
99 
100 static int
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:
111  *status = 0;
112  return 0;
113 
114 
117  case VA1J5JF8007T_ABORT:
118  *status |= FE_HAS_SIGNAL;
119  return 0;
120 
121  case VA1J5JF8007T_TRACK:
123  return 0;
124  }
125 
126  BUG();
127 }
128 
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 
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 
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
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 
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 
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
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)
279 
280  switch (state->tune_state) {
281  case VA1J5JF8007T_IDLE:
282  *delay = 3 * HZ;
283  *status = 0;
284  return 0;
285 
287  ret = va1j5jf8007t_set_frequency(state);
288  if (ret < 0)
289  return ret;
290 
292  *delay = 0;
293  *status = 0;
294  return 0;
295 
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 
308  *delay = 0;
309  *status = FE_HAS_SIGNAL;
310  return 0;
311 
313  ret = va1j5jf8007t_set_modulation(state);
314  if (ret < 0)
315  return ret;
316 
318  *delay = 0;
319  *status = FE_HAS_SIGNAL;
320  return 0;
321 
323  ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
324  if (ret < 0)
325  return ret;
326 
327  if (!lock) {
328  if (!retry) {
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 
340  /* fall through */
341 
342  case VA1J5JF8007T_TRACK:
343  *delay = 3 * HZ;
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 
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 
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 
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 
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 
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,
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 
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 *
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 }