va1j5jf8007t.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. /*
  2. * ISDB-T driver for VA1J5JF8007
  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_get_frontend_algo(struct dvb_frontend *fe)
  46. {
  47. return DVBFE_ALGO_HW;
  48. }
  49. static int
  50. va1j5jf8007t_read_status(struct dvb_frontend *fe, fe_status_t *status)
  51. {
  52. struct va1j5jf8007t_state *state;
  53. state = fe->demodulator_priv;
  54. switch (state->tune_state) {
  55. case VA1J5JF8007T_IDLE:
  56. case VA1J5JF8007T_SET_FREQUENCY:
  57. case VA1J5JF8007T_CHECK_FREQUENCY:
  58. *status = 0;
  59. return 0;
  60. case VA1J5JF8007T_SET_MODULATION:
  61. case VA1J5JF8007T_CHECK_MODULATION:
  62. case VA1J5JF8007T_ABORT:
  63. *status |= FE_HAS_SIGNAL;
  64. return 0;
  65. case VA1J5JF8007T_TRACK:
  66. *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
  67. return 0;
  68. }
  69. BUG();
  70. }
  71. struct va1j5jf8007t_cb_map {
  72. u32 frequency;
  73. u8 cb;
  74. };
  75. static const struct va1j5jf8007t_cb_map va1j5jf8007t_cb_maps[] = {
  76. { 90000000, 0x80 },
  77. { 140000000, 0x81 },
  78. { 170000000, 0xa1 },
  79. { 220000000, 0x62 },
  80. { 330000000, 0xa2 },
  81. { 402000000, 0xe2 },
  82. { 450000000, 0x64 },
  83. { 550000000, 0x84 },
  84. { 600000000, 0xa4 },
  85. { 700000000, 0xc4 },
  86. };
  87. static u8 va1j5jf8007t_lookup_cb(u32 frequency)
  88. {
  89. int i;
  90. const struct va1j5jf8007t_cb_map *map;
  91. for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_cb_maps); i++) {
  92. map = &va1j5jf8007t_cb_maps[i];
  93. if (frequency < map->frequency)
  94. return map->cb;
  95. }
  96. return 0xe4;
  97. }
  98. static int va1j5jf8007t_set_frequency(struct va1j5jf8007t_state *state)
  99. {
  100. u32 frequency;
  101. u16 word;
  102. u8 buf[6];
  103. struct i2c_msg msg;
  104. frequency = state->fe.dtv_property_cache.frequency;
  105. word = (frequency + 71428) / 142857 + 399;
  106. buf[0] = 0xfe;
  107. buf[1] = 0xc2;
  108. buf[2] = word >> 8;
  109. buf[3] = word;
  110. buf[4] = 0x80;
  111. buf[5] = va1j5jf8007t_lookup_cb(frequency);
  112. msg.addr = state->config->demod_address;
  113. msg.flags = 0;
  114. msg.len = sizeof(buf);
  115. msg.buf = buf;
  116. if (i2c_transfer(state->adap, &msg, 1) != 1)
  117. return -EREMOTEIO;
  118. return 0;
  119. }
  120. static int
  121. va1j5jf8007t_check_frequency(struct va1j5jf8007t_state *state, int *lock)
  122. {
  123. u8 addr;
  124. u8 write_buf[2], read_buf[1];
  125. struct i2c_msg msgs[2];
  126. addr = state->config->demod_address;
  127. write_buf[0] = 0xfe;
  128. write_buf[1] = 0xc3;
  129. msgs[0].addr = addr;
  130. msgs[0].flags = 0;
  131. msgs[0].len = sizeof(write_buf);
  132. msgs[0].buf = write_buf;
  133. msgs[1].addr = addr;
  134. msgs[1].flags = I2C_M_RD;
  135. msgs[1].len = sizeof(read_buf);
  136. msgs[1].buf = read_buf;
  137. if (i2c_transfer(state->adap, msgs, 2) != 2)
  138. return -EREMOTEIO;
  139. *lock = read_buf[0] & 0x40;
  140. return 0;
  141. }
  142. static int va1j5jf8007t_set_modulation(struct va1j5jf8007t_state *state)
  143. {
  144. u8 buf[2];
  145. struct i2c_msg msg;
  146. buf[0] = 0x01;
  147. buf[1] = 0x40;
  148. msg.addr = state->config->demod_address;
  149. msg.flags = 0;
  150. msg.len = sizeof(buf);
  151. msg.buf = buf;
  152. if (i2c_transfer(state->adap, &msg, 1) != 1)
  153. return -EREMOTEIO;
  154. return 0;
  155. }
  156. static int va1j5jf8007t_check_modulation(struct va1j5jf8007t_state *state,
  157. int *lock, int *retry)
  158. {
  159. u8 addr;
  160. u8 write_buf[1], read_buf[1];
  161. struct i2c_msg msgs[2];
  162. addr = state->config->demod_address;
  163. write_buf[0] = 0x80;
  164. msgs[0].addr = addr;
  165. msgs[0].flags = 0;
  166. msgs[0].len = sizeof(write_buf);
  167. msgs[0].buf = write_buf;
  168. msgs[1].addr = addr;
  169. msgs[1].flags = I2C_M_RD;
  170. msgs[1].len = sizeof(read_buf);
  171. msgs[1].buf = read_buf;
  172. if (i2c_transfer(state->adap, msgs, 2) != 2)
  173. return -EREMOTEIO;
  174. *lock = !(read_buf[0] & 0x10);
  175. *retry = read_buf[0] & 0x80;
  176. return 0;
  177. }
  178. static int
  179. va1j5jf8007t_tune(struct dvb_frontend *fe,
  180. struct dvb_frontend_parameters *params,
  181. unsigned int mode_flags, unsigned int *delay,
  182. fe_status_t *status)
  183. {
  184. struct va1j5jf8007t_state *state;
  185. int ret;
  186. int lock, retry;
  187. state = fe->demodulator_priv;
  188. if (params != NULL)
  189. state->tune_state = VA1J5JF8007T_SET_FREQUENCY;
  190. switch (state->tune_state) {
  191. case VA1J5JF8007T_IDLE:
  192. *delay = 3 * HZ;
  193. *status = 0;
  194. return 0;
  195. case VA1J5JF8007T_SET_FREQUENCY:
  196. ret = va1j5jf8007t_set_frequency(state);
  197. if (ret < 0)
  198. return ret;
  199. state->tune_state = VA1J5JF8007T_CHECK_FREQUENCY;
  200. *delay = 0;
  201. *status = 0;
  202. return 0;
  203. case VA1J5JF8007T_CHECK_FREQUENCY:
  204. ret = va1j5jf8007t_check_frequency(state, &lock);
  205. if (ret < 0)
  206. return ret;
  207. if (!lock) {
  208. *delay = (HZ + 999) / 1000;
  209. *status = 0;
  210. return 0;
  211. }
  212. state->tune_state = VA1J5JF8007T_SET_MODULATION;
  213. *delay = 0;
  214. *status = FE_HAS_SIGNAL;
  215. return 0;
  216. case VA1J5JF8007T_SET_MODULATION:
  217. ret = va1j5jf8007t_set_modulation(state);
  218. if (ret < 0)
  219. return ret;
  220. state->tune_state = VA1J5JF8007T_CHECK_MODULATION;
  221. *delay = 0;
  222. *status = FE_HAS_SIGNAL;
  223. return 0;
  224. case VA1J5JF8007T_CHECK_MODULATION:
  225. ret = va1j5jf8007t_check_modulation(state, &lock, &retry);
  226. if (ret < 0)
  227. return ret;
  228. if (!lock) {
  229. if (!retry) {
  230. state->tune_state = VA1J5JF8007T_ABORT;
  231. *delay = 3 * HZ;
  232. *status = FE_HAS_SIGNAL;
  233. return 0;
  234. }
  235. *delay = (HZ + 999) / 1000;
  236. *status = FE_HAS_SIGNAL;
  237. return 0;
  238. }
  239. state->tune_state = VA1J5JF8007T_TRACK;
  240. /* fall through */
  241. case VA1J5JF8007T_TRACK:
  242. *delay = 3 * HZ;
  243. *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
  244. return 0;
  245. case VA1J5JF8007T_ABORT:
  246. *delay = 3 * HZ;
  247. *status = FE_HAS_SIGNAL;
  248. return 0;
  249. }
  250. BUG();
  251. }
  252. static int va1j5jf8007t_init_frequency(struct va1j5jf8007t_state *state)
  253. {
  254. u8 buf[7];
  255. struct i2c_msg msg;
  256. buf[0] = 0xfe;
  257. buf[1] = 0xc2;
  258. buf[2] = 0x01;
  259. buf[3] = 0x8f;
  260. buf[4] = 0xc1;
  261. buf[5] = 0x80;
  262. buf[6] = 0x80;
  263. msg.addr = state->config->demod_address;
  264. msg.flags = 0;
  265. msg.len = sizeof(buf);
  266. msg.buf = buf;
  267. if (i2c_transfer(state->adap, &msg, 1) != 1)
  268. return -EREMOTEIO;
  269. return 0;
  270. }
  271. static int va1j5jf8007t_set_sleep(struct va1j5jf8007t_state *state, int sleep)
  272. {
  273. u8 buf[2];
  274. struct i2c_msg msg;
  275. buf[0] = 0x03;
  276. buf[1] = sleep ? 0x90 : 0x80;
  277. msg.addr = state->config->demod_address;
  278. msg.flags = 0;
  279. msg.len = sizeof(buf);
  280. msg.buf = buf;
  281. if (i2c_transfer(state->adap, &msg, 1) != 1)
  282. return -EREMOTEIO;
  283. return 0;
  284. }
  285. static int va1j5jf8007t_sleep(struct dvb_frontend *fe)
  286. {
  287. struct va1j5jf8007t_state *state;
  288. int ret;
  289. state = fe->demodulator_priv;
  290. ret = va1j5jf8007t_init_frequency(state);
  291. if (ret < 0)
  292. return ret;
  293. return va1j5jf8007t_set_sleep(state, 1);
  294. }
  295. static int va1j5jf8007t_init(struct dvb_frontend *fe)
  296. {
  297. struct va1j5jf8007t_state *state;
  298. state = fe->demodulator_priv;
  299. state->tune_state = VA1J5JF8007T_IDLE;
  300. return va1j5jf8007t_set_sleep(state, 0);
  301. }
  302. static void va1j5jf8007t_release(struct dvb_frontend *fe)
  303. {
  304. struct va1j5jf8007t_state *state;
  305. state = fe->demodulator_priv;
  306. kfree(state);
  307. }
  308. static struct dvb_frontend_ops va1j5jf8007t_ops = {
  309. .info = {
  310. .name = "VA1J5JF8007 ISDB-T",
  311. .type = FE_OFDM,
  312. .frequency_min = 90000000,
  313. .frequency_max = 770000000,
  314. .frequency_stepsize = 142857,
  315. .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
  316. FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
  317. FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
  318. },
  319. .get_frontend_algo = va1j5jf8007t_get_frontend_algo,
  320. .read_status = va1j5jf8007t_read_status,
  321. .tune = va1j5jf8007t_tune,
  322. .sleep = va1j5jf8007t_sleep,
  323. .init = va1j5jf8007t_init,
  324. .release = va1j5jf8007t_release,
  325. };
  326. static const u8 va1j5jf8007t_prepare_bufs[][2] = {
  327. {0x03, 0x90}, {0x14, 0x8f}, {0x1c, 0x2a}, {0x1d, 0xa8}, {0x1e, 0xa2},
  328. {0x22, 0x83}, {0x31, 0x0d}, {0x32, 0xe0}, {0x39, 0xd3}, {0x3a, 0x00},
  329. {0x5c, 0x40}, {0x5f, 0x80}, {0x75, 0x02}, {0x76, 0x4e}, {0x77, 0x03},
  330. {0xef, 0x01}
  331. };
  332. int va1j5jf8007t_prepare(struct dvb_frontend *fe)
  333. {
  334. struct va1j5jf8007t_state *state;
  335. u8 buf[2];
  336. struct i2c_msg msg;
  337. int i;
  338. state = fe->demodulator_priv;
  339. msg.addr = state->config->demod_address;
  340. msg.flags = 0;
  341. msg.len = sizeof(buf);
  342. msg.buf = buf;
  343. for (i = 0; i < ARRAY_SIZE(va1j5jf8007t_prepare_bufs); i++) {
  344. memcpy(buf, va1j5jf8007t_prepare_bufs[i], sizeof(buf));
  345. if (i2c_transfer(state->adap, &msg, 1) != 1)
  346. return -EREMOTEIO;
  347. }
  348. return va1j5jf8007t_init_frequency(state);
  349. }
  350. struct dvb_frontend *
  351. va1j5jf8007t_attach(const struct va1j5jf8007t_config *config,
  352. struct i2c_adapter *adap)
  353. {
  354. struct va1j5jf8007t_state *state;
  355. struct dvb_frontend *fe;
  356. u8 buf[2];
  357. struct i2c_msg msg;
  358. state = kzalloc(sizeof(struct va1j5jf8007t_state), GFP_KERNEL);
  359. if (!state)
  360. return NULL;
  361. state->config = config;
  362. state->adap = adap;
  363. fe = &state->fe;
  364. memcpy(&fe->ops, &va1j5jf8007t_ops, sizeof(struct dvb_frontend_ops));
  365. fe->demodulator_priv = state;
  366. buf[0] = 0x01;
  367. buf[1] = 0x80;
  368. msg.addr = state->config->demod_address;
  369. msg.flags = 0;
  370. msg.len = sizeof(buf);
  371. msg.buf = buf;
  372. if (i2c_transfer(state->adap, &msg, 1) != 1) {
  373. kfree(state);
  374. return NULL;
  375. }
  376. return fe;
  377. }