mxl111sf.c 27 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060
  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. #if 0
  290. } else {
  291. ret = mxl111sf_disable_656_port(state);
  292. mxl_fail(ret);
  293. #endif
  294. }
  295. return ret;
  296. }
  297. static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
  298. {
  299. struct dvb_usb_device *d = adap->dev;
  300. struct mxl111sf_state *state = d->priv;
  301. int ret = 0;
  302. deb_info("%s(%d)\n", __func__, onoff);
  303. if (onoff) {
  304. ret = mxl111sf_enable_usb_output(state);
  305. mxl_fail(ret);
  306. }
  307. return ret;
  308. }
  309. /* ------------------------------------------------------------------------ */
  310. static struct lgdt3305_config hauppauge_lgdt3305_config = {
  311. .i2c_addr = 0xb2 >> 1,
  312. .mpeg_mode = LGDT3305_MPEG_SERIAL,
  313. .tpclk_edge = LGDT3305_TPCLK_RISING_EDGE,
  314. .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
  315. .deny_i2c_rptr = 1,
  316. .spectral_inversion = 0,
  317. .qam_if_khz = 6000,
  318. .vsb_if_khz = 6000,
  319. };
  320. static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
  321. {
  322. struct dvb_usb_device *d = adap->dev;
  323. struct mxl111sf_state *state = d->priv;
  324. int fe_id = adap->num_frontends_initialized;
  325. struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
  326. int ret;
  327. deb_adv("%s()\n", __func__);
  328. /* save a pointer to the dvb_usb_device in device state */
  329. state->d = d;
  330. adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 2 : 1;
  331. state->alt_mode = adap_state->alt_mode;
  332. if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
  333. err("set interface failed");
  334. state->gpio_mode = MXL111SF_GPIO_MOD_ATSC;
  335. adap_state->gpio_mode = state->gpio_mode;
  336. adap_state->device_mode = MXL_TUNER_MODE;
  337. adap_state->ep6_clockphase = 1;
  338. ret = mxl1x1sf_soft_reset(state);
  339. if (mxl_fail(ret))
  340. goto fail;
  341. ret = mxl111sf_init_tuner_demod(state);
  342. if (mxl_fail(ret))
  343. goto fail;
  344. ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
  345. if (mxl_fail(ret))
  346. goto fail;
  347. ret = mxl111sf_enable_usb_output(state);
  348. if (mxl_fail(ret))
  349. goto fail;
  350. ret = mxl1x1sf_top_master_ctrl(state, 1);
  351. if (mxl_fail(ret))
  352. goto fail;
  353. ret = mxl111sf_init_port_expander(state);
  354. if (mxl_fail(ret))
  355. goto fail;
  356. ret = mxl111sf_gpio_mode_switch(state, state->gpio_mode);
  357. if (mxl_fail(ret))
  358. goto fail;
  359. adap->fe_adap[fe_id].fe = dvb_attach(lgdt3305_attach,
  360. &hauppauge_lgdt3305_config,
  361. &adap->dev->i2c_adap);
  362. if (adap->fe_adap[fe_id].fe) {
  363. adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
  364. adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
  365. adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
  366. adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
  367. return 0;
  368. }
  369. ret = -EIO;
  370. fail:
  371. return ret;
  372. }
  373. static struct mxl111sf_demod_config mxl_demod_config = {
  374. .read_reg = mxl111sf_read_reg,
  375. .write_reg = mxl111sf_write_reg,
  376. .program_regs = mxl111sf_ctrl_program_regs,
  377. };
  378. static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
  379. {
  380. struct dvb_usb_device *d = adap->dev;
  381. struct mxl111sf_state *state = d->priv;
  382. int fe_id = adap->num_frontends_initialized;
  383. struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
  384. int ret;
  385. deb_adv("%s()\n", __func__);
  386. /* save a pointer to the dvb_usb_device in device state */
  387. state->d = d;
  388. adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
  389. state->alt_mode = adap_state->alt_mode;
  390. if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
  391. err("set interface failed");
  392. state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
  393. adap_state->gpio_mode = state->gpio_mode;
  394. adap_state->device_mode = MXL_SOC_MODE;
  395. adap_state->ep6_clockphase = 1;
  396. ret = mxl1x1sf_soft_reset(state);
  397. if (mxl_fail(ret))
  398. goto fail;
  399. ret = mxl111sf_init_tuner_demod(state);
  400. if (mxl_fail(ret))
  401. goto fail;
  402. ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
  403. if (mxl_fail(ret))
  404. goto fail;
  405. ret = mxl111sf_enable_usb_output(state);
  406. if (mxl_fail(ret))
  407. goto fail;
  408. ret = mxl1x1sf_top_master_ctrl(state, 1);
  409. if (mxl_fail(ret))
  410. goto fail;
  411. /* dont care if this fails */
  412. mxl111sf_init_port_expander(state);
  413. adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
  414. &mxl_demod_config);
  415. if (adap->fe_adap[fe_id].fe) {
  416. adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
  417. adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
  418. adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
  419. adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
  420. return 0;
  421. }
  422. ret = -EIO;
  423. fail:
  424. return ret;
  425. }
  426. static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
  427. int antpath)
  428. {
  429. return mxl111sf_idac_config(state, 1, 1,
  430. (antpath == ANT_PATH_INTERNAL) ?
  431. 0x3f : 0x00, 0);
  432. }
  433. #define DbgAntHunt(x, pwr0, pwr1, pwr2, pwr3) \
  434. err("%s(%d) FINAL input set to %s rxPwr:%d|%d|%d|%d\n", \
  435. __func__, __LINE__, \
  436. (ANT_PATH_EXTERNAL == x) ? "EXTERNAL" : "INTERNAL", \
  437. pwr0, pwr1, pwr2, pwr3)
  438. #define ANT_HUNT_SLEEP 90
  439. #define ANT_EXT_TWEAK 0
  440. static int mxl111sf_ant_hunt(struct dvb_frontend *fe)
  441. {
  442. struct dvb_usb_adapter *adap = fe->dvb->priv;
  443. struct dvb_usb_device *d = adap->dev;
  444. struct mxl111sf_state *state = d->priv;
  445. int antctrl = dvb_usb_mxl111sf_rfswitch;
  446. u16 rxPwrA, rxPwr0, rxPwr1, rxPwr2;
  447. /* FIXME: must force EXTERNAL for QAM - done elsewhere */
  448. mxl111sf_set_ant_path(state, antctrl == ANT_PATH_AUTO ?
  449. ANT_PATH_EXTERNAL : antctrl);
  450. if (antctrl == ANT_PATH_AUTO) {
  451. #if 0
  452. msleep(ANT_HUNT_SLEEP);
  453. #endif
  454. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwrA);
  455. mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
  456. msleep(ANT_HUNT_SLEEP);
  457. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr0);
  458. mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
  459. msleep(ANT_HUNT_SLEEP);
  460. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr1);
  461. mxl111sf_set_ant_path(state, ANT_PATH_INTERNAL);
  462. msleep(ANT_HUNT_SLEEP);
  463. fe->ops.tuner_ops.get_rf_strength(fe, &rxPwr2);
  464. if (rxPwr1+ANT_EXT_TWEAK >= rxPwr2) {
  465. /* return with EXTERNAL enabled */
  466. mxl111sf_set_ant_path(state, ANT_PATH_EXTERNAL);
  467. DbgAntHunt(ANT_PATH_EXTERNAL, rxPwrA,
  468. rxPwr0, rxPwr1, rxPwr2);
  469. } else {
  470. /* return with INTERNAL enabled */
  471. DbgAntHunt(ANT_PATH_INTERNAL, rxPwrA,
  472. rxPwr0, rxPwr1, rxPwr2);
  473. }
  474. }
  475. return 0;
  476. }
  477. static struct mxl111sf_tuner_config mxl_tuner_config = {
  478. .if_freq = MXL_IF_6_0, /* applies to external IF output, only */
  479. .invert_spectrum = 0,
  480. .read_reg = mxl111sf_read_reg,
  481. .write_reg = mxl111sf_write_reg,
  482. .program_regs = mxl111sf_ctrl_program_regs,
  483. .top_master_ctrl = mxl1x1sf_top_master_ctrl,
  484. .ant_hunt = mxl111sf_ant_hunt,
  485. };
  486. static int mxl111sf_attach_tuner(struct dvb_usb_adapter *adap)
  487. {
  488. struct dvb_usb_device *d = adap->dev;
  489. struct mxl111sf_state *state = d->priv;
  490. int fe_id = adap->num_frontends_initialized;
  491. deb_adv("%s()\n", __func__);
  492. if (NULL != dvb_attach(mxl111sf_tuner_attach,
  493. adap->fe_adap[fe_id].fe, state,
  494. &mxl_tuner_config))
  495. return 0;
  496. return -EIO;
  497. }
  498. static int mxl111sf_fe_ioctl_override(struct dvb_frontend *fe,
  499. unsigned int cmd, void *parg,
  500. unsigned int stage)
  501. {
  502. int err = 0;
  503. switch (stage) {
  504. case DVB_FE_IOCTL_PRE:
  505. switch (cmd) {
  506. case FE_READ_SIGNAL_STRENGTH:
  507. err = fe->ops.tuner_ops.get_rf_strength(fe, parg);
  508. /* If no error occurs, prevent dvb-core from handling
  509. * this IOCTL, otherwise return the error */
  510. if (0 == err)
  511. err = 1;
  512. break;
  513. }
  514. break;
  515. case DVB_FE_IOCTL_POST:
  516. /* no post-ioctl handling required */
  517. break;
  518. }
  519. return err;
  520. };
  521. static u32 mxl111sf_i2c_func(struct i2c_adapter *adapter)
  522. {
  523. return I2C_FUNC_I2C;
  524. }
  525. struct i2c_algorithm mxl111sf_i2c_algo = {
  526. .master_xfer = mxl111sf_i2c_xfer,
  527. .functionality = mxl111sf_i2c_func,
  528. #ifdef NEED_ALGO_CONTROL
  529. .algo_control = dummy_algo_control,
  530. #endif
  531. };
  532. static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
  533. static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
  534. static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
  535. static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
  536. static int mxl111sf_probe(struct usb_interface *intf,
  537. const struct usb_device_id *id)
  538. {
  539. struct dvb_usb_device *d = NULL;
  540. deb_adv("%s()\n", __func__);
  541. if (((dvb_usb_mxl111sf_isoc) &&
  542. (0 == dvb_usb_device_init(intf,
  543. &mxl111sf_dvbt_isoc_properties,
  544. THIS_MODULE, &d, adapter_nr) ||
  545. 0 == dvb_usb_device_init(intf,
  546. &mxl111sf_atsc_isoc_properties,
  547. THIS_MODULE, &d, adapter_nr))) ||
  548. 0 == dvb_usb_device_init(intf,
  549. &mxl111sf_dvbt_bulk_properties,
  550. THIS_MODULE, &d, adapter_nr) ||
  551. 0 == dvb_usb_device_init(intf,
  552. &mxl111sf_atsc_bulk_properties,
  553. THIS_MODULE, &d, adapter_nr) || 0) {
  554. struct mxl111sf_state *state = d->priv;
  555. static u8 eeprom[256];
  556. struct i2c_client c;
  557. int ret;
  558. ret = get_chip_info(state);
  559. if (mxl_fail(ret))
  560. err("failed to get chip info during probe");
  561. mutex_init(&state->fe_lock);
  562. if (state->chip_rev > MXL111SF_V6)
  563. mxl111sf_config_pin_mux_modes(state,
  564. PIN_MUX_TS_SPI_IN_MODE_1);
  565. c.adapter = &d->i2c_adap;
  566. c.addr = 0xa0 >> 1;
  567. ret = tveeprom_read(&c, eeprom, sizeof(eeprom));
  568. if (mxl_fail(ret))
  569. return 0;
  570. tveeprom_hauppauge_analog(&c, &state->tv,
  571. (0x84 == eeprom[0xa0]) ?
  572. eeprom + 0xa0 : eeprom + 0x80);
  573. #if 0
  574. switch (state->tv.model) {
  575. case 117001:
  576. case 126001:
  577. case 138001:
  578. break;
  579. default:
  580. printk(KERN_WARNING "%s: warning: "
  581. "unknown hauppauge model #%d\n",
  582. __func__, state->tv.model);
  583. }
  584. #endif
  585. return 0;
  586. }
  587. err("Your device is not yet supported by this driver. "
  588. "See kernellabs.com for more info");
  589. return -EINVAL;
  590. }
  591. static struct usb_device_id mxl111sf_table[] = {
  592. /* 0 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc600) }, /* ATSC+ IR */
  593. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc601) }, /* ATSC */
  594. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc602) }, /* + */
  595. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc603) }, /* ATSC+ */
  596. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc604) }, /* DVBT */
  597. /* 5 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc609) }, /* ATSC IR */
  598. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60a) }, /* + IR */
  599. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60b) }, /* ATSC+ IR */
  600. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc60c) }, /* DVBT IR */
  601. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc653) }, /* ATSC+ */
  602. /*10 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc65b) }, /* ATSC+ IR */
  603. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb700) }, /* ATSC+ sw */
  604. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb701) }, /* ATSC sw */
  605. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb702) }, /* + sw */
  606. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb703) }, /* ATSC+ sw */
  607. /*15 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb704) }, /* DVBT sw */
  608. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb753) }, /* ATSC+ sw */
  609. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb763) }, /* ATSC+ no */
  610. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb764) }, /* DVBT no */
  611. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd853) }, /* ATSC+ sw */
  612. /*20 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd854) }, /* DVBT sw */
  613. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd863) }, /* ATSC+ no */
  614. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd864) }, /* DVBT no */
  615. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d3) }, /* ATSC+ sw */
  616. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8d4) }, /* DVBT sw */
  617. /*25 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e3) }, /* ATSC+ no */
  618. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8e4) }, /* DVBT no */
  619. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xd8ff) }, /* ATSC+ */
  620. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc612) }, /* + */
  621. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc613) }, /* ATSC+ */
  622. /*30 */ { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61a) }, /* + IR */
  623. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xc61b) }, /* ATSC+ IR */
  624. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb757) }, /* ATSC+DVBT sw */
  625. { USB_DEVICE(USB_VID_HAUPPAUGE, 0xb767) }, /* ATSC+DVBT no */
  626. {} /* Terminating entry */
  627. };
  628. MODULE_DEVICE_TABLE(usb, mxl111sf_table);
  629. #define MXL111SF_EP4_BULK_STREAMING_CONFIG \
  630. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  631. .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
  632. .stream = { \
  633. .type = USB_BULK, \
  634. .count = 5, \
  635. .endpoint = 0x04, \
  636. .u = { \
  637. .bulk = { \
  638. .buffersize = 8192, \
  639. } \
  640. } \
  641. }
  642. /* FIXME: works for v6 but not v8 silicon */
  643. #define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
  644. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  645. .streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
  646. .stream = { \
  647. .type = USB_ISOC, \
  648. .count = 5, \
  649. .endpoint = 0x04, \
  650. .u = { \
  651. .isoc = { \
  652. .framesperurb = 96, \
  653. /* FIXME: v6 SILICON: */ \
  654. .framesize = 564, \
  655. .interval = 1, \
  656. } \
  657. } \
  658. }
  659. #define MXL111SF_EP6_BULK_STREAMING_CONFIG \
  660. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  661. .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
  662. .stream = { \
  663. .type = USB_BULK, \
  664. .count = 5, \
  665. .endpoint = 0x06, \
  666. .u = { \
  667. .bulk = { \
  668. .buffersize = 8192, \
  669. } \
  670. } \
  671. }
  672. /* FIXME */
  673. #define MXL111SF_EP6_ISOC_STREAMING_CONFIG \
  674. .size_of_priv = sizeof(struct mxl111sf_adap_state), \
  675. .streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
  676. .stream = { \
  677. .type = USB_ISOC, \
  678. .count = 5, \
  679. .endpoint = 0x06, \
  680. .u = { \
  681. .isoc = { \
  682. .framesperurb = 24, \
  683. .framesize = 3072, \
  684. .interval = 1, \
  685. } \
  686. } \
  687. }
  688. #define MXL111SF_DEFAULT_DEVICE_PROPERTIES \
  689. .caps = DVB_USB_IS_AN_I2C_ADAPTER, \
  690. .usb_ctrl = DEVICE_SPECIFIC, \
  691. /* use usb alt setting 1 for EP4 ISOC transfer (dvb-t), \
  692. EP6 BULK transfer (atsc/qam), \
  693. use usb alt setting 2 for EP4 BULK transfer (dvb-t), \
  694. EP6 ISOC transfer (atsc/qam), \
  695. */ \
  696. .power_ctrl = mxl111sf_power_ctrl, \
  697. .i2c_algo = &mxl111sf_i2c_algo, \
  698. .generic_bulk_ctrl_endpoint = MXL_EP2_REG_WRITE, \
  699. .generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
  700. .size_of_priv = sizeof(struct mxl111sf_state)
  701. static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
  702. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  703. .num_adapters = 1,
  704. .adapter = {
  705. {
  706. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  707. .num_frontends = 1,
  708. .fe = {{
  709. .frontend_attach = mxl111sf_attach_demod,
  710. .tuner_attach = mxl111sf_attach_tuner,
  711. MXL111SF_EP4_BULK_STREAMING_CONFIG,
  712. } },
  713. },
  714. },
  715. .num_device_descs = 4,
  716. .devices = {
  717. { "Hauppauge 126xxx DVBT (bulk)",
  718. { NULL },
  719. { &mxl111sf_table[4], &mxl111sf_table[8],
  720. NULL },
  721. },
  722. { "Hauppauge 117xxx DVBT (bulk)",
  723. { NULL },
  724. { &mxl111sf_table[15], &mxl111sf_table[18],
  725. NULL },
  726. },
  727. { "Hauppauge 138xxx DVBT (bulk)",
  728. { NULL },
  729. { &mxl111sf_table[20], &mxl111sf_table[22],
  730. &mxl111sf_table[24], &mxl111sf_table[26],
  731. NULL },
  732. },
  733. { "Hauppauge 126xxx (tp-bulk)",
  734. { NULL },
  735. { &mxl111sf_table[28], &mxl111sf_table[30],
  736. NULL },
  737. },
  738. }
  739. };
  740. static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
  741. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  742. .num_adapters = 1,
  743. .adapter = {
  744. {
  745. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  746. .num_frontends = 1,
  747. .fe = {{
  748. .frontend_attach = mxl111sf_attach_demod,
  749. .tuner_attach = mxl111sf_attach_tuner,
  750. MXL111SF_EP4_ISOC_STREAMING_CONFIG,
  751. } },
  752. },
  753. },
  754. .num_device_descs = 4,
  755. .devices = {
  756. { "Hauppauge 126xxx DVBT (isoc)",
  757. { NULL },
  758. { &mxl111sf_table[4], &mxl111sf_table[8],
  759. NULL },
  760. },
  761. { "Hauppauge 117xxx DVBT (isoc)",
  762. { NULL },
  763. { &mxl111sf_table[15], &mxl111sf_table[18],
  764. NULL },
  765. },
  766. { "Hauppauge 138xxx DVBT (isoc)",
  767. { NULL },
  768. { &mxl111sf_table[20], &mxl111sf_table[22],
  769. &mxl111sf_table[24], &mxl111sf_table[26],
  770. NULL },
  771. },
  772. { "Hauppauge 126xxx (tp-isoc)",
  773. { NULL },
  774. { &mxl111sf_table[28], &mxl111sf_table[30],
  775. NULL },
  776. },
  777. }
  778. };
  779. static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
  780. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  781. .num_adapters = 1,
  782. .adapter = {
  783. {
  784. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  785. .num_frontends = 2,
  786. .fe = {{
  787. .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
  788. .tuner_attach = mxl111sf_attach_tuner,
  789. MXL111SF_EP6_BULK_STREAMING_CONFIG,
  790. },
  791. {
  792. .frontend_attach = mxl111sf_attach_demod,
  793. .tuner_attach = mxl111sf_attach_tuner,
  794. MXL111SF_EP4_BULK_STREAMING_CONFIG,
  795. }},
  796. },
  797. },
  798. .num_device_descs = 6,
  799. .devices = {
  800. { "Hauppauge 126xxx ATSC (bulk)",
  801. { NULL },
  802. { &mxl111sf_table[1], &mxl111sf_table[5],
  803. NULL },
  804. },
  805. { "Hauppauge 117xxx ATSC (bulk)",
  806. { NULL },
  807. { &mxl111sf_table[12],
  808. NULL },
  809. },
  810. { "Hauppauge 126xxx ATSC+ (bulk)",
  811. { NULL },
  812. { &mxl111sf_table[0], &mxl111sf_table[3],
  813. &mxl111sf_table[7], &mxl111sf_table[9],
  814. &mxl111sf_table[10], NULL },
  815. },
  816. { "Hauppauge 117xxx ATSC+ (bulk)",
  817. { NULL },
  818. { &mxl111sf_table[11], &mxl111sf_table[14],
  819. &mxl111sf_table[16], &mxl111sf_table[17],
  820. &mxl111sf_table[32], &mxl111sf_table[33],
  821. NULL },
  822. },
  823. { "Hauppauge Mercury (tp-bulk)",
  824. { NULL },
  825. { &mxl111sf_table[19], &mxl111sf_table[21],
  826. &mxl111sf_table[23], &mxl111sf_table[25],
  827. &mxl111sf_table[27], NULL },
  828. },
  829. { "Hauppauge WinTV-Aero-M",
  830. { NULL },
  831. { &mxl111sf_table[29], &mxl111sf_table[31],
  832. NULL },
  833. },
  834. }
  835. };
  836. static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
  837. MXL111SF_DEFAULT_DEVICE_PROPERTIES,
  838. .num_adapters = 1,
  839. .adapter = {
  840. {
  841. .fe_ioctl_override = mxl111sf_fe_ioctl_override,
  842. .num_frontends = 2,
  843. .fe = {{
  844. .frontend_attach = mxl111sf_lgdt3305_frontend_attach,
  845. .tuner_attach = mxl111sf_attach_tuner,
  846. MXL111SF_EP6_ISOC_STREAMING_CONFIG,
  847. },
  848. {
  849. .frontend_attach = mxl111sf_attach_demod,
  850. .tuner_attach = mxl111sf_attach_tuner,
  851. MXL111SF_EP4_ISOC_STREAMING_CONFIG,
  852. }},
  853. },
  854. },
  855. .num_device_descs = 6,
  856. .devices = {
  857. { "Hauppauge 126xxx ATSC (isoc)",
  858. { NULL },
  859. { &mxl111sf_table[1], &mxl111sf_table[5],
  860. NULL },
  861. },
  862. { "Hauppauge 117xxx ATSC (isoc)",
  863. { NULL },
  864. { &mxl111sf_table[12],
  865. NULL },
  866. },
  867. { "Hauppauge 126xxx ATSC+ (isoc)",
  868. { NULL },
  869. { &mxl111sf_table[0], &mxl111sf_table[3],
  870. &mxl111sf_table[7], &mxl111sf_table[9],
  871. &mxl111sf_table[10], NULL },
  872. },
  873. { "Hauppauge 117xxx ATSC+ (isoc)",
  874. { NULL },
  875. { &mxl111sf_table[11], &mxl111sf_table[14],
  876. &mxl111sf_table[16], &mxl111sf_table[17],
  877. &mxl111sf_table[32], &mxl111sf_table[33],
  878. NULL },
  879. },
  880. { "Hauppauge Mercury (tp-isoc)",
  881. { NULL },
  882. { &mxl111sf_table[19], &mxl111sf_table[21],
  883. &mxl111sf_table[23], &mxl111sf_table[25],
  884. &mxl111sf_table[27], NULL },
  885. },
  886. { "Hauppauge WinTV-Aero-M (tp-isoc)",
  887. { NULL },
  888. { &mxl111sf_table[29], &mxl111sf_table[31],
  889. NULL },
  890. },
  891. }
  892. };
  893. static struct usb_driver mxl111sf_driver = {
  894. .name = "dvb_usb_mxl111sf",
  895. .probe = mxl111sf_probe,
  896. .disconnect = dvb_usb_device_exit,
  897. .id_table = mxl111sf_table,
  898. };
  899. module_usb_driver(mxl111sf_driver);
  900. MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
  901. MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
  902. MODULE_VERSION("1.0");
  903. MODULE_LICENSE("GPL");
  904. /*
  905. * Local variables:
  906. * c-basic-offset: 8
  907. * End:
  908. */