mxl111sf.c 27 KB

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