tuner-simple.c 26 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042
  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. tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, Offset=%d.%02d MHz, div=%0d\n",
  862. freq / 16, freq % 16 * 100 / 16,
  863. IFPCoff / 16, IFPCoff % 16 * 100 / 16,
  864. offset / 16, offset % 16 * 100 / 16,
  865. div);
  866. if (t->type == TUNER_PHILIPS_SECAM && freq < t->freq) {
  867. buffer[0] = tun->config;
  868. buffer[1] = config;
  869. buffer[2] = (div>>8) & 0x7f;
  870. buffer[3] = div & 0xff;
  871. } else {
  872. buffer[0] = (div>>8) & 0x7f;
  873. buffer[1] = div & 0xff;
  874. buffer[2] = tun->config;
  875. buffer[3] = config;
  876. }
  877. tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
  878. buffer[0],buffer[1],buffer[2],buffer[3]);
  879. if (4 != (rc = i2c_master_send(c,buffer,4)))
  880. tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
  881. if (t->type == TUNER_MICROTUNE_4042FI5) {
  882. // FIXME - this may also work for other tuners
  883. unsigned long timeout = jiffies + msecs_to_jiffies(1);
  884. u8 status_byte = 0;
  885. /* Wait until the PLL locks */
  886. for (;;) {
  887. if (time_after(jiffies,timeout))
  888. return;
  889. if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
  890. tuner_warn("i2c i/o read error: rc == %d (should be 1)\n",rc);
  891. break;
  892. }
  893. if (status_byte & TUNER_PLL_LOCKED)
  894. break;
  895. udelay(10);
  896. }
  897. /* Set the charge pump for optimized phase noise figure */
  898. tun->config &= ~TUNER_CHARGE_PUMP;
  899. buffer[0] = (div>>8) & 0x7f;
  900. buffer[1] = div & 0xff;
  901. buffer[2] = tun->config;
  902. buffer[3] = config;
  903. tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
  904. buffer[0],buffer[1],buffer[2],buffer[3]);
  905. if (4 != (rc = i2c_master_send(c,buffer,4)))
  906. tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
  907. }
  908. }
  909. static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
  910. {
  911. struct tunertype *tun;
  912. struct tuner *t = i2c_get_clientdata(c);
  913. unsigned char buffer[4];
  914. unsigned div;
  915. int rc;
  916. tun = &tuners[t->type];
  917. div = (20 * freq / 16000) + (int)(20*10.7); /* IF 10.7 MHz */
  918. buffer[2] = (tun->config & ~TUNER_RATIO_MASK) | TUNER_RATIO_SELECT_50; /* 50 kHz step */
  919. switch (t->type) {
  920. case TUNER_TENA_9533_DI:
  921. case TUNER_YMEC_TVF_5533MF:
  922. tuner_dbg ("This tuner doesn't have FM. Most cards has a TEA5767 for FM\n");
  923. return;
  924. case TUNER_PHILIPS_FM1216ME_MK3:
  925. case TUNER_PHILIPS_FM1236_MK3:
  926. case TUNER_PHILIPS_FMD1216ME_MK3:
  927. buffer[3] = 0x19;
  928. break;
  929. case TUNER_PHILIPS_FM1256_IH3:
  930. div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
  931. buffer[3] = 0x19;
  932. break;
  933. case TUNER_LG_PAL_FM:
  934. buffer[3] = 0xa5;
  935. break;
  936. case TUNER_MICROTUNE_4049FM5:
  937. div = (20 * freq) / 16000 + (int)(33.3 * 20); /* IF 33.3 MHz */
  938. buffer[3] = 0xa4;
  939. break;
  940. default:
  941. buffer[3] = 0xa4;
  942. break;
  943. }
  944. buffer[0] = (div>>8) & 0x7f;
  945. buffer[1] = div & 0xff;
  946. tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
  947. buffer[0],buffer[1],buffer[2],buffer[3]);
  948. if (4 != (rc = i2c_master_send(c,buffer,4)))
  949. tuner_warn("i2c i/o error: rc == %d (should be 4)\n",rc);
  950. }
  951. int default_tuner_init(struct i2c_client *c)
  952. {
  953. struct tuner *t = i2c_get_clientdata(c);
  954. tuner_info("type set to %d (%s)\n",
  955. t->type, tuners[t->type].name);
  956. strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
  957. t->tv_freq = default_set_tv_freq;
  958. t->radio_freq = default_set_radio_freq;
  959. t->has_signal = tuner_signal;
  960. t->is_stereo = tuner_stereo;
  961. t->standby = NULL;
  962. return 0;
  963. }
  964. /*
  965. * Overrides for Emacs so that we follow Linus's tabbing style.
  966. * ---------------------------------------------------------------------------
  967. * Local variables:
  968. * c-basic-offset: 8
  969. * End:
  970. */