au8522_decoder.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. /*
  2. * Auvitek AU8522 QAM/8VSB demodulator driver and video decoder
  3. *
  4. * Copyright (C) 2009 Devin Heitmueller <dheitmueller@linuxtv.org>
  5. * Copyright (C) 2005-2008 Auvitek International, Ltd.
  6. *
  7. * This program is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU General Public License
  9. * As published by the Free Software Foundation; either version 2
  10. * of the License, or (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  20. * 02110-1301, USA.
  21. */
  22. /* Developer notes:
  23. *
  24. * VBI support is not yet working
  25. * Enough is implemented here for CVBS and S-Video inputs, but the actual
  26. * analog demodulator code isn't implemented (not needed for xc5000 since it
  27. * has its own demodulator and outputs CVBS)
  28. *
  29. */
  30. #include <linux/kernel.h>
  31. #include <linux/slab.h>
  32. #include <linux/videodev2.h>
  33. #include <linux/i2c.h>
  34. #include <linux/delay.h>
  35. #include <media/v4l2-common.h>
  36. #include <media/v4l2-chip-ident.h>
  37. #include <media/v4l2-device.h>
  38. #include "au8522.h"
  39. #include "au8522_priv.h"
  40. MODULE_AUTHOR("Devin Heitmueller");
  41. MODULE_LICENSE("GPL");
  42. static int au8522_analog_debug;
  43. module_param_named(analog_debug, au8522_analog_debug, int, 0644);
  44. MODULE_PARM_DESC(analog_debug,
  45. "Analog debugging messages [0=Off (default) 1=On]");
  46. struct au8522_register_config {
  47. u16 reg_name;
  48. u8 reg_val[8];
  49. };
  50. /* Video Decoder Filter Coefficients
  51. The values are as follows from left to right
  52. 0="ATV RF" 1="ATV RF13" 2="CVBS" 3="S-Video" 4="PAL" 5=CVBS13" 6="SVideo13"
  53. */
  54. static const struct au8522_register_config filter_coef[] = {
  55. {AU8522_FILTER_COEF_R410, {0x25, 0x00, 0x25, 0x25, 0x00, 0x00, 0x00} },
  56. {AU8522_FILTER_COEF_R411, {0x20, 0x00, 0x20, 0x20, 0x00, 0x00, 0x00} },
  57. {AU8522_FILTER_COEF_R412, {0x03, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00} },
  58. {AU8522_FILTER_COEF_R413, {0xe6, 0x00, 0xe6, 0xe6, 0x00, 0x00, 0x00} },
  59. {AU8522_FILTER_COEF_R414, {0x40, 0x00, 0x40, 0x40, 0x00, 0x00, 0x00} },
  60. {AU8522_FILTER_COEF_R415, {0x1b, 0x00, 0x1b, 0x1b, 0x00, 0x00, 0x00} },
  61. {AU8522_FILTER_COEF_R416, {0xc0, 0x00, 0xc0, 0x04, 0x00, 0x00, 0x00} },
  62. {AU8522_FILTER_COEF_R417, {0x04, 0x00, 0x04, 0x04, 0x00, 0x00, 0x00} },
  63. {AU8522_FILTER_COEF_R418, {0x8c, 0x00, 0x8c, 0x8c, 0x00, 0x00, 0x00} },
  64. {AU8522_FILTER_COEF_R419, {0xa0, 0x40, 0xa0, 0xa0, 0x40, 0x40, 0x40} },
  65. {AU8522_FILTER_COEF_R41A, {0x21, 0x09, 0x21, 0x21, 0x09, 0x09, 0x09} },
  66. {AU8522_FILTER_COEF_R41B, {0x6c, 0x38, 0x6c, 0x6c, 0x38, 0x38, 0x38} },
  67. {AU8522_FILTER_COEF_R41C, {0x03, 0xff, 0x03, 0x03, 0xff, 0xff, 0xff} },
  68. {AU8522_FILTER_COEF_R41D, {0xbf, 0xc7, 0xbf, 0xbf, 0xc7, 0xc7, 0xc7} },
  69. {AU8522_FILTER_COEF_R41E, {0xa0, 0xdf, 0xa0, 0xa0, 0xdf, 0xdf, 0xdf} },
  70. {AU8522_FILTER_COEF_R41F, {0x10, 0x06, 0x10, 0x10, 0x06, 0x06, 0x06} },
  71. {AU8522_FILTER_COEF_R420, {0xae, 0x30, 0xae, 0xae, 0x30, 0x30, 0x30} },
  72. {AU8522_FILTER_COEF_R421, {0xc4, 0x01, 0xc4, 0xc4, 0x01, 0x01, 0x01} },
  73. {AU8522_FILTER_COEF_R422, {0x54, 0xdd, 0x54, 0x54, 0xdd, 0xdd, 0xdd} },
  74. {AU8522_FILTER_COEF_R423, {0xd0, 0xaf, 0xd0, 0xd0, 0xaf, 0xaf, 0xaf} },
  75. {AU8522_FILTER_COEF_R424, {0x1c, 0xf7, 0x1c, 0x1c, 0xf7, 0xf7, 0xf7} },
  76. {AU8522_FILTER_COEF_R425, {0x76, 0xdb, 0x76, 0x76, 0xdb, 0xdb, 0xdb} },
  77. {AU8522_FILTER_COEF_R426, {0x61, 0xc0, 0x61, 0x61, 0xc0, 0xc0, 0xc0} },
  78. {AU8522_FILTER_COEF_R427, {0xd1, 0x2f, 0xd1, 0xd1, 0x2f, 0x2f, 0x2f} },
  79. {AU8522_FILTER_COEF_R428, {0x84, 0xd8, 0x84, 0x84, 0xd8, 0xd8, 0xd8} },
  80. {AU8522_FILTER_COEF_R429, {0x06, 0xfb, 0x06, 0x06, 0xfb, 0xfb, 0xfb} },
  81. {AU8522_FILTER_COEF_R42A, {0x21, 0xd5, 0x21, 0x21, 0xd5, 0xd5, 0xd5} },
  82. {AU8522_FILTER_COEF_R42B, {0x0a, 0x3e, 0x0a, 0x0a, 0x3e, 0x3e, 0x3e} },
  83. {AU8522_FILTER_COEF_R42C, {0xe6, 0x15, 0xe6, 0xe6, 0x15, 0x15, 0x15} },
  84. {AU8522_FILTER_COEF_R42D, {0x01, 0x34, 0x01, 0x01, 0x34, 0x34, 0x34} },
  85. };
  86. #define NUM_FILTER_COEF (sizeof(filter_coef)\
  87. / sizeof(struct au8522_register_config))
  88. /* Registers 0x060b through 0x0652 are the LP Filter coefficients
  89. The values are as follows from left to right
  90. 0="SIF" 1="ATVRF/ATVRF13"
  91. Note: the "ATVRF/ATVRF13" mode has never been tested
  92. */
  93. static const struct au8522_register_config lpfilter_coef[] = {
  94. {0x060b, {0x21, 0x0b} },
  95. {0x060c, {0xad, 0xad} },
  96. {0x060d, {0x70, 0xf0} },
  97. {0x060e, {0xea, 0xe9} },
  98. {0x060f, {0xdd, 0xdd} },
  99. {0x0610, {0x08, 0x64} },
  100. {0x0611, {0x60, 0x60} },
  101. {0x0612, {0xf8, 0xb2} },
  102. {0x0613, {0x01, 0x02} },
  103. {0x0614, {0xe4, 0xb4} },
  104. {0x0615, {0x19, 0x02} },
  105. {0x0616, {0xae, 0x2e} },
  106. {0x0617, {0xee, 0xc5} },
  107. {0x0618, {0x56, 0x56} },
  108. {0x0619, {0x30, 0x58} },
  109. {0x061a, {0xf9, 0xf8} },
  110. {0x061b, {0x24, 0x64} },
  111. {0x061c, {0x07, 0x07} },
  112. {0x061d, {0x30, 0x30} },
  113. {0x061e, {0xa9, 0xed} },
  114. {0x061f, {0x09, 0x0b} },
  115. {0x0620, {0x42, 0xc2} },
  116. {0x0621, {0x1d, 0x2a} },
  117. {0x0622, {0xd6, 0x56} },
  118. {0x0623, {0x95, 0x8b} },
  119. {0x0624, {0x2b, 0x2b} },
  120. {0x0625, {0x30, 0x24} },
  121. {0x0626, {0x3e, 0x3e} },
  122. {0x0627, {0x62, 0xe2} },
  123. {0x0628, {0xe9, 0xf5} },
  124. {0x0629, {0x99, 0x19} },
  125. {0x062a, {0xd4, 0x11} },
  126. {0x062b, {0x03, 0x04} },
  127. {0x062c, {0xb5, 0x85} },
  128. {0x062d, {0x1e, 0x20} },
  129. {0x062e, {0x2a, 0xea} },
  130. {0x062f, {0xd7, 0xd2} },
  131. {0x0630, {0x15, 0x15} },
  132. {0x0631, {0xa3, 0xa9} },
  133. {0x0632, {0x1f, 0x1f} },
  134. {0x0633, {0xf9, 0xd1} },
  135. {0x0634, {0xc0, 0xc3} },
  136. {0x0635, {0x4d, 0x8d} },
  137. {0x0636, {0x21, 0x31} },
  138. {0x0637, {0x83, 0x83} },
  139. {0x0638, {0x08, 0x8c} },
  140. {0x0639, {0x19, 0x19} },
  141. {0x063a, {0x45, 0xa5} },
  142. {0x063b, {0xef, 0xec} },
  143. {0x063c, {0x8a, 0x8a} },
  144. {0x063d, {0xf4, 0xf6} },
  145. {0x063e, {0x8f, 0x8f} },
  146. {0x063f, {0x44, 0x0c} },
  147. {0x0640, {0xef, 0xf0} },
  148. {0x0641, {0x66, 0x66} },
  149. {0x0642, {0xcc, 0xd2} },
  150. {0x0643, {0x41, 0x41} },
  151. {0x0644, {0x63, 0x93} },
  152. {0x0645, {0x8e, 0x8e} },
  153. {0x0646, {0xa2, 0x42} },
  154. {0x0647, {0x7b, 0x7b} },
  155. {0x0648, {0x04, 0x04} },
  156. {0x0649, {0x00, 0x00} },
  157. {0x064a, {0x40, 0x40} },
  158. {0x064b, {0x8c, 0x98} },
  159. {0x064c, {0x00, 0x00} },
  160. {0x064d, {0x63, 0xc3} },
  161. {0x064e, {0x04, 0x04} },
  162. {0x064f, {0x20, 0x20} },
  163. {0x0650, {0x00, 0x00} },
  164. {0x0651, {0x40, 0x40} },
  165. {0x0652, {0x01, 0x01} },
  166. };
  167. #define NUM_LPFILTER_COEF (sizeof(lpfilter_coef)\
  168. / sizeof(struct au8522_register_config))
  169. static inline struct au8522_state *to_state(struct v4l2_subdev *sd)
  170. {
  171. return container_of(sd, struct au8522_state, sd);
  172. }
  173. static void setup_vbi(struct au8522_state *state, int aud_input)
  174. {
  175. int i;
  176. /* These are set to zero regardless of what mode we're in */
  177. au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H, 0x00);
  178. au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_L_REG018H, 0x00);
  179. au8522_writereg(state, AU8522_TVDEC_VBI_USER_TOTAL_BITS_REG019H, 0x00);
  180. au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_H_REG01AH, 0x00);
  181. au8522_writereg(state, AU8522_TVDEC_VBI_USER_TUNIT_L_REG01BH, 0x00);
  182. au8522_writereg(state, AU8522_TVDEC_VBI_USER_THRESH1_REG01CH, 0x00);
  183. au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT2_REG01EH, 0x00);
  184. au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT1_REG01FH, 0x00);
  185. au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_PAT0_REG020H, 0x00);
  186. au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK2_REG021H,
  187. 0x00);
  188. au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK1_REG022H,
  189. 0x00);
  190. au8522_writereg(state, AU8522_TVDEC_VBI_USER_FRAME_MASK0_REG023H,
  191. 0x00);
  192. /* Setup the VBI registers */
  193. for (i = 0x30; i < 0x60; i++)
  194. au8522_writereg(state, i, 0x40);
  195. /* For some reason, every register is 0x40 except register 0x44
  196. (confirmed via the HVR-950q USB capture) */
  197. au8522_writereg(state, 0x44, 0x60);
  198. /* Enable VBI (we always do this regardless of whether the user is
  199. viewing closed caption info) */
  200. au8522_writereg(state, AU8522_TVDEC_VBI_CTRL_H_REG017H,
  201. AU8522_TVDEC_VBI_CTRL_H_REG017H_CCON);
  202. }
  203. static void setup_decoder_defaults(struct au8522_state *state, u8 input_mode)
  204. {
  205. int i;
  206. int filter_coef_type;
  207. /* Provide reasonable defaults for picture tuning values */
  208. au8522_writereg(state, AU8522_TVDEC_SHARPNESSREG009H, 0x07);
  209. au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH, 0xed);
  210. state->brightness = 0xed - 128;
  211. au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH, 0x79);
  212. state->contrast = 0x79;
  213. au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH, 0x80);
  214. au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH, 0x80);
  215. state->saturation = 0x80;
  216. au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH, 0x00);
  217. au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH, 0x00);
  218. state->hue = 0x00;
  219. /* Other decoder registers */
  220. au8522_writereg(state, AU8522_TVDEC_INT_MASK_REG010H, 0x00);
  221. if (input_mode == 0x23) {
  222. /* S-Video input mapping */
  223. au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x04);
  224. } else {
  225. /* All other modes (CVBS/ATVRF etc.) */
  226. au8522_writereg(state, AU8522_VIDEO_MODE_REG011H, 0x00);
  227. }
  228. au8522_writereg(state, AU8522_TVDEC_PGA_REG012H,
  229. AU8522_TVDEC_PGA_REG012H_CVBS);
  230. au8522_writereg(state, AU8522_TVDEC_COMB_MODE_REG015H,
  231. AU8522_TVDEC_COMB_MODE_REG015H_CVBS);
  232. au8522_writereg(state, AU8522_TVDED_DBG_MODE_REG060H,
  233. AU8522_TVDED_DBG_MODE_REG060H_CVBS);
  234. au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL1_REG061H,
  235. AU8522_TVDEC_FORMAT_CTRL1_REG061H_CVBS13);
  236. au8522_writereg(state, AU8522_TVDEC_FORMAT_CTRL2_REG062H,
  237. AU8522_TVDEC_FORMAT_CTRL2_REG062H_CVBS13);
  238. au8522_writereg(state, AU8522_TVDEC_VCR_DET_LLIM_REG063H,
  239. AU8522_TVDEC_VCR_DET_LLIM_REG063H_CVBS);
  240. au8522_writereg(state, AU8522_TVDEC_VCR_DET_HLIM_REG064H,
  241. AU8522_TVDEC_VCR_DET_HLIM_REG064H_CVBS);
  242. au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR1_REG065H,
  243. AU8522_TVDEC_COMB_VDIF_THR1_REG065H_CVBS);
  244. au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR2_REG066H,
  245. AU8522_TVDEC_COMB_VDIF_THR2_REG066H_CVBS);
  246. au8522_writereg(state, AU8522_TVDEC_COMB_VDIF_THR3_REG067H,
  247. AU8522_TVDEC_COMB_VDIF_THR3_REG067H_CVBS);
  248. au8522_writereg(state, AU8522_TVDEC_COMB_NOTCH_THR_REG068H,
  249. AU8522_TVDEC_COMB_NOTCH_THR_REG068H_CVBS);
  250. au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR1_REG069H,
  251. AU8522_TVDEC_COMB_HDIF_THR1_REG069H_CVBS);
  252. au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR2_REG06AH,
  253. AU8522_TVDEC_COMB_HDIF_THR2_REG06AH_CVBS);
  254. au8522_writereg(state, AU8522_TVDEC_COMB_HDIF_THR3_REG06BH,
  255. AU8522_TVDEC_COMB_HDIF_THR3_REG06BH_CVBS);
  256. if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
  257. input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
  258. au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
  259. AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_SVIDEO);
  260. au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
  261. AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_SVIDEO);
  262. } else {
  263. au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH,
  264. AU8522_TVDEC_COMB_DCDIF_THR1_REG06CH_CVBS);
  265. au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH,
  266. AU8522_TVDEC_COMB_DCDIF_THR2_REG06DH_CVBS);
  267. }
  268. au8522_writereg(state, AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH,
  269. AU8522_TVDEC_COMB_DCDIF_THR3_REG06EH_CVBS);
  270. au8522_writereg(state, AU8522_TVDEC_UV_SEP_THR_REG06FH,
  271. AU8522_TVDEC_UV_SEP_THR_REG06FH_CVBS);
  272. au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H,
  273. AU8522_TVDEC_COMB_DC_THR1_NTSC_REG070H_CVBS);
  274. au8522_writereg(state, AU8522_REG071H, AU8522_REG071H_CVBS);
  275. au8522_writereg(state, AU8522_REG072H, AU8522_REG072H_CVBS);
  276. au8522_writereg(state, AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H,
  277. AU8522_TVDEC_COMB_DC_THR2_NTSC_REG073H_CVBS);
  278. au8522_writereg(state, AU8522_REG074H, AU8522_REG074H_CVBS);
  279. au8522_writereg(state, AU8522_REG075H, AU8522_REG075H_CVBS);
  280. au8522_writereg(state, AU8522_TVDEC_DCAGC_CTRL_REG077H,
  281. AU8522_TVDEC_DCAGC_CTRL_REG077H_CVBS);
  282. au8522_writereg(state, AU8522_TVDEC_PIC_START_ADJ_REG078H,
  283. AU8522_TVDEC_PIC_START_ADJ_REG078H_CVBS);
  284. au8522_writereg(state, AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H,
  285. AU8522_TVDEC_AGC_HIGH_LIMIT_REG079H_CVBS);
  286. au8522_writereg(state, AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH,
  287. AU8522_TVDEC_MACROVISION_SYNC_THR_REG07AH_CVBS);
  288. au8522_writereg(state, AU8522_TVDEC_INTRP_CTRL_REG07BH,
  289. AU8522_TVDEC_INTRP_CTRL_REG07BH_CVBS);
  290. au8522_writereg(state, AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H,
  291. AU8522_TVDEC_AGC_LOW_LIMIT_REG0E4H_CVBS);
  292. au8522_writereg(state, AU8522_TOREGAAGC_REG0E5H,
  293. AU8522_TOREGAAGC_REG0E5H_CVBS);
  294. au8522_writereg(state, AU8522_REG016H, AU8522_REG016H_CVBS);
  295. setup_vbi(state, 0);
  296. if (input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13 ||
  297. input_mode == AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH24) {
  298. /* Despite what the table says, for the HVR-950q we still need
  299. to be in CVBS mode for the S-Video input (reason unknown). */
  300. /* filter_coef_type = 3; */
  301. filter_coef_type = 5;
  302. } else {
  303. filter_coef_type = 5;
  304. }
  305. /* Load the Video Decoder Filter Coefficients */
  306. for (i = 0; i < NUM_FILTER_COEF; i++) {
  307. au8522_writereg(state, filter_coef[i].reg_name,
  308. filter_coef[i].reg_val[filter_coef_type]);
  309. }
  310. /* It's not clear what these registers are for, but they are always
  311. set to the same value regardless of what mode we're in */
  312. au8522_writereg(state, AU8522_REG42EH, 0x87);
  313. au8522_writereg(state, AU8522_REG42FH, 0xa2);
  314. au8522_writereg(state, AU8522_REG430H, 0xbf);
  315. au8522_writereg(state, AU8522_REG431H, 0xcb);
  316. au8522_writereg(state, AU8522_REG432H, 0xa1);
  317. au8522_writereg(state, AU8522_REG433H, 0x41);
  318. au8522_writereg(state, AU8522_REG434H, 0x88);
  319. au8522_writereg(state, AU8522_REG435H, 0xc2);
  320. au8522_writereg(state, AU8522_REG436H, 0x3c);
  321. }
  322. static void au8522_setup_cvbs_mode(struct au8522_state *state)
  323. {
  324. /* here we're going to try the pre-programmed route */
  325. au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
  326. AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
  327. /* PGA in automatic mode */
  328. au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
  329. /* Enable clamping control */
  330. au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
  331. au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
  332. AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
  333. setup_decoder_defaults(state, AU8522_INPUT_CONTROL_REG081H_CVBS_CH1);
  334. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  335. AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
  336. }
  337. static void au8522_setup_cvbs_tuner_mode(struct au8522_state *state)
  338. {
  339. /* here we're going to try the pre-programmed route */
  340. au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
  341. AU8522_MODULE_CLOCK_CONTROL_REG0A3H_CVBS);
  342. /* It's not clear why we have to have the PGA in automatic mode while
  343. enabling clamp control, but it's what Windows does */
  344. au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
  345. /* Enable clamping control */
  346. au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x0e);
  347. /* Disable automatic PGA (since the CVBS is coming from the tuner) */
  348. au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x10);
  349. /* Set input mode to CVBS on channel 4 with SIF audio input enabled */
  350. au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
  351. AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
  352. setup_decoder_defaults(state,
  353. AU8522_INPUT_CONTROL_REG081H_CVBS_CH4_SIF);
  354. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  355. AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
  356. }
  357. static void au8522_setup_svideo_mode(struct au8522_state *state)
  358. {
  359. au8522_writereg(state, AU8522_MODULE_CLOCK_CONTROL_REG0A3H,
  360. AU8522_MODULE_CLOCK_CONTROL_REG0A3H_SVIDEO);
  361. /* Set input to Y on Channe1, C on Channel 3 */
  362. au8522_writereg(state, AU8522_INPUT_CONTROL_REG081H,
  363. AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
  364. /* PGA in automatic mode */
  365. au8522_writereg(state, AU8522_PGA_CONTROL_REG082H, 0x00);
  366. /* Enable clamping control */
  367. au8522_writereg(state, AU8522_CLAMPING_CONTROL_REG083H, 0x00);
  368. setup_decoder_defaults(state,
  369. AU8522_INPUT_CONTROL_REG081H_SVIDEO_CH13);
  370. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  371. AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
  372. }
  373. /* ----------------------------------------------------------------------- */
  374. static void disable_audio_input(struct au8522_state *state)
  375. {
  376. au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
  377. au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
  378. au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
  379. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x04);
  380. au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0x02);
  381. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  382. AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_SVIDEO);
  383. }
  384. /* 0=disable, 1=SIF */
  385. static void set_audio_input(struct au8522_state *state, int aud_input)
  386. {
  387. int i;
  388. /* Note that this function needs to be used in conjunction with setting
  389. the input routing via register 0x81 */
  390. if (aud_input == AU8522_AUDIO_NONE) {
  391. disable_audio_input(state);
  392. return;
  393. }
  394. if (aud_input != AU8522_AUDIO_SIF) {
  395. /* The caller asked for a mode we don't currently support */
  396. printk(KERN_ERR "Unsupported audio mode requested! mode=%d\n",
  397. aud_input);
  398. return;
  399. }
  400. /* Load the Audio Decoder Filter Coefficients */
  401. for (i = 0; i < NUM_LPFILTER_COEF; i++) {
  402. au8522_writereg(state, lpfilter_coef[i].reg_name,
  403. lpfilter_coef[i].reg_val[0]);
  404. }
  405. /* Setup audio */
  406. au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x00);
  407. au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x00);
  408. au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0x00);
  409. au8522_writereg(state, AU8522_I2C_CONTROL_REG1_REG091H, 0x80);
  410. au8522_writereg(state, AU8522_I2C_CONTROL_REG0_REG090H, 0x84);
  411. msleep(150);
  412. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x00);
  413. msleep(1);
  414. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H, 0x9d);
  415. msleep(50);
  416. au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
  417. au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
  418. au8522_writereg(state, AU8522_AUDIO_VOLUME_REG0F4H, 0xff);
  419. msleep(80);
  420. au8522_writereg(state, AU8522_AUDIO_VOLUME_L_REG0F2H, 0x7F);
  421. au8522_writereg(state, AU8522_AUDIO_VOLUME_R_REG0F3H, 0x7F);
  422. au8522_writereg(state, AU8522_REG0F9H, AU8522_REG0F9H_AUDIO);
  423. au8522_writereg(state, AU8522_AUDIO_MODE_REG0F1H, 0x82);
  424. msleep(70);
  425. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_1_REG0A5H, 0x09);
  426. au8522_writereg(state, AU8522_AUDIOFREQ_REG606H, 0x03);
  427. au8522_writereg(state, AU8522_I2S_CTRL_2_REG112H, 0xc2);
  428. }
  429. /* ----------------------------------------------------------------------- */
  430. static int au8522_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
  431. {
  432. struct au8522_state *state = to_state(sd);
  433. switch (ctrl->id) {
  434. case V4L2_CID_BRIGHTNESS:
  435. state->brightness = ctrl->value;
  436. au8522_writereg(state, AU8522_TVDEC_BRIGHTNESS_REG00AH,
  437. ctrl->value - 128);
  438. break;
  439. case V4L2_CID_CONTRAST:
  440. state->contrast = ctrl->value;
  441. au8522_writereg(state, AU8522_TVDEC_CONTRAST_REG00BH,
  442. ctrl->value);
  443. break;
  444. case V4L2_CID_SATURATION:
  445. state->saturation = ctrl->value;
  446. au8522_writereg(state, AU8522_TVDEC_SATURATION_CB_REG00CH,
  447. ctrl->value);
  448. au8522_writereg(state, AU8522_TVDEC_SATURATION_CR_REG00DH,
  449. ctrl->value);
  450. break;
  451. case V4L2_CID_HUE:
  452. state->hue = ctrl->value;
  453. au8522_writereg(state, AU8522_TVDEC_HUE_H_REG00EH,
  454. ctrl->value >> 8);
  455. au8522_writereg(state, AU8522_TVDEC_HUE_L_REG00FH,
  456. ctrl->value & 0xFF);
  457. break;
  458. case V4L2_CID_AUDIO_VOLUME:
  459. case V4L2_CID_AUDIO_BASS:
  460. case V4L2_CID_AUDIO_TREBLE:
  461. case V4L2_CID_AUDIO_BALANCE:
  462. case V4L2_CID_AUDIO_MUTE:
  463. /* Not yet implemented */
  464. default:
  465. return -EINVAL;
  466. }
  467. return 0;
  468. }
  469. static int au8522_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
  470. {
  471. struct au8522_state *state = to_state(sd);
  472. /* Note that we are using values cached in the state structure instead
  473. of reading the registers due to issues with i2c reads not working
  474. properly/consistently yet on the HVR-950q */
  475. switch (ctrl->id) {
  476. case V4L2_CID_BRIGHTNESS:
  477. ctrl->value = state->brightness;
  478. break;
  479. case V4L2_CID_CONTRAST:
  480. ctrl->value = state->contrast;
  481. break;
  482. case V4L2_CID_SATURATION:
  483. ctrl->value = state->saturation;
  484. break;
  485. case V4L2_CID_HUE:
  486. ctrl->value = state->hue;
  487. break;
  488. case V4L2_CID_AUDIO_VOLUME:
  489. case V4L2_CID_AUDIO_BASS:
  490. case V4L2_CID_AUDIO_TREBLE:
  491. case V4L2_CID_AUDIO_BALANCE:
  492. case V4L2_CID_AUDIO_MUTE:
  493. /* Not yet supported */
  494. default:
  495. return -EINVAL;
  496. }
  497. return 0;
  498. }
  499. /* ----------------------------------------------------------------------- */
  500. #ifdef CONFIG_VIDEO_ADV_DEBUG
  501. static int au8522_g_register(struct v4l2_subdev *sd,
  502. struct v4l2_dbg_register *reg)
  503. {
  504. struct i2c_client *client = v4l2_get_subdevdata(sd);
  505. struct au8522_state *state = to_state(sd);
  506. if (!v4l2_chip_match_i2c_client(client, &reg->match))
  507. return -EINVAL;
  508. if (!capable(CAP_SYS_ADMIN))
  509. return -EPERM;
  510. reg->val = au8522_readreg(state, reg->reg & 0xffff);
  511. return 0;
  512. }
  513. static int au8522_s_register(struct v4l2_subdev *sd,
  514. struct v4l2_dbg_register *reg)
  515. {
  516. struct i2c_client *client = v4l2_get_subdevdata(sd);
  517. struct au8522_state *state = to_state(sd);
  518. if (!v4l2_chip_match_i2c_client(client, &reg->match))
  519. return -EINVAL;
  520. if (!capable(CAP_SYS_ADMIN))
  521. return -EPERM;
  522. au8522_writereg(state, reg->reg, reg->val & 0xff);
  523. return 0;
  524. }
  525. #endif
  526. static int au8522_s_stream(struct v4l2_subdev *sd, int enable)
  527. {
  528. struct au8522_state *state = to_state(sd);
  529. if (enable) {
  530. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  531. 0x01);
  532. msleep(1);
  533. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  534. AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H_CVBS);
  535. } else {
  536. /* This does not completely power down the device
  537. (it only reduces it from around 140ma to 80ma) */
  538. au8522_writereg(state, AU8522_SYSTEM_MODULE_CONTROL_0_REG0A4H,
  539. 1 << 5);
  540. }
  541. return 0;
  542. }
  543. static int au8522_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
  544. {
  545. switch (qc->id) {
  546. case V4L2_CID_CONTRAST:
  547. return v4l2_ctrl_query_fill(qc, 0, 255, 1,
  548. AU8522_TVDEC_CONTRAST_REG00BH_CVBS);
  549. case V4L2_CID_BRIGHTNESS:
  550. return v4l2_ctrl_query_fill(qc, 0, 255, 1, 109);
  551. case V4L2_CID_SATURATION:
  552. return v4l2_ctrl_query_fill(qc, 0, 255, 1, 128);
  553. case V4L2_CID_HUE:
  554. return v4l2_ctrl_query_fill(qc, -32768, 32768, 1, 0);
  555. default:
  556. break;
  557. }
  558. qc->type = 0;
  559. return -EINVAL;
  560. }
  561. static int au8522_reset(struct v4l2_subdev *sd, u32 val)
  562. {
  563. struct au8522_state *state = to_state(sd);
  564. state->operational_mode = AU8522_ANALOG_MODE;
  565. /* Clear out any state associated with the digital side of the
  566. chip, so that when it gets powered back up it won't think
  567. that it is already tuned */
  568. state->current_frequency = 0;
  569. au8522_writereg(state, 0xa4, 1 << 5);
  570. return 0;
  571. }
  572. static int au8522_s_video_routing(struct v4l2_subdev *sd,
  573. u32 input, u32 output, u32 config)
  574. {
  575. struct au8522_state *state = to_state(sd);
  576. au8522_reset(sd, 0);
  577. /* Jam open the i2c gate to the tuner. We do this here to handle the
  578. case where the user went into digital mode (causing the gate to be
  579. closed), and then came back to analog mode */
  580. au8522_writereg(state, 0x106, 1);
  581. if (input == AU8522_COMPOSITE_CH1) {
  582. au8522_setup_cvbs_mode(state);
  583. } else if (input == AU8522_SVIDEO_CH13) {
  584. au8522_setup_svideo_mode(state);
  585. } else if (input == AU8522_COMPOSITE_CH4_SIF) {
  586. au8522_setup_cvbs_tuner_mode(state);
  587. } else {
  588. printk(KERN_ERR "au8522 mode not currently supported\n");
  589. return -EINVAL;
  590. }
  591. return 0;
  592. }
  593. static int au8522_s_audio_routing(struct v4l2_subdev *sd,
  594. u32 input, u32 output, u32 config)
  595. {
  596. struct au8522_state *state = to_state(sd);
  597. set_audio_input(state, input);
  598. return 0;
  599. }
  600. static int au8522_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
  601. {
  602. int val = 0;
  603. struct au8522_state *state = to_state(sd);
  604. u8 lock_status;
  605. /* Interrogate the decoder to see if we are getting a real signal */
  606. lock_status = au8522_readreg(state, 0x00);
  607. if (lock_status == 0xa2)
  608. vt->signal = 0x01;
  609. else
  610. vt->signal = 0x00;
  611. vt->capability |=
  612. V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
  613. V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
  614. val = V4L2_TUNER_SUB_MONO;
  615. vt->rxsubchans = val;
  616. vt->audmode = V4L2_TUNER_MODE_STEREO;
  617. return 0;
  618. }
  619. static int au8522_g_chip_ident(struct v4l2_subdev *sd,
  620. struct v4l2_dbg_chip_ident *chip)
  621. {
  622. struct au8522_state *state = to_state(sd);
  623. struct i2c_client *client = v4l2_get_subdevdata(sd);
  624. return v4l2_chip_ident_i2c_client(client, chip, state->id, state->rev);
  625. }
  626. static int au8522_log_status(struct v4l2_subdev *sd)
  627. {
  628. /* FIXME: Add some status info here */
  629. return 0;
  630. }
  631. /* ----------------------------------------------------------------------- */
  632. static const struct v4l2_subdev_core_ops au8522_core_ops = {
  633. .log_status = au8522_log_status,
  634. .g_chip_ident = au8522_g_chip_ident,
  635. .g_ctrl = au8522_g_ctrl,
  636. .s_ctrl = au8522_s_ctrl,
  637. .queryctrl = au8522_queryctrl,
  638. .reset = au8522_reset,
  639. #ifdef CONFIG_VIDEO_ADV_DEBUG
  640. .g_register = au8522_g_register,
  641. .s_register = au8522_s_register,
  642. #endif
  643. };
  644. static const struct v4l2_subdev_tuner_ops au8522_tuner_ops = {
  645. .g_tuner = au8522_g_tuner,
  646. };
  647. static const struct v4l2_subdev_audio_ops au8522_audio_ops = {
  648. .s_routing = au8522_s_audio_routing,
  649. };
  650. static const struct v4l2_subdev_video_ops au8522_video_ops = {
  651. .s_routing = au8522_s_video_routing,
  652. .s_stream = au8522_s_stream,
  653. };
  654. static const struct v4l2_subdev_ops au8522_ops = {
  655. .core = &au8522_core_ops,
  656. .tuner = &au8522_tuner_ops,
  657. .audio = &au8522_audio_ops,
  658. .video = &au8522_video_ops,
  659. };
  660. /* ----------------------------------------------------------------------- */
  661. static int au8522_probe(struct i2c_client *client,
  662. const struct i2c_device_id *did)
  663. {
  664. struct au8522_state *state;
  665. struct v4l2_subdev *sd;
  666. int instance;
  667. struct au8522_config *demod_config;
  668. /* Check if the adapter supports the needed features */
  669. if (!i2c_check_functionality(client->adapter,
  670. I2C_FUNC_SMBUS_BYTE_DATA)) {
  671. return -EIO;
  672. }
  673. /* allocate memory for the internal state */
  674. instance = au8522_get_state(&state, client->adapter, client->addr);
  675. switch (instance) {
  676. case 0:
  677. printk(KERN_ERR "au8522_decoder allocation failed\n");
  678. return -EIO;
  679. case 1:
  680. /* new demod instance */
  681. printk(KERN_INFO "au8522_decoder creating new instance...\n");
  682. break;
  683. default:
  684. /* existing demod instance */
  685. printk(KERN_INFO "au8522_decoder attach existing instance.\n");
  686. break;
  687. }
  688. demod_config = kzalloc(sizeof(struct au8522_config), GFP_KERNEL);
  689. if (demod_config == NULL) {
  690. if (instance == 1)
  691. kfree(state);
  692. return -ENOMEM;
  693. }
  694. demod_config->demod_address = 0x8e >> 1;
  695. state->config = demod_config;
  696. state->i2c = client->adapter;
  697. sd = &state->sd;
  698. v4l2_i2c_subdev_init(sd, client, &au8522_ops);
  699. state->c = client;
  700. state->vid_input = AU8522_COMPOSITE_CH1;
  701. state->aud_input = AU8522_AUDIO_NONE;
  702. state->id = 8522;
  703. state->rev = 0;
  704. /* Jam open the i2c gate to the tuner */
  705. au8522_writereg(state, 0x106, 1);
  706. return 0;
  707. }
  708. static int au8522_remove(struct i2c_client *client)
  709. {
  710. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  711. v4l2_device_unregister_subdev(sd);
  712. au8522_release_state(to_state(sd));
  713. return 0;
  714. }
  715. static const struct i2c_device_id au8522_id[] = {
  716. {"au8522", 0},
  717. {}
  718. };
  719. MODULE_DEVICE_TABLE(i2c, au8522_id);
  720. static struct i2c_driver au8522_driver = {
  721. .driver = {
  722. .owner = THIS_MODULE,
  723. .name = "au8522",
  724. },
  725. .probe = au8522_probe,
  726. .remove = au8522_remove,
  727. .id_table = au8522_id,
  728. };
  729. static __init int init_au8522(void)
  730. {
  731. return i2c_add_driver(&au8522_driver);
  732. }
  733. static __exit void exit_au8522(void)
  734. {
  735. i2c_del_driver(&au8522_driver);
  736. }
  737. module_init(init_au8522);
  738. module_exit(exit_au8522);