tuner-simple.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035
  1. /*
  2. *
  3. * i2c tv tuner chip device driver
  4. * controls all those simple 4-control-bytes style tuners.
  5. */
  6. #include <linux/delay.h>
  7. #include <linux/i2c.h>
  8. #include <linux/videodev.h>
  9. #include <media/tuner.h>
  10. static int offset = 0;
  11. module_param(offset, int, 0666);
  12. MODULE_PARM_DESC(offset,"Allows to specify an offset for tuner");
  13. /* ---------------------------------------------------------------------- */
  14. /* tv standard selection for Temic 4046 FM5
  15. this value takes the low bits of control byte 2
  16. from datasheet Rev.01, Feb.00
  17. standard BG I L L2 D
  18. picture IF 38.9 38.9 38.9 33.95 38.9
  19. sound 1 33.4 32.9 32.4 40.45 32.4
  20. sound 2 33.16
  21. NICAM 33.05 32.348 33.05 33.05
  22. */
  23. #define TEMIC_SET_PAL_I 0x05
  24. #define TEMIC_SET_PAL_DK 0x09
  25. #define TEMIC_SET_PAL_L 0x0a // SECAM ?
  26. #define TEMIC_SET_PAL_L2 0x0b // change IF !
  27. #define TEMIC_SET_PAL_BG 0x0c
  28. /* tv tuner system standard selection for Philips FQ1216ME
  29. this value takes the low bits of control byte 2
  30. from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
  31. standard BG DK I L L`
  32. picture carrier 38.90 38.90 38.90 38.90 33.95
  33. colour 34.47 34.47 34.47 34.47 38.38
  34. sound 1 33.40 32.40 32.90 32.40 40.45
  35. sound 2 33.16 - - - -
  36. NICAM 33.05 33.05 32.35 33.05 39.80
  37. */
  38. #define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
  39. #define PHILIPS_SET_PAL_BGDK 0x09
  40. #define PHILIPS_SET_PAL_L2 0x0a
  41. #define PHILIPS_SET_PAL_L 0x0b
  42. /* system switching for Philips FI1216MF MK2
  43. from datasheet "1996 Jul 09",
  44. standard BG L L'
  45. picture carrier 38.90 38.90 33.95
  46. colour 34.47 34.37 38.38
  47. sound 1 33.40 32.40 40.45
  48. sound 2 33.16 - -
  49. NICAM 33.05 33.05 39.80
  50. */
  51. #define PHILIPS_MF_SET_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
  52. #define PHILIPS_MF_SET_PAL_L 0x03 // France
  53. #define PHILIPS_MF_SET_PAL_L2 0x02 // L'
  54. /* Control byte */
  55. #define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */
  56. #define TUNER_RATIO_SELECT_50 0x00
  57. #define TUNER_RATIO_SELECT_32 0x02
  58. #define TUNER_RATIO_SELECT_166 0x04
  59. #define TUNER_RATIO_SELECT_62 0x06
  60. #define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */
  61. /* Status byte */
  62. #define TUNER_POR 0x80
  63. #define TUNER_FL 0x40
  64. #define TUNER_MODE 0x38
  65. #define TUNER_AFC 0x07
  66. #define TUNER_SIGNAL 0x07
  67. #define TUNER_STEREO 0x10
  68. #define TUNER_PLL_LOCKED 0x40
  69. #define TUNER_STEREO_MK3 0x04
  70. /* ---------------------------------------------------------------------- */
  71. struct tunertype
  72. {
  73. char *name;
  74. unsigned short thresh1; /* band switch VHF_LO <=> VHF_HI */
  75. unsigned short thresh2; /* band switch VHF_HI <=> UHF */
  76. unsigned char VHF_L;
  77. unsigned char VHF_H;
  78. unsigned char UHF;
  79. unsigned char config;
  80. };
  81. /*
  82. * The floats in the tuner struct are computed at compile time
  83. * by gcc and cast back to integers. Thus we don't violate the
  84. * "no float in kernel" rule.
  85. */
  86. static struct tunertype tuners[] = {
  87. /* 0-9 */
  88. [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
  89. .name = "Temic PAL (4002 FH5)",
  90. .thresh1= 16 * 140.25 /*MHz*/,
  91. .thresh2= 16 * 463.25 /*MHz*/,
  92. .VHF_L = 0x02,
  93. .VHF_H = 0x04,
  94. .UHF = 0x01,
  95. .config = 0x8e,
  96. },
  97. [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
  98. .name = "Philips PAL_I (FI1246 and compatibles)",
  99. .thresh1= 16 * 140.25 /*MHz*/,
  100. .thresh2= 16 * 463.25 /*MHz*/,
  101. .VHF_L = 0xa0,
  102. .VHF_H = 0x90,
  103. .UHF = 0x30,
  104. .config = 0x8e,
  105. },
  106. [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
  107. .name = "Philips NTSC (FI1236,FM1236 and compatibles)",
  108. .thresh1= 16 * 157.25 /*MHz*/,
  109. .thresh2= 16 * 451.25 /*MHz*/,
  110. .VHF_L = 0xa0,
  111. .VHF_H = 0x90,
  112. .UHF = 0x30,
  113. .config = 0x8e,
  114. },
  115. [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
  116. .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
  117. .thresh1= 16 * 168.25 /*MHz*/,
  118. .thresh2= 16 * 447.25 /*MHz*/,
  119. .VHF_L = 0xa7,
  120. .VHF_H = 0x97,
  121. .UHF = 0x37,
  122. .config = 0x8e,
  123. },
  124. [TUNER_ABSENT] = { /* Tuner Absent */
  125. .name = "NoTuner",
  126. .thresh1= 0 /*MHz*/,
  127. .thresh2= 0 /*MHz*/,
  128. .VHF_L = 0x00,
  129. .VHF_H = 0x00,
  130. .UHF = 0x00,
  131. .config = 0x00,
  132. },
  133. [TUNER_PHILIPS_PAL] = { /* Philips PAL */
  134. .name = "Philips PAL_BG (FI1216 and compatibles)",
  135. .thresh1= 16 * 168.25 /*MHz*/,
  136. .thresh2= 16 * 447.25 /*MHz*/,
  137. .VHF_L = 0xa0,
  138. .VHF_H = 0x90,
  139. .UHF = 0x30,
  140. .config = 0x8e,
  141. },
  142. [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
  143. .name = "Temic NTSC (4032 FY5)",
  144. .thresh1= 16 * 157.25 /*MHz*/,
  145. .thresh2= 16 * 463.25 /*MHz*/,
  146. .VHF_L = 0x02,
  147. .VHF_H = 0x04,
  148. .UHF = 0x01,
  149. .config = 0x8e,
  150. },
  151. [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
  152. .name = "Temic PAL_I (4062 FY5)",
  153. .thresh1= 16 * 170.00 /*MHz*/,
  154. .thresh2= 16 * 450.00 /*MHz*/,
  155. .VHF_L = 0x02,
  156. .VHF_H = 0x04,
  157. .UHF = 0x01,
  158. .config = 0x8e,
  159. },
  160. [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
  161. .name = "Temic NTSC (4036 FY5)",
  162. .thresh1= 16 * 157.25 /*MHz*/,
  163. .thresh2= 16 * 463.25 /*MHz*/,
  164. .VHF_L = 0xa0,
  165. .VHF_H = 0x90,
  166. .UHF = 0x30,
  167. .config = 0x8e,
  168. },
  169. [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
  170. .name = "Alps HSBH1",
  171. .thresh1= 16 * 137.25 /*MHz*/,
  172. .thresh2= 16 * 385.25 /*MHz*/,
  173. .VHF_L = 0x01,
  174. .VHF_H = 0x02,
  175. .UHF = 0x08,
  176. .config = 0x8e,
  177. },
  178. /* 10-19 */
  179. [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
  180. .name = "Alps TSBE1",
  181. .thresh1= 16 * 137.25 /*MHz*/,
  182. .thresh2= 16 * 385.25 /*MHz*/,
  183. .VHF_L = 0x01,
  184. .VHF_H = 0x02,
  185. .UHF = 0x08,
  186. .config = 0x8e,
  187. },
  188. [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
  189. .name = "Alps TSBB5",
  190. .thresh1= 16 * 133.25 /*MHz*/,
  191. .thresh2= 16 * 351.25 /*MHz*/,
  192. .VHF_L = 0x01,
  193. .VHF_H = 0x02,
  194. .UHF = 0x08,
  195. .config = 0x8e,
  196. },
  197. [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
  198. .name = "Alps TSBE5",
  199. .thresh1= 16 * 133.25 /*MHz*/,
  200. .thresh2= 16 * 351.25 /*MHz*/,
  201. .VHF_L = 0x01,
  202. .VHF_H = 0x02,
  203. .UHF = 0x08,
  204. .config = 0x8e,
  205. },
  206. [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
  207. .name = "Alps TSBC5",
  208. .thresh1= 16 * 133.25 /*MHz*/,
  209. .thresh2= 16 * 351.25 /*MHz*/,
  210. .VHF_L = 0x01,
  211. .VHF_H = 0x02,
  212. .UHF = 0x08,
  213. .config = 0x8e,
  214. },
  215. [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
  216. .name = "Temic PAL_BG (4006FH5)",
  217. .thresh1= 16 * 170.00 /*MHz*/,
  218. .thresh2= 16 * 450.00 /*MHz*/,
  219. .VHF_L = 0xa0,
  220. .VHF_H = 0x90,
  221. .UHF = 0x30,
  222. .config = 0x8e,
  223. },
  224. [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
  225. .name = "Alps TSCH6",
  226. .thresh1= 16 * 137.25 /*MHz*/,
  227. .thresh2= 16 * 385.25 /*MHz*/,
  228. .VHF_L = 0x14,
  229. .VHF_H = 0x12,
  230. .UHF = 0x11,
  231. .config = 0x8e,
  232. },
  233. [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
  234. .name = "Temic PAL_DK (4016 FY5)",
  235. .thresh1= 16 * 168.25 /*MHz*/,
  236. .thresh2= 16 * 456.25 /*MHz*/,
  237. .VHF_L = 0xa0,
  238. .VHF_H = 0x90,
  239. .UHF = 0x30,
  240. .config = 0x8e,
  241. },
  242. [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
  243. .name = "Philips NTSC_M (MK2)",
  244. .thresh1= 16 * 160.00 /*MHz*/,
  245. .thresh2= 16 * 454.00 /*MHz*/,
  246. .VHF_L = 0xa0,
  247. .VHF_H = 0x90,
  248. .UHF = 0x30,
  249. .config = 0x8e,
  250. },
  251. [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
  252. .name = "Temic PAL_I (4066 FY5)",
  253. .thresh1= 16 * 169.00 /*MHz*/,
  254. .thresh2= 16 * 454.00 /*MHz*/,
  255. .VHF_L = 0xa0,
  256. .VHF_H = 0x90,
  257. .UHF = 0x30,
  258. .config = 0x8e,
  259. },
  260. [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
  261. .name = "Temic PAL* auto (4006 FN5)",
  262. .thresh1= 16 * 169.00 /*MHz*/,
  263. .thresh2= 16 * 454.00 /*MHz*/,
  264. .VHF_L = 0xa0,
  265. .VHF_H = 0x90,
  266. .UHF = 0x30,
  267. .config = 0x8e,
  268. },
  269. /* 20-29 */
  270. [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
  271. .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
  272. .thresh1= 16 * 141.00 /*MHz*/,
  273. .thresh2= 16 * 464.00 /*MHz*/,
  274. .VHF_L = 0xa0,
  275. .VHF_H = 0x90,
  276. .UHF = 0x30,
  277. .config = 0x8e,
  278. },
  279. [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
  280. .name = "Temic NTSC (4039 FR5)",
  281. .thresh1= 16 * 158.00 /*MHz*/,
  282. .thresh2= 16 * 453.00 /*MHz*/,
  283. .VHF_L = 0xa0,
  284. .VHF_H = 0x90,
  285. .UHF = 0x30,
  286. .config = 0x8e,
  287. },
  288. [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
  289. .name = "Temic PAL/SECAM multi (4046 FM5)",
  290. .thresh1= 16 * 169.00 /*MHz*/,
  291. .thresh2= 16 * 454.00 /*MHz*/,
  292. .VHF_L = 0xa0,
  293. .VHF_H = 0x90,
  294. .UHF = 0x30,
  295. .config = 0x8e,
  296. },
  297. [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
  298. .name = "Philips PAL_DK (FI1256 and compatibles)",
  299. .thresh1= 16 * 170.00 /*MHz*/,
  300. .thresh2= 16 * 450.00 /*MHz*/,
  301. .VHF_L = 0xa0,
  302. .VHF_H = 0x90,
  303. .UHF = 0x30,
  304. .config = 0x8e,
  305. },
  306. [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
  307. .name = "Philips PAL/SECAM multi (FQ1216ME)",
  308. .thresh1= 16 * 170.00 /*MHz*/,
  309. .thresh2= 16 * 450.00 /*MHz*/,
  310. .VHF_L = 0xa0,
  311. .VHF_H = 0x90,
  312. .UHF = 0x30,
  313. .config = 0x8e,
  314. },
  315. [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
  316. .name = "LG PAL_I+FM (TAPC-I001D)",
  317. .thresh1= 16 * 170.00 /*MHz*/,
  318. .thresh2= 16 * 450.00 /*MHz*/,
  319. .VHF_L = 0xa0,
  320. .VHF_H = 0x90,
  321. .UHF = 0x30,
  322. .config = 0x8e,
  323. },
  324. [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
  325. .name = "LG PAL_I (TAPC-I701D)",
  326. .thresh1= 16 * 170.00 /*MHz*/,
  327. .thresh2= 16 * 450.00 /*MHz*/,
  328. .VHF_L = 0xa0,
  329. .VHF_H = 0x90,
  330. .UHF = 0x30,
  331. .config = 0x8e,
  332. },
  333. [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
  334. .name = "LG NTSC+FM (TPI8NSR01F)",
  335. .thresh1= 16 * 210.00 /*MHz*/,
  336. .thresh2= 16 * 497.00 /*MHz*/,
  337. .VHF_L = 0xa0,
  338. .VHF_H = 0x90,
  339. .UHF = 0x30,
  340. .config = 0x8e,
  341. },
  342. [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
  343. .name = "LG PAL_BG+FM (TPI8PSB01D)",
  344. .thresh1= 16 * 170.00 /*MHz*/,
  345. .thresh2= 16 * 450.00 /*MHz*/,
  346. .VHF_L = 0xa0,
  347. .VHF_H = 0x90,
  348. .UHF = 0x30,
  349. .config = 0x8e,
  350. },
  351. [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
  352. .name = "LG PAL_BG (TPI8PSB11D)",
  353. .thresh1= 16 * 170.00 /*MHz*/,
  354. .thresh2= 16 * 450.00 /*MHz*/,
  355. .VHF_L = 0xa0,
  356. .VHF_H = 0x90,
  357. .UHF = 0x30,
  358. .config = 0x8e,
  359. },
  360. /* 30-39 */
  361. [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
  362. .name = "Temic PAL* auto + FM (4009 FN5)",
  363. .thresh1= 16 * 141.00 /*MHz*/,
  364. .thresh2= 16 * 464.00 /*MHz*/,
  365. .VHF_L = 0xa0,
  366. .VHF_H = 0x90,
  367. .UHF = 0x30,
  368. .config = 0x8e,
  369. },
  370. [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
  371. .name = "SHARP NTSC_JP (2U5JF5540)",
  372. .thresh1= 16 * 137.25 /*MHz*/,
  373. .thresh2= 16 * 317.25 /*MHz*/,
  374. .VHF_L = 0x01,
  375. .VHF_H = 0x02,
  376. .UHF = 0x08,
  377. .config = 0x8e,
  378. },
  379. [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
  380. .name = "Samsung PAL TCPM9091PD27",
  381. .thresh1= 16 * 169 /*MHz*/,
  382. .thresh2= 16 * 464 /*MHz*/,
  383. .VHF_L = 0xa0,
  384. .VHF_H = 0x90,
  385. .UHF = 0x30,
  386. .config = 0x8e,
  387. },
  388. [TUNER_MT2032] = { /* Microtune PAL|NTSC */
  389. .name = "MT20xx universal",
  390. /* see mt20xx.c for details */ },
  391. [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
  392. .name = "Temic PAL_BG (4106 FH5)",
  393. .thresh1= 16 * 141.00 /*MHz*/,
  394. .thresh2= 16 * 464.00 /*MHz*/,
  395. .VHF_L = 0xa0,
  396. .VHF_H = 0x90,
  397. .UHF = 0x30,
  398. .config = 0x8e,
  399. },
  400. [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
  401. .name = "Temic PAL_DK/SECAM_L (4012 FY5)",
  402. .thresh1= 16 * 140.25 /*MHz*/,
  403. .thresh2= 16 * 463.25 /*MHz*/,
  404. .VHF_L = 0x02,
  405. .VHF_H = 0x04,
  406. .UHF = 0x01,
  407. .config = 0x8e,
  408. },
  409. [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
  410. .name = "Temic NTSC (4136 FY5)",
  411. .thresh1= 16 * 158.00 /*MHz*/,
  412. .thresh2= 16 * 453.00 /*MHz*/,
  413. .VHF_L = 0xa0,
  414. .VHF_H = 0x90,
  415. .UHF = 0x30,
  416. .config = 0x8e,
  417. },
  418. [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
  419. .name = "LG PAL (newer TAPC series)",
  420. .thresh1= 16 * 170.00 /*MHz*/,
  421. .thresh2= 16 * 450.00 /*MHz*/,
  422. .VHF_L = 0x01,
  423. .VHF_H = 0x02,
  424. .UHF = 0x08,
  425. .config = 0x8e,
  426. },
  427. [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
  428. .name = "Philips PAL/SECAM multi (FM1216ME MK3)",
  429. .thresh1= 16 * 158.00 /*MHz*/,
  430. .thresh2= 16 * 442.00 /*MHz*/,
  431. .VHF_L = 0x01,
  432. .VHF_H = 0x02,
  433. .UHF = 0x04,
  434. .config = 0x8e,
  435. },
  436. [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
  437. .name = "LG NTSC (newer TAPC series)",
  438. .thresh1= 16 * 170.00 /*MHz*/,
  439. .thresh2= 16 * 450.00 /*MHz*/,
  440. .VHF_L = 0x01,
  441. .VHF_H = 0x02,
  442. .UHF = 0x08,
  443. .config = 0x8e,
  444. },
  445. /* 40-49 */
  446. [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
  447. .name = "HITACHI V7-J180AT",
  448. .thresh1= 16 * 170.00 /*MHz*/,
  449. .thresh2= 16 * 450.00 /*MHz*/,
  450. .VHF_L = 0x01,
  451. .VHF_H = 0x02,
  452. .UHF = 0x08,
  453. .config = 0x8e,
  454. },
  455. [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
  456. .name = "Philips PAL_MK (FI1216 MK)",
  457. .thresh1= 16 * 140.25 /*MHz*/,
  458. .thresh2= 16 * 463.25 /*MHz*/,
  459. .VHF_L = 0x01,
  460. .VHF_H = 0xc2,
  461. .UHF = 0xcf,
  462. .config = 0x8e,
  463. },
  464. [TUNER_PHILIPS_ATSC] = { /* Philips ATSC */
  465. .name = "Philips 1236D ATSC/NTSC daul in",
  466. .thresh1= 16 * 157.25 /*MHz*/,
  467. .thresh2= 16 * 454.00 /*MHz*/,
  468. .VHF_L = 0xa0,
  469. .VHF_H = 0x90,
  470. .UHF = 0x30,
  471. .config = 0x8e,
  472. },
  473. [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
  474. .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
  475. .thresh1= 16 * 160.00 /*MHz*/,
  476. .thresh2= 16 * 442.00 /*MHz*/,
  477. .VHF_L = 0x01,
  478. .VHF_H = 0x02,
  479. .UHF = 0x04,
  480. .config = 0x8e,
  481. },
  482. [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
  483. .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
  484. .thresh1= 16 * 160.00 /*MHz*/,
  485. .thresh2= 16 * 442.00 /*MHz*/,
  486. .VHF_L = 0x01,
  487. .VHF_H = 0x02,
  488. .UHF = 0x04,
  489. .config = 0x8e,
  490. },
  491. [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
  492. .name = "Microtune 4049 FM5",
  493. .thresh1= 16 * 141.00 /*MHz*/,
  494. .thresh2= 16 * 464.00 /*MHz*/,
  495. .VHF_L = 0xa0,
  496. .VHF_H = 0x90,
  497. .UHF = 0x30,
  498. .config = 0x8e,
  499. },
  500. [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
  501. .name = "Panasonic VP27s/ENGE4324D",
  502. .thresh1= 16 * 160.00 /*MHz*/,
  503. .thresh2= 16 * 454.00 /*MHz*/,
  504. .VHF_L = 0x01,
  505. .VHF_H = 0x02,
  506. .UHF = 0x08,
  507. .config = 0xce,
  508. },
  509. [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
  510. .name = "LG NTSC (TAPE series)",
  511. .thresh1= 16 * 160.00 /*MHz*/,
  512. .thresh2= 16 * 442.00 /*MHz*/,
  513. .VHF_L = 0x01,
  514. .VHF_H = 0x02,
  515. .UHF = 0x04,
  516. .config = 0x8e,
  517. },
  518. [TUNER_TNF_8831BGFF] = { /* Philips PAL */
  519. .name = "Tenna TNF 8831 BGFF)",
  520. .thresh1= 16 * 161.25 /*MHz*/,
  521. .thresh2= 16 * 463.25 /*MHz*/,
  522. .VHF_L = 0xa0,
  523. .VHF_H = 0x90,
  524. .UHF = 0x30,
  525. .config = 0x8e,
  526. },
  527. [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
  528. .name = "Microtune 4042 FI5 ATSC/NTSC dual in",
  529. .thresh1= 16 * 162.00 /*MHz*/,
  530. .thresh2= 16 * 457.00 /*MHz*/,
  531. .VHF_L = 0xa2,
  532. .VHF_H = 0x94,
  533. .UHF = 0x31,
  534. .config = 0x8e,
  535. },
  536. /* 50-59 */
  537. [TUNER_TCL_2002N] = { /* TCL NTSC */
  538. .name = "TCL 2002N",
  539. .thresh1= 16 * 172.00 /*MHz*/,
  540. .thresh2= 16 * 448.00 /*MHz*/,
  541. .VHF_L = 0x01,
  542. .VHF_H = 0x02,
  543. .UHF = 0x08,
  544. .config = 0x8e,
  545. },
  546. [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
  547. .name = "Philips PAL/SECAM_D (FM 1256 I-H3)",
  548. .thresh1= 16 * 160.00 /*MHz*/,
  549. .thresh2= 16 * 442.00 /*MHz*/,
  550. .VHF_L = 0x01,
  551. .VHF_H = 0x02,
  552. .UHF = 0x04,
  553. .config = 0x8e,
  554. },
  555. [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
  556. .name = "Thomson DDT 7610 (ATSC/NTSC)",
  557. .thresh1= 16 * 157.25 /*MHz*/,
  558. .thresh2= 16 * 454.00 /*MHz*/,
  559. .VHF_L = 0x39,
  560. .VHF_H = 0x3a,
  561. .UHF = 0x3c,
  562. .config = 0x8e,
  563. },
  564. [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
  565. .name = "Philips FQ1286",
  566. .thresh1= 16 * 160.00 /*MHz*/,
  567. .thresh2= 16 * 454.00 /*MHz*/,
  568. .VHF_L = 0x41,
  569. .VHF_H = 0x42,
  570. .UHF = 0x04,
  571. .config = 0x8e,
  572. },
  573. [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
  574. .name = "tda8290+75",
  575. /* see tda8290.c for details */ },
  576. [TUNER_TCL_2002MB] = { /* TCL PAL */
  577. .name = "TCL 2002MB",
  578. .thresh1= 16 * 170.00 /*MHz*/,
  579. .thresh2= 16 * 450.00 /*MHz*/,
  580. .VHF_L = 0x01,
  581. .VHF_H = 0x02,
  582. .UHF = 0x08,
  583. .config = 0xce,
  584. },
  585. [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
  586. .name = "Philips PAL/SECAM multi (FQ1216AME MK4)",
  587. .thresh1= 16 * 160.00 /*MHz*/,
  588. .thresh2= 16 * 442.00 /*MHz*/,
  589. .VHF_L = 0x01,
  590. .VHF_H = 0x02,
  591. .UHF = 0x04,
  592. .config = 0xce,
  593. },
  594. [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
  595. .name = "Philips FQ1236A MK4",
  596. .thresh1= 16 * 160.00 /*MHz*/,
  597. .thresh2= 16 * 442.00 /*MHz*/,
  598. .VHF_L = 0x01,
  599. .VHF_H = 0x02,
  600. .UHF = 0x04,
  601. .config = 0x8e,
  602. },
  603. [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
  604. .name = "Ymec TVision TVF-8531MF/8831MF/8731MF",
  605. .thresh1= 16 * 160.00 /*MHz*/,
  606. .thresh2= 16 * 454.00 /*MHz*/,
  607. .VHF_L = 0xa0,
  608. .VHF_H = 0x90,
  609. .UHF = 0x30,
  610. .config = 0x8e,
  611. },
  612. [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
  613. .name = "Ymec TVision TVF-5533MF",
  614. .thresh1= 16 * 160.00 /*MHz*/,
  615. .thresh2= 16 * 454.00 /*MHz*/,
  616. .VHF_L = 0x01,
  617. .VHF_H = 0x02,
  618. .UHF = 0x04,
  619. .config = 0x8e,
  620. },
  621. /* 60-69 */
  622. [TUNER_THOMSON_DTT7611] = { /* THOMSON ATSC */
  623. .name = "Thomson DDT 7611 (ATSC/NTSC)",
  624. .thresh1= 16 * 157.25 /*MHz*/,
  625. .thresh2= 16 * 454.00 /*MHz*/,
  626. .VHF_L = 0x39,
  627. .VHF_H = 0x3a,
  628. .UHF = 0x3c,
  629. .config = 0x8e,
  630. },
  631. [TUNER_TENA_9533_DI] = { /* Philips PAL */
  632. .name = "Tena TNF9533-D/IF/TNF9533-B/DF",
  633. .thresh1= 16 * 160.25 /*MHz*/,
  634. .thresh2= 16 * 464.25 /*MHz*/,
  635. .VHF_L = 0x01,
  636. .VHF_H = 0x02,
  637. .UHF = 0x04,
  638. .config = 0x8e,
  639. },
  640. [TUNER_TEA5767] = { /* Philips RADIO */
  641. .name = "Philips TEA5767HN FM Radio",
  642. /* see tea5767.c for details */},
  643. [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
  644. .name = "Philips FMD1216ME MK3 Hybrid Tuner",
  645. .thresh1= 16 * 160.00 /*MHz*/,
  646. .thresh2= 16 * 442.00 /*MHz*/,
  647. .VHF_L = 0x51,
  648. .VHF_H = 0x52,
  649. .UHF = 0x54,
  650. .config = 0x86,
  651. },
  652. [TUNER_LG_TDVS_H062F] = { /* LGINNOTEK ATSC */
  653. .name = "LG TDVS-H062F/TUA6034",
  654. .thresh1= 16 * 160.00 /*MHz*/,
  655. .thresh2= 16 * 455.00 /*MHz*/,
  656. .VHF_L = 0x01,
  657. .VHF_H = 0x02,
  658. .UHF = 0x04,
  659. .config = 0x8e,
  660. },
  661. [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
  662. .name = "Ymec TVF66T5-B/DFF",
  663. .thresh1= 16 * 160.25 /*MHz*/,
  664. .thresh2= 16 * 464.25 /*MHz*/,
  665. .VHF_L = 0x01,
  666. .VHF_H = 0x02,
  667. .UHF = 0x08,
  668. .config = 0x8e,
  669. },
  670. [TUNER_LG_NTSC_TALN_MINI] = { /* LGINNOTEK NTSC */
  671. .name = "LG NTSC (TALN mini series)",
  672. .thresh1= 16 * 137.25 /*MHz*/,
  673. .thresh2= 16 * 373.25 /*MHz*/,
  674. .VHF_L = 0x01,
  675. .VHF_H = 0x02,
  676. .UHF = 0x08,
  677. .config = 0x8e,
  678. },
  679. [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
  680. .name = "Philips TD1316 Hybrid Tuner",
  681. .thresh1= 16 * 160.00 /*MHz*/,
  682. .thresh2= 16 * 442.00 /*MHz*/,
  683. .VHF_L = 0xa1,
  684. .VHF_H = 0xa2,
  685. .UHF = 0xa4,
  686. .config = 0xc8,
  687. },
  688. [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
  689. .name = "Philips TUV1236D ATSC/NTSC dual in",
  690. .thresh1= 16 * 157.25 /*MHz*/,
  691. .thresh2= 16 * 454.00 /*MHz*/,
  692. .VHF_L = 0x01,
  693. .VHF_H = 0x02,
  694. .UHF = 0x04,
  695. .config = 0xce,
  696. },
  697. [TUNER_TNF_5335MF] = { /* Philips NTSC */
  698. .name = "Tena TNF 5335 MF",
  699. .thresh1= 16 * 157.25 /*MHz*/,
  700. .thresh2= 16 * 454.00 /*MHz*/,
  701. .VHF_L = 0x01,
  702. .VHF_H = 0x02,
  703. .UHF = 0x04,
  704. .config = 0x8e,
  705. },
  706. };
  707. unsigned const int tuner_count = ARRAY_SIZE(tuners);
  708. /* ---------------------------------------------------------------------- */
  709. static int tuner_getstatus(struct i2c_client *c)
  710. {
  711. unsigned char byte;
  712. if (1 != i2c_master_recv(c,&byte,1))
  713. return 0;
  714. return byte;
  715. }
  716. static int tuner_signal(struct i2c_client *c)
  717. {
  718. return (tuner_getstatus(c) & TUNER_SIGNAL) << 13;
  719. }
  720. static int tuner_stereo(struct i2c_client *c)
  721. {
  722. int stereo, status;
  723. struct tuner *t = i2c_get_clientdata(c);
  724. status = tuner_getstatus (c);
  725. switch (t->type) {
  726. case TUNER_PHILIPS_FM1216ME_MK3:
  727. case TUNER_PHILIPS_FM1236_MK3:
  728. case TUNER_PHILIPS_FM1256_IH3:
  729. stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
  730. break;
  731. default:
  732. stereo = status & TUNER_STEREO;
  733. }
  734. return stereo;
  735. }
  736. /* ---------------------------------------------------------------------- */
  737. static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
  738. {
  739. struct tuner *t = i2c_get_clientdata(c);
  740. u8 config, tuneraddr;
  741. u16 div;
  742. struct tunertype *tun;
  743. unsigned char buffer[4];
  744. int rc, IFPCoff;
  745. tun = &tuners[t->type];
  746. if (freq < tun->thresh1) {
  747. config = tun->VHF_L;
  748. tuner_dbg("tv: VHF lowrange\n");
  749. } else if (freq < tun->thresh2) {
  750. config = tun->VHF_H;
  751. tuner_dbg("tv: VHF high range\n");
  752. } else {
  753. config = tun->UHF;
  754. tuner_dbg("tv: UHF range\n");
  755. }
  756. /* tv norm specific stuff for multi-norm tuners */
  757. switch (t->type) {
  758. case TUNER_PHILIPS_SECAM: // FI1216MF
  759. /* 0x01 -> ??? no change ??? */
  760. /* 0x02 -> PAL BDGHI / SECAM L */
  761. /* 0x04 -> ??? PAL others / SECAM others ??? */
  762. config &= ~0x02;
  763. if (t->std & V4L2_STD_SECAM)
  764. config |= 0x02;
  765. break;
  766. case TUNER_TEMIC_4046FM5:
  767. config &= ~0x0f;
  768. if (t->std & V4L2_STD_PAL_BG) {
  769. config |= TEMIC_SET_PAL_BG;
  770. } else if (t->std & V4L2_STD_PAL_I) {
  771. config |= TEMIC_SET_PAL_I;
  772. } else if (t->std & V4L2_STD_PAL_DK) {
  773. config |= TEMIC_SET_PAL_DK;
  774. } else if (t->std & V4L2_STD_SECAM_L) {
  775. config |= TEMIC_SET_PAL_L;
  776. }
  777. break;
  778. case TUNER_PHILIPS_FQ1216ME:
  779. config &= ~0x0f;
  780. if (t->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
  781. config |= PHILIPS_SET_PAL_BGDK;
  782. } else if (t->std & V4L2_STD_PAL_I) {
  783. config |= PHILIPS_SET_PAL_I;
  784. } else if (t->std & V4L2_STD_SECAM_L) {
  785. config |= PHILIPS_SET_PAL_L;
  786. }
  787. break;
  788. case TUNER_PHILIPS_ATSC:
  789. /* 0x00 -> ATSC antenna input 1 */
  790. /* 0x01 -> ATSC antenna input 2 */
  791. /* 0x02 -> NTSC antenna input 1 */
  792. /* 0x03 -> NTSC antenna input 2 */
  793. config &= ~0x03;
  794. if (!(t->std & V4L2_STD_ATSC))
  795. config |= 2;
  796. /* FIXME: input */
  797. break;
  798. case TUNER_MICROTUNE_4042FI5:
  799. /* Set the charge pump for fast tuning */
  800. tun->config |= TUNER_CHARGE_PUMP;
  801. break;
  802. case TUNER_PHILIPS_TUV1236D:
  803. /* 0x40 -> ATSC antenna input 1 */
  804. /* 0x48 -> ATSC antenna input 2 */
  805. /* 0x00 -> NTSC antenna input 1 */
  806. /* 0x08 -> NTSC antenna input 2 */
  807. buffer[0] = 0x14;
  808. buffer[1] = 0x00;
  809. buffer[2] = 0x17;
  810. buffer[3] = 0x00;
  811. config &= ~0x40;
  812. if (t->std & V4L2_STD_ATSC) {
  813. config |= 0x40;
  814. buffer[1] = 0x04;
  815. }
  816. /* set to the correct mode (analog or digital) */
  817. tuneraddr = c->addr;
  818. c->addr = 0x0a;
  819. if (2 != (rc = i2c_master_send(c,&buffer[0],2)))
  820. tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
  821. if (2 != (rc = i2c_master_send(c,&buffer[2],2)))
  822. tuner_warn("i2c i/o error: rc == %d (should be 2)\n",rc);
  823. c->addr = tuneraddr;
  824. /* FIXME: input */
  825. break;
  826. }
  827. /*
  828. * Philips FI1216MK2 remark from specification :
  829. * for channel selection involving band switching, and to ensure
  830. * smooth tuning to the desired channel without causing
  831. * unnecessary charge pump action, it is recommended to consider
  832. * the difference between wanted channel frequency and the
  833. * current channel frequency. Unnecessary charge pump action
  834. * will result in very low tuning voltage which may drive the
  835. * oscillator to extreme conditions.
  836. *
  837. * Progfou: specification says to send config data before
  838. * frequency in case (wanted frequency < current frequency).
  839. */
  840. /* IFPCoff = Video Intermediate Frequency - Vif:
  841. 940 =16*58.75 NTSC/J (Japan)
  842. 732 =16*45.75 M/N STD
  843. 704 =16*44 ATSC (at DVB code)
  844. 632 =16*39.50 I U.K.
  845. 622.4=16*38.90 B/G D/K I, L STD
  846. 592 =16*37.00 D China
  847. 590 =16.36.875 B Australia
  848. 543.2=16*33.95 L' STD
  849. 171.2=16*10.70 FM Radio (at set_radio_freq)
  850. */
  851. if (t->std & V4L2_STD_NTSC_M_JP) {
  852. IFPCoff = 940;
  853. } else if (t->std & V4L2_STD_MN) {
  854. IFPCoff = 732;
  855. } else if (t->std & V4L2_STD_SECAM_LC) {
  856. IFPCoff = 543;
  857. } else {
  858. IFPCoff = 623;
  859. }
  860. div=freq + IFPCoff + offset;
  861. if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
  862. buffer[0] = tun->config;
  863. buffer[1] = config;
  864. buffer[2] = (div>>8) & 0x7f;
  865. buffer[3] = div & 0xff;
  866. } else {
  867. buffer[0] = (div>>8) & 0x7f;
  868. buffer[1] = div & 0xff;
  869. buffer[2] = tun->config;
  870. buffer[3] = config;
  871. }
  872. tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
  873. buffer[0],buffer[1],buffer[2],buffer[3]);
  874. if (4 != (rc = i2c_master_send(c,buffer,4)))
  875. tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
  876. if (t->type == TUNER_MICROTUNE_4042FI5) {
  877. // FIXME - this may also work for other tuners
  878. unsigned long timeout = jiffies + msecs_to_jiffies(1);
  879. u8 status_byte = 0;
  880. /* Wait until the PLL locks */
  881. for (;;) {
  882. if (time_after(jiffies,timeout))
  883. return;
  884. if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
  885. tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
  886. break;
  887. }
  888. if (status_byte & TUNER_PLL_LOCKED)
  889. break;
  890. udelay(10);
  891. }
  892. /* Set the charge pump for optimized phase noise figure */
  893. tun->config &= ~TUNER_CHARGE_PUMP;
  894. buffer[0] = (div>>8) & 0x7f;
  895. buffer[1] = div & 0xff;
  896. buffer[2] = tun->config;
  897. buffer[3] = config;
  898. tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
  899. buffer[0],buffer[1],buffer[2],buffer[3]);
  900. if (4 != (rc = i2c_master_send(c,buffer,4)))
  901. tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
  902. }
  903. }
  904. static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
  905. {
  906. struct tunertype *tun;
  907. struct tuner *t = i2c_get_clientdata(c);
  908. unsigned char buffer[4];
  909. unsigned div;
  910. int rc;
  911. tun = &tuners[t->type];
  912. div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
  913. buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
  914. switch (t->type) {
  915. case TUNER_TENA_9533_DI:
  916. case TUNER_YMEC_TVF_5533MF:
  917. tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
  918. return;
  919. case TUNER_PHILIPS_FM1216ME_MK3:
  920. case TUNER_PHILIPS_FM1236_MK3:
  921. case TUNER_PHILIPS_FMD1216ME_MK3:
  922. buffer[3] = 0x19;
  923. break;
  924. case TUNER_PHILIPS_FM1256_IH3:
  925. div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
  926. buffer[3] = 0x19;
  927. break;
  928. case TUNER_LG_PAL_FM:
  929. buffer[3] = 0xa5;
  930. break;
  931. case TUNER_MICROTUNE_4049FM5:
  932. div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
  933. buffer[3] = 0xa4;
  934. break;
  935. default:
  936. buffer[3] = 0xa4;
  937. break;
  938. }
  939. buffer[0] = (div>>8) & 0x7f;
  940. buffer[1] = div & 0xff;
  941. tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
  942. buffer[0],buffer[1],buffer[2],buffer[3]);
  943. if (4 != (rc = i2c_master_send(c,buffer,4)))
  944. tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
  945. }
  946. int default_tuner_init(struct i2c_client *c)
  947. {
  948. struct tuner *t = i2c_get_clientdata(c);
  949. tuner_info("type set to %d (%s)\n",
  950. t->type, tuners[t->type].name);
  951. strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
  952. t->tv_freq = default_set_tv_freq;
  953. t->radio_freq = default_set_radio_freq;
  954. t->has_signal = tuner_signal;
  955. t->is_stereo = tuner_stereo;
  956. t->standby = NULL;
  957. return 0;
  958. }
  959. /*
  960. * Overrides for Emacs so that we follow Linus's tabbing style.
  961. * ---------------------------------------------------------------------------
  962. * Local variables:
  963. * c-basic-offset: 8
  964. * End:
  965. */