mxl111sf.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. /*
  2. * Copyright (C) 2010 Michael Krufky (mkrufky@kernellabs.com)
  3. *
  4. * This program is free software; you can redistribute it and/or modify it
  5. * under the terms of the GNU General Public License as published by the Free
  6. * Software Foundation, version 2.
  7. *
  8. * see Documentation/dvb/README.dvb-usb for more information
  9. */
  10. #include <linux/vmalloc.h>
  11. #include <linux/i2c.h>
  12. #include "mxl111sf.h"
  13. #include "mxl111sf-reg.h"
  14. #include "mxl111sf-phy.h"
  15. #include "mxl111sf-i2c.h"
  16. #include "mxl111sf-gpio.h"
  17. #include "mxl111sf-demod.h"
  18. #include "mxl111sf-tuner.h"
  19. #include "lgdt3305.h"
  20. int dvb_usb_mxl111sf_debug;
  21. module_param_named(debug, dvb_usb_mxl111sf_debug, int, 0644);
  22. MODULE_PARM_DESC(debug, "set debugging level "
  23. "(1=info, 2=xfer, 4=i2c, 8=reg, 16=adv (or-able)).");
  24. int dvb_usb_mxl111sf_isoc;
  25. module_param_named(isoc, dvb_usb_mxl111sf_isoc, int, 0644);
  26. MODULE_PARM_DESC(isoc, "enable usb isoc xfer (0=bulk, 1=isoc).");
  27. #define ANT_PATH_AUTO 0
  28. #define ANT_PATH_EXTERNAL 1
  29. #define ANT_PATH_INTERNAL 2
  30. int dvb_usb_mxl111sf_rfswitch =
  31. #if 0
  32. ANT_PATH_AUTO;
  33. #else
  34. ANT_PATH_EXTERNAL;
  35. #endif
  36. module_param_named(rfswitch, dvb_usb_mxl111sf_rfswitch, int, 0644);
  37. MODULE_PARM_DESC(rfswitch, "force rf switch position (0=auto, 1=ext, 2=int).");
  38. DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
  39. #define deb_info(args...) dprintk(dvb_usb_mxl111sf_debug, 0x13, args)
  40. #define deb_reg(args...) dprintk(dvb_usb_mxl111sf_debug, 0x08, args)
  41. #define deb_adv(args...) dprintk(dvb_usb_mxl111sf_debug, MXL_ADV_DBG, args)
  42. int mxl111sf_ctrl_msg(struct dvb_usb_device *d,
  43. u8 cmd, u8 *wbuf, int wlen, u8 *rbuf, int rlen)
  44. {
  45. int wo = (rbuf == NULL || rlen == 0); /* write-only */
  46. int ret;
  47. u8 sndbuf[1+wlen];
  48. deb_adv("%s(wlen = %d, rlen = %d)\n", __func__, wlen, rlen);
  49. memset(sndbuf, 0, 1+wlen);
  50. sndbuf[0] = cmd;
  51. memcpy(&sndbuf[1], wbuf, wlen);
  52. ret = (wo) ? dvb_usb_generic_write(d, sndbuf, 1+wlen) :
  53. dvb_usb_generic_rw(d, sndbuf, 1+wlen, rbuf, rlen, 0);
  54. mxl_fail(ret);
  55. return ret;
  56. }
  57. /* ------------------------------------------------------------------------ */
  58. #define MXL_CMD_REG_READ 0xaa
  59. #define MXL_CMD_REG_WRITE 0x55
  60. int mxl111sf_read_reg(struct mxl111sf_state *state, u8 addr, u8 *data)
  61. {
  62. u8 buf[2];
  63. int ret;
  64. ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_READ, &addr, 1, buf, 2);
  65. if (mxl_fail(ret)) {
  66. mxl_debug("error reading reg: 0x%02x", addr);
  67. goto fail;
  68. }
  69. if (buf[0] == addr)
  70. *data = buf[1];
  71. else {
  72. err("invalid response reading reg: 0x%02x != 0x%02x, 0x%02x",
  73. addr, buf[0], buf[1]);
  74. ret = -EINVAL;
  75. }
  76. deb_reg("R: (0x%02x, 0x%02x)\n", addr, *data);
  77. fail:
  78. return ret;
  79. }
  80. int mxl111sf_write_reg(struct mxl111sf_state *state, u8 addr, u8 data)
  81. {
  82. u8 buf[] = { addr, data };
  83. int ret;
  84. deb_reg("W: (0x%02x, 0x%02x)\n", addr, data);
  85. ret = mxl111sf_ctrl_msg(state->d, MXL_CMD_REG_WRITE, buf, 2, NULL, 0);
  86. if (mxl_fail(ret))
  87. err("error writing reg: 0x%02x, val: 0x%02x", addr, data);
  88. return ret;
  89. }
  90. /* ------------------------------------------------------------------------ */
  91. int mxl111sf_write_reg_mask(struct mxl111sf_state *state,
  92. u8 addr, u8 mask, u8 data)
  93. {
  94. int ret;
  95. u8 val;
  96. if (mask != 0xff) {
  97. ret = mxl111sf_read_reg(state, addr, &val);
  98. #if 1
  99. /* dont know why this usually errors out on the first try */
  100. if (mxl_fail(ret))
  101. err("error writing addr: 0x%02x, mask: 0x%02x, "
  102. "data: 0x%02x, retrying...", addr, mask, data);
  103. ret = mxl111sf_read_reg(state, addr, &val);
  104. #endif
  105. if (mxl_fail(ret))
  106. goto fail;
  107. }
  108. val &= ~mask;
  109. val |= data;
  110. ret = mxl111sf_write_reg(state, addr, val);
  111. mxl_fail(ret);
  112. fail:
  113. return ret;
  114. }
  115. /* ------------------------------------------------------------------------ */
  116. int mxl111sf_ctrl_program_regs(struct mxl111sf_state *state,
  117. struct mxl111sf_reg_ctrl_info *ctrl_reg_info)
  118. {
  119. int i, ret = 0;
  120. for (i = 0; ctrl_reg_info[i].addr |
  121. ctrl_reg_info[i].mask |
  122. ctrl_reg_info[i].data; i++) {
  123. ret = mxl111sf_write_reg_mask(state,
  124. ctrl_reg_info[i].addr,
  125. ctrl_reg_info[i].mask,
  126. ctrl_reg_info[i].data);
  127. if (mxl_fail(ret)) {
  128. err("failed on reg #%d (0x%02x)", i,
  129. ctrl_reg_info[i].addr);
  130. break;
  131. }
  132. }
  133. return ret;
  134. }
  135. /* ------------------------------------------------------------------------ */
  136. static int mxl1x1sf_get_chip_info(struct mxl111sf_state *state)
  137. {
  138. int ret;
  139. u8 id, ver;
  140. char *mxl_chip, *mxl_rev;
  141. if ((state->chip_id) && (state->chip_ver))
  142. return 0;
  143. ret = mxl111sf_read_reg(state, CHIP_ID_REG, &id);
  144. if (mxl_fail(ret))
  145. goto fail;
  146. state->chip_id = id;
  147. ret = mxl111sf_read_reg(state, TOP_CHIP_REV_ID_REG, &ver);
  148. if (mxl_fail(ret))
  149. goto fail;
  150. state->chip_ver = ver;
  151. switch (id) {
  152. case 0x61:
  153. mxl_chip = "MxL101SF";
  154. break;
  155. case 0x63:
  156. mxl_chip = "MxL111SF";
  157. break;
  158. default:
  159. mxl_chip = "UNKNOWN MxL1X1";
  160. break;
  161. }
  162. switch (ver) {
  163. case 0x36:
  164. state->chip_rev = MXL111SF_V6;
  165. mxl_rev = "v6";
  166. break;
  167. case 0x08:
  168. state->chip_rev = MXL111SF_V8_100;
  169. mxl_rev = "v8_100";
  170. break;
  171. case 0x18:
  172. state->chip_rev = MXL111SF_V8_200;
  173. mxl_rev = "v8_200";
  174. break;
  175. default:
  176. state->chip_rev = 0;
  177. mxl_rev = "UNKNOWN REVISION";
  178. break;
  179. }
  180. info("%s detected, %s (0x%x)", mxl_chip, mxl_rev, ver);
  181. fail:
  182. return ret;
  183. }
  184. #define get_chip_info(state) \
  185. ({ \
  186. int ___ret; \
  187. ___ret = mxl1x1sf_get_chip_info(state); \
  188. if (mxl_fail(___ret)) { \
  189. mxl_debug("failed to get chip info" \
  190. " on first probe attempt"); \
  191. ___ret = mxl1x1sf_get_chip_info(state); \
  192. if (mxl_fail(___ret)) \
  193. err("failed to get chip info during probe"); \
  194. else \
  195. mxl_debug("probe needed a retry " \
  196. "in order to succeed."); \
  197. } \
  198. ___ret; \
  199. })
  200. /* ------------------------------------------------------------------------ */
  201. static int mxl111sf_power_ctrl(struct dvb_usb_device *d, int onoff)
  202. {
  203. /* power control depends on which adapter is being woken:
  204. * save this for init, instead, via mxl111sf_adap_fe_init */
  205. return 0;
  206. }
  207. static int mxl111sf_adap_fe_init(struct dvb_frontend *fe)
  208. {
  209. struct dvb_usb_adapter *adap = fe->dvb->priv;
  210. struct dvb_usb_device *d = adap->dev;
  211. struct mxl111sf_state *state = d->priv;
  212. struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
  213. int err;
  214. /* exit if we didnt initialize the driver yet */
  215. if (!state->chip_id) {
  216. mxl_debug("driver not yet initialized, exit.");
  217. goto fail;
  218. }
  219. deb_info("%s()\n", __func__);
  220. mutex_lock(&state->fe_lock);
  221. state->alt_mode = adap_state->alt_mode;
  222. if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
  223. err("set interface failed");
  224. err = mxl1x1sf_soft_reset(state);
  225. mxl_fail(err);
  226. err = mxl111sf_init_tuner_demod(state);
  227. mxl_fail(err);
  228. err = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
  229. mxl_fail(err);
  230. mxl111sf_enable_usb_output(state);
  231. mxl_fail(err);
  232. mxl1x1sf_top_master_ctrl(state, 1);
  233. mxl_fail(err);
  234. if ((MXL111SF_GPIO_MOD_DVBT != adap_state->gpio_mode) &&
  235. (state->chip_rev > MXL111SF_V6)) {
  236. mxl111sf_config_pin_mux_modes(state,
  237. PIN_MUX_TS_SPI_IN_MODE_1);
  238. mxl_fail(err);
  239. }
  240. err = mxl111sf_init_port_expander(state);
  241. if (!mxl_fail(err)) {
  242. state->gpio_mode = adap_state->gpio_mode;
  243. err = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
  244. mxl_fail(err);
  245. #if 0
  246. err = fe->ops.init(fe);
  247. #endif
  248. msleep(100); /* add short delay after enabling
  249. * the demod before touching it */
  250. }
  251. return (adap_state->fe_init) ? adap_state->fe_init(fe) : 0;
  252. fail:
  253. return -ENODEV;
  254. }
  255. static int mxl111sf_adap_fe_sleep(struct dvb_frontend *fe)
  256. {
  257. struct dvb_usb_adapter *adap = fe->dvb->priv;
  258. struct dvb_usb_device *d = adap->dev;
  259. struct mxl111sf_state *state = d->priv;
  260. struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe->id].priv;
  261. int err;
  262. /* exit if we didnt initialize the driver yet */
  263. if (!state->chip_id) {
  264. mxl_debug("driver not yet initialized, exit.");
  265. goto fail;
  266. }
  267. deb_info("%s()\n", __func__);
  268. err = (adap_state->fe_sleep) ? adap_state->fe_sleep(fe) : 0;
  269. mutex_unlock(&state->fe_lock);
  270. return err;
  271. fail:
  272. return -ENODEV;
  273. }
  274. static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
  275. {
  276. struct dvb_usb_device *d = adap->dev;
  277. struct mxl111sf_state *state = d->priv;
  278. struct mxl111sf_adap_state *adap_state = adap->fe_adap[adap->active_fe].priv;
  279. int ret = 0;
  280. u8 tmp;
  281. deb_info("%s(%d)\n", __func__, onoff);
  282. if (onoff) {
  283. ret = mxl111sf_enable_usb_output(state);
  284. mxl_fail(ret);
  285. ret = mxl111sf_config_mpeg_in(state, 1, 1,
  286. adap_state->ep6_clockphase,
  287. 0, 0);
  288. mxl_fail(ret);
  289. } else {
  290. ret = mxl111sf_disable_656_port(state);
  291. mxl_fail(ret);
  292. }
  293. mxl111sf_read_reg(state, 0x12, &tmp);
  294. tmp &= ~0x04;
  295. mxl111sf_write_reg(state, 0x12, tmp);
  296. return ret;
  297. }
  298. static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
  299. {
  300. struct dvb_usb_device *d = adap->dev;
  301. struct mxl111sf_state *state = d->priv;
  302. int ret = 0;
  303. deb_info("%s(%d)\n", __func__, onoff);
  304. if (onoff) {
  305. ret = mxl111sf_enable_usb_output(state);
  306. mxl_fail(ret);
  307. }
  308. return ret;
  309. }
  310. /* ------------------------------------------------------------------------ */
  311. static struct lgdt3305_config hauppauge_lgdt3305_config = {
  312. .i2c_addr = 0xb2 >> 1,
  313. .mpeg_mode = LGDT3305_MPEG_SERIAL,
  314. .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
  315. .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
  316. .deny_i2c_rptr = 1,
  317. .spectral_inversion = 0,
  318. .qam_if_khz = 6000,
  319. .vsb_if_khz = 6000,
  320. };
  321. static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
  322. {
  323. struct dvb_usb_device *d = adap->dev;
  324. struct mxl111sf_state *state = d->priv;
  325. int fe_id = adap->num_frontends_initialized;
  326. struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
  327. int ret;
  328. deb_adv("%s()\n", __func__);
  329. /* save a pointer to the dvb_usb_device in device state */
  330. state->d = d;
  331. adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
  332. state->alt_mode = adap_state->alt_mode;
  333. if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
  334. err("set interface failed");
  335. state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
  336. adap_state->gpio_mode = state->gpio_mode;
  337. adap_state->device_mode = MXL_TUNER_MODE;
  338. adap_state->ep6_clockphase = 1;
  339. ret = mxl1x1sf_soft_reset(state);
  340. if (mxl_fail(ret))
  341. goto fail;
  342. ret = mxl111sf_init_tuner_demod(state);
  343. if (mxl_fail(ret))
  344. goto fail;
  345. ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
  346. if (mxl_fail(ret))
  347. goto fail;
  348. ret = mxl111sf_enable_usb_output(state);
  349. if (mxl_fail(ret))
  350. goto fail;
  351. ret = mxl1x1sf_top_master_ctrl(state, 1);
  352. if (mxl_fail(ret))
  353. goto fail;
  354. ret = mxl111sf_init_port_expander(state);
  355. if (mxl_fail(ret))
  356. goto fail;
  357. ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
  358. if (mxl_fail(ret))
  359. goto fail;
  360. adap->fe_adap[fe_id].fe = dvb_attach(lgdt3305_attach,
  361. &hauppauge_lgdt3305_config,
  362. &adap->dev->i2c_adap);
  363. if (adap->fe_adap[fe_id].fe) {
  364. adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
  365. adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
  366. adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
  367. adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
  368. return 0;
  369. }
  370. ret = -EIO;
  371. fail:
  372. return ret;
  373. }
  374. static struct mxl111sf_demod_config mxl_demod_config = {
  375. .read_reg = mxl111sf_read_reg,
  376. .write_reg = mxl111sf_write_reg,
  377. .program_regs = mxl111sf_ctrl_program_regs,
  378. };
  379. static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
  380. {
  381. struct dvb_usb_device *d = adap->dev;
  382. struct mxl111sf_state *state = d->priv;
  383. int fe_id = adap->num_frontends_initialized;
  384. struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
  385. int ret;
  386. deb_adv("%s()\n", __func__);
  387. /* save a pointer to the dvb_usb_device in device state */
  388. state->d = d;
  389. adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
  390. state->alt_mode = adap_state->alt_mode;
  391. if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
  392. err("set interface failed");
  393. state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
  394. adap_state->gpio_mode = state->gpio_mode;
  395. adap_state->device_mode = MXL_SOC_MODE;
  396. adap_state->ep6_clockphase = 1;
  397. ret = mxl1x1sf_soft_reset(state);
  398. if (mxl_fail(ret))
  399. goto fail;
  400. ret = mxl111sf_init_tuner_demod(state);
  401. if (mxl_fail(ret))
  402. goto fail;
  403. ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
  404. if (mxl_fail(ret))
  405. goto fail;
  406. ret = mxl111sf_enable_usb_output(state);
  407. if (mxl_fail(ret))
  408. goto fail;
  409. ret = mxl1x1sf_top_master_ctrl(state, 1);
  410. if (mxl_fail(ret))
  411. goto fail;
  412. /* dont care if this fails */
  413. mxl111sf_init_port_expander(state);
  414. adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
  415. &mxl_demod_config);
  416. if (adap->fe_adap[fe_id].fe) {
  417. adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
  418. adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
  419. adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
  420. adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
  421. return 0;
  422. }
  423. ret = -EIO;
  424. fail:
  425. return ret;
  426. }
  427. static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
  428. int antpath)
  429. {
  430. return mxl111sf_idac_config(state, 1, 1,
  431. (antpath == ANT_PATH_INTERNAL) ?
  432. 0x3f : 0x00, 0);
  433. }
  434. #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
  435. err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
  436. __func__, __LINE__, \
  437. (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
  438. pwr0, pwr1, pwr2, pwr3)
  439. #define ANT_HUNT_SLEEP 90
  440. #define ANT_EXT_TWEAK 0
  441. static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
  442. {
  443. struct dvb_usb_adapter *adap = fe->dvb->priv;
  444. struct dvb_usb_device *d = adap->dev;
  445. struct mxl111sf_state *state = d->priv;
  446. int antctrl = dvb_usb_mxl111sf_rfswitch;
  447. u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
  448. /* FIXME: must force EXTERNAL for QAM - done elsewhere */
  449. mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
  450. ANT_PATH_EXTERNAL : antctrl);
  451. if (antctrl == ANT_PATH_AUTO) {
  452. #if 0
  453. msleep(ANT_HUNT_SLEEP);
  454. #endif
  455. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
  456. mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
  457. msleep(ANT_HUNT_SLEEP);
  458. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
  459. mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
  460. msleep(ANT_HUNT_SLEEP);
  461. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
  462. mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
  463. msleep(ANT_HUNT_SLEEP);
  464. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
  465. if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
  466. /* return with EXTERNAL enabled */
  467. mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
  468. DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
  469. rxPwr0, rxPwr1, rxPwr2);
  470. } else {
  471. /* return with INTERNAL enabled */
  472. DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
  473. rxPwr0, rxPwr1, rxPwr2);
  474. }
  475. }
  476. return 0;
  477. }
  478. static struct mxl111sf_tuner_config mxl_tuner_config = {
  479. .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
  480. .invert_spectrum = 0,
  481. .read_reg = mxl111sf_read_reg,
  482. .write_reg = mxl111sf_write_reg,
  483. .program_regs = mxl111sf_ctrl_program_regs,
  484. .top_master_ctrl = mxl1x1sf_top_master_ctrl,
  485. .ant_hunt = mxl111sf_ant_hunt,
  486. };
  487. static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
  488. {
  489. struct dvb_usb_device *d = adap->dev;
  490. struct mxl111sf_state *state = d->priv;
  491. int fe_id = adap->num_frontends_initialized;
  492. deb_adv("%s()\n", __func__);
  493. if (NULL != dvb_attach(mxl111sf_tuner_attach,
  494. adap->fe_adap[fe_id].fe, state,
  495. &mxl_tuner_config))
  496. return 0;
  497. return -EIO;
  498. }
  499. static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
  500. unsigned int cmd, void *parg,
  501. unsigned int stage)
  502. {
  503. int err = 0;
  504. switch (stage) {
  505. case DVB_FE_IOCTL_PRE:
  506. switch (cmd) {
  507. case FE_READ_SIGNAL_STRENGTH:
  508. err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
  509. /* If no error occurs, prevent dvb-core from handling
  510. * this IOCTL, otherwise return the error */
  511. if (0 == err)
  512. err = 1;
  513. break;
  514. }
  515. break;
  516. case DVB_FE_IOCTL_POST:
  517. /* no post-ioctl handling required */
  518. break;
  519. }
  520. return err;
  521. };
  522. static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
  523. {
  524. return I2C_FUNC_I2C;
  525. }
  526. struct i2c_algorithm mxl111sf_i2c_algo = {
  527. .master_xfer = mxl111sf_i2c_xfer,
  528. .functionality = mxl111sf_i2c_func,
  529. #ifdef NEED_ALGO_CONTROL
  530. .algo_control = dummy_algo_control,
  531. #endif
  532. };
  533. static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
  534. static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
  535. static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
  536. static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
  537. static int mxl111sf_probe(struct usb_interface *intf,
  538. const struct usb_device_id *id)
  539. {
  540. struct dvb_usb_device *d = NULL;
  541. deb_adv("%s()\n", __func__);
  542. if (((dvb_usb_mxl111sf_isoc) &&
  543. (0 == dvb_usb_device_init(intf,
  544. &mxl111sf_dvbt_isoc_properties,
  545. THIS_MODULE, &d, adapter_nr) ||
  546. 0 == dvb_usb_device_init(intf,
  547. &mxl111sf_atsc_isoc_properties,
  548. THIS_MODULE, &d, adapter_nr))) ||
  549. 0 == dvb_usb_device_init(intf,
  550. &mxl111sf_dvbt_bulk_properties,
  551. THIS_MODULE, &d, adapter_nr) ||
  552. 0 == dvb_usb_device_init(intf,
  553. &mxl111sf_atsc_bulk_properties,
  554. THIS_MODULE, &d, adapter_nr) || 0) {
  555. struct mxl111sf_state *state = d->priv;
  556. static u8 eeprom[256];
  557. struct i2c_client c;
  558. int ret;
  559. ret = get_chip_info(state);
  560. if (mxl_fail(ret))
  561. err("failed to get chip info during probe");
  562. mutex_init(&state->fe_lock);
  563. if (state->chip_rev > MXL111SF_V6)
  564. mxl111sf_config_pin_mux_modes(state,
  565. PIN_MUX_TS_SPI_IN_MODE_1);
  566. c.adapter = &d->i2c_adap;
  567. c.addr = 0xa0 >> 1;
  568. ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
  569. if (mxl_fail(ret))
  570. return 0;
  571. tveeprom_hauppauge_analog(&c, &state->tv,
  572. (0x84 == eeprom[0xa0]) ?
  573. eeprom + 0xa0 : eeprom + 0x80);
  574. #if 0
  575. switch (state->tv.model) {
  576. case 117001:
  577. case 126001:
  578. case 138001:
  579. break;
  580. default:
  581. printk(KERN_WARNING "%s: warning: "
  582. "unknown hauppauge model #%d\n",
  583. __func__, state->tv.model);
  584. }
  585. #endif
  586. return 0;
  587. }
  588. err("Your device is not yet supported by this driver. "
  589. "See kernellabs.com for more info");
  590. return -EINVAL;
  591. }
  592. static struct usb_device_id mxl111sf_table[] = {
  593. /* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600) }, /* ATSC+ IR */
  594. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601) }, /* ATSC */
  595. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602) }, /* + */
  596. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603) }, /* ATSC+ */
  597. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604) }, /* DVBT */
  598. /* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609) }, /* ATSC IR */
  599. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a) }, /* + IR */
  600. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b) }, /* ATSC+ IR */
  601. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c) }, /* DVBT IR */
  602. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653) }, /* ATSC+ */
  603. /*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b) }, /* ATSC+ IR */
  604. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700) }, /* ATSC+ sw */
  605. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701) }, /* ATSC sw */
  606. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702) }, /* + sw */
  607. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703) }, /* ATSC+ sw */
  608. /*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704) }, /* DVBT sw */
  609. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753) }, /* ATSC+ sw */
  610. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763) }, /* ATSC+ no */
  611. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764) }, /* DVBT no */
  612. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853) }, /* ATSC+ sw */
  613. /*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854) }, /* DVBT sw */
  614. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863) }, /* ATSC+ no */
  615. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864) }, /* DVBT no */
  616. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3) }, /* ATSC+ sw */
  617. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4) }, /* DVBT sw */
  618. /*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3) }, /* ATSC+ no */
  619. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4) }, /* DVBT no */
  620. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff) }, /* ATSC+ */
  621. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612) }, /* + */
  622. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613) }, /* ATSC+ */
  623. /*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a) }, /* + IR */
  624. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b) }, /* ATSC+ IR */
  625. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757) }, /* ATSC+DVBT sw */
  626. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767) }, /* ATSC+DVBT no */
  627. {} /* Terminating entry */
  628. };
  629. MODULE_DEVICE_TABLE(usb, mxl111sf_table);
  630. #define MXL111SF_EP4_BULK_STREAMING_CONFIG \
  631. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  632. .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
  633. .stream = { \
  634. .type = USB_BULK, \
  635. .count = 5, \
  636. .endpoint = 0x04, \
  637. .u = { \
  638. .bulk = { \
  639. .buffersize = 8192, \
  640. } \
  641. } \
  642. }
  643. /* FIXME: works for v6 but not v8 silicon */
  644. #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
  645. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  646. .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
  647. .stream = { \
  648. .type = USB_ISOC, \
  649. .count = 5, \
  650. .endpoint = 0x04, \
  651. .u = { \
  652. .isoc = { \
  653. .framesperurb = 96, \
  654. /* FIXME: v6 SILICON: */ \
  655. .framesize = 564, \
  656. .interval = 1, \
  657. } \
  658. } \
  659. }
  660. #define MXL111SF_EP6_BULK_STREAMING_CONFIG \
  661. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  662. .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
  663. .stream = { \
  664. .type = USB_BULK, \
  665. .count = 5, \
  666. .endpoint = 0x06, \
  667. .u = { \
  668. .bulk = { \
  669. .buffersize = 8192, \
  670. } \
  671. } \
  672. }
  673. /* FIXME */
  674. #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
  675. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  676. .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
  677. .stream = { \
  678. .type = USB_ISOC, \
  679. .count = 5, \
  680. .endpoint = 0x06, \
  681. .u = { \
  682. .isoc = { \
  683. .framesperurb = 24, \
  684. .framesize = 3072, \
  685. .interval = 1, \
  686. } \
  687. } \
  688. }
  689. #define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
  690. .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
  691. .usb_ctrl = DEVICE_SPECIFIC, \
  692. /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
  693. EP6 BULK transfer (atsc/qam), \
  694. use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
  695. EP6 ISOC transfer (atsc/qam), \
  696. */ \
  697. .power_ctrl = mxl111sf_power_ctrl, \
  698. .i2c_algo = &mxl111sf_i2c_algo, \
  699. .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
  700. .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
  701. .size_of_priv = sizeof(struct mxl111sf_state)
  702. static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
  703. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  704. .num_adapters = 1,
  705. .adapter = {
  706. {
  707. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  708. .num_frontends = 1,
  709. .fe = {{
  710. .frontend_attach = mxl111sf_attach_demod,
  711. .tuner_attach = mxl111sf_attach_tuner,
  712. MXL111SF_EP4_BULK_STREAMING_CONFIG,
  713. } },
  714. },
  715. },
  716. .num_device_descs = 4,
  717. .devices = {
  718. { "Hauppauge 126xxx DVBT (bulk)",
  719. { NULL },
  720. { &mxl111sf_table[4], &mxl111sf_table[8],
  721. NULL },
  722. },
  723. { "Hauppauge 117xxx DVBT (bulk)",
  724. { NULL },
  725. { &mxl111sf_table[15], &mxl111sf_table[18],
  726. NULL },
  727. },
  728. { "Hauppauge 138xxx DVBT (bulk)",
  729. { NULL },
  730. { &mxl111sf_table[20], &mxl111sf_table[22],
  731. &mxl111sf_table[24], &mxl111sf_table[26],
  732. NULL },
  733. },
  734. { "Hauppauge 126xxx (tp-bulk)",
  735. { NULL },
  736. { &mxl111sf_table[28], &mxl111sf_table[30],
  737. NULL },
  738. },
  739. }
  740. };
  741. static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
  742. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  743. .num_adapters = 1,
  744. .adapter = {
  745. {
  746. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  747. .num_frontends = 1,
  748. .fe = {{
  749. .frontend_attach = mxl111sf_attach_demod,
  750. .tuner_attach = mxl111sf_attach_tuner,
  751. MXL111SF_EP4_ISOC_STREAMING_CONFIG,
  752. } },
  753. },
  754. },
  755. .num_device_descs = 4,
  756. .devices = {
  757. { "Hauppauge 126xxx DVBT (isoc)",
  758. { NULL },
  759. { &mxl111sf_table[4], &mxl111sf_table[8],
  760. NULL },
  761. },
  762. { "Hauppauge 117xxx DVBT (isoc)",
  763. { NULL },
  764. { &mxl111sf_table[15], &mxl111sf_table[18],
  765. NULL },
  766. },
  767. { "Hauppauge 138xxx DVBT (isoc)",
  768. { NULL },
  769. { &mxl111sf_table[20], &mxl111sf_table[22],
  770. &mxl111sf_table[24], &mxl111sf_table[26],
  771. NULL },
  772. },
  773. { "Hauppauge 126xxx (tp-isoc)",
  774. { NULL },
  775. { &mxl111sf_table[28], &mxl111sf_table[30],
  776. NULL },
  777. },
  778. }
  779. };
  780. static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
  781. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  782. .num_adapters = 1,
  783. .adapter = {
  784. {
  785. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  786. .num_frontends = 2,
  787. .fe = {{
  788. .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
  789. .tuner_attach = mxl111sf_attach_tuner,
  790. MXL111SF_EP6_BULK_STREAMING_CONFIG,
  791. },
  792. {
  793. .frontend_attach = mxl111sf_attach_demod,
  794. .tuner_attach = mxl111sf_attach_tuner,
  795. MXL111SF_EP4_BULK_STREAMING_CONFIG,
  796. }},
  797. },
  798. },
  799. .num_device_descs = 6,
  800. .devices = {
  801. { "Hauppauge 126xxx ATSC (bulk)",
  802. { NULL },
  803. { &mxl111sf_table[1], &mxl111sf_table[5],
  804. NULL },
  805. },
  806. { "Hauppauge 117xxx ATSC (bulk)",
  807. { NULL },
  808. { &mxl111sf_table[12],
  809. NULL },
  810. },
  811. { "Hauppauge 126xxx ATSC+ (bulk)",
  812. { NULL },
  813. { &mxl111sf_table[0], &mxl111sf_table[3],
  814. &mxl111sf_table[7], &mxl111sf_table[9],
  815. &mxl111sf_table[10], NULL },
  816. },
  817. { "Hauppauge 117xxx ATSC+ (bulk)",
  818. { NULL },
  819. { &mxl111sf_table[11], &mxl111sf_table[14],
  820. &mxl111sf_table[16], &mxl111sf_table[17],
  821. &mxl111sf_table[32], &mxl111sf_table[33],
  822. NULL },
  823. },
  824. { "Hauppauge Mercury (tp-bulk)",
  825. { NULL },
  826. { &mxl111sf_table[19], &mxl111sf_table[21],
  827. &mxl111sf_table[23], &mxl111sf_table[25],
  828. &mxl111sf_table[27], NULL },
  829. },
  830. { "Hauppauge WinTV-Aero-M",
  831. { NULL },
  832. { &mxl111sf_table[29], &mxl111sf_table[31],
  833. NULL },
  834. },
  835. }
  836. };
  837. static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
  838. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  839. .num_adapters = 1,
  840. .adapter = {
  841. {
  842. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  843. .num_frontends = 2,
  844. .fe = {{
  845. .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
  846. .tuner_attach = mxl111sf_attach_tuner,
  847. MXL111SF_EP6_ISOC_STREAMING_CONFIG,
  848. },
  849. {
  850. .frontend_attach = mxl111sf_attach_demod,
  851. .tuner_attach = mxl111sf_attach_tuner,
  852. MXL111SF_EP4_ISOC_STREAMING_CONFIG,
  853. }},
  854. },
  855. },
  856. .num_device_descs = 6,
  857. .devices = {
  858. { "Hauppauge 126xxx ATSC (isoc)",
  859. { NULL },
  860. { &mxl111sf_table[1], &mxl111sf_table[5],
  861. NULL },
  862. },
  863. { "Hauppauge 117xxx ATSC (isoc)",
  864. { NULL },
  865. { &mxl111sf_table[12],
  866. NULL },
  867. },
  868. { "Hauppauge 126xxx ATSC+ (isoc)",
  869. { NULL },
  870. { &mxl111sf_table[0], &mxl111sf_table[3],
  871. &mxl111sf_table[7], &mxl111sf_table[9],
  872. &mxl111sf_table[10], NULL },
  873. },
  874. { "Hauppauge 117xxx ATSC+ (isoc)",
  875. { NULL },
  876. { &mxl111sf_table[11], &mxl111sf_table[14],
  877. &mxl111sf_table[16], &mxl111sf_table[17],
  878. &mxl111sf_table[32], &mxl111sf_table[33],
  879. NULL },
  880. },
  881. { "Hauppauge Mercury (tp-isoc)",
  882. { NULL },
  883. { &mxl111sf_table[19], &mxl111sf_table[21],
  884. &mxl111sf_table[23], &mxl111sf_table[25],
  885. &mxl111sf_table[27], NULL },
  886. },
  887. { "Hauppauge WinTV-Aero-M (tp-isoc)",
  888. { NULL },
  889. { &mxl111sf_table[29], &mxl111sf_table[31],
  890. NULL },
  891. },
  892. }
  893. };
  894. static struct usb_driver mxl111sf_driver = {
  895. .name = "dvb_usb_mxl111sf",
  896. .probe = mxl111sf_probe,
  897. .disconnect = dvb_usb_device_exit,
  898. .id_table = mxl111sf_table,
  899. };
  900. static int __init mxl111sf_module_init(void)
  901. {
  902. int result = usb_register(&mxl111sf_driver);
  903. if (result) {
  904. err("usb_register failed. Error number %d", result);
  905. return result;
  906. }
  907. return 0;
  908. }
  909. static void __exit mxl111sf_module_exit(void)
  910. {
  911. usb_deregister(&mxl111sf_driver);
  912. }
  913. module_init(mxl111sf_module_init);
  914. module_exit(mxl111sf_module_exit);
  915. MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
  916. MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
  917. MODULE_VERSION("1.0");
  918. MODULE_LICENSE("GPL");
  919. /*
  920. * Local variables:
  921. * c-basic-offset: 8
  922. * End:
  923. */