fq1216me_demod.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385
  1. /*
  2. * PHILIPS FQ1216ME-MK3 Demodulation Device Driver
  3. *
  4. * Author: Bobby Yang <bo.yang@amlogic.com>
  5. *
  6. *
  7. * Copyright (C) 2010 Amlogic Inc.
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License version 2 as
  11. * published by the Free Software Foundation.
  12. */
  13. /* Standard Liniux Headers */
  14. #include <linux/module.h>
  15. #include <linux/i2c.h>
  16. /* Amlogic Headers */
  17. #include <linux/tvin/tvin.h>
  18. /* Local Headers */
  19. #include "tvin_demod.h"
  20. /*********************IF configure*****************************/
  21. //// first reg (b)
  22. #define VideoTrapBypassOFF 0x00 // bit b0
  23. #define VideoTrapBypassON 0x01 // bit b0
  24. #define AutoMuteFmInactive 0x00 // bit b1
  25. #define AutoMuteFmActive 0x02 // bit b1
  26. #define Intercarrier 0x00 // bit b2
  27. #define QSS 0x04 // bit b2
  28. #define PositiveAmTV 0x00 // bit b3:4
  29. #define FmRadio 0x08 // bit b3:4
  30. #define NegativeFmTV 0x10 // bit b3:4
  31. #define ForcedMuteAudioON 0x20 // bit b5
  32. #define ForcedMuteAudioOFF 0x00 // bit b5
  33. #define OutputPort1Active 0x00 // bit b6
  34. #define OutputPort1Inactive 0x40 // bit b6
  35. #define OutputPort2Active 0x00 // bit b7
  36. #define OutputPort2Inactive 0x80 // bit b7
  37. //// second reg (c)
  38. #define DeemphasisOFF 0x00 // bit c5
  39. #define DeemphasisON 0x20 // bit c5
  40. #define Deemphasis75 0x00 // bit c6
  41. #define Deemphasis50 0x40 // bit c6
  42. #define AudioGain0 0x00 // bit c7
  43. #define AudioGain6 0x80 // bit c7
  44. #define TopMask 0x1f // bit c0:4
  45. #define TopDefault 0x10 // bit c0:4
  46. //// third reg (e)
  47. #define AudioIF_4_5 0x00 // bit e0:1
  48. #define AudioIF_5_5 0x01 // bit e0:1
  49. #define AudioIF_6_0 0x02 // bit e0:1
  50. #define AudioIF_6_5 0x03 // bit e0:1
  51. #define VideoIFMask 0x1c // bit e2:4
  52. /* Video IF selection in TV Mode (bit B3=0) */
  53. #define VideoIF_58_75 0x00 // bit e2:4
  54. #define VideoIF_45_75 0x04 // bit e2:4
  55. #define VideoIF_38_90 0x08 // bit e2:4
  56. #define VideoIF_38_00 0x0C // bit e2:4
  57. #define VideoIF_33_90 0x10 // bit e2:4
  58. #define VideoIF_33_40 0x14 // bit e2:4
  59. #define RadioIF_45_75 0x18 // bit e2:4
  60. #define RadioIF_38_90 0x1C // bit e2:4
  61. /* IF1 selection in Radio Mode (bit B3=1) */
  62. #define RadioIF_33_30 0x00 // bit e2,4 (also 0x10,0x14)
  63. #define RadioIF_41_30 0x04 // bit e2,4
  64. /* Output of AFC pin in radio mode when bit E7=1 */
  65. #define RadioAGC_SIF 0x00 // bit e3
  66. #define RadioAGC_FM 0x08 // bit e3
  67. #define TunerGainNormal 0x00 // bit e5
  68. #define TunerGainLow 0x20 // bit e5
  69. #define Gating_18 0x00 // bit e6
  70. #define Gating_36 0x40 // bit e6
  71. #define AgcOutON 0x80 // bit e7
  72. #define AgcOutOFF 0x00 // bit e7
  73. #define FQ1216_DEMOD_I2C_NAME "fq1216me_demod_i2c"
  74. typedef struct if_param_s {
  75. tuner_std_id std;
  76. unsigned char b;
  77. unsigned char c;
  78. unsigned char e;
  79. } if_param_t;
  80. static struct if_param_s if_param[] = {
  81. {
  82. .std = TUNER_STD_PAL_BG,
  83. .b = ( NegativeFmTV |
  84. AutoMuteFmActive |
  85. QSS ),
  86. .c = ( DeemphasisON |
  87. Deemphasis50 |
  88. TopDefault),
  89. .e = ( Gating_36 |
  90. AudioIF_5_5 |
  91. VideoIF_38_90),
  92. },
  93. {
  94. .std = TUNER_STD_PAL_I,
  95. .b = ( NegativeFmTV |
  96. AutoMuteFmActive |
  97. QSS ),
  98. .c = ( DeemphasisON |
  99. Deemphasis50 |
  100. TopDefault),
  101. .e = ( Gating_36 |
  102. AudioIF_6_0 |
  103. VideoIF_38_90 ),
  104. },
  105. {
  106. .std = TUNER_STD_PAL_DK,
  107. .b = ( NegativeFmTV |
  108. AutoMuteFmActive |
  109. QSS ),
  110. .c = ( DeemphasisON |
  111. Deemphasis50 |
  112. TopDefault),
  113. .e = ( Gating_36 |
  114. AudioIF_6_5 |
  115. VideoIF_38_90 ),
  116. },
  117. {
  118. .std = TUNER_STD_SECAM_L,
  119. .b = ( PositiveAmTV |
  120. AutoMuteFmActive |
  121. QSS ),
  122. .c = ( TopDefault),
  123. .e = ( Gating_36 |
  124. AudioIF_6_5 |
  125. VideoIF_38_90 ),
  126. },
  127. {
  128. .std = TUNER_STD_SECAM_LC,
  129. .b = ( OutputPort2Inactive |
  130. AutoMuteFmActive |
  131. PositiveAmTV |
  132. QSS ),
  133. .c = ( TopDefault),
  134. .e = ( Gating_36 |
  135. AudioIF_6_5 |
  136. VideoIF_33_90 ),
  137. }
  138. };
  139. static tuner_std_id demod_std = 0;
  140. void tvin_demod_set_std(tuner_std_id ptstd)
  141. {
  142. demod_std = ptstd;
  143. }
  144. static struct i2c_client *tuner_afc_client = NULL;
  145. static int fq1216me_afc_read(char *buf, int len)
  146. {
  147. int i2c_flag = -1;
  148. int i = 0;
  149. unsigned int i2c_try_cnt = I2C_TRY_MAX_CNT;
  150. struct i2c_msg msg[] = {
  151. {
  152. .addr = tuner_afc_client->addr,
  153. .flags = I2C_M_RD,
  154. .len = len,
  155. .buf = buf,
  156. },
  157. };
  158. repeat:
  159. i2c_flag = i2c_transfer(tuner_afc_client->adapter, msg, 1);
  160. if (i2c_flag < 0) {
  161. pr_err("error in read fq1216me_afc, %d byte(s) should be read,. \n", len);
  162. if (i++ < i2c_try_cnt)
  163. goto repeat;
  164. return -EIO;
  165. }
  166. else
  167. {
  168. // pr_info("fq1216me_afc_read is ok. \n");
  169. return 0;
  170. }
  171. }
  172. static int fq1216me_afc_write(char *buf, int len)
  173. {
  174. int i2c_flag = -1;
  175. int i = 0;
  176. unsigned int i2c_try_cnt = I2C_TRY_MAX_CNT;
  177. struct i2c_msg msg[] = {
  178. {
  179. .addr = tuner_afc_client->addr,
  180. .flags = 0, //|I2C_M_TEN,
  181. .len = len,
  182. .buf = buf,
  183. }
  184. };
  185. repeat:
  186. i2c_flag = i2c_transfer(tuner_afc_client->adapter, msg, 1);
  187. if (i2c_flag < 0) {
  188. pr_err("error in writing fq1216me_afc, %d byte(s) should be writen,. \n", len);
  189. if (i++ < i2c_try_cnt)
  190. goto repeat;
  191. return -EIO;
  192. }
  193. else
  194. {
  195. // pr_info("fq1216me_afc_write is ok. \n");
  196. return 0;
  197. }
  198. }
  199. void tvin_demod_get_afc(struct tuner_parm_s *ptp)
  200. {
  201. #if 0
  202. static int afc_bits_2_hz[] = {
  203. -12500, -37500, -62500, -87500,
  204. -112500, -137500, -162500, -187500,
  205. 187500, 162500, 137500, 112500,
  206. 87500, 62500, 37500, 12500
  207. };
  208. #endif
  209. int i2c_flag;
  210. unsigned char status;
  211. i2c_flag = fq1216me_afc_read(&status, 1);
  212. if(i2c_flag == 0)
  213. ptp->if_status = status; //afc_bits_2_hz[(status >> 1) & 0x0F];
  214. }
  215. int tvin_set_demod(unsigned int bce)
  216. {
  217. struct if_param_s *param = NULL;
  218. unsigned char buf[4] = {0, 0, 0, 0};
  219. int i, i2c_flag = -1;
  220. if (bce != 0)
  221. {
  222. buf[1] = (unsigned char)((bce&0xff0000) >> 16);//param->b;
  223. buf[2] = (unsigned char)((bce&0x00ff00) >> 8);//param->c;
  224. buf[3] = (unsigned char)((bce&0x0000ff) >> 0);//param->e;
  225. //pr_info( " %s: b=0x%x, c=0x%x, e=0x%x\n", __func__, buf[1], buf[2], buf[3]);
  226. i2c_flag = fq1216me_afc_write(buf, 4);
  227. return i2c_flag;
  228. }
  229. for (i = 0; i < ARRAY_SIZE(if_param); i++) {
  230. if (if_param[i].std & demod_std) {
  231. param = if_param + i;
  232. break;
  233. }
  234. }
  235. if (NULL == param) {
  236. //tuner_dbg("Unsupported tvnorm entry - audio muted\n");
  237. /*audio muted*/
  238. buf[1] = if_param[0].b | ForcedMuteAudioON;
  239. buf[2] = if_param[0].c;
  240. buf[3] = if_param[0].e;
  241. pr_info("tuner test: b=0x%x.\n", buf[1]);
  242. i2c_flag = fq1216me_afc_write(buf, 4);
  243. return -1;
  244. }
  245. //tuner_dbg("configure for: %s\n", norm->name);
  246. buf[1] = param->b;
  247. buf[2] = param->c;
  248. buf[3] = param->e;
  249. i2c_flag = fq1216me_afc_write(buf, 4);
  250. return i2c_flag;
  251. }
  252. static int fq1216me_demod_probe(struct i2c_client *client, const struct i2c_device_id *id)
  253. {
  254. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
  255. pr_info("%s: functionality check failed\n", __FUNCTION__);
  256. return -ENODEV;
  257. }
  258. tuner_afc_client = client;
  259. pr_info( " %s: tuner_demod_client->addr = %x\n", __FUNCTION__, tuner_afc_client->addr);
  260. return 0;
  261. }
  262. static int fq1216me_demod_remove(struct i2c_client *client)
  263. {
  264. pr_info("%s driver removed ok.\n", client->name);
  265. return 0;
  266. }
  267. static const struct i2c_device_id fq1216me_demod_id[] = {
  268. { FQ1216_DEMOD_I2C_NAME, 0 },
  269. { }
  270. };
  271. static struct i2c_driver fq1216me_demod_driver = {
  272. .driver = {
  273. .owner = THIS_MODULE,
  274. .name = FQ1216_DEMOD_I2C_NAME,
  275. },
  276. .probe = fq1216me_demod_probe,
  277. .remove = fq1216me_demod_remove,
  278. .id_table = fq1216me_demod_id,
  279. };
  280. static int __init fq1216me_demod_init(void)
  281. {
  282. int ret = 0;
  283. pr_info( "%s . \n", __FUNCTION__ );
  284. ret = i2c_add_driver(&fq1216me_demod_driver);
  285. if (ret < 0 || tuner_afc_client == NULL) {
  286. pr_err("tuner demod: failed to add i2c driver. \n");
  287. ret = -ENOTSUPP;
  288. }
  289. return ret;
  290. }
  291. static void __exit fq1216me_demod_exit(void)
  292. {
  293. pr_info( "%s . \n", __FUNCTION__ );
  294. i2c_del_driver(&fq1216me_demod_driver);
  295. }
  296. MODULE_AUTHOR("Bobby Yang <bo.yang@amlogic.com>");
  297. MODULE_DESCRIPTION("Philips FQ1216ME-MK3 demodulation i2c device driver");
  298. MODULE_LICENSE("GPL");
  299. module_init(fq1216me_demod_init);
  300. module_exit(fq1216me_demod_exit);