nxt6000.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637
  1. /*
  2. NxtWave Communications - NXT6000 demodulator driver
  3. Copyright (C) 2002-2003 Florian Schirmer <jolt@tuxbox.org>
  4. Copyright (C) 2003 Paul Andreassen <paul@andreassen.com.au>
  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. This program is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with this program; if not, write to the Free Software
  15. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  16. */
  17. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  18. #include <linux/init.h>
  19. #include <linux/kernel.h>
  20. #include <linux/module.h>
  21. #include <linux/string.h>
  22. #include <linux/slab.h>
  23. #include <media/dvb_frontend.h>
  24. #include "nxt6000_priv.h"
  25. #include "nxt6000.h"
  26. struct nxt6000_state {
  27. struct i2c_adapter* i2c;
  28. /* configuration settings */
  29. const struct nxt6000_config* config;
  30. struct dvb_frontend frontend;
  31. };
  32. static int debug;
  33. #define dprintk(fmt, arg...) do { \
  34. if (debug) \
  35. printk(KERN_DEBUG pr_fmt("%s: " fmt), \
  36. __func__, ##arg); \
  37. } while (0)
  38. static int nxt6000_writereg(struct nxt6000_state* state, u8 reg, u8 data)
  39. {
  40. u8 buf[] = { reg, data };
  41. struct i2c_msg msg = {.addr = state->config->demod_address,.flags = 0,.buf = buf,.len = 2 };
  42. int ret;
  43. if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
  44. dprintk("nxt6000: nxt6000_write error (reg: 0x%02X, data: 0x%02X, ret: %d)\n", reg, data, ret);
  45. return (ret != 1) ? -EIO : 0;
  46. }
  47. static u8 nxt6000_readreg(struct nxt6000_state* state, u8 reg)
  48. {
  49. int ret;
  50. u8 b0[] = { reg };
  51. u8 b1[] = { 0 };
  52. struct i2c_msg msgs[] = {
  53. {.addr = state->config->demod_address,.flags = 0,.buf = b0,.len = 1},
  54. {.addr = state->config->demod_address,.flags = I2C_M_RD,.buf = b1,.len = 1}
  55. };
  56. ret = i2c_transfer(state->i2c, msgs, 2);
  57. if (ret != 2)
  58. dprintk("nxt6000: nxt6000_read error (reg: 0x%02X, ret: %d)\n", reg, ret);
  59. return b1[0];
  60. }
  61. static void nxt6000_reset(struct nxt6000_state* state)
  62. {
  63. u8 val;
  64. val = nxt6000_readreg(state, OFDM_COR_CTL);
  65. nxt6000_writereg(state, OFDM_COR_CTL, val & ~COREACT);
  66. nxt6000_writereg(state, OFDM_COR_CTL, val | COREACT);
  67. }
  68. static int nxt6000_set_bandwidth(struct nxt6000_state *state, u32 bandwidth)
  69. {
  70. u16 nominal_rate;
  71. int result;
  72. switch (bandwidth) {
  73. case 6000000:
  74. nominal_rate = 0x55B7;
  75. break;
  76. case 7000000:
  77. nominal_rate = 0x6400;
  78. break;
  79. case 8000000:
  80. nominal_rate = 0x7249;
  81. break;
  82. default:
  83. return -EINVAL;
  84. }
  85. if ((result = nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, nominal_rate & 0xFF)) < 0)
  86. return result;
  87. return nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, (nominal_rate >> 8) & 0xFF);
  88. }
  89. static int nxt6000_set_guard_interval(struct nxt6000_state *state,
  90. enum fe_guard_interval guard_interval)
  91. {
  92. switch (guard_interval) {
  93. case GUARD_INTERVAL_1_32:
  94. return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x00 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
  95. case GUARD_INTERVAL_1_16:
  96. return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x01 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
  97. case GUARD_INTERVAL_AUTO:
  98. case GUARD_INTERVAL_1_8:
  99. return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x02 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
  100. case GUARD_INTERVAL_1_4:
  101. return nxt6000_writereg(state, OFDM_COR_MODEGUARD, 0x03 | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x03));
  102. default:
  103. return -EINVAL;
  104. }
  105. }
  106. static int nxt6000_set_inversion(struct nxt6000_state *state,
  107. enum fe_spectral_inversion inversion)
  108. {
  109. switch (inversion) {
  110. case INVERSION_OFF:
  111. return nxt6000_writereg(state, OFDM_ITB_CTL, 0x00);
  112. case INVERSION_ON:
  113. return nxt6000_writereg(state, OFDM_ITB_CTL, ITBINV);
  114. default:
  115. return -EINVAL;
  116. }
  117. }
  118. static int
  119. nxt6000_set_transmission_mode(struct nxt6000_state *state,
  120. enum fe_transmit_mode transmission_mode)
  121. {
  122. int result;
  123. switch (transmission_mode) {
  124. case TRANSMISSION_MODE_2K:
  125. if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x00 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
  126. return result;
  127. return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x00 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
  128. case TRANSMISSION_MODE_8K:
  129. case TRANSMISSION_MODE_AUTO:
  130. if ((result = nxt6000_writereg(state, EN_DMD_RACQ, 0x02 | (nxt6000_readreg(state, EN_DMD_RACQ) & ~0x03))) < 0)
  131. return result;
  132. return nxt6000_writereg(state, OFDM_COR_MODEGUARD, (0x01 << 2) | (nxt6000_readreg(state, OFDM_COR_MODEGUARD) & ~0x04));
  133. default:
  134. return -EINVAL;
  135. }
  136. }
  137. static void nxt6000_setup(struct dvb_frontend* fe)
  138. {
  139. struct nxt6000_state* state = fe->demodulator_priv;
  140. nxt6000_writereg(state, RS_COR_SYNC_PARAM, SYNC_PARAM);
  141. nxt6000_writereg(state, BER_CTRL, /*(1 << 2) | */ (0x01 << 1) | 0x01);
  142. nxt6000_writereg(state, VIT_BERTIME_2, 0x00); // BER Timer = 0x000200 * 256 = 131072 bits
  143. nxt6000_writereg(state, VIT_BERTIME_1, 0x02); //
  144. nxt6000_writereg(state, VIT_BERTIME_0, 0x00); //
  145. nxt6000_writereg(state, VIT_COR_INTEN, 0x98); // Enable BER interrupts
  146. nxt6000_writereg(state, VIT_COR_CTL, 0x82); // Enable BER measurement
  147. nxt6000_writereg(state, VIT_COR_CTL, VIT_COR_RESYNC | 0x02 );
  148. nxt6000_writereg(state, OFDM_COR_CTL, (0x01 << 5) | (nxt6000_readreg(state, OFDM_COR_CTL) & 0x0F));
  149. nxt6000_writereg(state, OFDM_COR_MODEGUARD, FORCEMODE8K | 0x02);
  150. nxt6000_writereg(state, OFDM_AGC_CTL, AGCLAST | INITIAL_AGC_BW);
  151. nxt6000_writereg(state, OFDM_ITB_FREQ_1, 0x06);
  152. nxt6000_writereg(state, OFDM_ITB_FREQ_2, 0x31);
  153. nxt6000_writereg(state, OFDM_CAS_CTL, (0x01 << 7) | (0x02 << 3) | 0x04);
  154. nxt6000_writereg(state, CAS_FREQ, 0xBB); /* CHECKME */
  155. nxt6000_writereg(state, OFDM_SYR_CTL, 1 << 2);
  156. nxt6000_writereg(state, OFDM_PPM_CTL_1, PPM256);
  157. nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_1, 0x49);
  158. nxt6000_writereg(state, OFDM_TRL_NOMINALRATE_2, 0x72);
  159. nxt6000_writereg(state, ANALOG_CONTROL_0, 1 << 5);
  160. nxt6000_writereg(state, EN_DMD_RACQ, (1 << 7) | (3 << 4) | 2);
  161. nxt6000_writereg(state, DIAG_CONFIG, TB_SET);
  162. if (state->config->clock_inversion)
  163. nxt6000_writereg(state, SUB_DIAG_MODE_SEL, CLKINVERSION);
  164. else
  165. nxt6000_writereg(state, SUB_DIAG_MODE_SEL, 0);
  166. nxt6000_writereg(state, TS_FORMAT, 0);
  167. }
  168. static void nxt6000_dump_status(struct nxt6000_state *state)
  169. {
  170. u8 val;
  171. #if 0
  172. pr_info("RS_COR_STAT: 0x%02X\n",
  173. nxt6000_readreg(fe, RS_COR_STAT));
  174. pr_info("VIT_SYNC_STATUS: 0x%02X\n",
  175. nxt6000_readreg(fe, VIT_SYNC_STATUS));
  176. pr_info("OFDM_COR_STAT: 0x%02X\n",
  177. nxt6000_readreg(fe, OFDM_COR_STAT));
  178. pr_info("OFDM_SYR_STAT: 0x%02X\n",
  179. nxt6000_readreg(fe, OFDM_SYR_STAT));
  180. pr_info("OFDM_TPS_RCVD_1: 0x%02X\n",
  181. nxt6000_readreg(fe, OFDM_TPS_RCVD_1));
  182. pr_info("OFDM_TPS_RCVD_2: 0x%02X\n",
  183. nxt6000_readreg(fe, OFDM_TPS_RCVD_2));
  184. pr_info("OFDM_TPS_RCVD_3: 0x%02X\n",
  185. nxt6000_readreg(fe, OFDM_TPS_RCVD_3));
  186. pr_info("OFDM_TPS_RCVD_4: 0x%02X\n",
  187. nxt6000_readreg(fe, OFDM_TPS_RCVD_4));
  188. pr_info("OFDM_TPS_RESERVED_1: 0x%02X\n",
  189. nxt6000_readreg(fe, OFDM_TPS_RESERVED_1));
  190. pr_info("OFDM_TPS_RESERVED_2: 0x%02X\n",
  191. nxt6000_readreg(fe, OFDM_TPS_RESERVED_2));
  192. #endif
  193. pr_info("NXT6000 status:");
  194. val = nxt6000_readreg(state, RS_COR_STAT);
  195. pr_cont(" DATA DESCR LOCK: %d,", val & 0x01);
  196. pr_cont(" DATA SYNC LOCK: %d,", (val >> 1) & 0x01);
  197. val = nxt6000_readreg(state, VIT_SYNC_STATUS);
  198. pr_cont(" VITERBI LOCK: %d,", (val >> 7) & 0x01);
  199. switch ((val >> 4) & 0x07) {
  200. case 0x00:
  201. pr_cont(" VITERBI CODERATE: 1/2,");
  202. break;
  203. case 0x01:
  204. pr_cont(" VITERBI CODERATE: 2/3,");
  205. break;
  206. case 0x02:
  207. pr_cont(" VITERBI CODERATE: 3/4,");
  208. break;
  209. case 0x03:
  210. pr_cont(" VITERBI CODERATE: 5/6,");
  211. break;
  212. case 0x04:
  213. pr_cont(" VITERBI CODERATE: 7/8,");
  214. break;
  215. default:
  216. pr_cont(" VITERBI CODERATE: Reserved,");
  217. }
  218. val = nxt6000_readreg(state, OFDM_COR_STAT);
  219. pr_cont(" CHCTrack: %d,", (val >> 7) & 0x01);
  220. pr_cont(" TPSLock: %d,", (val >> 6) & 0x01);
  221. pr_cont(" SYRLock: %d,", (val >> 5) & 0x01);
  222. pr_cont(" AGCLock: %d,", (val >> 4) & 0x01);
  223. switch (val & 0x0F) {
  224. case 0x00:
  225. pr_cont(" CoreState: IDLE,");
  226. break;
  227. case 0x02:
  228. pr_cont(" CoreState: WAIT_AGC,");
  229. break;
  230. case 0x03:
  231. pr_cont(" CoreState: WAIT_SYR,");
  232. break;
  233. case 0x04:
  234. pr_cont(" CoreState: WAIT_PPM,");
  235. break;
  236. case 0x01:
  237. pr_cont(" CoreState: WAIT_TRL,");
  238. break;
  239. case 0x05:
  240. pr_cont(" CoreState: WAIT_TPS,");
  241. break;
  242. case 0x06:
  243. pr_cont(" CoreState: MONITOR_TPS,");
  244. break;
  245. default:
  246. pr_cont(" CoreState: Reserved,");
  247. }
  248. val = nxt6000_readreg(state, OFDM_SYR_STAT);
  249. pr_cont(" SYRLock: %d,", (val >> 4) & 0x01);
  250. pr_cont(" SYRMode: %s,", (val >> 2) & 0x01 ? "8K" : "2K");
  251. switch ((val >> 4) & 0x03) {
  252. case 0x00:
  253. pr_cont(" SYRGuard: 1/32,");
  254. break;
  255. case 0x01:
  256. pr_cont(" SYRGuard: 1/16,");
  257. break;
  258. case 0x02:
  259. pr_cont(" SYRGuard: 1/8,");
  260. break;
  261. case 0x03:
  262. pr_cont(" SYRGuard: 1/4,");
  263. break;
  264. }
  265. val = nxt6000_readreg(state, OFDM_TPS_RCVD_3);
  266. switch ((val >> 4) & 0x07) {
  267. case 0x00:
  268. pr_cont(" TPSLP: 1/2,");
  269. break;
  270. case 0x01:
  271. pr_cont(" TPSLP: 2/3,");
  272. break;
  273. case 0x02:
  274. pr_cont(" TPSLP: 3/4,");
  275. break;
  276. case 0x03:
  277. pr_cont(" TPSLP: 5/6,");
  278. break;
  279. case 0x04:
  280. pr_cont(" TPSLP: 7/8,");
  281. break;
  282. default:
  283. pr_cont(" TPSLP: Reserved,");
  284. }
  285. switch (val & 0x07) {
  286. case 0x00:
  287. pr_cont(" TPSHP: 1/2,");
  288. break;
  289. case 0x01:
  290. pr_cont(" TPSHP: 2/3,");
  291. break;
  292. case 0x02:
  293. pr_cont(" TPSHP: 3/4,");
  294. break;
  295. case 0x03:
  296. pr_cont(" TPSHP: 5/6,");
  297. break;
  298. case 0x04:
  299. pr_cont(" TPSHP: 7/8,");
  300. break;
  301. default:
  302. pr_cont(" TPSHP: Reserved,");
  303. }
  304. val = nxt6000_readreg(state, OFDM_TPS_RCVD_4);
  305. pr_cont(" TPSMode: %s,", val & 0x01 ? "8K" : "2K");
  306. switch ((val >> 4) & 0x03) {
  307. case 0x00:
  308. pr_cont(" TPSGuard: 1/32,");
  309. break;
  310. case 0x01:
  311. pr_cont(" TPSGuard: 1/16,");
  312. break;
  313. case 0x02:
  314. pr_cont(" TPSGuard: 1/8,");
  315. break;
  316. case 0x03:
  317. pr_cont(" TPSGuard: 1/4,");
  318. break;
  319. }
  320. /* Strange magic required to gain access to RF_AGC_STATUS */
  321. nxt6000_readreg(state, RF_AGC_VAL_1);
  322. val = nxt6000_readreg(state, RF_AGC_STATUS);
  323. val = nxt6000_readreg(state, RF_AGC_STATUS);
  324. pr_cont(" RF AGC LOCK: %d,", (val >> 4) & 0x01);
  325. pr_cont("\n");
  326. }
  327. static int nxt6000_read_status(struct dvb_frontend *fe, enum fe_status *status)
  328. {
  329. u8 core_status;
  330. struct nxt6000_state* state = fe->demodulator_priv;
  331. *status = 0;
  332. core_status = nxt6000_readreg(state, OFDM_COR_STAT);
  333. if (core_status & AGCLOCKED)
  334. *status |= FE_HAS_SIGNAL;
  335. if (nxt6000_readreg(state, OFDM_SYR_STAT) & GI14_SYR_LOCK)
  336. *status |= FE_HAS_CARRIER;
  337. if (nxt6000_readreg(state, VIT_SYNC_STATUS) & VITINSYNC)
  338. *status |= FE_HAS_VITERBI;
  339. if (nxt6000_readreg(state, RS_COR_STAT) & RSCORESTATUS)
  340. *status |= FE_HAS_SYNC;
  341. if ((core_status & TPSLOCKED) && (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI | FE_HAS_SYNC)))
  342. *status |= FE_HAS_LOCK;
  343. if (debug)
  344. nxt6000_dump_status(state);
  345. return 0;
  346. }
  347. static int nxt6000_init(struct dvb_frontend* fe)
  348. {
  349. struct nxt6000_state* state = fe->demodulator_priv;
  350. nxt6000_reset(state);
  351. nxt6000_setup(fe);
  352. return 0;
  353. }
  354. static int nxt6000_set_frontend(struct dvb_frontend *fe)
  355. {
  356. struct dtv_frontend_properties *p = &fe->dtv_property_cache;
  357. struct nxt6000_state* state = fe->demodulator_priv;
  358. int result;
  359. if (fe->ops.tuner_ops.set_params) {
  360. fe->ops.tuner_ops.set_params(fe);
  361. if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
  362. }
  363. result = nxt6000_set_bandwidth(state, p->bandwidth_hz);
  364. if (result < 0)
  365. return result;
  366. result = nxt6000_set_guard_interval(state, p->guard_interval);
  367. if (result < 0)
  368. return result;
  369. result = nxt6000_set_transmission_mode(state, p->transmission_mode);
  370. if (result < 0)
  371. return result;
  372. result = nxt6000_set_inversion(state, p->inversion);
  373. if (result < 0)
  374. return result;
  375. msleep(500);
  376. return 0;
  377. }
  378. static void nxt6000_release(struct dvb_frontend* fe)
  379. {
  380. struct nxt6000_state* state = fe->demodulator_priv;
  381. kfree(state);
  382. }
  383. static int nxt6000_read_snr(struct dvb_frontend* fe, u16* snr)
  384. {
  385. struct nxt6000_state* state = fe->demodulator_priv;
  386. *snr = nxt6000_readreg( state, OFDM_CHC_SNR) / 8;
  387. return 0;
  388. }
  389. static int nxt6000_read_ber(struct dvb_frontend* fe, u32* ber)
  390. {
  391. struct nxt6000_state* state = fe->demodulator_priv;
  392. nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18 );
  393. *ber = (nxt6000_readreg( state, VIT_BER_1 ) << 8 ) |
  394. nxt6000_readreg( state, VIT_BER_0 );
  395. nxt6000_writereg( state, VIT_COR_INTSTAT, 0x18); // Clear BER Done interrupts
  396. return 0;
  397. }
  398. static int nxt6000_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
  399. {
  400. struct nxt6000_state* state = fe->demodulator_priv;
  401. *signal_strength = (short) (511 -
  402. (nxt6000_readreg(state, AGC_GAIN_1) +
  403. ((nxt6000_readreg(state, AGC_GAIN_2) & 0x03) << 8)));
  404. return 0;
  405. }
  406. static int nxt6000_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
  407. {
  408. tune->min_delay_ms = 500;
  409. return 0;
  410. }
  411. static int nxt6000_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
  412. {
  413. struct nxt6000_state* state = fe->demodulator_priv;
  414. if (enable) {
  415. return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x01);
  416. } else {
  417. return nxt6000_writereg(state, ENABLE_TUNER_IIC, 0x00);
  418. }
  419. }
  420. static const struct dvb_frontend_ops nxt6000_ops;
  421. struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
  422. struct i2c_adapter* i2c)
  423. {
  424. struct nxt6000_state* state = NULL;
  425. /* allocate memory for the internal state */
  426. state = kzalloc(sizeof(struct nxt6000_state), GFP_KERNEL);
  427. if (state == NULL) goto error;
  428. /* setup the state */
  429. state->config = config;
  430. state->i2c = i2c;
  431. /* check if the demod is there */
  432. if (nxt6000_readreg(state, OFDM_MSC_REV) != NXT6000ASICDEVICE) goto error;
  433. /* create dvb_frontend */
  434. memcpy(&state->frontend.ops, &nxt6000_ops, sizeof(struct dvb_frontend_ops));
  435. state->frontend.demodulator_priv = state;
  436. return &state->frontend;
  437. error:
  438. kfree(state);
  439. return NULL;
  440. }
  441. static const struct dvb_frontend_ops nxt6000_ops = {
  442. .delsys = { SYS_DVBT },
  443. .info = {
  444. .name = "NxtWave NXT6000 DVB-T",
  445. .frequency_min_hz = 0,
  446. .frequency_max_hz = 863250 * kHz,
  447. .frequency_stepsize_hz = 62500,
  448. /*.frequency_tolerance = *//* FIXME: 12% of SR */
  449. .symbol_rate_min = 0, /* FIXME */
  450. .symbol_rate_max = 9360000, /* FIXME */
  451. .symbol_rate_tolerance = 4000,
  452. .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
  453. FE_CAN_FEC_4_5 | FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 |
  454. FE_CAN_FEC_7_8 | FE_CAN_FEC_8_9 | FE_CAN_FEC_AUTO |
  455. FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
  456. FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
  457. FE_CAN_HIERARCHY_AUTO,
  458. },
  459. .release = nxt6000_release,
  460. .init = nxt6000_init,
  461. .i2c_gate_ctrl = nxt6000_i2c_gate_ctrl,
  462. .get_tune_settings = nxt6000_fe_get_tune_settings,
  463. .set_frontend = nxt6000_set_frontend,
  464. .read_status = nxt6000_read_status,
  465. .read_ber = nxt6000_read_ber,
  466. .read_signal_strength = nxt6000_read_signal_strength,
  467. .read_snr = nxt6000_read_snr,
  468. };
  469. module_param(debug, int, 0644);
  470. MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  471. MODULE_DESCRIPTION("NxtWave NXT6000 DVB-T demodulator driver");
  472. MODULE_AUTHOR("Florian Schirmer");
  473. MODULE_LICENSE("GPL");
  474. EXPORT_SYMBOL(nxt6000_attach);