nxt200x.c 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238
  1. /*
  2. * Support for NXT2002 and NXT2004 - VSB/QAM
  3. *
  4. * Copyright (C) 2005 Kirk Lapray <kirk.lapray@gmail.com>
  5. * Copyright (C) 2006 Michael Krufky <mkrufky@m1k.net>
  6. * based on nxt2002 by Taylor Jacob <rtjacob@earthlink.net>
  7. * and nxt2004 by Jean-Francois Thibert <jeanfrancois@sagetv.com>
  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. */
  24. /*
  25. * NOTES ABOUT THIS DRIVER
  26. *
  27. * This Linux driver supports:
  28. * B2C2/BBTI Technisat Air2PC - ATSC (NXT2002)
  29. * AverTVHD MCE A180 (NXT2004)
  30. * ATI HDTV Wonder (NXT2004)
  31. *
  32. * This driver needs external firmware. Please use the command
  33. * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2002" or
  34. * "<kerneldir>/Documentation/dvb/get_dvb_firmware nxt2004" to
  35. * download/extract the appropriate firmware, and then copy it to
  36. * /usr/lib/hotplug/firmware/ or /lib/firmware/
  37. * (depending on configuration of firmware hotplug).
  38. */
  39. #define NXT2002_DEFAULT_FIRMWARE "dvb-fe-nxt2002.fw"
  40. #define NXT2004_DEFAULT_FIRMWARE "dvb-fe-nxt2004.fw"
  41. #define CRC_CCIT_MASK 0x1021
  42. #include <linux/kernel.h>
  43. #include <linux/init.h>
  44. #include <linux/module.h>
  45. #include <linux/slab.h>
  46. #include <linux/string.h>
  47. #include "dvb_frontend.h"
  48. #include "nxt200x.h"
  49. struct nxt200x_state {
  50. struct i2c_adapter* i2c;
  51. const struct nxt200x_config* config;
  52. struct dvb_frontend frontend;
  53. /* demodulator private data */
  54. nxt_chip_type demod_chip;
  55. u8 initialised:1;
  56. };
  57. static int debug;
  58. #define dprintk(args...) \
  59. do { \
  60. if (debug) printk(KERN_DEBUG "nxt200x: " args); \
  61. } while (0)
  62. static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len)
  63. {
  64. int err;
  65. struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = len };
  66. if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
  67. printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
  68. __FUNCTION__, addr, err);
  69. return -EREMOTEIO;
  70. }
  71. return 0;
  72. }
  73. static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
  74. {
  75. int err;
  76. struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = buf, .len = len };
  77. if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
  78. printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
  79. __FUNCTION__, addr, err);
  80. return -EREMOTEIO;
  81. }
  82. return 0;
  83. }
  84. static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8 len)
  85. {
  86. u8 buf2 [len+1];
  87. int err;
  88. struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf2, .len = len + 1 };
  89. buf2[0] = reg;
  90. memcpy(&buf2[1], buf, len);
  91. if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
  92. printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
  93. __FUNCTION__, state->config->demod_address, err);
  94. return -EREMOTEIO;
  95. }
  96. return 0;
  97. }
  98. static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 len)
  99. {
  100. u8 reg2 [] = { reg };
  101. struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = reg2, .len = 1 },
  102. { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = buf, .len = len } };
  103. int err;
  104. if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
  105. printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
  106. __FUNCTION__, state->config->demod_address, err);
  107. return -EREMOTEIO;
  108. }
  109. return 0;
  110. }
  111. static u16 nxt200x_crc(u16 crc, u8 c)
  112. {
  113. u8 i;
  114. u16 input = (u16) c & 0xFF;
  115. input<<=8;
  116. for(i=0; i<8; i++) {
  117. if((crc^input) & 0x8000)
  118. crc=(crc<<1)^CRC_CCIT_MASK;
  119. else
  120. crc<<=1;
  121. input<<=1;
  122. }
  123. return crc;
  124. }
  125. static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
  126. {
  127. u8 attr, len2, buf;
  128. dprintk("%s\n", __FUNCTION__);
  129. /* set mutli register register */
  130. nxt200x_writebytes(state, 0x35, &reg, 1);
  131. /* send the actual data */
  132. nxt200x_writebytes(state, 0x36, data, len);
  133. switch (state->demod_chip) {
  134. case NXT2002:
  135. len2 = len;
  136. buf = 0x02;
  137. break;
  138. case NXT2004:
  139. /* probably not right, but gives correct values */
  140. attr = 0x02;
  141. if (reg & 0x80) {
  142. attr = attr << 1;
  143. if (reg & 0x04)
  144. attr = attr >> 1;
  145. }
  146. /* set write bit */
  147. len2 = ((attr << 4) | 0x10) | len;
  148. buf = 0x80;
  149. break;
  150. default:
  151. return -EINVAL;
  152. break;
  153. }
  154. /* set multi register length */
  155. nxt200x_writebytes(state, 0x34, &len2, 1);
  156. /* toggle the multireg write bit */
  157. nxt200x_writebytes(state, 0x21, &buf, 1);
  158. nxt200x_readbytes(state, 0x21, &buf, 1);
  159. switch (state->demod_chip) {
  160. case NXT2002:
  161. if ((buf & 0x02) == 0)
  162. return 0;
  163. break;
  164. case NXT2004:
  165. if (buf == 0)
  166. return 0;
  167. break;
  168. default:
  169. return -EINVAL;
  170. break;
  171. }
  172. printk(KERN_WARNING "nxt200x: Error writing multireg register 0x%02X\n",reg);
  173. return 0;
  174. }
  175. static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
  176. {
  177. int i;
  178. u8 buf, len2, attr;
  179. dprintk("%s\n", __FUNCTION__);
  180. /* set mutli register register */
  181. nxt200x_writebytes(state, 0x35, &reg, 1);
  182. switch (state->demod_chip) {
  183. case NXT2002:
  184. /* set multi register length */
  185. len2 = len & 0x80;
  186. nxt200x_writebytes(state, 0x34, &len2, 1);
  187. /* read the actual data */
  188. nxt200x_readbytes(state, reg, data, len);
  189. return 0;
  190. break;
  191. case NXT2004:
  192. /* probably not right, but gives correct values */
  193. attr = 0x02;
  194. if (reg & 0x80) {
  195. attr = attr << 1;
  196. if (reg & 0x04)
  197. attr = attr >> 1;
  198. }
  199. /* set multi register length */
  200. len2 = (attr << 4) | len;
  201. nxt200x_writebytes(state, 0x34, &len2, 1);
  202. /* toggle the multireg bit*/
  203. buf = 0x80;
  204. nxt200x_writebytes(state, 0x21, &buf, 1);
  205. /* read the actual data */
  206. for(i = 0; i < len; i++) {
  207. nxt200x_readbytes(state, 0x36 + i, &data[i], 1);
  208. }
  209. return 0;
  210. break;
  211. default:
  212. return -EINVAL;
  213. break;
  214. }
  215. }
  216. static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
  217. {
  218. u8 buf, stopval, counter = 0;
  219. dprintk("%s\n", __FUNCTION__);
  220. /* set correct stop value */
  221. switch (state->demod_chip) {
  222. case NXT2002:
  223. stopval = 0x40;
  224. break;
  225. case NXT2004:
  226. stopval = 0x10;
  227. break;
  228. default:
  229. stopval = 0;
  230. break;
  231. }
  232. buf = 0x80;
  233. nxt200x_writebytes(state, 0x22, &buf, 1);
  234. while (counter < 20) {
  235. nxt200x_readbytes(state, 0x31, &buf, 1);
  236. if (buf & stopval)
  237. return;
  238. msleep(10);
  239. counter++;
  240. }
  241. printk(KERN_WARNING "nxt200x: Timeout waiting for nxt200x to stop. This is ok after firmware upload.\n");
  242. return;
  243. }
  244. static void nxt200x_microcontroller_start (struct nxt200x_state* state)
  245. {
  246. u8 buf;
  247. dprintk("%s\n", __FUNCTION__);
  248. buf = 0x00;
  249. nxt200x_writebytes(state, 0x22, &buf, 1);
  250. }
  251. static void nxt2004_microcontroller_init (struct nxt200x_state* state)
  252. {
  253. u8 buf[9];
  254. u8 counter = 0;
  255. dprintk("%s\n", __FUNCTION__);
  256. buf[0] = 0x00;
  257. nxt200x_writebytes(state, 0x2b, buf, 1);
  258. buf[0] = 0x70;
  259. nxt200x_writebytes(state, 0x34, buf, 1);
  260. buf[0] = 0x04;
  261. nxt200x_writebytes(state, 0x35, buf, 1);
  262. buf[0] = 0x01; buf[1] = 0x23; buf[2] = 0x45; buf[3] = 0x67; buf[4] = 0x89;
  263. buf[5] = 0xAB; buf[6] = 0xCD; buf[7] = 0xEF; buf[8] = 0xC0;
  264. nxt200x_writebytes(state, 0x36, buf, 9);
  265. buf[0] = 0x80;
  266. nxt200x_writebytes(state, 0x21, buf, 1);
  267. while (counter < 20) {
  268. nxt200x_readbytes(state, 0x21, buf, 1);
  269. if (buf[0] == 0)
  270. return;
  271. msleep(10);
  272. counter++;
  273. }
  274. printk(KERN_WARNING "nxt200x: Timeout waiting for nxt2004 to init.\n");
  275. return;
  276. }
  277. static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
  278. {
  279. u8 buf, count = 0;
  280. dprintk("%s\n", __FUNCTION__);
  281. dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]);
  282. /* if NXT2004, write directly to tuner. if NXT2002, write through NXT chip.
  283. * direct write is required for Philips TUV1236D and ALPS TDHU2 */
  284. switch (state->demod_chip) {
  285. case NXT2004:
  286. if (i2c_writebytes(state, data[0], data+1, 4))
  287. printk(KERN_WARNING "nxt200x: error writing to tuner\n");
  288. /* wait until we have a lock */
  289. while (count < 20) {
  290. i2c_readbytes(state, data[0], &buf, 1);
  291. if (buf & 0x40)
  292. return 0;
  293. msleep(100);
  294. count++;
  295. }
  296. printk("nxt2004: timeout waiting for tuner lock\n");
  297. break;
  298. case NXT2002:
  299. /* set the i2c transfer speed to the tuner */
  300. buf = 0x03;
  301. nxt200x_writebytes(state, 0x20, &buf, 1);
  302. /* setup to transfer 4 bytes via i2c */
  303. buf = 0x04;
  304. nxt200x_writebytes(state, 0x34, &buf, 1);
  305. /* write actual tuner bytes */
  306. nxt200x_writebytes(state, 0x36, data+1, 4);
  307. /* set tuner i2c address */
  308. buf = data[0] << 1;
  309. nxt200x_writebytes(state, 0x35, &buf, 1);
  310. /* write UC Opmode to begin transfer */
  311. buf = 0x80;
  312. nxt200x_writebytes(state, 0x21, &buf, 1);
  313. while (count < 20) {
  314. nxt200x_readbytes(state, 0x21, &buf, 1);
  315. if ((buf & 0x80)== 0x00)
  316. return 0;
  317. msleep(100);
  318. count++;
  319. }
  320. printk("nxt2002: timeout error writing tuner\n");
  321. break;
  322. default:
  323. return -EINVAL;
  324. break;
  325. }
  326. return 0;
  327. }
  328. static void nxt200x_agc_reset(struct nxt200x_state* state)
  329. {
  330. u8 buf;
  331. dprintk("%s\n", __FUNCTION__);
  332. switch (state->demod_chip) {
  333. case NXT2002:
  334. buf = 0x08;
  335. nxt200x_writebytes(state, 0x08, &buf, 1);
  336. buf = 0x00;
  337. nxt200x_writebytes(state, 0x08, &buf, 1);
  338. break;
  339. case NXT2004:
  340. nxt200x_readreg_multibyte(state, 0x08, &buf, 1);
  341. buf = 0x08;
  342. nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
  343. buf = 0x00;
  344. nxt200x_writereg_multibyte(state, 0x08, &buf, 1);
  345. break;
  346. default:
  347. break;
  348. }
  349. return;
  350. }
  351. static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
  352. {
  353. struct nxt200x_state* state = fe->demodulator_priv;
  354. u8 buf[3], written = 0, chunkpos = 0;
  355. u16 rambase, position, crc = 0;
  356. dprintk("%s\n", __FUNCTION__);
  357. dprintk("Firmware is %zu bytes\n", fw->size);
  358. /* Get the RAM base for this nxt2002 */
  359. nxt200x_readbytes(state, 0x10, buf, 1);
  360. if (buf[0] & 0x10)
  361. rambase = 0x1000;
  362. else
  363. rambase = 0x0000;
  364. dprintk("rambase on this nxt2002 is %04X\n", rambase);
  365. /* Hold the micro in reset while loading firmware */
  366. buf[0] = 0x80;
  367. nxt200x_writebytes(state, 0x2B, buf, 1);
  368. for (position = 0; position < fw->size; position++) {
  369. if (written == 0) {
  370. crc = 0;
  371. chunkpos = 0x28;
  372. buf[0] = ((rambase + position) >> 8);
  373. buf[1] = (rambase + position) & 0xFF;
  374. buf[2] = 0x81;
  375. /* write starting address */
  376. nxt200x_writebytes(state, 0x29, buf, 3);
  377. }
  378. written++;
  379. chunkpos++;
  380. if ((written % 4) == 0)
  381. nxt200x_writebytes(state, chunkpos, &fw->data[position-3], 4);
  382. crc = nxt200x_crc(crc, fw->data[position]);
  383. if ((written == 255) || (position+1 == fw->size)) {
  384. /* write remaining bytes of firmware */
  385. nxt200x_writebytes(state, chunkpos+4-(written %4),
  386. &fw->data[position-(written %4) + 1],
  387. written %4);
  388. buf[0] = crc << 8;
  389. buf[1] = crc & 0xFF;
  390. /* write crc */
  391. nxt200x_writebytes(state, 0x2C, buf, 2);
  392. /* do a read to stop things */
  393. nxt200x_readbytes(state, 0x2A, buf, 1);
  394. /* set transfer mode to complete */
  395. buf[0] = 0x80;
  396. nxt200x_writebytes(state, 0x2B, buf, 1);
  397. written = 0;
  398. }
  399. }
  400. return 0;
  401. };
  402. static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
  403. {
  404. struct nxt200x_state* state = fe->demodulator_priv;
  405. u8 buf[3];
  406. u16 rambase, position, crc=0;
  407. dprintk("%s\n", __FUNCTION__);
  408. dprintk("Firmware is %zu bytes\n", fw->size);
  409. /* set rambase */
  410. rambase = 0x1000;
  411. /* hold the micro in reset while loading firmware */
  412. buf[0] = 0x80;
  413. nxt200x_writebytes(state, 0x2B, buf,1);
  414. /* calculate firmware CRC */
  415. for (position = 0; position < fw->size; position++) {
  416. crc = nxt200x_crc(crc, fw->data[position]);
  417. }
  418. buf[0] = rambase >> 8;
  419. buf[1] = rambase & 0xFF;
  420. buf[2] = 0x81;
  421. /* write starting address */
  422. nxt200x_writebytes(state,0x29,buf,3);
  423. for (position = 0; position < fw->size;) {
  424. nxt200x_writebytes(state, 0x2C, &fw->data[position],
  425. fw->size-position > 255 ? 255 : fw->size-position);
  426. position += (fw->size-position > 255 ? 255 : fw->size-position);
  427. }
  428. buf[0] = crc >> 8;
  429. buf[1] = crc & 0xFF;
  430. dprintk("firmware crc is 0x%02X 0x%02X\n", buf[0], buf[1]);
  431. /* write crc */
  432. nxt200x_writebytes(state, 0x2C, buf,2);
  433. /* do a read to stop things */
  434. nxt200x_readbytes(state, 0x2C, buf, 1);
  435. /* set transfer mode to complete */
  436. buf[0] = 0x80;
  437. nxt200x_writebytes(state, 0x2B, buf,1);
  438. return 0;
  439. };
  440. static int nxt200x_setup_frontend_parameters (struct dvb_frontend* fe,
  441. struct dvb_frontend_parameters *p)
  442. {
  443. struct nxt200x_state* state = fe->demodulator_priv;
  444. u8 buf[5];
  445. /* stop the micro first */
  446. nxt200x_microcontroller_stop(state);
  447. if (state->demod_chip == NXT2004) {
  448. /* make sure demod is set to digital */
  449. buf[0] = 0x04;
  450. nxt200x_writebytes(state, 0x14, buf, 1);
  451. buf[0] = 0x00;
  452. nxt200x_writebytes(state, 0x17, buf, 1);
  453. }
  454. /* set additional params */
  455. switch (p->u.vsb.modulation) {
  456. case QAM_64:
  457. case QAM_256:
  458. /* Set punctured clock for QAM */
  459. /* This is just a guess since I am unable to test it */
  460. if (state->config->set_ts_params)
  461. state->config->set_ts_params(fe, 1);
  462. break;
  463. case VSB_8:
  464. /* Set non-punctured clock for VSB */
  465. if (state->config->set_ts_params)
  466. state->config->set_ts_params(fe, 0);
  467. break;
  468. default:
  469. return -EINVAL;
  470. break;
  471. }
  472. if (fe->ops.tuner_ops.calc_regs) {
  473. /* get tuning information */
  474. fe->ops.tuner_ops.calc_regs(fe, p, buf, 5);
  475. /* write frequency information */
  476. nxt200x_writetuner(state, buf);
  477. }
  478. /* reset the agc now that tuning has been completed */
  479. nxt200x_agc_reset(state);
  480. /* set target power level */
  481. switch (p->u.vsb.modulation) {
  482. case QAM_64:
  483. case QAM_256:
  484. buf[0] = 0x74;
  485. break;
  486. case VSB_8:
  487. buf[0] = 0x70;
  488. break;
  489. default:
  490. return -EINVAL;
  491. break;
  492. }
  493. nxt200x_writebytes(state, 0x42, buf, 1);
  494. /* configure sdm */
  495. switch (state->demod_chip) {
  496. case NXT2002:
  497. buf[0] = 0x87;
  498. break;
  499. case NXT2004:
  500. buf[0] = 0x07;
  501. break;
  502. default:
  503. return -EINVAL;
  504. break;
  505. }
  506. nxt200x_writebytes(state, 0x57, buf, 1);
  507. /* write sdm1 input */
  508. buf[0] = 0x10;
  509. buf[1] = 0x00;
  510. switch (state->demod_chip) {
  511. case NXT2002:
  512. nxt200x_writereg_multibyte(state, 0x58, buf, 2);
  513. break;
  514. case NXT2004:
  515. nxt200x_writebytes(state, 0x58, buf, 2);
  516. break;
  517. default:
  518. return -EINVAL;
  519. break;
  520. }
  521. /* write sdmx input */
  522. switch (p->u.vsb.modulation) {
  523. case QAM_64:
  524. buf[0] = 0x68;
  525. break;
  526. case QAM_256:
  527. buf[0] = 0x64;
  528. break;
  529. case VSB_8:
  530. buf[0] = 0x60;
  531. break;
  532. default:
  533. return -EINVAL;
  534. break;
  535. }
  536. buf[1] = 0x00;
  537. switch (state->demod_chip) {
  538. case NXT2002:
  539. nxt200x_writereg_multibyte(state, 0x5C, buf, 2);
  540. break;
  541. case NXT2004:
  542. nxt200x_writebytes(state, 0x5C, buf, 2);
  543. break;
  544. default:
  545. return -EINVAL;
  546. break;
  547. }
  548. /* write adc power lpf fc */
  549. buf[0] = 0x05;
  550. nxt200x_writebytes(state, 0x43, buf, 1);
  551. if (state->demod_chip == NXT2004) {
  552. /* write ??? */
  553. buf[0] = 0x00;
  554. buf[1] = 0x00;
  555. nxt200x_writebytes(state, 0x46, buf, 2);
  556. }
  557. /* write accumulator2 input */
  558. buf[0] = 0x80;
  559. buf[1] = 0x00;
  560. switch (state->demod_chip) {
  561. case NXT2002:
  562. nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
  563. break;
  564. case NXT2004:
  565. nxt200x_writebytes(state, 0x4B, buf, 2);
  566. break;
  567. default:
  568. return -EINVAL;
  569. break;
  570. }
  571. /* write kg1 */
  572. buf[0] = 0x00;
  573. nxt200x_writebytes(state, 0x4D, buf, 1);
  574. /* write sdm12 lpf fc */
  575. buf[0] = 0x44;
  576. nxt200x_writebytes(state, 0x55, buf, 1);
  577. /* write agc control reg */
  578. buf[0] = 0x04;
  579. nxt200x_writebytes(state, 0x41, buf, 1);
  580. if (state->demod_chip == NXT2004) {
  581. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  582. buf[0] = 0x24;
  583. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  584. /* soft reset? */
  585. nxt200x_readreg_multibyte(state, 0x08, buf, 1);
  586. buf[0] = 0x10;
  587. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  588. nxt200x_readreg_multibyte(state, 0x08, buf, 1);
  589. buf[0] = 0x00;
  590. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  591. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  592. buf[0] = 0x04;
  593. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  594. buf[0] = 0x00;
  595. nxt200x_writereg_multibyte(state, 0x81, buf, 1);
  596. buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
  597. nxt200x_writereg_multibyte(state, 0x82, buf, 3);
  598. nxt200x_readreg_multibyte(state, 0x88, buf, 1);
  599. buf[0] = 0x11;
  600. nxt200x_writereg_multibyte(state, 0x88, buf, 1);
  601. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  602. buf[0] = 0x44;
  603. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  604. }
  605. /* write agc ucgp0 */
  606. switch (p->u.vsb.modulation) {
  607. case QAM_64:
  608. buf[0] = 0x02;
  609. break;
  610. case QAM_256:
  611. buf[0] = 0x03;
  612. break;
  613. case VSB_8:
  614. buf[0] = 0x00;
  615. break;
  616. default:
  617. return -EINVAL;
  618. break;
  619. }
  620. nxt200x_writebytes(state, 0x30, buf, 1);
  621. /* write agc control reg */
  622. buf[0] = 0x00;
  623. nxt200x_writebytes(state, 0x41, buf, 1);
  624. /* write accumulator2 input */
  625. buf[0] = 0x80;
  626. buf[1] = 0x00;
  627. switch (state->demod_chip) {
  628. case NXT2002:
  629. nxt200x_writereg_multibyte(state, 0x49, buf, 2);
  630. nxt200x_writereg_multibyte(state, 0x4B, buf, 2);
  631. break;
  632. case NXT2004:
  633. nxt200x_writebytes(state, 0x49, buf, 2);
  634. nxt200x_writebytes(state, 0x4B, buf, 2);
  635. break;
  636. default:
  637. return -EINVAL;
  638. break;
  639. }
  640. /* write agc control reg */
  641. buf[0] = 0x04;
  642. nxt200x_writebytes(state, 0x41, buf, 1);
  643. nxt200x_microcontroller_start(state);
  644. if (state->demod_chip == NXT2004) {
  645. nxt2004_microcontroller_init(state);
  646. /* ???? */
  647. buf[0] = 0xF0;
  648. buf[1] = 0x00;
  649. nxt200x_writebytes(state, 0x5C, buf, 2);
  650. }
  651. /* adjacent channel detection should be done here, but I don't
  652. have any stations with this need so I cannot test it */
  653. return 0;
  654. }
  655. static int nxt200x_read_status(struct dvb_frontend* fe, fe_status_t* status)
  656. {
  657. struct nxt200x_state* state = fe->demodulator_priv;
  658. u8 lock;
  659. nxt200x_readbytes(state, 0x31, &lock, 1);
  660. *status = 0;
  661. if (lock & 0x20) {
  662. *status |= FE_HAS_SIGNAL;
  663. *status |= FE_HAS_CARRIER;
  664. *status |= FE_HAS_VITERBI;
  665. *status |= FE_HAS_SYNC;
  666. *status |= FE_HAS_LOCK;
  667. }
  668. return 0;
  669. }
  670. static int nxt200x_read_ber(struct dvb_frontend* fe, u32* ber)
  671. {
  672. struct nxt200x_state* state = fe->demodulator_priv;
  673. u8 b[3];
  674. nxt200x_readreg_multibyte(state, 0xE6, b, 3);
  675. *ber = ((b[0] << 8) + b[1]) * 8;
  676. return 0;
  677. }
  678. static int nxt200x_read_signal_strength(struct dvb_frontend* fe, u16* strength)
  679. {
  680. struct nxt200x_state* state = fe->demodulator_priv;
  681. u8 b[2];
  682. u16 temp = 0;
  683. /* setup to read cluster variance */
  684. b[0] = 0x00;
  685. nxt200x_writebytes(state, 0xA1, b, 1);
  686. /* get multreg val */
  687. nxt200x_readreg_multibyte(state, 0xA6, b, 2);
  688. temp = (b[0] << 8) | b[1];
  689. *strength = ((0x7FFF - temp) & 0x0FFF) * 16;
  690. return 0;
  691. }
  692. static int nxt200x_read_snr(struct dvb_frontend* fe, u16* snr)
  693. {
  694. struct nxt200x_state* state = fe->demodulator_priv;
  695. u8 b[2];
  696. u16 temp = 0, temp2;
  697. u32 snrdb = 0;
  698. /* setup to read cluster variance */
  699. b[0] = 0x00;
  700. nxt200x_writebytes(state, 0xA1, b, 1);
  701. /* get multreg val from 0xA6 */
  702. nxt200x_readreg_multibyte(state, 0xA6, b, 2);
  703. temp = (b[0] << 8) | b[1];
  704. temp2 = 0x7FFF - temp;
  705. /* snr will be in db */
  706. if (temp2 > 0x7F00)
  707. snrdb = 1000*24 + ( 1000*(30-24) * ( temp2 - 0x7F00 ) / ( 0x7FFF - 0x7F00 ) );
  708. else if (temp2 > 0x7EC0)
  709. snrdb = 1000*18 + ( 1000*(24-18) * ( temp2 - 0x7EC0 ) / ( 0x7F00 - 0x7EC0 ) );
  710. else if (temp2 > 0x7C00)
  711. snrdb = 1000*12 + ( 1000*(18-12) * ( temp2 - 0x7C00 ) / ( 0x7EC0 - 0x7C00 ) );
  712. else
  713. snrdb = 1000*0 + ( 1000*(12-0) * ( temp2 - 0 ) / ( 0x7C00 - 0 ) );
  714. /* the value reported back from the frontend will be FFFF=32db 0000=0db */
  715. *snr = snrdb * (0xFFFF/32000);
  716. return 0;
  717. }
  718. static int nxt200x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
  719. {
  720. struct nxt200x_state* state = fe->demodulator_priv;
  721. u8 b[3];
  722. nxt200x_readreg_multibyte(state, 0xE6, b, 3);
  723. *ucblocks = b[2];
  724. return 0;
  725. }
  726. static int nxt200x_sleep(struct dvb_frontend* fe)
  727. {
  728. return 0;
  729. }
  730. static int nxt2002_init(struct dvb_frontend* fe)
  731. {
  732. struct nxt200x_state* state = fe->demodulator_priv;
  733. const struct firmware *fw;
  734. int ret;
  735. u8 buf[2];
  736. /* request the firmware, this will block until someone uploads it */
  737. printk("nxt2002: Waiting for firmware upload (%s)...\n", NXT2002_DEFAULT_FIRMWARE);
  738. ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, &state->i2c->dev);
  739. printk("nxt2002: Waiting for firmware upload(2)...\n");
  740. if (ret) {
  741. printk("nxt2002: No firmware uploaded (timeout or file not found?)\n");
  742. return ret;
  743. }
  744. ret = nxt2002_load_firmware(fe, fw);
  745. release_firmware(fw);
  746. if (ret) {
  747. printk("nxt2002: Writing firmware to device failed\n");
  748. return ret;
  749. }
  750. printk("nxt2002: Firmware upload complete\n");
  751. /* Put the micro into reset */
  752. nxt200x_microcontroller_stop(state);
  753. /* ensure transfer is complete */
  754. buf[0]=0x00;
  755. nxt200x_writebytes(state, 0x2B, buf, 1);
  756. /* Put the micro into reset for real this time */
  757. nxt200x_microcontroller_stop(state);
  758. /* soft reset everything (agc,frontend,eq,fec)*/
  759. buf[0] = 0x0F;
  760. nxt200x_writebytes(state, 0x08, buf, 1);
  761. buf[0] = 0x00;
  762. nxt200x_writebytes(state, 0x08, buf, 1);
  763. /* write agc sdm configure */
  764. buf[0] = 0xF1;
  765. nxt200x_writebytes(state, 0x57, buf, 1);
  766. /* write mod output format */
  767. buf[0] = 0x20;
  768. nxt200x_writebytes(state, 0x09, buf, 1);
  769. /* write fec mpeg mode */
  770. buf[0] = 0x7E;
  771. buf[1] = 0x00;
  772. nxt200x_writebytes(state, 0xE9, buf, 2);
  773. /* write mux selection */
  774. buf[0] = 0x00;
  775. nxt200x_writebytes(state, 0xCC, buf, 1);
  776. return 0;
  777. }
  778. static int nxt2004_init(struct dvb_frontend* fe)
  779. {
  780. struct nxt200x_state* state = fe->demodulator_priv;
  781. const struct firmware *fw;
  782. int ret;
  783. u8 buf[3];
  784. /* ??? */
  785. buf[0]=0x00;
  786. nxt200x_writebytes(state, 0x1E, buf, 1);
  787. /* request the firmware, this will block until someone uploads it */
  788. printk("nxt2004: Waiting for firmware upload (%s)...\n", NXT2004_DEFAULT_FIRMWARE);
  789. ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, &state->i2c->dev);
  790. printk("nxt2004: Waiting for firmware upload(2)...\n");
  791. if (ret) {
  792. printk("nxt2004: No firmware uploaded (timeout or file not found?)\n");
  793. return ret;
  794. }
  795. ret = nxt2004_load_firmware(fe, fw);
  796. release_firmware(fw);
  797. if (ret) {
  798. printk("nxt2004: Writing firmware to device failed\n");
  799. return ret;
  800. }
  801. printk("nxt2004: Firmware upload complete\n");
  802. /* ensure transfer is complete */
  803. buf[0] = 0x01;
  804. nxt200x_writebytes(state, 0x19, buf, 1);
  805. nxt2004_microcontroller_init(state);
  806. nxt200x_microcontroller_stop(state);
  807. nxt200x_microcontroller_stop(state);
  808. nxt2004_microcontroller_init(state);
  809. nxt200x_microcontroller_stop(state);
  810. /* soft reset everything (agc,frontend,eq,fec)*/
  811. buf[0] = 0xFF;
  812. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  813. buf[0] = 0x00;
  814. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  815. /* write agc sdm configure */
  816. buf[0] = 0xD7;
  817. nxt200x_writebytes(state, 0x57, buf, 1);
  818. /* ???*/
  819. buf[0] = 0x07;
  820. buf[1] = 0xfe;
  821. nxt200x_writebytes(state, 0x35, buf, 2);
  822. buf[0] = 0x12;
  823. nxt200x_writebytes(state, 0x34, buf, 1);
  824. buf[0] = 0x80;
  825. nxt200x_writebytes(state, 0x21, buf, 1);
  826. /* ???*/
  827. buf[0] = 0x21;
  828. nxt200x_writebytes(state, 0x0A, buf, 1);
  829. /* ???*/
  830. buf[0] = 0x01;
  831. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  832. /* write fec mpeg mode */
  833. buf[0] = 0x7E;
  834. buf[1] = 0x00;
  835. nxt200x_writebytes(state, 0xE9, buf, 2);
  836. /* write mux selection */
  837. buf[0] = 0x00;
  838. nxt200x_writebytes(state, 0xCC, buf, 1);
  839. /* ???*/
  840. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  841. buf[0] = 0x00;
  842. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  843. /* soft reset? */
  844. nxt200x_readreg_multibyte(state, 0x08, buf, 1);
  845. buf[0] = 0x10;
  846. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  847. nxt200x_readreg_multibyte(state, 0x08, buf, 1);
  848. buf[0] = 0x00;
  849. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  850. /* ???*/
  851. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  852. buf[0] = 0x01;
  853. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  854. buf[0] = 0x70;
  855. nxt200x_writereg_multibyte(state, 0x81, buf, 1);
  856. buf[0] = 0x31; buf[1] = 0x5E; buf[2] = 0x66;
  857. nxt200x_writereg_multibyte(state, 0x82, buf, 3);
  858. nxt200x_readreg_multibyte(state, 0x88, buf, 1);
  859. buf[0] = 0x11;
  860. nxt200x_writereg_multibyte(state, 0x88, buf, 1);
  861. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  862. buf[0] = 0x40;
  863. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  864. nxt200x_readbytes(state, 0x10, buf, 1);
  865. buf[0] = 0x10;
  866. nxt200x_writebytes(state, 0x10, buf, 1);
  867. nxt200x_readbytes(state, 0x0A, buf, 1);
  868. buf[0] = 0x21;
  869. nxt200x_writebytes(state, 0x0A, buf, 1);
  870. nxt2004_microcontroller_init(state);
  871. buf[0] = 0x21;
  872. nxt200x_writebytes(state, 0x0A, buf, 1);
  873. buf[0] = 0x7E;
  874. nxt200x_writebytes(state, 0xE9, buf, 1);
  875. buf[0] = 0x00;
  876. nxt200x_writebytes(state, 0xEA, buf, 1);
  877. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  878. buf[0] = 0x00;
  879. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  880. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  881. buf[0] = 0x00;
  882. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  883. /* soft reset? */
  884. nxt200x_readreg_multibyte(state, 0x08, buf, 1);
  885. buf[0] = 0x10;
  886. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  887. nxt200x_readreg_multibyte(state, 0x08, buf, 1);
  888. buf[0] = 0x00;
  889. nxt200x_writereg_multibyte(state, 0x08, buf, 1);
  890. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  891. buf[0] = 0x04;
  892. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  893. buf[0] = 0x00;
  894. nxt200x_writereg_multibyte(state, 0x81, buf, 1);
  895. buf[0] = 0x80; buf[1] = 0x00; buf[2] = 0x00;
  896. nxt200x_writereg_multibyte(state, 0x82, buf, 3);
  897. nxt200x_readreg_multibyte(state, 0x88, buf, 1);
  898. buf[0] = 0x11;
  899. nxt200x_writereg_multibyte(state, 0x88, buf, 1);
  900. nxt200x_readreg_multibyte(state, 0x80, buf, 1);
  901. buf[0] = 0x44;
  902. nxt200x_writereg_multibyte(state, 0x80, buf, 1);
  903. /* initialize tuner */
  904. nxt200x_readbytes(state, 0x10, buf, 1);
  905. buf[0] = 0x12;
  906. nxt200x_writebytes(state, 0x10, buf, 1);
  907. buf[0] = 0x04;
  908. nxt200x_writebytes(state, 0x13, buf, 1);
  909. buf[0] = 0x00;
  910. nxt200x_writebytes(state, 0x16, buf, 1);
  911. buf[0] = 0x04;
  912. nxt200x_writebytes(state, 0x14, buf, 1);
  913. buf[0] = 0x00;
  914. nxt200x_writebytes(state, 0x14, buf, 1);
  915. nxt200x_writebytes(state, 0x17, buf, 1);
  916. nxt200x_writebytes(state, 0x14, buf, 1);
  917. nxt200x_writebytes(state, 0x17, buf, 1);
  918. return 0;
  919. }
  920. static int nxt200x_init(struct dvb_frontend* fe)
  921. {
  922. struct nxt200x_state* state = fe->demodulator_priv;
  923. int ret = 0;
  924. if (!state->initialised) {
  925. switch (state->demod_chip) {
  926. case NXT2002:
  927. ret = nxt2002_init(fe);
  928. break;
  929. case NXT2004:
  930. ret = nxt2004_init(fe);
  931. break;
  932. default:
  933. return -EINVAL;
  934. break;
  935. }
  936. state->initialised = 1;
  937. }
  938. return ret;
  939. }
  940. static int nxt200x_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
  941. {
  942. fesettings->min_delay_ms = 500;
  943. fesettings->step_size = 0;
  944. fesettings->max_drift = 0;
  945. return 0;
  946. }
  947. static void nxt200x_release(struct dvb_frontend* fe)
  948. {
  949. struct nxt200x_state* state = fe->demodulator_priv;
  950. kfree(state);
  951. }
  952. static struct dvb_frontend_ops nxt200x_ops;
  953. struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
  954. struct i2c_adapter* i2c)
  955. {
  956. struct nxt200x_state* state = NULL;
  957. u8 buf [] = {0,0,0,0,0};
  958. /* allocate memory for the internal state */
  959. state = kzalloc(sizeof(struct nxt200x_state), GFP_KERNEL);
  960. if (state == NULL)
  961. goto error;
  962. /* setup the state */
  963. state->config = config;
  964. state->i2c = i2c;
  965. state->initialised = 0;
  966. /* read card id */
  967. nxt200x_readbytes(state, 0x00, buf, 5);
  968. dprintk("NXT info: %02X %02X %02X %02X %02X\n",
  969. buf[0], buf[1], buf[2], buf[3], buf[4]);
  970. /* set demod chip */
  971. switch (buf[0]) {
  972. case 0x04:
  973. state->demod_chip = NXT2002;
  974. printk("nxt200x: NXT2002 Detected\n");
  975. break;
  976. case 0x05:
  977. state->demod_chip = NXT2004;
  978. printk("nxt200x: NXT2004 Detected\n");
  979. break;
  980. default:
  981. goto error;
  982. }
  983. /* make sure demod chip is supported */
  984. switch (state->demod_chip) {
  985. case NXT2002:
  986. if (buf[0] != 0x04) goto error; /* device id */
  987. if (buf[1] != 0x02) goto error; /* fab id */
  988. if (buf[2] != 0x11) goto error; /* month */
  989. if (buf[3] != 0x20) goto error; /* year msb */
  990. if (buf[4] != 0x00) goto error; /* year lsb */
  991. break;
  992. case NXT2004:
  993. if (buf[0] != 0x05) goto error; /* device id */
  994. break;
  995. default:
  996. goto error;
  997. }
  998. /* create dvb_frontend */
  999. memcpy(&state->frontend.ops, &nxt200x_ops, sizeof(struct dvb_frontend_ops));
  1000. state->frontend.demodulator_priv = state;
  1001. return &state->frontend;
  1002. error:
  1003. kfree(state);
  1004. printk("Unknown/Unsupported NXT chip: %02X %02X %02X %02X %02X\n",
  1005. buf[0], buf[1], buf[2], buf[3], buf[4]);
  1006. return NULL;
  1007. }
  1008. static struct dvb_frontend_ops nxt200x_ops = {
  1009. .info = {
  1010. .name = "Nextwave NXT200X VSB/QAM frontend",
  1011. .type = FE_ATSC,
  1012. .frequency_min = 54000000,
  1013. .frequency_max = 860000000,
  1014. .frequency_stepsize = 166666, /* stepsize is just a guess */
  1015. .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
  1016. FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
  1017. FE_CAN_8VSB | FE_CAN_QAM_64 | FE_CAN_QAM_256
  1018. },
  1019. .release = nxt200x_release,
  1020. .init = nxt200x_init,
  1021. .sleep = nxt200x_sleep,
  1022. .set_frontend = nxt200x_setup_frontend_parameters,
  1023. .get_tune_settings = nxt200x_get_tune_settings,
  1024. .read_status = nxt200x_read_status,
  1025. .read_ber = nxt200x_read_ber,
  1026. .read_signal_strength = nxt200x_read_signal_strength,
  1027. .read_snr = nxt200x_read_snr,
  1028. .read_ucblocks = nxt200x_read_ucblocks,
  1029. };
  1030. module_param(debug, int, 0644);
  1031. MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  1032. MODULE_DESCRIPTION("NXT200X (ATSC 8VSB & ITU-T J.83 AnnexB 64/256 QAM) Demodulator Driver");
  1033. MODULE_AUTHOR("Kirk Lapray, Michael Krufky, Jean-Francois Thibert, and Taylor Jacob");
  1034. MODULE_LICENSE("GPL");
  1035. EXPORT_SYMBOL(nxt200x_attach);