tuner-xc2028.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522
  1. /* tuner-xc2028
  2. *
  3. * Copyright (c) 2007 Mauro Carvalho Chehab (mchehab@infradead.org)
  4. * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
  5. * - frontend interface
  6. * This code is placed under the terms of the GNU General Public License v2
  7. */
  8. #include <linux/i2c.h>
  9. #include <asm/div64.h>
  10. #include <linux/firmware.h>
  11. #include <linux/videodev.h>
  12. #include <linux/delay.h>
  13. #include <media/tuner.h>
  14. #include <linux/mutex.h>
  15. #include "tuner-driver.h"
  16. #include "tuner-xc2028.h"
  17. #include <linux/dvb/frontend.h>
  18. #include "dvb_frontend.h"
  19. /* digital TV standards */
  20. #define V4L2_STD_DTV_6MHZ ((v4l2_std_id)0x04000000)
  21. #define V4L2_STD_DTV_7MHZ ((v4l2_std_id)0x08000000)
  22. #define V4L2_STD_DTV_8MHZ ((v4l2_std_id)0x10000000)
  23. /* Firmwares used on tm5600/tm6000 + xc2028/xc3028 */
  24. /* Generic firmwares */
  25. static const char *firmware_INIT0 = "tm_xc3028_MTS_init0.fw";
  26. static const char *firmware_8MHZ_INIT0 = "tm_xc3028_8M_MTS_init0.fw";
  27. static const char *firmware_INIT1 = "tm_xc3028_68M_MTS_init1.fw";
  28. /* Standard-specific firmwares */
  29. static const char *firmware_6M = "tm_xc3028_DTV_6M.fw";
  30. static const char *firmware_7M = "tm_xc3028_DTV_7M.fw";
  31. static const char *firmware_8M = "tm_xc3028_DTV_8M.fw";
  32. static const char *firmware_B = "tm_xc3028_B_PAL.fw";
  33. static const char *firmware_DK = "tm_xc3028_DK_PAL_MTS.fw";
  34. static const char *firmware_MN = "tm_xc3028_MN_BTSC.fw";
  35. struct xc2028_data {
  36. v4l2_std_id firm_type; /* video stds supported
  37. by current firmware */
  38. fe_bandwidth_t bandwidth; /* Firmware bandwidth:
  39. 6M, 7M or 8M */
  40. int need_load_generic; /* The generic firmware
  41. were loaded? */
  42. enum tuner_mode mode;
  43. struct i2c_client *i2c_client;
  44. struct mutex lock;
  45. };
  46. #define i2c_send(rc,c,buf,size) \
  47. if (size != (rc = i2c_master_send(c, buf, size))) \
  48. tuner_warn("i2c output error: rc = %d (should be %d)\n", \
  49. rc, (int)size);
  50. #define i2c_rcv(rc,c,buf,size) \
  51. if (size != (rc = i2c_master_recv(c, buf, size))) \
  52. tuner_warn("i2c input error: rc = %d (should be %d)\n", \
  53. rc, (int)size);
  54. #define send_seq(c, data...) \
  55. { int rc; \
  56. const static u8 _val[] = data; \
  57. if (sizeof(_val) != \
  58. (rc = i2c_master_send \
  59. (c, _val, sizeof(_val)))) { \
  60. printk(KERN_ERR "Error on line %d: %d\n",__LINE__,rc); \
  61. return; \
  62. } \
  63. msleep (10); \
  64. }
  65. static int xc2028_get_reg(struct i2c_client *c, u16 reg)
  66. {
  67. int rc;
  68. unsigned char buf[1];
  69. struct tuner *t = i2c_get_clientdata(c);
  70. buf[0]= reg;
  71. i2c_send(rc, c, buf, sizeof(buf));
  72. if (rc<0)
  73. return rc;
  74. i2c_rcv(rc, c, buf, 2);
  75. if (rc<0)
  76. return rc;
  77. return (buf[1])|(buf[0]<<8);
  78. }
  79. static int load_firmware (struct i2c_client *c, const char *name)
  80. {
  81. const struct firmware *fw=NULL;
  82. struct tuner *t = i2c_get_clientdata(c);
  83. unsigned char *p, *endp;
  84. int len=0, rc=0;
  85. static const char firmware_ver[] = "tm6000/xcv v1";
  86. tuner_info("xc2028: Loading firmware %s\n", name);
  87. rc = request_firmware(&fw, name, &c->dev);
  88. if (rc < 0) {
  89. if (rc==-ENOENT)
  90. tuner_info("Error: firmware %s not found.\n", name);
  91. else
  92. tuner_info("Error %d while requesting firmware %s \n", rc, name);
  93. return rc;
  94. }
  95. p=fw->data;
  96. endp=p+fw->size;
  97. if(fw->size==0) {
  98. tuner_info("Error: firmware size is zero!\n");
  99. rc=-EINVAL;
  100. goto err;
  101. }
  102. if (fw->size<sizeof(firmware_ver)-1) {
  103. /* Firmware is incorrect */
  104. tuner_info("Error: firmware size is less than header (%d<%d)!\n",
  105. (int)fw->size,(int)sizeof(firmware_ver)-1);
  106. rc=-EINVAL;
  107. goto err;
  108. }
  109. if (memcmp(p,firmware_ver,sizeof(firmware_ver)-1)) {
  110. /* Firmware is incorrect */
  111. tuner_info("Error: firmware is not for tm5600/6000 + Xcv2028/3028!\n");
  112. rc=-EINVAL;
  113. goto err;
  114. }
  115. p+=sizeof(firmware_ver)-1;
  116. while(p<endp) {
  117. if ((*p) & 0x80) {
  118. /* Special callback command received */
  119. rc = t->tuner_callback(c->adapter->algo_data,
  120. XC2028_TUNER_RESET, (*p)&0x7f);
  121. if (rc<0) {
  122. tuner_info("Error at RESET code %d\n",
  123. (*p)&0x7f);
  124. goto err;
  125. }
  126. p++;
  127. continue;
  128. }
  129. len=*p;
  130. p++;
  131. if (p+len+1>endp) {
  132. /* Firmware is incorrect */
  133. tuner_info("Error: firmware is truncated!\n");
  134. rc=-EINVAL;
  135. goto err;
  136. }
  137. if (len<=0) {
  138. tuner_info("Error: firmware file is corrupted!\n");
  139. rc=-EINVAL;
  140. goto err;
  141. }
  142. i2c_send(rc, c, p, len);
  143. if (rc<0)
  144. goto err;
  145. p+=len;
  146. if (*p)
  147. msleep(*p);
  148. p++;
  149. }
  150. err:
  151. release_firmware(fw);
  152. return rc;
  153. }
  154. static int check_firmware(struct i2c_client *c, enum tuner_mode new_mode,
  155. fe_bandwidth_t bandwidth)
  156. {
  157. int rc, version;
  158. struct tuner *t = i2c_get_clientdata(c);
  159. struct xc2028_data *xc2028 = t->priv;
  160. const char *name;
  161. int change_digital_bandwidth;
  162. if (!t->tuner_callback) {
  163. printk(KERN_ERR "xc2028: need tuner_callback to load firmware\n");
  164. return -EINVAL;
  165. }
  166. printk(KERN_INFO "xc2028: I am in mode %u and I should switch to mode %i\n",
  167. xc2028->mode, new_mode);
  168. /* first of all, determine whether we have switched the mode */
  169. if(new_mode != xc2028->mode) {
  170. xc2028->mode = new_mode;
  171. xc2028->need_load_generic = 1;
  172. }
  173. change_digital_bandwidth = (xc2028->mode == T_DIGITAL_TV
  174. && bandwidth != xc2028->bandwidth) ? 1 : 0;
  175. tuner_info("xc2028: old bandwidth %u, new bandwidth %u\n", xc2028->bandwidth,
  176. bandwidth);
  177. if (xc2028->need_load_generic) {
  178. if (xc2028->bandwidth==8)
  179. name = firmware_8MHZ_INIT0;
  180. else
  181. name = firmware_INIT0;
  182. /* Reset is needed before loading firmware */
  183. rc = t->tuner_callback(c->adapter->algo_data,
  184. XC2028_TUNER_RESET, 0);
  185. if (rc<0)
  186. return rc;
  187. rc = load_firmware(c,name);
  188. if (rc<0)
  189. return rc;
  190. xc2028->need_load_generic=0;
  191. xc2028->firm_type=0;
  192. if(xc2028->mode == T_DIGITAL_TV) {
  193. change_digital_bandwidth=1;
  194. }
  195. }
  196. tuner_info("xc2028: I should change bandwidth %u\n",
  197. change_digital_bandwidth);
  198. if (change_digital_bandwidth) {
  199. switch(bandwidth) {
  200. case BANDWIDTH_8_MHZ:
  201. t->std = V4L2_STD_DTV_8MHZ;
  202. break;
  203. case BANDWIDTH_7_MHZ:
  204. t->std = V4L2_STD_DTV_7MHZ;
  205. break;
  206. case BANDWIDTH_6_MHZ:
  207. t->std = V4L2_STD_DTV_6MHZ;
  208. break;
  209. default:
  210. tuner_info("error: bandwidth not supported.\n");
  211. };
  212. xc2028->bandwidth = bandwidth;
  213. }
  214. if (xc2028->firm_type & t->std) {
  215. tuner_info("xc3028: no need to load a std-specific firmware.\n");
  216. return 0;
  217. }
  218. rc = load_firmware(c,firmware_INIT1);
  219. if (t->std & V4L2_STD_MN)
  220. name=firmware_MN;
  221. else if (t->std & V4L2_STD_DTV_6MHZ)
  222. name=firmware_6M;
  223. else if (t->std & V4L2_STD_DTV_7MHZ)
  224. name=firmware_7M;
  225. else if (t->std & V4L2_STD_DTV_8MHZ)
  226. name=firmware_8M;
  227. else if (t->std & V4L2_STD_PAL_B)
  228. name=firmware_B;
  229. else
  230. name=firmware_DK;
  231. tuner_info("xc2028: loading firmware named %s.\n", name);
  232. rc = load_firmware(c, name);
  233. if (rc<0)
  234. return rc;
  235. version = xc2028_get_reg(c, 0x4);
  236. tuner_info("Firmware version is %d.%d\n",
  237. (version>>4)&0x0f,(version)&0x0f);
  238. xc2028->firm_type=t->std;
  239. return 0;
  240. }
  241. static int xc2028_signal(struct i2c_client *c)
  242. {
  243. struct tuner *t = i2c_get_clientdata(c);
  244. struct xc2028_data *xc2028 = t->priv;
  245. int frq_lock, signal=0;
  246. mutex_lock(&xc2028->lock);
  247. printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
  248. frq_lock = xc2028_get_reg(c, 0x2);
  249. if (frq_lock<=0)
  250. goto ret;
  251. /* Frequency is locked. Return signal quality */
  252. signal = xc2028_get_reg(c, 0x40);
  253. if(signal<=0) {
  254. signal=frq_lock;
  255. }
  256. ret:
  257. mutex_unlock(&xc2028->lock);
  258. return signal;
  259. }
  260. #define DIV 15625
  261. static void generic_set_tv_freq(struct i2c_client *c, u32 freq /* in Hz */,
  262. enum tuner_mode new_mode, fe_bandwidth_t bandwidth)
  263. {
  264. int rc;
  265. unsigned char buf[5];
  266. struct tuner *t = i2c_get_clientdata(c);
  267. u32 div, offset = 0;
  268. /* HACK: It seems that specific firmware need to be reloaded
  269. when freq is changed */
  270. struct xc2028_data *xc2028 = t->priv;
  271. mutex_lock(&xc2028->lock);
  272. xc2028->firm_type=0;
  273. /* Reset GPIO 1 */
  274. if (t->tuner_callback) {
  275. rc = t->tuner_callback( c->adapter->algo_data,
  276. XC2028_TUNER_RESET, 0);
  277. if (rc<0)
  278. goto ret;
  279. }
  280. msleep(10);
  281. printk("xc3028: should set frequency %d kHz)\n", freq / 1000);
  282. if (check_firmware(c, new_mode, bandwidth)<0)
  283. goto ret;
  284. if(new_mode == T_DIGITAL_TV)
  285. offset = 2750000;
  286. div = (freq - offset + DIV/2)/DIV;
  287. /* CMD= Set frequency */
  288. send_seq(c, {0x00, 0x02, 0x00, 0x00});
  289. if (t->tuner_callback) {
  290. rc = t->tuner_callback( c->adapter->algo_data,
  291. XC2028_RESET_CLK, 1);
  292. if (rc<0)
  293. goto ret;
  294. }
  295. msleep(10);
  296. buf[0]= 0xff & (div>>24);
  297. buf[1]= 0xff & (div>>16);
  298. buf[2]= 0xff & (div>>8);
  299. buf[3]= 0xff & (div);
  300. buf[4]= 0;
  301. i2c_send(rc, c, buf, sizeof(buf));
  302. if (rc<0)
  303. goto ret;
  304. msleep(100);
  305. printk("divider= %02x %02x %02x %02x (freq=%d.%02d)\n",
  306. buf[1],buf[2],buf[3],buf[4],
  307. freq / 16, freq % 16 * 100 / 16);
  308. ret:
  309. mutex_unlock(&xc2028->lock);
  310. }
  311. static void set_tv_freq(struct i2c_client *c, unsigned int freq)
  312. {
  313. printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
  314. generic_set_tv_freq(c, freq * 62500l, T_ANALOG_TV,
  315. BANDWIDTH_8_MHZ /* unimportant */);
  316. }
  317. static void xc2028_release(struct i2c_client *c)
  318. {
  319. struct tuner *t = i2c_get_clientdata(c);
  320. kfree(t->priv);
  321. t->priv = NULL;
  322. }
  323. static struct tuner_operations tea5767_tuner_ops = {
  324. .set_tv_freq = set_tv_freq,
  325. .has_signal = xc2028_signal,
  326. .release = xc2028_release,
  327. // .is_stereo = xc2028_stereo,
  328. };
  329. static int init=0;
  330. int xc2028_tuner_init(struct i2c_client *c)
  331. {
  332. struct tuner *t = i2c_get_clientdata(c);
  333. int version = xc2028_get_reg(c, 0x4);
  334. int prd_id = xc2028_get_reg(c, 0x8);
  335. struct xc2028_data *xc2028;
  336. tuner_info("Xcv2028/3028 init called!\n");
  337. if (init) {
  338. printk (KERN_ERR "Module already initialized!\n");
  339. return 0;
  340. }
  341. init++;
  342. xc2028 = kzalloc(sizeof(*xc2028), GFP_KERNEL);
  343. if (!xc2028)
  344. return -ENOMEM;
  345. t->priv = xc2028;
  346. xc2028->bandwidth=BANDWIDTH_6_MHZ;
  347. xc2028->need_load_generic=1;
  348. xc2028->mode = T_UNINITIALIZED;
  349. mutex_init(&xc2028->lock);
  350. /* FIXME: Check where t->priv will be freed */
  351. if (version<0)
  352. version=0;
  353. if (prd_id<0)
  354. prd_id=0;
  355. strlcpy(c->name, "xc2028", sizeof(c->name));
  356. tuner_info("type set to %d (%s, hw ver=%d.%d, fw ver=%d.%d, id=0x%04x)\n",
  357. t->type, c->name,
  358. (version>>12)&0x0f,(version>>8)&0x0f,
  359. (version>>4)&0x0f,(version)&0x0f, prd_id);
  360. memcpy(&t->ops, &tea5767_tuner_ops, sizeof(struct tuner_operations));
  361. return 0;
  362. }
  363. static int xc3028_set_params(struct dvb_frontend *fe,
  364. struct dvb_frontend_parameters *p)
  365. {
  366. struct i2c_client *c = fe->tuner_priv;
  367. printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
  368. generic_set_tv_freq(c, p->frequency, T_DIGITAL_TV,
  369. p->u.ofdm.bandwidth);
  370. return 0;
  371. }
  372. static int xc3028_dvb_release(struct dvb_frontend *fe)
  373. {
  374. printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
  375. fe->tuner_priv = NULL;
  376. return 0;
  377. }
  378. static int xc3028_dvb_init(struct dvb_frontend *fe)
  379. {
  380. printk(KERN_INFO "xc2028: %s called\n", __FUNCTION__);
  381. return 0;
  382. }
  383. static const struct dvb_tuner_ops xc3028_dvb_tuner_ops = {
  384. .info = {
  385. .name = "Xceive XC3028",
  386. .frequency_min = 42000000,
  387. .frequency_max = 864000000,
  388. .frequency_step = 50000,
  389. },
  390. .release = xc3028_dvb_release,
  391. .init = xc3028_dvb_init,
  392. // int (*sleep)(struct dvb_frontend *fe);
  393. /** This is for simple PLLs - set all parameters in one go. */
  394. .set_params = xc3028_set_params,
  395. /** This is support for demods like the mt352 - fills out the supplied buffer with what to write. */
  396. // int (*calc_regs)(struct dvb_frontend *fe, struct dvb_frontend_parameters *p, u8 *buf, int buf_len);
  397. // int (*get_frequency)(struct dvb_frontend *fe, u32 *frequency);
  398. // int (*get_bandwidth)(struct dvb_frontend *fe, u32 *bandwidth);
  399. // int (*get_status)(struct dvb_frontend *fe, u32 *status);
  400. };
  401. int xc2028_attach(struct i2c_client *c, struct dvb_frontend *fe)
  402. {
  403. fe->tuner_priv = c;
  404. memcpy(&fe->ops.tuner_ops, &xc3028_dvb_tuner_ops, sizeof(fe->ops.tuner_ops));
  405. return 0;
  406. }
  407. EXPORT_SYMBOL(xc2028_attach);