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