va1j5jf8007s.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736
  1. /*
  2. * ISDB-S 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 "va1j5jf8007s.h"
  29. enum va1j5jf8007s_tune_state {
  30. VA1J5JF8007S_IDLE,
  31. VA1J5JF8007S_SET_FREQUENCY_1,
  32. VA1J5JF8007S_SET_FREQUENCY_2,
  33. VA1J5JF8007S_SET_FREQUENCY_3,
  34. VA1J5JF8007S_CHECK_FREQUENCY,
  35. VA1J5JF8007S_SET_MODULATION,
  36. VA1J5JF8007S_CHECK_MODULATION,
  37. VA1J5JF8007S_SET_TS_ID,
  38. VA1J5JF8007S_CHECK_TS_ID,
  39. VA1J5JF8007S_TRACK,
  40. };
  41. struct va1j5jf8007s_state {
  42. const struct va1j5jf8007s_config *config;
  43. struct i2c_adapter *adap;
  44. struct dvb_frontend fe;
  45. enum va1j5jf8007s_tune_state tune_state;
  46. };
  47. static int va1j5jf8007s_read_snr(struct dvb_frontend *fe, u16 *snr)
  48. {
  49. struct va1j5jf8007s_state *state;
  50. u8 addr;
  51. int i;
  52. u8 write_buf[1], read_buf[1];
  53. struct i2c_msg msgs[2];
  54. s32 word, x1, x2, x3, x4, x5, y;
  55. state = fe->demodulator_priv;
  56. addr = state->config->demod_address;
  57. word = 0;
  58. for (i = 0; i < 2; i++) {
  59. write_buf[0] = 0xbc + i;
  60. msgs[0].addr = addr;
  61. msgs[0].flags = 0;
  62. msgs[0].len = sizeof(write_buf);
  63. msgs[0].buf = write_buf;
  64. msgs[1].addr = addr;
  65. msgs[1].flags = I2C_M_RD;
  66. msgs[1].len = sizeof(read_buf);
  67. msgs[1].buf = read_buf;
  68. if (i2c_transfer(state->adap, msgs, 2) != 2)
  69. return -EREMOTEIO;
  70. word <<= 8;
  71. word |= read_buf[0];
  72. }
  73. word -= 3000;
  74. if (word < 0)
  75. word = 0;
  76. x1 = int_sqrt(word << 16) * ((15625ll << 21) / 1000000);
  77. x2 = (s64)x1 * x1 >> 31;
  78. x3 = (s64)x2 * x1 >> 31;
  79. x4 = (s64)x2 * x2 >> 31;
  80. x5 = (s64)x4 * x1 >> 31;
  81. y = (58857ll << 23) / 1000;
  82. y -= (s64)x1 * ((89565ll << 24) / 1000) >> 30;
  83. y += (s64)x2 * ((88977ll << 24) / 1000) >> 28;
  84. y -= (s64)x3 * ((50259ll << 25) / 1000) >> 27;
  85. y += (s64)x4 * ((14341ll << 27) / 1000) >> 27;
  86. y -= (s64)x5 * ((16346ll << 30) / 10000) >> 28;
  87. *snr = y < 0 ? 0 : y >> 15;
  88. return 0;
  89. }
  90. static int va1j5jf8007s_get_frontend_algo(struct dvb_frontend *fe)
  91. {
  92. return DVBFE_ALGO_HW;
  93. }
  94. static int
  95. va1j5jf8007s_read_status(struct dvb_frontend *fe, fe_status_t *status)
  96. {
  97. struct va1j5jf8007s_state *state;
  98. state = fe->demodulator_priv;
  99. switch (state->tune_state) {
  100. case VA1J5JF8007S_IDLE:
  101. case VA1J5JF8007S_SET_FREQUENCY_1:
  102. case VA1J5JF8007S_SET_FREQUENCY_2:
  103. case VA1J5JF8007S_SET_FREQUENCY_3:
  104. case VA1J5JF8007S_CHECK_FREQUENCY:
  105. *status = 0;
  106. return 0;
  107. case VA1J5JF8007S_SET_MODULATION:
  108. case VA1J5JF8007S_CHECK_MODULATION:
  109. *status |= FE_HAS_SIGNAL;
  110. return 0;
  111. case VA1J5JF8007S_SET_TS_ID:
  112. case VA1J5JF8007S_CHECK_TS_ID:
  113. *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER;
  114. return 0;
  115. case VA1J5JF8007S_TRACK:
  116. *status |= FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
  117. return 0;
  118. }
  119. BUG();
  120. }
  121. struct va1j5jf8007s_cb_map {
  122. u32 frequency;
  123. u8 cb;
  124. };
  125. static const struct va1j5jf8007s_cb_map va1j5jf8007s_cb_maps[] = {
  126. { 986000, 0xb2 },
  127. { 1072000, 0xd2 },
  128. { 1154000, 0xe2 },
  129. { 1291000, 0x20 },
  130. { 1447000, 0x40 },
  131. { 1615000, 0x60 },
  132. { 1791000, 0x80 },
  133. { 1972000, 0xa0 },
  134. };
  135. static u8 va1j5jf8007s_lookup_cb(u32 frequency)
  136. {
  137. int i;
  138. const struct va1j5jf8007s_cb_map *map;
  139. for (i = 0; i < ARRAY_SIZE(va1j5jf8007s_cb_maps); i++) {
  140. map = &va1j5jf8007s_cb_maps[i];
  141. if (frequency < map->frequency)
  142. return map->cb;
  143. }
  144. return 0xc0;
  145. }
  146. static int va1j5jf8007s_set_frequency_1(struct va1j5jf8007s_state *state)
  147. {
  148. u32 frequency;
  149. u16 word;
  150. u8 buf[6];
  151. struct i2c_msg msg;
  152. frequency = state->fe.dtv_property_cache.frequency;
  153. word = (frequency + 500) / 1000;
  154. if (frequency < 1072000)
  155. word = (word << 1 & ~0x1f) | (word & 0x0f);
  156. buf[0] = 0xfe;
  157. buf[1] = 0xc0;
  158. buf[2] = 0x40 | word >> 8;
  159. buf[3] = word;
  160. buf[4] = 0xe0;
  161. buf[5] = va1j5jf8007s_lookup_cb(frequency);
  162. msg.addr = state->config->demod_address;
  163. msg.flags = 0;
  164. msg.len = sizeof(buf);
  165. msg.buf = buf;
  166. if (i2c_transfer(state->adap, &msg, 1) != 1)
  167. return -EREMOTEIO;
  168. return 0;
  169. }
  170. static int va1j5jf8007s_set_frequency_2(struct va1j5jf8007s_state *state)
  171. {
  172. u8 buf[3];
  173. struct i2c_msg msg;
  174. buf[0] = 0xfe;
  175. buf[1] = 0xc0;
  176. buf[2] = 0xe4;
  177. msg.addr = state->config->demod_address;
  178. msg.flags = 0;
  179. msg.len = sizeof(buf);
  180. msg.buf = buf;
  181. if (i2c_transfer(state->adap, &msg, 1) != 1)
  182. return -EREMOTEIO;
  183. return 0;
  184. }
  185. static int va1j5jf8007s_set_frequency_3(struct va1j5jf8007s_state *state)
  186. {
  187. u32 frequency;
  188. u8 buf[4];
  189. struct i2c_msg msg;
  190. frequency = state->fe.dtv_property_cache.frequency;
  191. buf[0] = 0xfe;
  192. buf[1] = 0xc0;
  193. buf[2] = 0xf4;
  194. buf[3] = va1j5jf8007s_lookup_cb(frequency) | 0x4;
  195. msg.addr = state->config->demod_address;
  196. msg.flags = 0;
  197. msg.len = sizeof(buf);
  198. msg.buf = buf;
  199. if (i2c_transfer(state->adap, &msg, 1) != 1)
  200. return -EREMOTEIO;
  201. return 0;
  202. }
  203. static int
  204. va1j5jf8007s_check_frequency(struct va1j5jf8007s_state *state, int *lock)
  205. {
  206. u8 addr;
  207. u8 write_buf[2], read_buf[1];
  208. struct i2c_msg msgs[2];
  209. addr = state->config->demod_address;
  210. write_buf[0] = 0xfe;
  211. write_buf[1] = 0xc1;
  212. msgs[0].addr = addr;
  213. msgs[0].flags = 0;
  214. msgs[0].len = sizeof(write_buf);
  215. msgs[0].buf = write_buf;
  216. msgs[1].addr = addr;
  217. msgs[1].flags = I2C_M_RD;
  218. msgs[1].len = sizeof(read_buf);
  219. msgs[1].buf = read_buf;
  220. if (i2c_transfer(state->adap, msgs, 2) != 2)
  221. return -EREMOTEIO;
  222. *lock = read_buf[0] & 0x40;
  223. return 0;
  224. }
  225. static int va1j5jf8007s_set_modulation(struct va1j5jf8007s_state *state)
  226. {
  227. u8 buf[2];
  228. struct i2c_msg msg;
  229. buf[0] = 0x03;
  230. buf[1] = 0x01;
  231. msg.addr = state->config->demod_address;
  232. msg.flags = 0;
  233. msg.len = sizeof(buf);
  234. msg.buf = buf;
  235. if (i2c_transfer(state->adap, &msg, 1) != 1)
  236. return -EREMOTEIO;
  237. return 0;
  238. }
  239. static int
  240. va1j5jf8007s_check_modulation(struct va1j5jf8007s_state *state, int *lock)
  241. {
  242. u8 addr;
  243. u8 write_buf[1], read_buf[1];
  244. struct i2c_msg msgs[2];
  245. addr = state->config->demod_address;
  246. write_buf[0] = 0xc3;
  247. msgs[0].addr = addr;
  248. msgs[0].flags = 0;
  249. msgs[0].len = sizeof(write_buf);
  250. msgs[0].buf = write_buf;
  251. msgs[1].addr = addr;
  252. msgs[1].flags = I2C_M_RD;
  253. msgs[1].len = sizeof(read_buf);
  254. msgs[1].buf = read_buf;
  255. if (i2c_transfer(state->adap, msgs, 2) != 2)
  256. return -EREMOTEIO;
  257. *lock = !(read_buf[0] & 0x10);
  258. return 0;
  259. }
  260. static int
  261. va1j5jf8007s_set_ts_id(struct va1j5jf8007s_state *state)
  262. {
  263. u32 ts_id;
  264. u8 buf[3];
  265. struct i2c_msg msg;
  266. ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
  267. if (!ts_id)
  268. return 0;
  269. buf[0] = 0x8f;
  270. buf[1] = ts_id >> 8;
  271. buf[2] = ts_id;
  272. msg.addr = state->config->demod_address;
  273. msg.flags = 0;
  274. msg.len = sizeof(buf);
  275. msg.buf = buf;
  276. if (i2c_transfer(state->adap, &msg, 1) != 1)
  277. return -EREMOTEIO;
  278. return 0;
  279. }
  280. static int
  281. va1j5jf8007s_check_ts_id(struct va1j5jf8007s_state *state, int *lock)
  282. {
  283. u8 addr;
  284. u8 write_buf[1], read_buf[2];
  285. struct i2c_msg msgs[2];
  286. u32 ts_id;
  287. ts_id = state->fe.dtv_property_cache.isdbs_ts_id;
  288. if (!ts_id) {
  289. *lock = 1;
  290. return 0;
  291. }
  292. addr = state->config->demod_address;
  293. write_buf[0] = 0xe6;
  294. msgs[0].addr = addr;
  295. msgs[0].flags = 0;
  296. msgs[0].len = sizeof(write_buf);
  297. msgs[0].buf = write_buf;
  298. msgs[1].addr = addr;
  299. msgs[1].flags = I2C_M_RD;
  300. msgs[1].len = sizeof(read_buf);
  301. msgs[1].buf = read_buf;
  302. if (i2c_transfer(state->adap, msgs, 2) != 2)
  303. return -EREMOTEIO;
  304. *lock = (read_buf[0] << 8 | read_buf[1]) == ts_id;
  305. return 0;
  306. }
  307. static int
  308. va1j5jf8007s_tune(struct dvb_frontend *fe,
  309. struct dvb_frontend_parameters *params,
  310. unsigned int mode_flags, unsigned int *delay,
  311. fe_status_t *status)
  312. {
  313. struct va1j5jf8007s_state *state;
  314. int ret;
  315. int lock = 0;
  316. state = fe->demodulator_priv;
  317. if (params != NULL)
  318. state->tune_state = VA1J5JF8007S_SET_FREQUENCY_1;
  319. switch (state->tune_state) {
  320. case VA1J5JF8007S_IDLE:
  321. *delay = 3 * HZ;
  322. *status = 0;
  323. return 0;
  324. case VA1J5JF8007S_SET_FREQUENCY_1:
  325. ret = va1j5jf8007s_set_frequency_1(state);
  326. if (ret < 0)
  327. return ret;
  328. state->tune_state = VA1J5JF8007S_SET_FREQUENCY_2;
  329. *delay = 0;
  330. *status = 0;
  331. return 0;
  332. case VA1J5JF8007S_SET_FREQUENCY_2:
  333. ret = va1j5jf8007s_set_frequency_2(state);
  334. if (ret < 0)
  335. return ret;
  336. state->tune_state = VA1J5JF8007S_SET_FREQUENCY_3;
  337. *delay = (HZ + 99) / 100;
  338. *status = 0;
  339. return 0;
  340. case VA1J5JF8007S_SET_FREQUENCY_3:
  341. ret = va1j5jf8007s_set_frequency_3(state);
  342. if (ret < 0)
  343. return ret;
  344. state->tune_state = VA1J5JF8007S_CHECK_FREQUENCY;
  345. *delay = 0;
  346. *status = 0;
  347. return 0;
  348. case VA1J5JF8007S_CHECK_FREQUENCY:
  349. ret = va1j5jf8007s_check_frequency(state, &lock);
  350. if (ret < 0)
  351. return ret;
  352. if (!lock) {
  353. *delay = (HZ + 999) / 1000;
  354. *status = 0;
  355. return 0;
  356. }
  357. state->tune_state = VA1J5JF8007S_SET_MODULATION;
  358. *delay = 0;
  359. *status = FE_HAS_SIGNAL;
  360. return 0;
  361. case VA1J5JF8007S_SET_MODULATION:
  362. ret = va1j5jf8007s_set_modulation(state);
  363. if (ret < 0)
  364. return ret;
  365. state->tune_state = VA1J5JF8007S_CHECK_MODULATION;
  366. *delay = 0;
  367. *status = FE_HAS_SIGNAL;
  368. return 0;
  369. case VA1J5JF8007S_CHECK_MODULATION:
  370. ret = va1j5jf8007s_check_modulation(state, &lock);
  371. if (ret < 0)
  372. return ret;
  373. if (!lock) {
  374. *delay = (HZ + 49) / 50;
  375. *status = FE_HAS_SIGNAL;
  376. return 0;
  377. }
  378. state->tune_state = VA1J5JF8007S_SET_TS_ID;
  379. *delay = 0;
  380. *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
  381. return 0;
  382. case VA1J5JF8007S_SET_TS_ID:
  383. ret = va1j5jf8007s_set_ts_id(state);
  384. if (ret < 0)
  385. return ret;
  386. state->tune_state = VA1J5JF8007S_CHECK_TS_ID;
  387. return 0;
  388. case VA1J5JF8007S_CHECK_TS_ID:
  389. ret = va1j5jf8007s_check_ts_id(state, &lock);
  390. if (ret < 0)
  391. return ret;
  392. if (!lock) {
  393. *delay = (HZ + 99) / 100;
  394. *status = FE_HAS_SIGNAL | FE_HAS_CARRIER;
  395. return 0;
  396. }
  397. state->tune_state = VA1J5JF8007S_TRACK;
  398. /* fall through */
  399. case VA1J5JF8007S_TRACK:
  400. *delay = 3 * HZ;
  401. *status = FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_LOCK;
  402. return 0;
  403. }
  404. BUG();
  405. }
  406. static int va1j5jf8007s_init_frequency(struct va1j5jf8007s_state *state)
  407. {
  408. u8 buf[4];
  409. struct i2c_msg msg;
  410. buf[0] = 0xfe;
  411. buf[1] = 0xc0;
  412. buf[2] = 0xf0;
  413. buf[3] = 0x04;
  414. msg.addr = state->config->demod_address;
  415. msg.flags = 0;
  416. msg.len = sizeof(buf);
  417. msg.buf = buf;
  418. if (i2c_transfer(state->adap, &msg, 1) != 1)
  419. return -EREMOTEIO;
  420. return 0;
  421. }
  422. static int va1j5jf8007s_set_sleep(struct va1j5jf8007s_state *state, int sleep)
  423. {
  424. u8 buf[2];
  425. struct i2c_msg msg;
  426. buf[0] = 0x17;
  427. buf[1] = sleep ? 0x01 : 0x00;
  428. msg.addr = state->config->demod_address;
  429. msg.flags = 0;
  430. msg.len = sizeof(buf);
  431. msg.buf = buf;
  432. if (i2c_transfer(state->adap, &msg, 1) != 1)
  433. return -EREMOTEIO;
  434. return 0;
  435. }
  436. static int va1j5jf8007s_sleep(struct dvb_frontend *fe)
  437. {
  438. struct va1j5jf8007s_state *state;
  439. int ret;
  440. state = fe->demodulator_priv;
  441. ret = va1j5jf8007s_init_frequency(state);
  442. if (ret < 0)
  443. return ret;
  444. return va1j5jf8007s_set_sleep(state, 1);
  445. }
  446. static int va1j5jf8007s_init(struct dvb_frontend *fe)
  447. {
  448. struct va1j5jf8007s_state *state;
  449. state = fe->demodulator_priv;
  450. state->tune_state = VA1J5JF8007S_IDLE;
  451. return va1j5jf8007s_set_sleep(state, 0);
  452. }
  453. static void va1j5jf8007s_release(struct dvb_frontend *fe)
  454. {
  455. struct va1j5jf8007s_state *state;
  456. state = fe->demodulator_priv;
  457. kfree(state);
  458. }
  459. static struct dvb_frontend_ops va1j5jf8007s_ops = {
  460. .info = {
  461. .name = "VA1J5JF8007/VA1J5JF8011 ISDB-S",
  462. .type = FE_QPSK,
  463. .frequency_min = 950000,
  464. .frequency_max = 2150000,
  465. .frequency_stepsize = 1000,
  466. .caps = FE_CAN_INVERSION_AUTO | FE_CAN_FEC_AUTO |
  467. FE_CAN_QAM_AUTO | FE_CAN_TRANSMISSION_MODE_AUTO |
  468. FE_CAN_GUARD_INTERVAL_AUTO | FE_CAN_HIERARCHY_AUTO,
  469. },
  470. .read_snr = va1j5jf8007s_read_snr,
  471. .get_frontend_algo = va1j5jf8007s_get_frontend_algo,
  472. .read_status = va1j5jf8007s_read_status,
  473. .tune = va1j5jf8007s_tune,
  474. .sleep = va1j5jf8007s_sleep,
  475. .init = va1j5jf8007s_init,
  476. .release = va1j5jf8007s_release,
  477. };
  478. static int va1j5jf8007s_prepare_1(struct va1j5jf8007s_state *state)
  479. {
  480. u8 addr;
  481. u8 write_buf[1], read_buf[1];
  482. struct i2c_msg msgs[2];
  483. addr = state->config->demod_address;
  484. write_buf[0] = 0x07;
  485. msgs[0].addr = addr;
  486. msgs[0].flags = 0;
  487. msgs[0].len = sizeof(write_buf);
  488. msgs[0].buf = write_buf;
  489. msgs[1].addr = addr;
  490. msgs[1].flags = I2C_M_RD;
  491. msgs[1].len = sizeof(read_buf);
  492. msgs[1].buf = read_buf;
  493. if (i2c_transfer(state->adap, msgs, 2) != 2)
  494. return -EREMOTEIO;
  495. if (read_buf[0] != 0x41)
  496. return -EIO;
  497. return 0;
  498. }
  499. static const u8 va1j5jf8007s_20mhz_prepare_bufs[][2] = {
  500. {0x04, 0x02}, {0x0d, 0x55}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01},
  501. {0x1c, 0x0a}, {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0},
  502. {0x52, 0x89}, {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69},
  503. {0x87, 0x04}, {0x8e, 0x02}, {0xa3, 0xf7}, {0xa5, 0xc0},
  504. };
  505. static const u8 va1j5jf8007s_25mhz_prepare_bufs[][2] = {
  506. {0x04, 0x02}, {0x11, 0x40}, {0x13, 0x80}, {0x17, 0x01}, {0x1c, 0x0a},
  507. {0x1d, 0xaa}, {0x1e, 0x20}, {0x1f, 0x88}, {0x51, 0xb0}, {0x52, 0x89},
  508. {0x53, 0xb3}, {0x5a, 0x2d}, {0x5b, 0xd3}, {0x85, 0x69}, {0x87, 0x04},
  509. {0x8e, 0x26}, {0xa3, 0xf7}, {0xa5, 0xc0},
  510. };
  511. static int va1j5jf8007s_prepare_2(struct va1j5jf8007s_state *state)
  512. {
  513. const u8 (*bufs)[2];
  514. int size;
  515. u8 addr;
  516. u8 buf[2];
  517. struct i2c_msg msg;
  518. int i;
  519. switch (state->config->frequency) {
  520. case VA1J5JF8007S_20MHZ:
  521. bufs = va1j5jf8007s_20mhz_prepare_bufs;
  522. size = ARRAY_SIZE(va1j5jf8007s_20mhz_prepare_bufs);
  523. break;
  524. case VA1J5JF8007S_25MHZ:
  525. bufs = va1j5jf8007s_25mhz_prepare_bufs;
  526. size = ARRAY_SIZE(va1j5jf8007s_25mhz_prepare_bufs);
  527. break;
  528. default:
  529. return -EINVAL;
  530. }
  531. addr = state->config->demod_address;
  532. msg.addr = addr;
  533. msg.flags = 0;
  534. msg.len = 2;
  535. msg.buf = buf;
  536. for (i = 0; i < size; i++) {
  537. memcpy(buf, bufs[i], sizeof(buf));
  538. if (i2c_transfer(state->adap, &msg, 1) != 1)
  539. return -EREMOTEIO;
  540. }
  541. return 0;
  542. }
  543. /* must be called after va1j5jf8007t_attach */
  544. int va1j5jf8007s_prepare(struct dvb_frontend *fe)
  545. {
  546. struct va1j5jf8007s_state *state;
  547. int ret;
  548. state = fe->demodulator_priv;
  549. ret = va1j5jf8007s_prepare_1(state);
  550. if (ret < 0)
  551. return ret;
  552. ret = va1j5jf8007s_prepare_2(state);
  553. if (ret < 0)
  554. return ret;
  555. return va1j5jf8007s_init_frequency(state);
  556. }
  557. struct dvb_frontend *
  558. va1j5jf8007s_attach(const struct va1j5jf8007s_config *config,
  559. struct i2c_adapter *adap)
  560. {
  561. struct va1j5jf8007s_state *state;
  562. struct dvb_frontend *fe;
  563. u8 buf[2];
  564. struct i2c_msg msg;
  565. state = kzalloc(sizeof(struct va1j5jf8007s_state), GFP_KERNEL);
  566. if (!state)
  567. return NULL;
  568. state->config = config;
  569. state->adap = adap;
  570. fe = &state->fe;
  571. memcpy(&fe->ops, &va1j5jf8007s_ops, sizeof(struct dvb_frontend_ops));
  572. fe->demodulator_priv = state;
  573. buf[0] = 0x01;
  574. buf[1] = 0x80;
  575. msg.addr = state->config->demod_address;
  576. msg.flags = 0;
  577. msg.len = sizeof(buf);
  578. msg.buf = buf;
  579. if (i2c_transfer(state->adap, &msg, 1) != 1) {
  580. kfree(state);
  581. return NULL;
  582. }
  583. return fe;
  584. }