mxl111sf.c 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061
  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. module_usb_driver(mxl111sf_driver);
  901. MODULE_AUTHOR("Michael Krufky <mkrufky@kernellabs.com>");
  902. MODULE_DESCRIPTION("Driver for MaxLinear MxL111SF");
  903. MODULE_VERSION("1.0");
  904. MODULE_LICENSE("GPL");
  905. /*
  906. * Local variables:
  907. * c-basic-offset: 8
  908. * End:
  909. */