Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
va1j5jf8007s.c
Go to the documentation of this file.
1 /*
2  * ISDB-S 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 "va1j5jf8007s.h"
30 
42 };
43 
45  const struct va1j5jf8007s_config *config;
46  struct i2c_adapter *adap;
47  struct dvb_frontend fe;
49 };
50 
51 static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
52 {
53  struct va1j5jf8007s_state *state;
54  u8 addr;
55  int i;
56  u8 write_buf[1], read_buf[1];
57  struct i2c_msg msgs[2];
58  s32 word, x1, x2, x3, x4, x5, y;
59 
60  state = fe->demodulator_priv;
61  addr = state->config->demod_address;
62 
63  word = 0;
64  for (i = 0; i < 2; i++) {
65  write_buf[0] = 0xbc + i;
66 
67  msgs[0].addr = addr;
68  msgs[0].flags = 0;
69  msgs[0].len = sizeof(write_buf);
70  msgs[0].buf = write_buf;
71 
72  msgs[1].addr = addr;
73  msgs[1].flags = I2C_M_RD;
74  msgs[1].len = sizeof(read_buf);
75  msgs[1].buf = read_buf;
76 
77  if (i2c_transfer(state->adap, msgs, 2) != 2)
78  return -EREMOTEIO;
79 
80  word <<= 8;
81  word |= read_buf[0];
82  }
83 
84  word -= 3000;
85  if (word < 0)
86  word = 0;
87 
88  x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
89  x2 = (s64)x1 * x1 >> 31;
90  x3 = (s64)x2 * x1 >> 31;
91  x4 = (s64)x2 * x2 >> 31;
92  x5 = (s64)x4 * x1 >> 31;
93 
94  y = (58857ll << 23) / 1000;
95  y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
96  y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
97  y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
98  y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
99  y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
100 
101  *snr = y < 0 ? 0 : y >> 15;
102  return 0;
103 }
104 
105 static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
106 {
107  return DVBFE_ALGO_HW;
108 }
109 
110 static int
111 va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
112 {
113  struct va1j5jf8007s_state *state;
114 
115  state = fe->demodulator_priv;
116 
117  switch (state->tune_state) {
118  case VA1J5JF8007S_IDLE:
123  *status = 0;
124  return 0;
125 
126 
129  *status |= FE_HAS_SIGNAL;
130  return 0;
131 
134  *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
135  return 0;
136 
137  case VA1J5JF8007S_TRACK:
139  return 0;
140  }
141 
142  BUG();
143 }
144 
148 };
149 
150 static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
151  { 986000, 0xb2 },
152  { 1072000, 0xd2 },
153  { 1154000, 0xe2 },
154  { 1291000, 0x20 },
155  { 1447000, 0x40 },
156  { 1615000, 0x60 },
157  { 1791000, 0x80 },
158  { 1972000, 0xa0 },
159 };
160 
161 static u8 va1j5jf8007s_lookup_cb(u32 frequency)
162 {
163  int i;
164  const struct va1j5jf8007s_cb_map *map;
165 
166  for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
167  map = &va1j5jf8007s_cb_maps[i];
168  if (frequency < map->frequency)
169  return map->cb;
170  }
171  return 0xc0;
172 }
173 
174 static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
175 {
176  u32 frequency;
177  u16 word;
178  u8 buf[6];
179  struct i2c_msg msg;
180 
181  frequency = state->fe.dtv_property_cache.frequency;
182 
183  word = (frequency + 500) / 1000;
184  if (frequency < 1072000)
185  word = (word << 1 & ~0x1f) | (word & 0x0f);
186 
187  buf[0] = 0xfe;
188  buf[1] = 0xc0;
189  buf[2] = 0x40 | word >> 8;
190  buf[3] = word;
191  buf[4] = 0xe0;
192  buf[5] = va1j5jf8007s_lookup_cb(frequency);
193 
194  msg.addr = state->config->demod_address;
195  msg.flags = 0;
196  msg.len = sizeof(buf);
197  msg.buf = buf;
198 
199  if (i2c_transfer(state->adap, &msg, 1) != 1)
200  return -EREMOTEIO;
201 
202  return 0;
203 }
204 
205 static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
206 {
207  u8 buf[3];
208  struct i2c_msg msg;
209 
210  buf[0] = 0xfe;
211  buf[1] = 0xc0;
212  buf[2] = 0xe4;
213 
214  msg.addr = state->config->demod_address;
215  msg.flags = 0;
216  msg.len = sizeof(buf);
217  msg.buf = buf;
218 
219  if (i2c_transfer(state->adap, &msg, 1) != 1)
220  return -EREMOTEIO;
221 
222  return 0;
223 }
224 
225 static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
226 {
227  u32 frequency;
228  u8 buf[4];
229  struct i2c_msg msg;
230 
231  frequency = state->fe.dtv_property_cache.frequency;
232 
233  buf[0] = 0xfe;
234  buf[1] = 0xc0;
235  buf[2] = 0xf4;
236  buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
237 
238  msg.addr = state->config->demod_address;
239  msg.flags = 0;
240  msg.len = sizeof(buf);
241  msg.buf = buf;
242 
243  if (i2c_transfer(state->adap, &msg, 1) != 1)
244  return -EREMOTEIO;
245 
246  return 0;
247 }
248 
249 static int
250 va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
251 {
252  u8 addr;
253  u8 write_buf[2], read_buf[1];
254  struct i2c_msg msgs[2];
255 
256  addr = state->config->demod_address;
257 
258  write_buf[0] = 0xfe;
259  write_buf[1] = 0xc1;
260 
261  msgs[0].addr = addr;
262  msgs[0].flags = 0;
263  msgs[0].len = sizeof(write_buf);
264  msgs[0].buf = write_buf;
265 
266  msgs[1].addr = addr;
267  msgs[1].flags = I2C_M_RD;
268  msgs[1].len = sizeof(read_buf);
269  msgs[1].buf = read_buf;
270 
271  if (i2c_transfer(state->adap, msgs, 2) != 2)
272  return -EREMOTEIO;
273 
274  *lock = read_buf[0] & 0x40;
275  return 0;
276 }
277 
278 static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
279 {
280  u8 buf[2];
281  struct i2c_msg msg;
282 
283  buf[0] = 0x03;
284  buf[1] = 0x01;
285 
286  msg.addr = state->config->demod_address;
287  msg.flags = 0;
288  msg.len = sizeof(buf);
289  msg.buf = buf;
290 
291  if (i2c_transfer(state->adap, &msg, 1) != 1)
292  return -EREMOTEIO;
293 
294  return 0;
295 }
296 
297 static int
298 va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
299 {
300  u8 addr;
301  u8 write_buf[1], read_buf[1];
302  struct i2c_msg msgs[2];
303 
304  addr = state->config->demod_address;
305 
306  write_buf[0] = 0xc3;
307 
308  msgs[0].addr = addr;
309  msgs[0].flags = 0;
310  msgs[0].len = sizeof(write_buf);
311  msgs[0].buf = write_buf;
312 
313  msgs[1].addr = addr;
314  msgs[1].flags = I2C_M_RD;
315  msgs[1].len = sizeof(read_buf);
316  msgs[1].buf = read_buf;
317 
318  if (i2c_transfer(state->adap, msgs, 2) != 2)
319  return -EREMOTEIO;
320 
321  *lock = !(read_buf[0] & 0x10);
322  return 0;
323 }
324 
325 static int
326 va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
327 {
328  u32 ts_id;
329  u8 buf[3];
330  struct i2c_msg msg;
331 
332  ts_id = state->fe.dtv_property_cache.stream_id;
333  if (!ts_id || ts_id == NO_STREAM_ID_FILTER)
334  return 0;
335 
336  buf[0] = 0x8f;
337  buf[1] = ts_id >> 8;
338  buf[2] = ts_id;
339 
340  msg.addr = state->config->demod_address;
341  msg.flags = 0;
342  msg.len = sizeof(buf);
343  msg.buf = buf;
344 
345  if (i2c_transfer(state->adap, &msg, 1) != 1)
346  return -EREMOTEIO;
347 
348  return 0;
349 }
350 
351 static int
352 va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
353 {
354  u8 addr;
355  u8 write_buf[1], read_buf[2];
356  struct i2c_msg msgs[2];
357  u32 ts_id;
358 
359  ts_id = state->fe.dtv_property_cache.stream_id;
360  if (!ts_id || ts_id == NO_STREAM_ID_FILTER) {
361  *lock = 1;
362  return 0;
363  }
364 
365  addr = state->config->demod_address;
366 
367  write_buf[0] = 0xe6;
368 
369  msgs[0].addr = addr;
370  msgs[0].flags = 0;
371  msgs[0].len = sizeof(write_buf);
372  msgs[0].buf = write_buf;
373 
374  msgs[1].addr = addr;
375  msgs[1].flags = I2C_M_RD;
376  msgs[1].len = sizeof(read_buf);
377  msgs[1].buf = read_buf;
378 
379  if (i2c_transfer(state->adap, msgs, 2) != 2)
380  return -EREMOTEIO;
381 
382  *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
383  return 0;
384 }
385 
386 static int
387 va1j5jf8007s_tune(struct dvb_frontend *fe,
388  bool re_tune,
389  unsigned int mode_flags, unsigned int *delay,
390  fe_status_t *status)
391 {
392  struct va1j5jf8007s_state *state;
393  int ret;
394  int lock = 0;
395 
396  state = fe->demodulator_priv;
397 
398  if (re_tune)
400 
401  switch (state->tune_state) {
402  case VA1J5JF8007S_IDLE:
403  *delay = 3 * HZ;
404  *status = 0;
405  return 0;
406 
408  ret = va1j5jf8007s_set_frequency_1(state);
409  if (ret < 0)
410  return ret;
411 
413  *delay = 0;
414  *status = 0;
415  return 0;
416 
418  ret = va1j5jf8007s_set_frequency_2(state);
419  if (ret < 0)
420  return ret;
421 
423  *delay = (HZ + 99) / 100;
424  *status = 0;
425  return 0;
426 
428  ret = va1j5jf8007s_set_frequency_3(state);
429  if (ret < 0)
430  return ret;
431 
433  *delay = 0;
434  *status = 0;
435  return 0;
436 
438  ret = va1j5jf8007s_check_frequency(state, &lock);
439  if (ret < 0)
440  return ret;
441 
442  if (!lock) {
443  *delay = (HZ + 999) / 1000;
444  *status = 0;
445  return 0;
446  }
447 
449  *delay = 0;
450  *status = FE_HAS_SIGNAL;
451  return 0;
452 
454  ret = va1j5jf8007s_set_modulation(state);
455  if (ret < 0)
456  return ret;
457 
459  *delay = 0;
460  *status = FE_HAS_SIGNAL;
461  return 0;
462 
464  ret = va1j5jf8007s_check_modulation(state, &lock);
465  if (ret < 0)
466  return ret;
467 
468  if (!lock) {
469  *delay = (HZ + 49) / 50;
470  *status = FE_HAS_SIGNAL;
471  return 0;
472  }
473 
475  *delay = 0;
476  *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
477  return 0;
478 
480  ret = va1j5jf8007s_set_ts_id(state);
481  if (ret < 0)
482  return ret;
483 
485  return 0;
486 
488  ret = va1j5jf8007s_check_ts_id(state, &lock);
489  if (ret < 0)
490  return ret;
491 
492  if (!lock) {
493  *delay = (HZ + 99) / 100;
494  *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
495  return 0;
496  }
497 
499  /* fall through */
500 
501  case VA1J5JF8007S_TRACK:
502  *delay = 3 * HZ;
504  return 0;
505  }
506 
507  BUG();
508 }
509 
510 static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
511 {
512  u8 buf[4];
513  struct i2c_msg msg;
514 
515  buf[0] = 0xfe;
516  buf[1] = 0xc0;
517  buf[2] = 0xf0;
518  buf[3] = 0x04;
519 
520  msg.addr = state->config->demod_address;
521  msg.flags = 0;
522  msg.len = sizeof(buf);
523  msg.buf = buf;
524 
525  if (i2c_transfer(state->adap, &msg, 1) != 1)
526  return -EREMOTEIO;
527 
528  return 0;
529 }
530 
531 static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
532 {
533  u8 buf[2];
534  struct i2c_msg msg;
535 
536  buf[0] = 0x17;
537  buf[1] = sleep ? 0x01 : 0x00;
538 
539  msg.addr = state->config->demod_address;
540  msg.flags = 0;
541  msg.len = sizeof(buf);
542  msg.buf = buf;
543 
544  if (i2c_transfer(state->adap, &msg, 1) != 1)
545  return -EREMOTEIO;
546 
547  return 0;
548 }
549 
550 static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
551 {
552  struct va1j5jf8007s_state *state;
553  int ret;
554 
555  state = fe->demodulator_priv;
556 
557  ret = va1j5jf8007s_init_frequency(state);
558  if (ret < 0)
559  return ret;
560 
561  return va1j5jf8007s_set_sleep(state, 1);
562 }
563 
564 static int va1j5jf8007s_init(struct dvb_frontend *fe)
565 {
566  struct va1j5jf8007s_state *state;
567 
568  state = fe->demodulator_priv;
569  state->tune_state = VA1J5JF8007S_IDLE;
570 
571  return va1j5jf8007s_set_sleep(state, 0);
572 }
573 
574 static void va1j5jf8007s_release(struct dvb_frontend *fe)
575 {
576  struct va1j5jf8007s_state *state;
577  state = fe->demodulator_priv;
578  kfree(state);
579 }
580 
581 static struct dvb_frontend_ops va1j5jf8007s_ops = {
582  .delsys = { SYS_ISDBS },
583  .info = {
584  .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S",
585  .frequency_min = 950000,
586  .frequency_max = 2150000,
587  .frequency_stepsize = 1000,
592  },
593 
594  .read_snr = va1j5jf8007s_read_snr,
595  .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
596  .read_status = va1j5jf8007s_read_status,
597  .tune = va1j5jf8007s_tune,
598  .sleep = va1j5jf8007s_sleep,
599  .init = va1j5jf8007s_init,
600  .release = va1j5jf8007s_release,
601 };
602 
603 static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
604 {
605  u8 addr;
606  u8 write_buf[1], read_buf[1];
607  struct i2c_msg msgs[2];
608 
609  addr = state->config->demod_address;
610 
611  write_buf[0] = 0x07;
612 
613  msgs[0].addr = addr;
614  msgs[0].flags = 0;
615  msgs[0].len = sizeof(write_buf);
616  msgs[0].buf = write_buf;
617 
618  msgs[1].addr = addr;
619  msgs[1].flags = I2C_M_RD;
620  msgs[1].len = sizeof(read_buf);
621  msgs[1].buf = read_buf;
622 
623  if (i2c_transfer(state->adap, msgs, 2) != 2)
624  return -EREMOTEIO;
625 
626  if (read_buf[0] != 0x41)
627  return -EIO;
628 
629  return 0;
630 }
631 
632 static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = {
633  {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
634  {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
635  {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
636  {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
637 };
638 
639 static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = {
640  {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
641  {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
642  {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
643  {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
644 };
645 
646 static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
647 {
648  const u8 (*bufs)[2];
649  int size;
650  u8 addr;
651  u8 buf[2];
652  struct i2c_msg msg;
653  int i;
654 
655  switch (state->config->frequency) {
656  case VA1J5JF8007S_20MHZ:
657  bufs = va1j5jf8007s_20mhz_prepare_bufs;
658  size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs);
659  break;
660  case VA1J5JF8007S_25MHZ:
661  bufs = va1j5jf8007s_25mhz_prepare_bufs;
662  size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs);
663  break;
664  default:
665  return -EINVAL;
666  }
667 
668  addr = state->config->demod_address;
669 
670  msg.addr = addr;
671  msg.flags = 0;
672  msg.len = 2;
673  msg.buf = buf;
674  for (i = 0; i < size; i++) {
675  memcpy(buf, bufs[i], sizeof(buf));
676  if (i2c_transfer(state->adap, &msg, 1) != 1)
677  return -EREMOTEIO;
678  }
679 
680  return 0;
681 }
682 
683 /* must be called after va1j5jf8007t_attach */
685 {
686  struct va1j5jf8007s_state *state;
687  int ret;
688 
689  state = fe->demodulator_priv;
690 
691  ret = va1j5jf8007s_prepare_1(state);
692  if (ret < 0)
693  return ret;
694 
695  ret = va1j5jf8007s_prepare_2(state);
696  if (ret < 0)
697  return ret;
698 
699  return va1j5jf8007s_init_frequency(state);
700 }
701 
702 struct dvb_frontend *
704  struct i2c_adapter *adap)
705 {
706  struct va1j5jf8007s_state *state;
707  struct dvb_frontend *fe;
708  u8 buf[2];
709  struct i2c_msg msg;
710 
711  state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
712  if (!state)
713  return NULL;
714 
715  state->config = config;
716  state->adap = adap;
717 
718  fe = &state->fe;
719  memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
720  fe->demodulator_priv = state;
721 
722  buf[0] = 0x01;
723  buf[1] = 0x80;
724 
725  msg.addr = state->config->demod_address;
726  msg.flags = 0;
727  msg.len = sizeof(buf);
728  msg.buf = buf;
729 
730  if (i2c_transfer(state->adap, &msg, 1) != 1) {
731  kfree(state);
732  return NULL;
733  }
734 
735  return fe;
736 }