va1j5jf8007t.c 11 KB

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