tuner-xc2028.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846
  1. /* tuner-xc2028
  2. *
  3. * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org)
  4. *
  5. * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
  6. * - frontend interface
  7. *
  8. * This code is placed under the terms of the GNU General Public License v2
  9. */
  10. #include <linux/i2c.h>
  11. #include <asm/div64.h>
  12. #include <linux/firmware.h>
  13. #include <linux/videodev2.h>
  14. #include <linux/delay.h>
  15. #include <media/tuner.h>
  16. #include <linux/mutex.h>
  17. #include "tuner-i2c.h"
  18. #include "tuner-xc2028.h"
  19. #include "tuner-xc2028-types.h"
  20. #include <linux/dvb/frontend.h>
  21. #include "dvb_frontend.h"
  22. #define PREFIX "xc2028"
  23. static LIST_HEAD(xc2028_list);
  24. /* struct for storing firmware table */
  25. struct firmware_description {
  26. unsigned int type;
  27. v4l2_std_id id;
  28. unsigned char *ptr;
  29. unsigned int size;
  30. };
  31. struct xc2028_data {
  32. struct list_head xc2028_list;
  33. struct tuner_i2c_props i2c_props;
  34. int (*tuner_callback) (void *dev,
  35. int command, int arg);
  36. struct device *dev;
  37. void *video_dev;
  38. int count;
  39. __u32 frequency;
  40. struct firmware_description *firm;
  41. int firm_size;
  42. __u16 version;
  43. struct xc2028_ctrl ctrl;
  44. v4l2_std_id firm_type; /* video stds supported
  45. by current firmware */
  46. fe_bandwidth_t bandwidth; /* Firmware bandwidth:
  47. 6M, 7M or 8M */
  48. int need_load_generic; /* The generic firmware
  49. were loaded? */
  50. int max_len; /* Max firmware chunk */
  51. enum tuner_mode mode;
  52. struct i2c_client *i2c_client;
  53. struct mutex lock;
  54. };
  55. #define i2c_send(rc, priv, buf, size) do { \
  56. rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \
  57. if (size != rc) \
  58. tuner_info("i2c output error: rc = %d (should be %d)\n",\
  59. rc, (int)size); \
  60. } while (0)
  61. #define i2c_rcv(rc, priv, buf, size) do { \
  62. rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \
  63. if (size != rc) \
  64. tuner_info("i2c input error: rc = %d (should be %d)\n", \
  65. rc, (int)size); \
  66. } while (0)
  67. #define send_seq(priv, data...) do { \
  68. int rc; \
  69. static u8 _val[] = data; \
  70. if (sizeof(_val) != \
  71. (rc = tuner_i2c_xfer_send(&priv->i2c_props, \
  72. _val, sizeof(_val)))) { \
  73. tuner_info("Error on line %d: %d\n", __LINE__, rc); \
  74. return -EINVAL; \
  75. } \
  76. msleep(10); \
  77. } while (0)
  78. static unsigned int xc2028_get_reg(struct xc2028_data *priv, u16 reg)
  79. {
  80. int rc;
  81. unsigned char buf[2];
  82. tuner_info("%s called\n", __FUNCTION__);
  83. buf[0] = reg>>8;
  84. buf[1] = (unsigned char) reg;
  85. i2c_send(rc, priv, buf, 2);
  86. if (rc < 0)
  87. return rc;
  88. i2c_rcv(rc, priv, buf, 2);
  89. if (rc < 0)
  90. return rc;
  91. return (buf[1]) | (buf[0] << 8);
  92. }
  93. void dump_firm_type(unsigned int type)
  94. {
  95. if (type & BASE)
  96. printk("BASE ");
  97. if (type & F8MHZ)
  98. printk("F8MHZ ");
  99. if (type & MTS)
  100. printk("MTS ");
  101. if (type & D2620)
  102. printk("D2620 ");
  103. if (type & D2633)
  104. printk("D2633 ");
  105. if (type & DTV6)
  106. printk("DTV6 ");
  107. if (type & QAM)
  108. printk("QAM ");
  109. if (type & DTV7)
  110. printk("DTV7 ");
  111. if (type & DTV78)
  112. printk("DTV78 ");
  113. if (type & DTV8)
  114. printk("DTV8 ");
  115. if (type & FM)
  116. printk("FM ");
  117. if (type & INPUT1)
  118. printk("INPUT1 ");
  119. if (type & LCD)
  120. printk("LCD ");
  121. if (type & NOGD)
  122. printk("NOGD ");
  123. if (type & MONO)
  124. printk("MONO ");
  125. if (type & ATSC)
  126. printk("ATSC ");
  127. if (type & IF)
  128. printk("IF ");
  129. if (type & LG60)
  130. printk("LG60 ");
  131. if (type & ATI638)
  132. printk("ATI638 ");
  133. if (type & OREN538)
  134. printk("OREN538 ");
  135. if (type & OREN36)
  136. printk("OREN36 ");
  137. if (type & TOYOTA388)
  138. printk("TOYOTA388 ");
  139. if (type & TOYOTA794)
  140. printk("TOYOTA794 ");
  141. if (type & DIBCOM52)
  142. printk("DIBCOM52 ");
  143. if (type & ZARLINK456)
  144. printk("ZARLINK456 ");
  145. if (type & CHINA)
  146. printk("CHINA ");
  147. if (type & F6MHZ)
  148. printk("F6MHZ ");
  149. if (type & INPUT2)
  150. printk("INPUT2 ");
  151. if (type & SCODE)
  152. printk("SCODE ");
  153. }
  154. static void free_firmware(struct xc2028_data *priv)
  155. {
  156. int i;
  157. if (!priv->firm)
  158. return;
  159. for (i = 0; i < priv->firm_size; i++)
  160. kfree(priv->firm[i].ptr);
  161. kfree(priv->firm);
  162. priv->firm = NULL;
  163. priv->need_load_generic = 1;
  164. }
  165. static int load_all_firmwares(struct dvb_frontend *fe)
  166. {
  167. struct xc2028_data *priv = fe->tuner_priv;
  168. const struct firmware *fw = NULL;
  169. unsigned char *p, *endp;
  170. int rc = 0;
  171. int n, n_array;
  172. char name[33];
  173. tuner_info("%s called\n", __FUNCTION__);
  174. tuner_info("Loading firmware %s\n", priv->ctrl.fname);
  175. rc = request_firmware(&fw, priv->ctrl.fname, priv->dev);
  176. if (rc < 0) {
  177. if (rc == -ENOENT)
  178. tuner_info("Error: firmware %s not found.\n",
  179. priv->ctrl.fname);
  180. else
  181. tuner_info("Error %d while requesting firmware %s \n",
  182. rc, priv->ctrl.fname);
  183. return rc;
  184. }
  185. p = fw->data;
  186. endp = p + fw->size;
  187. if (fw->size < sizeof(name) - 1 + 2) {
  188. tuner_info("Error: firmware size is zero!\n");
  189. rc = -EINVAL;
  190. goto done;
  191. }
  192. memcpy(name, p, sizeof(name) - 1);
  193. name[sizeof(name) - 1] = 0;
  194. p += sizeof(name) - 1;
  195. priv->version = le16_to_cpu(*(__u16 *) p);
  196. p += 2;
  197. tuner_info("firmware: %s, ver %d.%d\n", name,
  198. priv->version >> 8, priv->version & 0xff);
  199. if (p + 2 > endp)
  200. goto corrupt;
  201. n_array = le16_to_cpu(*(__u16 *) p);
  202. p += 2;
  203. tuner_info("there are %d firmwares at %s\n", n_array, priv->ctrl.fname);
  204. priv->firm = kzalloc(sizeof(*priv->firm) * n_array, GFP_KERNEL);
  205. if (!fw) {
  206. tuner_info("Not enough memory for loading firmware.\n");
  207. rc = -ENOMEM;
  208. goto done;
  209. }
  210. priv->firm_size = n_array;
  211. n = -1;
  212. while (p < endp) {
  213. __u32 type, size;
  214. v4l2_std_id id;
  215. n++;
  216. if (n >= n_array) {
  217. tuner_info("Too much firmwares at the file\n");
  218. goto corrupt;
  219. }
  220. /* Checks if there's enough bytes to read */
  221. if (p + sizeof(type) + sizeof(id) + sizeof(size) > endp) {
  222. tuner_info("Lost firmware!\n");
  223. goto corrupt;
  224. }
  225. type = le32_to_cpu(*(__u32 *) p);
  226. p += sizeof(type);
  227. id = le64_to_cpu(*(v4l2_std_id *) p);
  228. p += sizeof(id);
  229. size = le32_to_cpu(*(v4l2_std_id *) p);
  230. p += sizeof(size);
  231. if ((!size) || (size + p > endp)) {
  232. tuner_info("Firmware type ");
  233. dump_firm_type(type);
  234. printk("(%x), id %lx corrupt (size=%ld, expected %d)\n",
  235. type, (unsigned long)id, endp - p, size);
  236. goto corrupt;
  237. }
  238. priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
  239. if (!priv->firm[n].ptr) {
  240. tuner_info("Not enough memory.\n");
  241. rc = -ENOMEM;
  242. goto err;
  243. }
  244. tuner_info("Loading firmware type ");
  245. dump_firm_type(type);
  246. printk("(%x), id %lx, size=%d.\n",
  247. type, (unsigned long)id, size);
  248. memcpy(priv->firm[n].ptr, p, size);
  249. priv->firm[n].type = type;
  250. priv->firm[n].id = id;
  251. priv->firm[n].size = size;
  252. p += size;
  253. }
  254. if (n + 1 != priv->firm_size) {
  255. tuner_info("Firmware file is incomplete!\n");
  256. goto corrupt;
  257. }
  258. goto done;
  259. corrupt:
  260. rc = -EINVAL;
  261. tuner_info("Error: firmware file is corrupted!\n");
  262. err:
  263. tuner_info("Releasing loaded firmware file.\n");
  264. free_firmware(priv);
  265. done:
  266. release_firmware(fw);
  267. tuner_info("Firmware files loaded.\n");
  268. return rc;
  269. }
  270. static int load_firmware(struct dvb_frontend *fe, unsigned int type,
  271. v4l2_std_id * id)
  272. {
  273. struct xc2028_data *priv = fe->tuner_priv;
  274. int i, rc;
  275. unsigned char *p, *endp, buf[priv->max_len];
  276. tuner_info("%s called\n", __FUNCTION__);
  277. if (!priv->firm) {
  278. printk(KERN_ERR PREFIX "Error! firmware not loaded\n");
  279. return -EINVAL;
  280. }
  281. if ((type == 0) && (*id == 0))
  282. *id = V4L2_STD_PAL;
  283. /* Seek for exact match */
  284. for (i = 0; i < priv->firm_size; i++) {
  285. if ((type == priv->firm[i].type) && (*id == priv->firm[i].id))
  286. goto found;
  287. }
  288. /* Seek for generic video standard match */
  289. for (i = 0; i < priv->firm_size; i++) {
  290. if ((type == priv->firm[i].type) && (*id & priv->firm[i].id))
  291. goto found;
  292. }
  293. /*FIXME: Would make sense to seek for type "hint" match ? */
  294. tuner_info("Can't find firmware for type=%x, id=%lx\n", type,
  295. (long int)*id);
  296. return -EINVAL;
  297. found:
  298. *id = priv->firm[i].id;
  299. tuner_info("Found firmware for type=%x, id=%lx\n", type, (long int)*id);
  300. p = priv->firm[i].ptr;
  301. if (!p) {
  302. printk(KERN_ERR PREFIX "Firmware pointer were freed!");
  303. return -EINVAL;
  304. }
  305. endp = p + priv->firm[i].size;
  306. while (p < endp) {
  307. __u16 size;
  308. /* Checks if there's enough bytes to read */
  309. if (p + sizeof(size) > endp) {
  310. tuner_info("missing bytes\n");
  311. return -EINVAL;
  312. }
  313. size = le16_to_cpu(*(__u16 *) p);
  314. p += sizeof(size);
  315. if (size == 0xffff)
  316. return 0;
  317. if (!size) {
  318. /* Special callback command received */
  319. rc = priv->tuner_callback(priv->video_dev,
  320. XC2028_TUNER_RESET, 0);
  321. if (rc < 0) {
  322. tuner_info("Error at RESET code %d\n",
  323. (*p) & 0x7f);
  324. return -EINVAL;
  325. }
  326. continue;
  327. }
  328. /* Checks for a sleep command */
  329. if (size & 0x8000) {
  330. msleep(size & 0x7fff);
  331. continue;
  332. }
  333. if ((size + p > endp)) {
  334. tuner_info("missing bytes: need %d, have %d\n",
  335. size, (int)(endp - p));
  336. return -EINVAL;
  337. }
  338. buf[0] = *p;
  339. p++;
  340. size--;
  341. /* Sends message chunks */
  342. while (size > 0) {
  343. int len = (size < priv->max_len - 1) ?
  344. size : priv->max_len - 1;
  345. memcpy(buf + 1, p, len);
  346. i2c_send(rc, priv, buf, len + 1);
  347. if (rc < 0) {
  348. tuner_info("%d returned from send\n", rc);
  349. return -EINVAL;
  350. }
  351. p += len;
  352. size -= len;
  353. }
  354. }
  355. return 0;
  356. }
  357. static int check_firmware(struct dvb_frontend *fe, enum tuner_mode new_mode,
  358. v4l2_std_id std, fe_bandwidth_t bandwidth)
  359. {
  360. struct xc2028_data *priv = fe->tuner_priv;
  361. int rc, version, hwmodel;
  362. v4l2_std_id std0 = 0;
  363. unsigned int type0 = 0, type = 0;
  364. int change_digital_bandwidth;
  365. tuner_info("%s called\n", __FUNCTION__);
  366. if (!priv->firm) {
  367. if (!priv->ctrl.fname)
  368. return -EINVAL;
  369. rc = load_all_firmwares(fe);
  370. if (rc < 0)
  371. return rc;
  372. }
  373. tuner_info("I am in mode %u and I should switch to mode %i\n",
  374. priv->mode, new_mode);
  375. /* first of all, determine whether we have switched the mode */
  376. if (new_mode != priv->mode) {
  377. priv->mode = new_mode;
  378. priv->need_load_generic = 1;
  379. }
  380. change_digital_bandwidth = (priv->mode == T_DIGITAL_TV
  381. && bandwidth != priv->bandwidth) ? 1 : 0;
  382. tuner_info("old bandwidth %u, new bandwidth %u\n", priv->bandwidth,
  383. bandwidth);
  384. if (priv->need_load_generic) {
  385. /* Reset is needed before loading firmware */
  386. rc = priv->tuner_callback(priv->video_dev,
  387. XC2028_TUNER_RESET, 0);
  388. if (rc < 0)
  389. return rc;
  390. type0 = BASE;
  391. if (priv->ctrl.type == XC2028_FIRM_MTS)
  392. type0 |= MTS;
  393. if (priv->bandwidth == 8)
  394. type0 |= F8MHZ;
  395. /* FIXME: How to load FM and FM|INPUT1 firmwares? */
  396. rc = load_firmware(fe, type0, &std0);
  397. if (rc < 0) {
  398. tuner_info("Error %d while loading generic firmware\n",
  399. rc);
  400. return rc;
  401. }
  402. priv->need_load_generic = 0;
  403. priv->firm_type = 0;
  404. if (priv->mode == T_DIGITAL_TV)
  405. change_digital_bandwidth = 1;
  406. }
  407. tuner_info("I should change bandwidth %u\n", change_digital_bandwidth);
  408. if (change_digital_bandwidth) {
  409. /*FIXME: Should allow selecting between D2620 and D2633 */
  410. type |= D2620;
  411. /* FIXME: When should select a DTV78 firmware?
  412. */
  413. switch (bandwidth) {
  414. case BANDWIDTH_8_MHZ:
  415. type |= DTV8;
  416. break;
  417. case BANDWIDTH_7_MHZ:
  418. type |= DTV7;
  419. break;
  420. case BANDWIDTH_6_MHZ:
  421. /* FIXME: Should allow select also ATSC */
  422. type |= DTV6 | QAM;
  423. break;
  424. default:
  425. tuner_info("error: bandwidth not supported.\n");
  426. };
  427. priv->bandwidth = bandwidth;
  428. }
  429. /* Load INIT1, if needed */
  430. tuner_info("Trying to load init1 firmware\n");
  431. type0 = BASE | INIT1 | priv->ctrl.type;
  432. if (priv->ctrl.type == XC2028_FIRM_MTS)
  433. type0 |= MTS;
  434. /* FIXME: Should handle errors - if INIT1 found */
  435. rc = load_firmware(fe, type0, &std0);
  436. /* FIXME: Should add support for FM radio
  437. */
  438. if (priv->ctrl.type == XC2028_FIRM_MTS)
  439. type |= MTS;
  440. tuner_info("firmware standard to load: %08lx\n", (unsigned long)std);
  441. if (priv->firm_type & std) {
  442. tuner_info("no need to load a std-specific firmware.\n");
  443. return 0;
  444. }
  445. rc = load_firmware(fe, type, &std);
  446. if (rc < 0)
  447. return rc;
  448. /* Load SCODE firmware, if needed */
  449. tuner_info("Trying to load scode firmware\n");
  450. type0 = SCODE | priv->ctrl.type;
  451. if (priv->ctrl.type == XC2028_FIRM_MTS)
  452. type0 |= MTS;
  453. version = xc2028_get_reg(priv, 0x0004);
  454. hwmodel = xc2028_get_reg(priv, 0x0008);
  455. tuner_info("Device is Xceive %d version %d.%d, "
  456. "firmware version %d.%d\n",
  457. hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
  458. (version & 0xf0) >> 4, version & 0xf);
  459. priv->firm_type = std;
  460. return 0;
  461. }
  462. static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
  463. {
  464. struct xc2028_data *priv = fe->tuner_priv;
  465. int frq_lock, signal = 0;
  466. tuner_info("%s called\n", __FUNCTION__);
  467. mutex_lock(&priv->lock);
  468. *strength = 0;
  469. /* Sync Lock Indicator */
  470. frq_lock = xc2028_get_reg(priv, 0x0002);
  471. if (frq_lock <= 0)
  472. goto ret;
  473. /* Frequency is locked. Return signal quality */
  474. /* Get SNR of the video signal */
  475. signal = xc2028_get_reg(priv, 0x0040);
  476. if (signal <= 0)
  477. signal = frq_lock;
  478. ret:
  479. mutex_unlock(&priv->lock);
  480. *strength = signal;
  481. return 0;
  482. }
  483. #define DIV 15625
  484. static int generic_set_tv_freq(struct dvb_frontend *fe, u32 freq /* in Hz */ ,
  485. enum tuner_mode new_mode,
  486. v4l2_std_id std, fe_bandwidth_t bandwidth)
  487. {
  488. struct xc2028_data *priv = fe->tuner_priv;
  489. int rc = -EINVAL;
  490. unsigned char buf[5];
  491. u32 div, offset = 0;
  492. tuner_info("%s called\n", __FUNCTION__);
  493. mutex_lock(&priv->lock);
  494. /* HACK: It seems that specific firmware need to be reloaded
  495. when freq is changed */
  496. priv->firm_type = 0;
  497. /* Reset GPIO 1 */
  498. rc = priv->tuner_callback(priv->video_dev, XC2028_TUNER_RESET, 0);
  499. if (rc < 0)
  500. goto ret;
  501. msleep(10);
  502. tuner_info("should set frequency %d kHz)\n", freq / 1000);
  503. if (check_firmware(fe, new_mode, std, bandwidth) < 0)
  504. goto ret;
  505. if (new_mode == T_DIGITAL_TV)
  506. offset = 2750000;
  507. div = (freq - offset + DIV / 2) / DIV;
  508. /* CMD= Set frequency */
  509. if (priv->version < 0x0202) {
  510. send_seq(priv, {0x00, 0x02, 0x00, 0x00});
  511. } else {
  512. send_seq(priv, {0x80, 0x02, 0x00, 0x00});
  513. }
  514. rc = priv->tuner_callback(priv->video_dev, XC2028_RESET_CLK, 1);
  515. if (rc < 0)
  516. goto ret;
  517. msleep(10);
  518. buf[0] = 0xff & (div >> 24);
  519. buf[1] = 0xff & (div >> 16);
  520. buf[2] = 0xff & (div >> 8);
  521. buf[3] = 0xff & (div);
  522. buf[4] = 0;
  523. i2c_send(rc, priv, buf, sizeof(buf));
  524. if (rc < 0)
  525. goto ret;
  526. msleep(100);
  527. priv->frequency = freq;
  528. printk("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
  529. buf[1], buf[2], buf[3], buf[4],
  530. freq / 1000000, (freq % 1000000) / 10000);
  531. rc = 0;
  532. ret:
  533. mutex_unlock(&priv->lock);
  534. return rc;
  535. }
  536. static int xc2028_set_tv_freq(struct dvb_frontend *fe,
  537. struct analog_parameters *p)
  538. {
  539. struct xc2028_data *priv = fe->tuner_priv;
  540. tuner_info("%s called\n", __FUNCTION__);
  541. return generic_set_tv_freq(fe, 62500l * p->frequency, T_ANALOG_TV,
  542. p->std, BANDWIDTH_8_MHZ /* NOT USED */);
  543. }
  544. static int xc2028_set_params(struct dvb_frontend *fe,
  545. struct dvb_frontend_parameters *p)
  546. {
  547. struct xc2028_data *priv = fe->tuner_priv;
  548. tuner_info("%s called\n", __FUNCTION__);
  549. /* FIXME: Only OFDM implemented */
  550. if (fe->ops.info.type != FE_OFDM) {
  551. tuner_info("DTV type not implemented.\n");
  552. return -EINVAL;
  553. }
  554. return generic_set_tv_freq(fe, p->frequency, T_DIGITAL_TV,
  555. 0 /* NOT USED */,
  556. p->u.ofdm.bandwidth);
  557. }
  558. static int xc2028_dvb_release(struct dvb_frontend *fe)
  559. {
  560. struct xc2028_data *priv = fe->tuner_priv;
  561. tuner_info("%s called\n", __FUNCTION__);
  562. priv->count--;
  563. if (!priv->count) {
  564. list_del(&priv->xc2028_list);
  565. kfree(priv->ctrl.fname);
  566. free_firmware(priv);
  567. kfree(priv);
  568. }
  569. return 0;
  570. }
  571. static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
  572. {
  573. struct xc2028_data *priv = fe->tuner_priv;
  574. tuner_info("%s called\n", __FUNCTION__);
  575. *frequency = priv->frequency;
  576. return 0;
  577. }
  578. static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
  579. {
  580. struct xc2028_data *priv = fe->tuner_priv;
  581. struct xc2028_ctrl *p = priv_cfg;
  582. tuner_info("%s called\n", __FUNCTION__);
  583. priv->ctrl.type = p->type;
  584. if (p->fname) {
  585. kfree(priv->ctrl.fname);
  586. priv->ctrl.fname = kmalloc(strlen(p->fname) + 1, GFP_KERNEL);
  587. if (!priv->ctrl.fname)
  588. return -ENOMEM;
  589. free_firmware(priv);
  590. strcpy(priv->ctrl.fname, p->fname);
  591. }
  592. if (p->max_len > 0)
  593. priv->max_len = p->max_len;
  594. tuner_info("%s OK\n", __FUNCTION__);
  595. return 0;
  596. }
  597. static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
  598. .info = {
  599. .name = "Xceive XC3028",
  600. .frequency_min = 42000000,
  601. .frequency_max = 864000000,
  602. .frequency_step = 50000,
  603. },
  604. .set_config = xc2028_set_config,
  605. .set_analog_params = xc2028_set_tv_freq,
  606. .release = xc2028_dvb_release,
  607. .get_frequency = xc2028_get_frequency,
  608. .get_rf_strength = xc2028_signal,
  609. .set_params = xc2028_set_params,
  610. };
  611. int xc2028_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c_adap,
  612. u8 i2c_addr, struct device *dev, void *video_dev,
  613. int (*tuner_callback) (void *dev, int command, int arg))
  614. {
  615. struct xc2028_data *priv;
  616. printk(KERN_INFO PREFIX "Xcv2028/3028 init called!\n");
  617. if (NULL == dev)
  618. return -ENODEV;
  619. if (NULL == video_dev)
  620. return -ENODEV;
  621. if (!tuner_callback) {
  622. printk(KERN_ERR PREFIX "No tuner callback!\n");
  623. return -EINVAL;
  624. }
  625. list_for_each_entry(priv, &xc2028_list, xc2028_list) {
  626. if (priv->dev == dev)
  627. dev = NULL;
  628. }
  629. if (dev) {
  630. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  631. if (priv == NULL)
  632. return -ENOMEM;
  633. fe->tuner_priv = priv;
  634. priv->bandwidth = BANDWIDTH_6_MHZ;
  635. priv->need_load_generic = 1;
  636. priv->mode = T_UNINITIALIZED;
  637. priv->i2c_props.addr = i2c_addr;
  638. priv->i2c_props.adap = i2c_adap;
  639. priv->dev = dev;
  640. priv->video_dev = video_dev;
  641. priv->tuner_callback = tuner_callback;
  642. priv->max_len = 13;
  643. mutex_init(&priv->lock);
  644. list_add_tail(&priv->xc2028_list, &xc2028_list);
  645. }
  646. priv->count++;
  647. memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
  648. sizeof(xc2028_dvb_tuner_ops));
  649. tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
  650. return 0;
  651. }
  652. EXPORT_SYMBOL(xc2028_attach);
  653. MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
  654. MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
  655. MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
  656. MODULE_LICENSE("GPL");