si21xx.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974
  1. /* DVB compliant Linux driver for the DVB-S si2109/2110 demodulator
  2. *
  3. * Copyright (C) 2008 Igor M. Liplianin (liplianin@me.by)
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. */
  11. #include <linux/version.h>
  12. #include <linux/init.h>
  13. #include <linux/kernel.h>
  14. #include <linux/module.h>
  15. #include <linux/string.h>
  16. #include <linux/slab.h>
  17. #include <linux/jiffies.h>
  18. #include <asm/div64.h>
  19. #include "dvb_frontend.h"
  20. #include "si21xx.h"
  21. #define REVISION_REG 0x00
  22. #define SYSTEM_MODE_REG 0x01
  23. #define TS_CTRL_REG_1 0x02
  24. #define TS_CTRL_REG_2 0x03
  25. #define PIN_CTRL_REG_1 0x04
  26. #define PIN_CTRL_REG_2 0x05
  27. #define LOCK_STATUS_REG_1 0x0f
  28. #define LOCK_STATUS_REG_2 0x10
  29. #define ACQ_STATUS_REG 0x11
  30. #define ACQ_CTRL_REG_1 0x13
  31. #define ACQ_CTRL_REG_2 0x14
  32. #define PLL_DIVISOR_REG 0x15
  33. #define COARSE_TUNE_REG 0x16
  34. #define FINE_TUNE_REG_L 0x17
  35. #define FINE_TUNE_REG_H 0x18
  36. #define ANALOG_AGC_POWER_LEVEL_REG 0x28
  37. #define CFO_ESTIMATOR_CTRL_REG_1 0x29
  38. #define CFO_ESTIMATOR_CTRL_REG_2 0x2a
  39. #define CFO_ESTIMATOR_CTRL_REG_3 0x2b
  40. #define SYM_RATE_ESTIMATE_REG_L 0x31
  41. #define SYM_RATE_ESTIMATE_REG_M 0x32
  42. #define SYM_RATE_ESTIMATE_REG_H 0x33
  43. #define CFO_ESTIMATOR_OFFSET_REG_L 0x36
  44. #define CFO_ESTIMATOR_OFFSET_REG_H 0x37
  45. #define CFO_ERROR_REG_L 0x38
  46. #define CFO_ERROR_REG_H 0x39
  47. #define SYM_RATE_ESTIMATOR_CTRL_REG 0x3a
  48. #define SYM_RATE_REG_L 0x3f
  49. #define SYM_RATE_REG_M 0x40
  50. #define SYM_RATE_REG_H 0x41
  51. #define SYM_RATE_ESTIMATOR_MAXIMUM_REG 0x42
  52. #define SYM_RATE_ESTIMATOR_MINIMUM_REG 0x43
  53. #define C_N_ESTIMATOR_CTRL_REG 0x7c
  54. #define C_N_ESTIMATOR_THRSHLD_REG 0x7d
  55. #define C_N_ESTIMATOR_LEVEL_REG_L 0x7e
  56. #define C_N_ESTIMATOR_LEVEL_REG_H 0x7f
  57. #define BLIND_SCAN_CTRL_REG 0x80
  58. #define LSA_CTRL_REG_1 0x8D
  59. #define SPCTRM_TILT_CORR_THRSHLD_REG 0x8f
  60. #define ONE_DB_BNDWDTH_THRSHLD_REG 0x90
  61. #define TWO_DB_BNDWDTH_THRSHLD_REG 0x91
  62. #define THREE_DB_BNDWDTH_THRSHLD_REG 0x92
  63. #define INBAND_POWER_THRSHLD_REG 0x93
  64. #define REF_NOISE_LVL_MRGN_THRSHLD_REG 0x94
  65. #define VIT_SRCH_CTRL_REG_1 0xa0
  66. #define VIT_SRCH_CTRL_REG_2 0xa1
  67. #define VIT_SRCH_CTRL_REG_3 0xa2
  68. #define VIT_SRCH_STATUS_REG 0xa3
  69. #define VITERBI_BER_COUNT_REG_L 0xab
  70. #define REED_SOLOMON_CTRL_REG 0xb0
  71. #define REED_SOLOMON_ERROR_COUNT_REG_L 0xb1
  72. #define PRBS_CTRL_REG 0xb5
  73. #define LNB_CTRL_REG_1 0xc0
  74. #define LNB_CTRL_REG_2 0xc1
  75. #define LNB_CTRL_REG_3 0xc2
  76. #define LNB_CTRL_REG_4 0xc3
  77. #define LNB_CTRL_STATUS_REG 0xc4
  78. #define LNB_FIFO_REGS_0 0xc5
  79. #define LNB_FIFO_REGS_1 0xc6
  80. #define LNB_FIFO_REGS_2 0xc7
  81. #define LNB_FIFO_REGS_3 0xc8
  82. #define LNB_FIFO_REGS_4 0xc9
  83. #define LNB_FIFO_REGS_5 0xca
  84. #define LNB_SUPPLY_CTRL_REG_1 0xcb
  85. #define LNB_SUPPLY_CTRL_REG_2 0xcc
  86. #define LNB_SUPPLY_CTRL_REG_3 0xcd
  87. #define LNB_SUPPLY_CTRL_REG_4 0xce
  88. #define LNB_SUPPLY_STATUS_REG 0xcf
  89. #define FALSE 0
  90. #define TRUE 1
  91. #define FAIL -1
  92. #define PASS 0
  93. #define ALLOWABLE_FS_COUNT 10
  94. #define STATUS_BER 0
  95. #define STATUS_UCBLOCKS 1
  96. static int debug;
  97. #define dprintk(args...) \
  98. do { \
  99. if (debug) \
  100. printk(KERN_DEBUG "si21xx: " args); \
  101. } while (0)
  102. enum {
  103. ACTIVE_HIGH,
  104. ACTIVE_LOW
  105. };
  106. enum {
  107. BYTE_WIDE,
  108. BIT_WIDE
  109. };
  110. enum {
  111. CLK_GAPPED_MODE,
  112. CLK_CONTINUOUS_MODE
  113. };
  114. enum {
  115. RISING_EDGE,
  116. FALLING_EDGE
  117. };
  118. enum {
  119. MSB_FIRST,
  120. LSB_FIRST
  121. };
  122. enum {
  123. SERIAL,
  124. PARALLEL
  125. };
  126. struct si21xx_state {
  127. struct i2c_adapter *i2c;
  128. const struct si21xx_config *config;
  129. struct dvb_frontend frontend;
  130. u8 initialised:1;
  131. int errmode;
  132. int fs; /*Sampling rate of the ADC in MHz*/
  133. };
  134. /* register default initialization */
  135. static u8 serit_sp1511lhb_inittab[] = {
  136. 0x01, 0x28, /* set i2c_inc_disable */
  137. 0x20, 0x03,
  138. 0x27, 0x20,
  139. 0xe0, 0x45,
  140. 0xe1, 0x08,
  141. 0xfe, 0x01,
  142. 0x01, 0x28,
  143. 0x89, 0x09,
  144. 0x04, 0x80,
  145. 0x05, 0x01,
  146. 0x06, 0x00,
  147. 0x20, 0x03,
  148. 0x24, 0x88,
  149. 0x29, 0x09,
  150. 0x2a, 0x0f,
  151. 0x2c, 0x10,
  152. 0x2d, 0x19,
  153. 0x2e, 0x08,
  154. 0x2f, 0x10,
  155. 0x30, 0x19,
  156. 0x34, 0x20,
  157. 0x35, 0x03,
  158. 0x45, 0x02,
  159. 0x46, 0x45,
  160. 0x47, 0xd0,
  161. 0x48, 0x00,
  162. 0x49, 0x40,
  163. 0x4a, 0x03,
  164. 0x4c, 0xfd,
  165. 0x4f, 0x2e,
  166. 0x50, 0x2e,
  167. 0x51, 0x10,
  168. 0x52, 0x10,
  169. 0x56, 0x92,
  170. 0x59, 0x00,
  171. 0x5a, 0x2d,
  172. 0x5b, 0x33,
  173. 0x5c, 0x1f,
  174. 0x5f, 0x76,
  175. 0x62, 0xc0,
  176. 0x63, 0xc0,
  177. 0x64, 0xf3,
  178. 0x65, 0xf3,
  179. 0x79, 0x40,
  180. 0x6a, 0x40,
  181. 0x6b, 0x0a,
  182. 0x6c, 0x80,
  183. 0x6d, 0x27,
  184. 0x71, 0x06,
  185. 0x75, 0x60,
  186. 0x78, 0x00,
  187. 0x79, 0xb5,
  188. 0x7c, 0x05,
  189. 0x7d, 0x1a,
  190. 0x87, 0x55,
  191. 0x88, 0x72,
  192. 0x8f, 0x08,
  193. 0x90, 0xe0,
  194. 0x94, 0x40,
  195. 0xa0, 0x3f,
  196. 0xa1, 0xc0,
  197. 0xa4, 0xcc,
  198. 0xa5, 0x66,
  199. 0xa6, 0x66,
  200. 0xa7, 0x7b,
  201. 0xa8, 0x7b,
  202. 0xa9, 0x7b,
  203. 0xaa, 0x9a,
  204. 0xed, 0x04,
  205. 0xad, 0x00,
  206. 0xae, 0x03,
  207. 0xcc, 0xab,
  208. 0x01, 0x08,
  209. 0xff, 0xff
  210. };
  211. /* low level read/writes */
  212. static int si21_writeregs(struct si21xx_state *state, u8 reg1,
  213. u8 *data, int len)
  214. {
  215. int ret;
  216. u8 buf[60];/* = { reg1, data };*/
  217. struct i2c_msg msg = {
  218. .addr = state->config->demod_address,
  219. .flags = 0,
  220. .buf = buf,
  221. .len = len + 1
  222. };
  223. msg.buf[0] = reg1;
  224. memcpy(msg.buf + 1, data, len);
  225. ret = i2c_transfer(state->i2c, &msg, 1);
  226. if (ret != 1)
  227. dprintk("%s: writereg error (reg1 == 0x%02x, data == 0x%02x, "
  228. "ret == %i)\n", __func__, reg1, data[0], ret);
  229. return (ret != 1) ? -EREMOTEIO : 0;
  230. }
  231. static int si21_writereg(struct si21xx_state *state, u8 reg, u8 data)
  232. {
  233. int ret;
  234. u8 buf[] = { reg, data };
  235. struct i2c_msg msg = {
  236. .addr = state->config->demod_address,
  237. .flags = 0,
  238. .buf = buf,
  239. .len = 2
  240. };
  241. ret = i2c_transfer(state->i2c, &msg, 1);
  242. if (ret != 1)
  243. dprintk("%s: writereg error (reg == 0x%02x, data == 0x%02x, "
  244. "ret == %i)\n", __func__, reg, data, ret);
  245. return (ret != 1) ? -EREMOTEIO : 0;
  246. }
  247. static int si21_write(struct dvb_frontend *fe, u8 *buf, int len)
  248. {
  249. struct si21xx_state *state = fe->demodulator_priv;
  250. if (len != 2)
  251. return -EINVAL;
  252. return si21_writereg(state, buf[0], buf[1]);
  253. }
  254. static u8 si21_readreg(struct si21xx_state *state, u8 reg)
  255. {
  256. int ret;
  257. u8 b0[] = { reg };
  258. u8 b1[] = { 0 };
  259. struct i2c_msg msg[] = {
  260. {
  261. .addr = state->config->demod_address,
  262. .flags = 0,
  263. .buf = b0,
  264. .len = 1
  265. }, {
  266. .addr = state->config->demod_address,
  267. .flags = I2C_M_RD,
  268. .buf = b1,
  269. .len = 1
  270. }
  271. };
  272. ret = i2c_transfer(state->i2c, msg, 2);
  273. if (ret != 2)
  274. dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
  275. __func__, reg, ret);
  276. return b1[0];
  277. }
  278. static int si21_readregs(struct si21xx_state *state, u8 reg1, u8 *b, u8 len)
  279. {
  280. int ret;
  281. struct i2c_msg msg[] = {
  282. {
  283. .addr = state->config->demod_address,
  284. .flags = 0,
  285. .buf = &reg1,
  286. .len = 1
  287. }, {
  288. .addr = state->config->demod_address,
  289. .flags = I2C_M_RD,
  290. .buf = b,
  291. .len = len
  292. }
  293. };
  294. ret = i2c_transfer(state->i2c, msg, 2);
  295. if (ret != 2)
  296. dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
  297. return ret == 2 ? 0 : -1;
  298. }
  299. static int si21xx_wait_diseqc_idle(struct si21xx_state *state, int timeout)
  300. {
  301. unsigned long start = jiffies;
  302. dprintk("%s\n", __func__);
  303. while ((si21_readreg(state, LNB_CTRL_REG_1) & 0x8) == 8) {
  304. if (jiffies - start > timeout) {
  305. dprintk("%s: timeout!!\n", __func__);
  306. return -ETIMEDOUT;
  307. }
  308. msleep(10);
  309. };
  310. return 0;
  311. }
  312. static int si21xx_set_symbolrate(struct dvb_frontend *fe, u32 srate)
  313. {
  314. struct si21xx_state *state = fe->demodulator_priv;
  315. u32 sym_rate, data_rate;
  316. int i;
  317. u8 sym_rate_bytes[3];
  318. dprintk("%s : srate = %i\n", __func__ , srate);
  319. if ((srate < 1000000) || (srate > 45000000))
  320. return -EINVAL;
  321. data_rate = srate;
  322. sym_rate = 0;
  323. for (i = 0; i < 4; ++i) {
  324. sym_rate /= 100;
  325. sym_rate = sym_rate + ((data_rate % 100) * 0x800000) /
  326. state->fs;
  327. data_rate /= 100;
  328. }
  329. for (i = 0; i < 3; ++i)
  330. sym_rate_bytes[i] = (u8)((sym_rate >> (i * 8)) & 0xff);
  331. si21_writeregs(state, SYM_RATE_REG_L, sym_rate_bytes, 0x03);
  332. return 0;
  333. }
  334. static int si21xx_send_diseqc_msg(struct dvb_frontend *fe,
  335. struct dvb_diseqc_master_cmd *m)
  336. {
  337. struct si21xx_state *state = fe->demodulator_priv;
  338. u8 lnb_status;
  339. u8 LNB_CTRL_1;
  340. int status;
  341. dprintk("%s\n", __func__);
  342. status = PASS;
  343. LNB_CTRL_1 = 0;
  344. status |= si21_readregs(state, LNB_CTRL_STATUS_REG, &lnb_status, 0x01);
  345. status |= si21_readregs(state, LNB_CTRL_REG_1, &lnb_status, 0x01);
  346. /*fill the FIFO*/
  347. status |= si21_writeregs(state, LNB_FIFO_REGS_0, m->msg, m->msg_len);
  348. LNB_CTRL_1 = (lnb_status & 0x70);
  349. LNB_CTRL_1 |= m->msg_len;
  350. LNB_CTRL_1 |= 0x80; /* begin LNB signaling */
  351. status |= si21_writeregs(state, LNB_CTRL_REG_1, &LNB_CTRL_1, 0x01);
  352. return status;
  353. }
  354. static int si21xx_send_diseqc_burst(struct dvb_frontend *fe,
  355. fe_sec_mini_cmd_t burst)
  356. {
  357. struct si21xx_state *state = fe->demodulator_priv;
  358. u8 val;
  359. dprintk("%s\n", __func__);
  360. if (si21xx_wait_diseqc_idle(state, 100) < 0)
  361. return -ETIMEDOUT;
  362. val = (0x80 | si21_readreg(state, 0xc1));
  363. if (si21_writereg(state, LNB_CTRL_REG_1,
  364. burst == SEC_MINI_A ? (val & ~0x10) : (val | 0x10)))
  365. return -EREMOTEIO;
  366. if (si21xx_wait_diseqc_idle(state, 100) < 0)
  367. return -ETIMEDOUT;
  368. if (si21_writereg(state, LNB_CTRL_REG_1, val))
  369. return -EREMOTEIO;
  370. return 0;
  371. }
  372. /* 30.06.2008 */
  373. static int si21xx_set_tone(struct dvb_frontend *fe, fe_sec_tone_mode_t tone)
  374. {
  375. struct si21xx_state *state = fe->demodulator_priv;
  376. u8 val;
  377. dprintk("%s\n", __func__);
  378. val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
  379. switch (tone) {
  380. case SEC_TONE_ON:
  381. return si21_writereg(state, LNB_CTRL_REG_1, val | 0x20);
  382. case SEC_TONE_OFF:
  383. return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x20));
  384. default:
  385. return -EINVAL;
  386. }
  387. }
  388. static int si21xx_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t volt)
  389. {
  390. struct si21xx_state *state = fe->demodulator_priv;
  391. u8 val;
  392. dprintk("%s: %s\n", __func__,
  393. volt == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
  394. volt == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
  395. val = (0x80 | si21_readreg(state, LNB_CTRL_REG_1));
  396. switch (volt) {
  397. case SEC_VOLTAGE_18:
  398. return si21_writereg(state, LNB_CTRL_REG_1, val | 0x40);
  399. break;
  400. case SEC_VOLTAGE_13:
  401. return si21_writereg(state, LNB_CTRL_REG_1, (val & ~0x40));
  402. break;
  403. default:
  404. return -EINVAL;
  405. };
  406. }
  407. static int si21xx_init(struct dvb_frontend *fe)
  408. {
  409. struct si21xx_state *state = fe->demodulator_priv;
  410. int i;
  411. int status = 0;
  412. u8 reg1;
  413. u8 val;
  414. u8 reg2[2];
  415. dprintk("%s\n", __func__);
  416. for (i = 0; ; i += 2) {
  417. reg1 = serit_sp1511lhb_inittab[i];
  418. val = serit_sp1511lhb_inittab[i+1];
  419. if (reg1 == 0xff && val == 0xff)
  420. break;
  421. si21_writeregs(state, reg1, &val, 1);
  422. }
  423. /*DVB QPSK SYSTEM MODE REG*/
  424. reg1 = 0x08;
  425. si21_writeregs(state, SYSTEM_MODE_REG, &reg1, 0x01);
  426. /*transport stream config*/
  427. /*
  428. mode = PARALLEL;
  429. sdata_form = LSB_FIRST;
  430. clk_edge = FALLING_EDGE;
  431. clk_mode = CLK_GAPPED_MODE;
  432. strt_len = BYTE_WIDE;
  433. sync_pol = ACTIVE_HIGH;
  434. val_pol = ACTIVE_HIGH;
  435. err_pol = ACTIVE_HIGH;
  436. sclk_rate = 0x00;
  437. parity = 0x00 ;
  438. data_delay = 0x00;
  439. clk_delay = 0x00;
  440. pclk_smooth = 0x00;
  441. */
  442. reg2[0] =
  443. PARALLEL + (LSB_FIRST << 1)
  444. + (FALLING_EDGE << 2) + (CLK_GAPPED_MODE << 3)
  445. + (BYTE_WIDE << 4) + (ACTIVE_HIGH << 5)
  446. + (ACTIVE_HIGH << 6) + (ACTIVE_HIGH << 7);
  447. reg2[1] = 0;
  448. /* sclk_rate + (parity << 2)
  449. + (data_delay << 3) + (clk_delay << 4)
  450. + (pclk_smooth << 5);
  451. */
  452. status |= si21_writeregs(state, TS_CTRL_REG_1, reg2, 0x02);
  453. if (status != 0)
  454. dprintk(" %s : TS Set Error\n", __func__);
  455. return 0;
  456. }
  457. static int si21_read_status(struct dvb_frontend *fe, fe_status_t *status)
  458. {
  459. struct si21xx_state *state = fe->demodulator_priv;
  460. u8 regs_read[2];
  461. u8 reg_read;
  462. u8 i;
  463. u8 lock;
  464. u8 signal = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG);
  465. si21_readregs(state, LOCK_STATUS_REG_1, regs_read, 0x02);
  466. reg_read = 0;
  467. for (i = 0; i < 7; ++i)
  468. reg_read |= ((regs_read[0] >> i) & 0x01) << (6 - i);
  469. lock = ((reg_read & 0x7f) | (regs_read[1] & 0x80));
  470. dprintk("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, lock);
  471. *status = 0;
  472. if (signal > 10)
  473. *status |= FE_HAS_SIGNAL;
  474. if (lock & 0x2)
  475. *status |= FE_HAS_CARRIER;
  476. if (lock & 0x20)
  477. *status |= FE_HAS_VITERBI;
  478. if (lock & 0x40)
  479. *status |= FE_HAS_SYNC;
  480. if ((lock & 0x7b) == 0x7b)
  481. *status |= FE_HAS_LOCK;
  482. return 0;
  483. }
  484. static int si21_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
  485. {
  486. struct si21xx_state *state = fe->demodulator_priv;
  487. /*status = si21_readreg(state, ANALOG_AGC_POWER_LEVEL_REG,
  488. (u8*)agclevel, 0x01);*/
  489. u16 signal = (3 * si21_readreg(state, 0x27) *
  490. si21_readreg(state, 0x28));
  491. dprintk("%s : AGCPWR: 0x%02x%02x, signal=0x%04x\n", __func__,
  492. si21_readreg(state, 0x27),
  493. si21_readreg(state, 0x28), (int) signal);
  494. signal <<= 4;
  495. *strength = signal;
  496. return 0;
  497. }
  498. static int si21_read_ber(struct dvb_frontend *fe, u32 *ber)
  499. {
  500. struct si21xx_state *state = fe->demodulator_priv;
  501. dprintk("%s\n", __func__);
  502. if (state->errmode != STATUS_BER)
  503. return 0;
  504. *ber = (si21_readreg(state, 0x1d) << 8) |
  505. si21_readreg(state, 0x1e);
  506. return 0;
  507. }
  508. static int si21_read_snr(struct dvb_frontend *fe, u16 *snr)
  509. {
  510. struct si21xx_state *state = fe->demodulator_priv;
  511. s32 xsnr = 0xffff - ((si21_readreg(state, 0x24) << 8) |
  512. si21_readreg(state, 0x25));
  513. xsnr = 3 * (xsnr - 0xa100);
  514. *snr = (xsnr > 0xffff) ? 0xffff : (xsnr < 0) ? 0 : xsnr;
  515. dprintk("%s\n", __func__);
  516. return 0;
  517. }
  518. static int si21_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
  519. {
  520. struct si21xx_state *state = fe->demodulator_priv;
  521. dprintk("%s\n", __func__);
  522. if (state->errmode != STATUS_UCBLOCKS)
  523. *ucblocks = 0;
  524. else
  525. *ucblocks = (si21_readreg(state, 0x1d) << 8) |
  526. si21_readreg(state, 0x1e);
  527. return 0;
  528. }
  529. /* initiates a channel acquisition sequence
  530. using the specified symbol rate and code rate */
  531. static int si21xx_setacquire(struct dvb_frontend *fe, int symbrate,
  532. fe_code_rate_t crate)
  533. {
  534. struct si21xx_state *state = fe->demodulator_priv;
  535. u8 coderates[] = {
  536. 0x0, 0x01, 0x02, 0x04, 0x00,
  537. 0x8, 0x10, 0x20, 0x00, 0x3f
  538. };
  539. u8 coderate_ptr;
  540. int status;
  541. u8 start_acq = 0x80;
  542. u8 reg, regs[3];
  543. dprintk("%s\n", __func__);
  544. status = PASS;
  545. coderate_ptr = coderates[crate];
  546. si21xx_set_symbolrate(fe, symbrate);
  547. /* write code rates to use in the Viterbi search */
  548. status |= si21_writeregs(state,
  549. VIT_SRCH_CTRL_REG_1,
  550. &coderate_ptr, 0x01);
  551. /* clear acq_start bit */
  552. status |= si21_readregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
  553. reg &= ~start_acq;
  554. status |= si21_writeregs(state, ACQ_CTRL_REG_2, &reg, 0x01);
  555. /* use new Carrier Frequency Offset Estimator (QuickLock) */
  556. regs[0] = 0xCB;
  557. regs[1] = 0x40;
  558. regs[2] = 0xCB;
  559. status |= si21_writeregs(state,
  560. TWO_DB_BNDWDTH_THRSHLD_REG,
  561. &regs[0], 0x03);
  562. reg = 0x56;
  563. status |= si21_writeregs(state,
  564. LSA_CTRL_REG_1, &reg, 1);
  565. reg = 0x05;
  566. status |= si21_writeregs(state,
  567. BLIND_SCAN_CTRL_REG, &reg, 1);
  568. /* start automatic acq */
  569. status |= si21_writeregs(state,
  570. ACQ_CTRL_REG_2, &start_acq, 0x01);
  571. return status;
  572. }
  573. static int si21xx_set_property(struct dvb_frontend *fe, struct dtv_property *p)
  574. {
  575. dprintk("%s(..)\n", __func__);
  576. return 0;
  577. }
  578. static int si21xx_get_property(struct dvb_frontend *fe, struct dtv_property *p)
  579. {
  580. dprintk("%s(..)\n", __func__);
  581. return 0;
  582. }
  583. static int si21xx_set_frontend(struct dvb_frontend *fe,
  584. struct dvb_frontend_parameters *dfp)
  585. {
  586. struct si21xx_state *state = fe->demodulator_priv;
  587. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  588. /* freq Channel carrier frequency in KHz (i.e. 1550000 KHz)
  589. datarate Channel symbol rate in Sps (i.e. 22500000 Sps)*/
  590. /* in MHz */
  591. unsigned char coarse_tune_freq;
  592. int fine_tune_freq;
  593. unsigned char sample_rate = 0;
  594. /* boolean */
  595. unsigned int inband_interferer_ind;
  596. /* INTERMEDIATE VALUES */
  597. int icoarse_tune_freq; /* MHz */
  598. int ifine_tune_freq; /* MHz */
  599. unsigned int band_high;
  600. unsigned int band_low;
  601. unsigned int x1;
  602. unsigned int x2;
  603. int i;
  604. unsigned int inband_interferer_div2[ALLOWABLE_FS_COUNT] = {
  605. FALSE, FALSE, FALSE, FALSE, FALSE,
  606. FALSE, FALSE, FALSE, FALSE, FALSE
  607. };
  608. unsigned int inband_interferer_div4[ALLOWABLE_FS_COUNT] = {
  609. FALSE, FALSE, FALSE, FALSE, FALSE,
  610. FALSE, FALSE, FALSE, FALSE, FALSE
  611. };
  612. int status;
  613. /* allowable sample rates for ADC in MHz */
  614. int afs[ALLOWABLE_FS_COUNT] = { 200, 192, 193, 194, 195,
  615. 196, 204, 205, 206, 207
  616. };
  617. /* in MHz */
  618. int if_limit_high;
  619. int if_limit_low;
  620. int lnb_lo;
  621. int lnb_uncertanity;
  622. int rf_freq;
  623. int data_rate;
  624. unsigned char regs[4];
  625. dprintk("%s : FE_SET_FRONTEND\n", __func__);
  626. if (c->delivery_system != SYS_DVBS) {
  627. dprintk("%s: unsupported delivery system selected (%d)\n",
  628. __func__, c->delivery_system);
  629. return -EOPNOTSUPP;
  630. }
  631. for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
  632. inband_interferer_div2[i] = inband_interferer_div4[i] = FALSE;
  633. if_limit_high = -700000;
  634. if_limit_low = -100000;
  635. /* in MHz */
  636. lnb_lo = 0;
  637. lnb_uncertanity = 0;
  638. rf_freq = 10 * c->frequency ;
  639. data_rate = c->symbol_rate / 100;
  640. status = PASS;
  641. band_low = (rf_freq - lnb_lo) - ((lnb_uncertanity * 200)
  642. + (data_rate * 135)) / 200;
  643. band_high = (rf_freq - lnb_lo) + ((lnb_uncertanity * 200)
  644. + (data_rate * 135)) / 200;
  645. icoarse_tune_freq = 100000 *
  646. (((rf_freq - lnb_lo) -
  647. (if_limit_low + if_limit_high) / 2)
  648. / 100000);
  649. ifine_tune_freq = (rf_freq - lnb_lo) - icoarse_tune_freq ;
  650. for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
  651. x1 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
  652. (afs[i] * 2500) + afs[i] * 2500;
  653. x2 = ((rf_freq - lnb_lo) / (afs[i] * 2500)) *
  654. (afs[i] * 2500);
  655. if (((band_low < x1) && (x1 < band_high)) ||
  656. ((band_low < x2) && (x2 < band_high)))
  657. inband_interferer_div4[i] = TRUE;
  658. }
  659. for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
  660. x1 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
  661. (afs[i] * 5000) + afs[i] * 5000;
  662. x2 = ((rf_freq - lnb_lo) / (afs[i] * 5000)) *
  663. (afs[i] * 5000);
  664. if (((band_low < x1) && (x1 < band_high)) ||
  665. ((band_low < x2) && (x2 < band_high)))
  666. inband_interferer_div2[i] = TRUE;
  667. }
  668. inband_interferer_ind = TRUE;
  669. for (i = 0; i < ALLOWABLE_FS_COUNT; ++i)
  670. inband_interferer_ind &= inband_interferer_div2[i] |
  671. inband_interferer_div4[i];
  672. if (inband_interferer_ind) {
  673. for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
  674. if (inband_interferer_div2[i] == FALSE) {
  675. sample_rate = (u8) afs[i];
  676. break;
  677. }
  678. }
  679. } else {
  680. for (i = 0; i < ALLOWABLE_FS_COUNT; ++i) {
  681. if ((inband_interferer_div2[i] |
  682. inband_interferer_div4[i]) == FALSE) {
  683. sample_rate = (u8) afs[i];
  684. break;
  685. }
  686. }
  687. }
  688. if (sample_rate > 207 || sample_rate < 192)
  689. sample_rate = 200;
  690. fine_tune_freq = ((0x4000 * (ifine_tune_freq / 10)) /
  691. ((sample_rate) * 1000));
  692. coarse_tune_freq = (u8)(icoarse_tune_freq / 100000);
  693. regs[0] = sample_rate;
  694. regs[1] = coarse_tune_freq;
  695. regs[2] = fine_tune_freq & 0xFF;
  696. regs[3] = fine_tune_freq >> 8 & 0xFF;
  697. status |= si21_writeregs(state, PLL_DIVISOR_REG, &regs[0], 0x04);
  698. state->fs = sample_rate;/*ADC MHz*/
  699. si21xx_setacquire(fe, c->symbol_rate, c->fec_inner);
  700. return 0;
  701. }
  702. static int si21xx_sleep(struct dvb_frontend *fe)
  703. {
  704. struct si21xx_state *state = fe->demodulator_priv;
  705. u8 regdata;
  706. dprintk("%s\n", __func__);
  707. si21_readregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
  708. regdata |= 1 << 6;
  709. si21_writeregs(state, SYSTEM_MODE_REG, &regdata, 0x01);
  710. state->initialised = 0;
  711. return 0;
  712. }
  713. static void si21xx_release(struct dvb_frontend *fe)
  714. {
  715. struct si21xx_state *state = fe->demodulator_priv;
  716. dprintk("%s\n", __func__);
  717. kfree(state);
  718. }
  719. static struct dvb_frontend_ops si21xx_ops = {
  720. .info = {
  721. .name = "SL SI21XX DVB-S",
  722. .type = FE_QPSK,
  723. .frequency_min = 950000,
  724. .frequency_max = 2150000,
  725. .frequency_stepsize = 125, /* kHz for QPSK frontends */
  726. .frequency_tolerance = 0,
  727. .symbol_rate_min = 1000000,
  728. .symbol_rate_max = 45000000,
  729. .symbol_rate_tolerance = 500, /* ppm */
  730. .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
  731. FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 |
  732. FE_CAN_QPSK |
  733. FE_CAN_FEC_AUTO
  734. },
  735. .release = si21xx_release,
  736. .init = si21xx_init,
  737. .sleep = si21xx_sleep,
  738. .write = si21_write,
  739. .read_status = si21_read_status,
  740. .read_ber = si21_read_ber,
  741. .read_signal_strength = si21_read_signal_strength,
  742. .read_snr = si21_read_snr,
  743. .read_ucblocks = si21_read_ucblocks,
  744. .diseqc_send_master_cmd = si21xx_send_diseqc_msg,
  745. .diseqc_send_burst = si21xx_send_diseqc_burst,
  746. .set_tone = si21xx_set_tone,
  747. .set_voltage = si21xx_set_voltage,
  748. .set_property = si21xx_set_property,
  749. .get_property = si21xx_get_property,
  750. .set_frontend = si21xx_set_frontend,
  751. };
  752. struct dvb_frontend *si21xx_attach(const struct si21xx_config *config,
  753. struct i2c_adapter *i2c)
  754. {
  755. struct si21xx_state *state = NULL;
  756. int id;
  757. dprintk("%s\n", __func__);
  758. /* allocate memory for the internal state */
  759. state = kmalloc(sizeof(struct si21xx_state), GFP_KERNEL);
  760. if (state == NULL)
  761. goto error;
  762. /* setup the state */
  763. state->config = config;
  764. state->i2c = i2c;
  765. state->initialised = 0;
  766. state->errmode = STATUS_BER;
  767. /* check if the demod is there */
  768. id = si21_readreg(state, SYSTEM_MODE_REG);
  769. si21_writereg(state, SYSTEM_MODE_REG, id | 0x40); /* standby off */
  770. msleep(200);
  771. id = si21_readreg(state, 0x00);
  772. /* register 0x00 contains:
  773. 0x34 for SI2107
  774. 0x24 for SI2108
  775. 0x14 for SI2109
  776. 0x04 for SI2110
  777. */
  778. if (id != 0x04 && id != 0x14)
  779. goto error;
  780. /* create dvb_frontend */
  781. memcpy(&state->frontend.ops, &si21xx_ops,
  782. sizeof(struct dvb_frontend_ops));
  783. state->frontend.demodulator_priv = state;
  784. return &state->frontend;
  785. error:
  786. kfree(state);
  787. return NULL;
  788. }
  789. EXPORT_SYMBOL(si21xx_attach);
  790. module_param(debug, int, 0644);
  791. MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  792. MODULE_DESCRIPTION("SL SI21XX DVB Demodulator driver");
  793. MODULE_AUTHOR("Igor M. Liplianin");
  794. MODULE_LICENSE("GPL");