tda827x.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /*
  2. *
  3. * (c) 2005 Hartmut Hackmann
  4. * (c) 2007 Michael Krufky
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. */
  16. #include <linux/module.h>
  17. #include <linux/slab.h>
  18. #include <asm/types.h>
  19. #include <linux/dvb/frontend.h>
  20. #include <linux/videodev2.h>
  21. #include "tda827x.h"
  22. static int debug;
  23. module_param(debug, int, 0644);
  24. MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
  25. #define dprintk(args...) \
  26. do { \
  27. if (debug) printk(KERN_DEBUG "tda827x: " args); \
  28. } while (0)
  29. struct tda827x_priv {
  30. int i2c_addr;
  31. struct i2c_adapter *i2c_adap;
  32. struct tda827x_config *cfg;
  33. unsigned int sgIF;
  34. unsigned char lpsel;
  35. u32 frequency;
  36. u32 bandwidth;
  37. };
  38. static void tda827x_set_std(struct dvb_frontend *fe,
  39. struct analog_parameters *params)
  40. {
  41. struct tda827x_priv *priv = fe->tuner_priv;
  42. char *mode;
  43. priv->lpsel = 0;
  44. if (params->std & V4L2_STD_MN) {
  45. priv->sgIF = 92;
  46. priv->lpsel = 1;
  47. mode = "MN";
  48. } else if (params->std & V4L2_STD_B) {
  49. priv->sgIF = 108;
  50. mode = "B";
  51. } else if (params->std & V4L2_STD_GH) {
  52. priv->sgIF = 124;
  53. mode = "GH";
  54. } else if (params->std & V4L2_STD_PAL_I) {
  55. priv->sgIF = 124;
  56. mode = "I";
  57. } else if (params->std & V4L2_STD_DK) {
  58. priv->sgIF = 124;
  59. mode = "DK";
  60. } else if (params->std & V4L2_STD_SECAM_L) {
  61. priv->sgIF = 124;
  62. mode = "L";
  63. } else if (params->std & V4L2_STD_SECAM_LC) {
  64. priv->sgIF = 20;
  65. mode = "LC";
  66. } else {
  67. priv->sgIF = 124;
  68. mode = "xx";
  69. }
  70. if (params->mode == V4L2_TUNER_RADIO) {
  71. priv->sgIF = 88; /* if frequency is 5.5 MHz */
  72. dprintk("setting tda827x to radio FM\n");
  73. } else
  74. dprintk("setting tda827x to system %s\n", mode);
  75. }
  76. /* ------------------------------------------------------------------ */
  77. struct tda827x_data {
  78. u32 lomax;
  79. u8 spd;
  80. u8 bs;
  81. u8 bp;
  82. u8 cp;
  83. u8 gc3;
  84. u8 div1p5;
  85. };
  86. static const struct tda827x_data tda827x_table[] = {
  87. { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
  88. { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
  89. { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
  90. { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
  91. { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
  92. { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
  93. { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
  94. { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
  95. { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
  96. { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
  97. { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
  98. { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
  99. { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
  100. { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
  101. { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
  102. { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
  103. { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
  104. { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
  105. { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
  106. { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
  107. { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
  108. { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
  109. { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
  110. { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
  111. { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
  112. { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
  113. { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
  114. { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
  115. { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
  116. };
  117. static int tuner_transfer(struct dvb_frontend *fe,
  118. struct i2c_msg *msg,
  119. const int size)
  120. {
  121. int rc;
  122. struct tda827x_priv *priv = fe->tuner_priv;
  123. if (fe->ops.i2c_gate_ctrl)
  124. fe->ops.i2c_gate_ctrl(fe, 1);
  125. rc = i2c_transfer(priv->i2c_adap, msg, size);
  126. if (fe->ops.i2c_gate_ctrl)
  127. fe->ops.i2c_gate_ctrl(fe, 0);
  128. if (rc >= 0 && rc != size)
  129. return -EIO;
  130. return rc;
  131. }
  132. static int tda827xo_set_params(struct dvb_frontend *fe)
  133. {
  134. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  135. struct tda827x_priv *priv = fe->tuner_priv;
  136. u8 buf[14];
  137. int rc;
  138. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
  139. .buf = buf, .len = sizeof(buf) };
  140. int i, tuner_freq, if_freq;
  141. u32 N;
  142. dprintk("%s:\n", __func__);
  143. if (c->bandwidth_hz == 0) {
  144. if_freq = 5000000;
  145. } else if (c->bandwidth_hz <= 6000000) {
  146. if_freq = 4000000;
  147. } else if (c->bandwidth_hz <= 7000000) {
  148. if_freq = 4500000;
  149. } else { /* 8 MHz */
  150. if_freq = 5000000;
  151. }
  152. tuner_freq = c->frequency;
  153. i = 0;
  154. while (tda827x_table[i].lomax < tuner_freq) {
  155. if (tda827x_table[i + 1].lomax == 0)
  156. break;
  157. i++;
  158. }
  159. tuner_freq += if_freq;
  160. N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
  161. buf[0] = 0;
  162. buf[1] = (N>>8) | 0x40;
  163. buf[2] = N & 0xff;
  164. buf[3] = 0;
  165. buf[4] = 0x52;
  166. buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
  167. (tda827x_table[i].bs << 3) +
  168. tda827x_table[i].bp;
  169. buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
  170. buf[7] = 0xbf;
  171. buf[8] = 0x2a;
  172. buf[9] = 0x05;
  173. buf[10] = 0xff;
  174. buf[11] = 0x00;
  175. buf[12] = 0x00;
  176. buf[13] = 0x40;
  177. msg.len = 14;
  178. rc = tuner_transfer(fe, &msg, 1);
  179. if (rc < 0)
  180. goto err;
  181. msleep(500);
  182. /* correct CP value */
  183. buf[0] = 0x30;
  184. buf[1] = 0x50 + tda827x_table[i].cp;
  185. msg.len = 2;
  186. rc = tuner_transfer(fe, &msg, 1);
  187. if (rc < 0)
  188. goto err;
  189. priv->frequency = c->frequency;
  190. priv->bandwidth = c->bandwidth_hz;
  191. return 0;
  192. err:
  193. printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
  194. __func__, priv->i2c_addr << 1);
  195. return rc;
  196. }
  197. static int tda827xo_sleep(struct dvb_frontend *fe)
  198. {
  199. struct tda827x_priv *priv = fe->tuner_priv;
  200. static u8 buf[] = { 0x30, 0xd0 };
  201. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
  202. .buf = buf, .len = sizeof(buf) };
  203. dprintk("%s:\n", __func__);
  204. tuner_transfer(fe, &msg, 1);
  205. if (priv->cfg && priv->cfg->sleep)
  206. priv->cfg->sleep(fe);
  207. return 0;
  208. }
  209. /* ------------------------------------------------------------------ */
  210. static int tda827xo_set_analog_params(struct dvb_frontend *fe,
  211. struct analog_parameters *params)
  212. {
  213. unsigned char tuner_reg[8];
  214. unsigned char reg2[2];
  215. u32 N;
  216. int i;
  217. struct tda827x_priv *priv = fe->tuner_priv;
  218. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
  219. unsigned int freq = params->frequency;
  220. tda827x_set_std(fe, params);
  221. if (params->mode == V4L2_TUNER_RADIO)
  222. freq = freq / 1000;
  223. N = freq + priv->sgIF;
  224. i = 0;
  225. while (tda827x_table[i].lomax < N * 62500) {
  226. if (tda827x_table[i + 1].lomax == 0)
  227. break;
  228. i++;
  229. }
  230. N = N << tda827x_table[i].spd;
  231. tuner_reg[0] = 0;
  232. tuner_reg[1] = (unsigned char)(N>>8);
  233. tuner_reg[2] = (unsigned char) N;
  234. tuner_reg[3] = 0x40;
  235. tuner_reg[4] = 0x52 + (priv->lpsel << 5);
  236. tuner_reg[5] = (tda827x_table[i].spd << 6) +
  237. (tda827x_table[i].div1p5 << 5) +
  238. (tda827x_table[i].bs << 3) + tda827x_table[i].bp;
  239. tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
  240. tuner_reg[7] = 0x8f;
  241. msg.buf = tuner_reg;
  242. msg.len = 8;
  243. tuner_transfer(fe, &msg, 1);
  244. msg.buf = reg2;
  245. msg.len = 2;
  246. reg2[0] = 0x80;
  247. reg2[1] = 0;
  248. tuner_transfer(fe, &msg, 1);
  249. reg2[0] = 0x60;
  250. reg2[1] = 0xbf;
  251. tuner_transfer(fe, &msg, 1);
  252. reg2[0] = 0x30;
  253. reg2[1] = tuner_reg[4] + 0x80;
  254. tuner_transfer(fe, &msg, 1);
  255. msleep(1);
  256. reg2[0] = 0x30;
  257. reg2[1] = tuner_reg[4] + 4;
  258. tuner_transfer(fe, &msg, 1);
  259. msleep(1);
  260. reg2[0] = 0x30;
  261. reg2[1] = tuner_reg[4];
  262. tuner_transfer(fe, &msg, 1);
  263. msleep(550);
  264. reg2[0] = 0x30;
  265. reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
  266. tuner_transfer(fe, &msg, 1);
  267. reg2[0] = 0x60;
  268. reg2[1] = 0x3f;
  269. tuner_transfer(fe, &msg, 1);
  270. reg2[0] = 0x80;
  271. reg2[1] = 0x08; /* Vsync en */
  272. tuner_transfer(fe, &msg, 1);
  273. priv->frequency = params->frequency;
  274. return 0;
  275. }
  276. static void tda827xo_agcf(struct dvb_frontend *fe)
  277. {
  278. struct tda827x_priv *priv = fe->tuner_priv;
  279. unsigned char data[] = { 0x80, 0x0c };
  280. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
  281. .buf = data, .len = 2};
  282. tuner_transfer(fe, &msg, 1);
  283. }
  284. /* ------------------------------------------------------------------ */
  285. struct tda827xa_data {
  286. u32 lomax;
  287. u8 svco;
  288. u8 spd;
  289. u8 scr;
  290. u8 sbs;
  291. u8 gc3;
  292. };
  293. static struct tda827xa_data tda827xa_dvbt[] = {
  294. { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
  295. { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
  296. { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
  297. { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
  298. { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
  299. { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  300. { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  301. { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  302. { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  303. { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
  304. { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
  305. { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
  306. { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
  307. { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
  308. { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
  309. { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
  310. { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
  311. { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
  312. { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
  313. { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
  314. { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
  315. { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
  316. { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
  317. { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
  318. { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
  319. { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
  320. { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
  321. };
  322. static struct tda827xa_data tda827xa_dvbc[] = {
  323. { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
  324. { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
  325. { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
  326. { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
  327. { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
  328. { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
  329. { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
  330. { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
  331. { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
  332. { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
  333. { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
  334. { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
  335. { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
  336. { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
  337. { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
  338. { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
  339. { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
  340. { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
  341. { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
  342. { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
  343. { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
  344. { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
  345. { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
  346. { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
  347. { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
  348. { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
  349. { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
  350. };
  351. static struct tda827xa_data tda827xa_analog[] = {
  352. { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
  353. { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
  354. { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
  355. { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
  356. { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
  357. { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  358. { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  359. { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  360. { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
  361. { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
  362. { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
  363. { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
  364. { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
  365. { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
  366. { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
  367. { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
  368. { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
  369. { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
  370. { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
  371. { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
  372. { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
  373. { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
  374. { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
  375. { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
  376. { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
  377. { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
  378. };
  379. static int tda827xa_sleep(struct dvb_frontend *fe)
  380. {
  381. struct tda827x_priv *priv = fe->tuner_priv;
  382. static u8 buf[] = { 0x30, 0x90 };
  383. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
  384. .buf = buf, .len = sizeof(buf) };
  385. dprintk("%s:\n", __func__);
  386. tuner_transfer(fe, &msg, 1);
  387. if (priv->cfg && priv->cfg->sleep)
  388. priv->cfg->sleep(fe);
  389. return 0;
  390. }
  391. static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
  392. struct analog_parameters *params)
  393. {
  394. struct tda827x_priv *priv = fe->tuner_priv;
  395. unsigned char buf[] = {0x22, 0x01};
  396. int arg;
  397. int gp_func;
  398. struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
  399. if (NULL == priv->cfg) {
  400. dprintk("tda827x_config not defined, cannot set LNA gain!\n");
  401. return;
  402. }
  403. msg.addr = priv->cfg->switch_addr;
  404. if (priv->cfg->config) {
  405. if (high)
  406. dprintk("setting LNA to high gain\n");
  407. else
  408. dprintk("setting LNA to low gain\n");
  409. }
  410. switch (priv->cfg->config) {
  411. case TDA8290_LNA_OFF: /* no LNA */
  412. break;
  413. case TDA8290_LNA_GP0_HIGH_ON: /* switch is GPIO 0 of tda8290 */
  414. case TDA8290_LNA_GP0_HIGH_OFF:
  415. if (params == NULL) {
  416. gp_func = 0;
  417. arg = 0;
  418. } else {
  419. /* turn Vsync on */
  420. gp_func = 1;
  421. if (params->std & V4L2_STD_MN)
  422. arg = 1;
  423. else
  424. arg = 0;
  425. }
  426. if (fe->callback)
  427. fe->callback(priv->i2c_adap->algo_data,
  428. DVB_FRONTEND_COMPONENT_TUNER,
  429. gp_func, arg);
  430. buf[1] = high ? 0 : 1;
  431. if (priv->cfg->config == TDA8290_LNA_GP0_HIGH_OFF)
  432. buf[1] = high ? 1 : 0;
  433. tuner_transfer(fe, &msg, 1);
  434. break;
  435. case TDA8290_LNA_ON_BRIDGE: /* switch with GPIO of saa713x */
  436. if (fe->callback)
  437. fe->callback(priv->i2c_adap->algo_data,
  438. DVB_FRONTEND_COMPONENT_TUNER, 0, high);
  439. break;
  440. }
  441. }
  442. static int tda827xa_set_params(struct dvb_frontend *fe)
  443. {
  444. struct dtv_frontend_properties *c = &fe->dtv_property_cache;
  445. struct tda827x_priv *priv = fe->tuner_priv;
  446. struct tda827xa_data *frequency_map = tda827xa_dvbt;
  447. u8 buf[11];
  448. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
  449. .buf = buf, .len = sizeof(buf) };
  450. int i, tuner_freq, if_freq, rc;
  451. u32 N;
  452. dprintk("%s:\n", __func__);
  453. tda827xa_lna_gain(fe, 1, NULL);
  454. msleep(20);
  455. if (c->bandwidth_hz == 0) {
  456. if_freq = 5000000;
  457. } else if (c->bandwidth_hz <= 6000000) {
  458. if_freq = 4000000;
  459. } else if (c->bandwidth_hz <= 7000000) {
  460. if_freq = 4500000;
  461. } else { /* 8 MHz */
  462. if_freq = 5000000;
  463. }
  464. tuner_freq = c->frequency;
  465. switch (c->delivery_system) {
  466. case SYS_DVBC_ANNEX_A:
  467. case SYS_DVBC_ANNEX_C:
  468. dprintk("%s select tda827xa_dvbc\n", __func__);
  469. frequency_map = tda827xa_dvbc;
  470. break;
  471. default:
  472. break;
  473. }
  474. i = 0;
  475. while (frequency_map[i].lomax < tuner_freq) {
  476. if (frequency_map[i + 1].lomax == 0)
  477. break;
  478. i++;
  479. }
  480. tuner_freq += if_freq;
  481. N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
  482. buf[0] = 0; // subaddress
  483. buf[1] = N >> 8;
  484. buf[2] = N & 0xff;
  485. buf[3] = 0;
  486. buf[4] = 0x16;
  487. buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
  488. frequency_map[i].sbs;
  489. buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
  490. buf[7] = 0x1c;
  491. buf[8] = 0x06;
  492. buf[9] = 0x24;
  493. buf[10] = 0x00;
  494. msg.len = 11;
  495. rc = tuner_transfer(fe, &msg, 1);
  496. if (rc < 0)
  497. goto err;
  498. buf[0] = 0x90;
  499. buf[1] = 0xff;
  500. buf[2] = 0x60;
  501. buf[3] = 0x00;
  502. buf[4] = 0x59; // lpsel, for 6MHz + 2
  503. msg.len = 5;
  504. rc = tuner_transfer(fe, &msg, 1);
  505. if (rc < 0)
  506. goto err;
  507. buf[0] = 0xa0;
  508. buf[1] = 0x40;
  509. msg.len = 2;
  510. rc = tuner_transfer(fe, &msg, 1);
  511. if (rc < 0)
  512. goto err;
  513. msleep(11);
  514. msg.flags = I2C_M_RD;
  515. rc = tuner_transfer(fe, &msg, 1);
  516. if (rc < 0)
  517. goto err;
  518. msg.flags = 0;
  519. buf[1] >>= 4;
  520. dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
  521. if ((buf[1]) < 2) {
  522. tda827xa_lna_gain(fe, 0, NULL);
  523. buf[0] = 0x60;
  524. buf[1] = 0x0c;
  525. rc = tuner_transfer(fe, &msg, 1);
  526. if (rc < 0)
  527. goto err;
  528. }
  529. buf[0] = 0xc0;
  530. buf[1] = 0x99; // lpsel, for 6MHz + 2
  531. rc = tuner_transfer(fe, &msg, 1);
  532. if (rc < 0)
  533. goto err;
  534. buf[0] = 0x60;
  535. buf[1] = 0x3c;
  536. rc = tuner_transfer(fe, &msg, 1);
  537. if (rc < 0)
  538. goto err;
  539. /* correct CP value */
  540. buf[0] = 0x30;
  541. buf[1] = 0x10 + frequency_map[i].scr;
  542. rc = tuner_transfer(fe, &msg, 1);
  543. if (rc < 0)
  544. goto err;
  545. msleep(163);
  546. buf[0] = 0xc0;
  547. buf[1] = 0x39; // lpsel, for 6MHz + 2
  548. rc = tuner_transfer(fe, &msg, 1);
  549. if (rc < 0)
  550. goto err;
  551. msleep(3);
  552. /* freeze AGC1 */
  553. buf[0] = 0x50;
  554. buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
  555. rc = tuner_transfer(fe, &msg, 1);
  556. if (rc < 0)
  557. goto err;
  558. priv->frequency = c->frequency;
  559. priv->bandwidth = c->bandwidth_hz;
  560. return 0;
  561. err:
  562. printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
  563. __func__, priv->i2c_addr << 1);
  564. return rc;
  565. }
  566. static int tda827xa_set_analog_params(struct dvb_frontend *fe,
  567. struct analog_parameters *params)
  568. {
  569. unsigned char tuner_reg[11];
  570. u32 N;
  571. int i;
  572. struct tda827x_priv *priv = fe->tuner_priv;
  573. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
  574. .buf = tuner_reg, .len = sizeof(tuner_reg) };
  575. unsigned int freq = params->frequency;
  576. tda827x_set_std(fe, params);
  577. tda827xa_lna_gain(fe, 1, params);
  578. msleep(10);
  579. if (params->mode == V4L2_TUNER_RADIO)
  580. freq = freq / 1000;
  581. N = freq + priv->sgIF;
  582. i = 0;
  583. while (tda827xa_analog[i].lomax < N * 62500) {
  584. if (tda827xa_analog[i + 1].lomax == 0)
  585. break;
  586. i++;
  587. }
  588. N = N << tda827xa_analog[i].spd;
  589. tuner_reg[0] = 0;
  590. tuner_reg[1] = (unsigned char)(N>>8);
  591. tuner_reg[2] = (unsigned char) N;
  592. tuner_reg[3] = 0;
  593. tuner_reg[4] = 0x16;
  594. tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
  595. (tda827xa_analog[i].svco << 3) +
  596. tda827xa_analog[i].sbs;
  597. tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
  598. tuner_reg[7] = 0x1c;
  599. tuner_reg[8] = 4;
  600. tuner_reg[9] = 0x20;
  601. tuner_reg[10] = 0x00;
  602. msg.len = 11;
  603. tuner_transfer(fe, &msg, 1);
  604. tuner_reg[0] = 0x90;
  605. tuner_reg[1] = 0xff;
  606. tuner_reg[2] = 0xe0;
  607. tuner_reg[3] = 0;
  608. tuner_reg[4] = 0x99 + (priv->lpsel << 1);
  609. msg.len = 5;
  610. tuner_transfer(fe, &msg, 1);
  611. tuner_reg[0] = 0xa0;
  612. tuner_reg[1] = 0xc0;
  613. msg.len = 2;
  614. tuner_transfer(fe, &msg, 1);
  615. tuner_reg[0] = 0x30;
  616. tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
  617. tuner_transfer(fe, &msg, 1);
  618. msg.flags = I2C_M_RD;
  619. tuner_transfer(fe, &msg, 1);
  620. msg.flags = 0;
  621. tuner_reg[1] >>= 4;
  622. dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
  623. if (tuner_reg[1] < 1)
  624. tda827xa_lna_gain(fe, 0, params);
  625. msleep(100);
  626. tuner_reg[0] = 0x60;
  627. tuner_reg[1] = 0x3c;
  628. tuner_transfer(fe, &msg, 1);
  629. msleep(163);
  630. tuner_reg[0] = 0x50;
  631. tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
  632. tuner_transfer(fe, &msg, 1);
  633. tuner_reg[0] = 0x80;
  634. tuner_reg[1] = 0x28;
  635. tuner_transfer(fe, &msg, 1);
  636. tuner_reg[0] = 0xb0;
  637. tuner_reg[1] = 0x01;
  638. tuner_transfer(fe, &msg, 1);
  639. tuner_reg[0] = 0xc0;
  640. tuner_reg[1] = 0x19 + (priv->lpsel << 1);
  641. tuner_transfer(fe, &msg, 1);
  642. priv->frequency = params->frequency;
  643. return 0;
  644. }
  645. static void tda827xa_agcf(struct dvb_frontend *fe)
  646. {
  647. struct tda827x_priv *priv = fe->tuner_priv;
  648. unsigned char data[] = {0x80, 0x2c};
  649. struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
  650. .buf = data, .len = 2};
  651. tuner_transfer(fe, &msg, 1);
  652. }
  653. /* ------------------------------------------------------------------ */
  654. static void tda827x_release(struct dvb_frontend *fe)
  655. {
  656. kfree(fe->tuner_priv);
  657. fe->tuner_priv = NULL;
  658. }
  659. static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
  660. {
  661. struct tda827x_priv *priv = fe->tuner_priv;
  662. *frequency = priv->frequency;
  663. return 0;
  664. }
  665. static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
  666. {
  667. struct tda827x_priv *priv = fe->tuner_priv;
  668. *bandwidth = priv->bandwidth;
  669. return 0;
  670. }
  671. static int tda827x_init(struct dvb_frontend *fe)
  672. {
  673. struct tda827x_priv *priv = fe->tuner_priv;
  674. dprintk("%s:\n", __func__);
  675. if (priv->cfg && priv->cfg->init)
  676. priv->cfg->init(fe);
  677. return 0;
  678. }
  679. static int tda827x_probe_version(struct dvb_frontend *fe);
  680. static int tda827x_initial_init(struct dvb_frontend *fe)
  681. {
  682. int ret;
  683. ret = tda827x_probe_version(fe);
  684. if (ret)
  685. return ret;
  686. return fe->ops.tuner_ops.init(fe);
  687. }
  688. static int tda827x_initial_sleep(struct dvb_frontend *fe)
  689. {
  690. int ret;
  691. ret = tda827x_probe_version(fe);
  692. if (ret)
  693. return ret;
  694. return fe->ops.tuner_ops.sleep(fe);
  695. }
  696. static const struct dvb_tuner_ops tda827xo_tuner_ops = {
  697. .info = {
  698. .name = "Philips TDA827X",
  699. .frequency_min_hz = 55 * MHz,
  700. .frequency_max_hz = 860 * MHz,
  701. .frequency_step_hz = 250 * kHz
  702. },
  703. .release = tda827x_release,
  704. .init = tda827x_initial_init,
  705. .sleep = tda827x_initial_sleep,
  706. .set_params = tda827xo_set_params,
  707. .set_analog_params = tda827xo_set_analog_params,
  708. .get_frequency = tda827x_get_frequency,
  709. .get_bandwidth = tda827x_get_bandwidth,
  710. };
  711. static const struct dvb_tuner_ops tda827xa_tuner_ops = {
  712. .info = {
  713. .name = "Philips TDA827XA",
  714. .frequency_min_hz = 44 * MHz,
  715. .frequency_max_hz = 906 * MHz,
  716. .frequency_step_hz = 62500
  717. },
  718. .release = tda827x_release,
  719. .init = tda827x_init,
  720. .sleep = tda827xa_sleep,
  721. .set_params = tda827xa_set_params,
  722. .set_analog_params = tda827xa_set_analog_params,
  723. .get_frequency = tda827x_get_frequency,
  724. .get_bandwidth = tda827x_get_bandwidth,
  725. };
  726. static int tda827x_probe_version(struct dvb_frontend *fe)
  727. {
  728. u8 data;
  729. int rc;
  730. struct tda827x_priv *priv = fe->tuner_priv;
  731. struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
  732. .buf = &data, .len = 1 };
  733. rc = tuner_transfer(fe, &msg, 1);
  734. if (rc < 0) {
  735. printk("%s: could not read from tuner at addr: 0x%02x\n",
  736. __func__, msg.addr << 1);
  737. return rc;
  738. }
  739. if ((data & 0x3c) == 0) {
  740. dprintk("tda827x tuner found\n");
  741. fe->ops.tuner_ops.init = tda827x_init;
  742. fe->ops.tuner_ops.sleep = tda827xo_sleep;
  743. if (priv->cfg)
  744. priv->cfg->agcf = tda827xo_agcf;
  745. } else {
  746. dprintk("tda827xa tuner found\n");
  747. memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
  748. if (priv->cfg)
  749. priv->cfg->agcf = tda827xa_agcf;
  750. }
  751. return 0;
  752. }
  753. struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
  754. struct i2c_adapter *i2c,
  755. struct tda827x_config *cfg)
  756. {
  757. struct tda827x_priv *priv = NULL;
  758. dprintk("%s:\n", __func__);
  759. priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
  760. if (priv == NULL)
  761. return NULL;
  762. priv->i2c_addr = addr;
  763. priv->i2c_adap = i2c;
  764. priv->cfg = cfg;
  765. memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
  766. fe->tuner_priv = priv;
  767. dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
  768. return fe;
  769. }
  770. EXPORT_SYMBOL_GPL(tda827x_attach);
  771. MODULE_DESCRIPTION("DVB TDA827x driver");
  772. MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
  773. MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
  774. MODULE_LICENSE("GPL");