PageRenderTime 58ms CodeModel.GetById 19ms app.highlight 33ms RepoModel.GetById 0ms app.codeStats 0ms

/drivers/media/video/tvp7002.c

https://bitbucket.org/ndreys/linux-sunxi
C | 1100 lines | 739 code | 116 blank | 245 comment | 58 complexity | 029656a1d6efe30747738e0d36db4f7a MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
   1/* Texas Instruments Triple 8-/10-BIT 165-/110-MSPS Video and Graphics
   2 * Digitizer with Horizontal PLL registers
   3 *
   4 * Copyright (C) 2009 Texas Instruments Inc
   5 * Author: Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>
   6 *
   7 * This code is partially based upon the TVP5150 driver
   8 * written by Mauro Carvalho Chehab (mchehab@infradead.org),
   9 * the TVP514x driver written by Vaibhav Hiremath <hvaibhav@ti.com>
  10 * and the TVP7002 driver in the TI LSP 2.10.00.14. Revisions by
  11 * Muralidharan Karicheri and Snehaprabha Narnakaje (TI).
  12 *
  13 * This program is free software; you can redistribute it and/or modify
  14 * it under the terms of the GNU General Public License as published by
  15 * the Free Software Foundation; either version 2 of the License, or
  16 * (at your option) any later version.
  17 *
  18 * This program is distributed in the hope that it will be useful,
  19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  21 * GNU General Public License for more details.
  22 *
  23 * You should have received a copy of the GNU General Public License
  24 * along with this program; if not, write to the Free Software
  25 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  26 */
  27#include <linux/delay.h>
  28#include <linux/i2c.h>
  29#include <linux/slab.h>
  30#include <linux/videodev2.h>
  31#include <media/tvp7002.h>
  32#include <media/v4l2-device.h>
  33#include <media/v4l2-chip-ident.h>
  34#include <media/v4l2-common.h>
  35#include <media/v4l2-ctrls.h>
  36#include "tvp7002_reg.h"
  37
  38MODULE_DESCRIPTION("TI TVP7002 Video and Graphics Digitizer driver");
  39MODULE_AUTHOR("Santiago Nunez-Corrales <santiago.nunez@ridgerun.com>");
  40MODULE_LICENSE("GPL");
  41
  42/* Module Name */
  43#define TVP7002_MODULE_NAME	"tvp7002"
  44
  45/* I2C retry attempts */
  46#define I2C_RETRY_COUNT		(5)
  47
  48/* End of registers */
  49#define TVP7002_EOR		0x5c
  50
  51/* Read write definition for registers */
  52#define TVP7002_READ		0
  53#define TVP7002_WRITE		1
  54#define TVP7002_RESERVED	2
  55
  56/* Interlaced vs progressive mask and shift */
  57#define TVP7002_IP_SHIFT	5
  58#define TVP7002_INPR_MASK	(0x01 << TVP7002_IP_SHIFT)
  59
  60/* Shift for CPL and LPF registers */
  61#define TVP7002_CL_SHIFT	8
  62#define TVP7002_CL_MASK		0x0f
  63
  64/* Debug functions */
  65static int debug;
  66module_param(debug, bool, 0644);
  67MODULE_PARM_DESC(debug, "Debug level (0-2)");
  68
  69/* Structure for register values */
  70struct i2c_reg_value {
  71	u8 reg;
  72	u8 value;
  73	u8 type;
  74};
  75
  76/*
  77 * Register default values (according to tvp7002 datasheet)
  78 * In the case of read-only registers, the value (0xff) is
  79 * never written. R/W functionality is controlled by the
  80 * writable bit in the register struct definition.
  81 */
  82static const struct i2c_reg_value tvp7002_init_default[] = {
  83	{ TVP7002_CHIP_REV, 0xff, TVP7002_READ },
  84	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
  85	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
  86	{ TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
  87	{ TVP7002_HPLL_PHASE_SEL, 0x80, TVP7002_WRITE },
  88	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
  89	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
  90	{ TVP7002_HSYNC_OUT_W, 0x60, TVP7002_WRITE },
  91	{ TVP7002_B_FINE_GAIN, 0x00, TVP7002_WRITE },
  92	{ TVP7002_G_FINE_GAIN, 0x00, TVP7002_WRITE },
  93	{ TVP7002_R_FINE_GAIN, 0x00, TVP7002_WRITE },
  94	{ TVP7002_B_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
  95	{ TVP7002_G_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
  96	{ TVP7002_R_FINE_OFF_MSBS, 0x80, TVP7002_WRITE },
  97	{ TVP7002_SYNC_CTL_1, 0x20, TVP7002_WRITE },
  98	{ TVP7002_HPLL_AND_CLAMP_CTL, 0x2e, TVP7002_WRITE },
  99	{ TVP7002_SYNC_ON_G_THRS, 0x5d, TVP7002_WRITE },
 100	{ TVP7002_SYNC_SEPARATOR_THRS, 0x47, TVP7002_WRITE },
 101	{ TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
 102	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
 103	{ TVP7002_SYNC_DETECT_STAT, 0xff, TVP7002_READ },
 104	{ TVP7002_OUT_FORMATTER, 0x47, TVP7002_WRITE },
 105	{ TVP7002_MISC_CTL_1, 0x01, TVP7002_WRITE },
 106	{ TVP7002_MISC_CTL_2, 0x00, TVP7002_WRITE },
 107	{ TVP7002_MISC_CTL_3, 0x01, TVP7002_WRITE },
 108	{ TVP7002_IN_MUX_SEL_1, 0x00, TVP7002_WRITE },
 109	{ TVP7002_IN_MUX_SEL_2, 0x67, TVP7002_WRITE },
 110	{ TVP7002_B_AND_G_COARSE_GAIN, 0x77, TVP7002_WRITE },
 111	{ TVP7002_R_COARSE_GAIN, 0x07, TVP7002_WRITE },
 112	{ TVP7002_FINE_OFF_LSBS, 0x00, TVP7002_WRITE },
 113	{ TVP7002_B_COARSE_OFF, 0x10, TVP7002_WRITE },
 114	{ TVP7002_G_COARSE_OFF, 0x10, TVP7002_WRITE },
 115	{ TVP7002_R_COARSE_OFF, 0x10, TVP7002_WRITE },
 116	{ TVP7002_HSOUT_OUT_START, 0x08, TVP7002_WRITE },
 117	{ TVP7002_MISC_CTL_4, 0x00, TVP7002_WRITE },
 118	{ TVP7002_B_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
 119	{ TVP7002_G_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
 120	{ TVP7002_R_DGTL_ALC_OUT_LSBS, 0xff, TVP7002_READ },
 121	{ TVP7002_AUTO_LVL_CTL_ENABLE, 0x80, TVP7002_WRITE },
 122	{ TVP7002_DGTL_ALC_OUT_MSBS, 0xff, TVP7002_READ },
 123	{ TVP7002_AUTO_LVL_CTL_FILTER, 0x53, TVP7002_WRITE },
 124	{ 0x29, 0x08, TVP7002_RESERVED },
 125	{ TVP7002_FINE_CLAMP_CTL, 0x07, TVP7002_WRITE },
 126	/* PWR_CTL is controlled only by the probe and reset functions */
 127	{ TVP7002_PWR_CTL, 0x00, TVP7002_RESERVED },
 128	{ TVP7002_ADC_SETUP, 0x50, TVP7002_WRITE },
 129	{ TVP7002_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
 130	{ TVP7002_SOG_CLAMP, 0x80, TVP7002_WRITE },
 131	{ TVP7002_RGB_COARSE_CLAMP_CTL, 0x00, TVP7002_WRITE },
 132	{ TVP7002_SOG_COARSE_CLAMP_CTL, 0x04, TVP7002_WRITE },
 133	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
 134	{ 0x32, 0x18, TVP7002_RESERVED },
 135	{ 0x33, 0x60, TVP7002_RESERVED },
 136	{ TVP7002_MVIS_STRIPPER_W, 0xff, TVP7002_RESERVED },
 137	{ TVP7002_VSYNC_ALGN, 0x10, TVP7002_WRITE },
 138	{ TVP7002_SYNC_BYPASS, 0x00, TVP7002_WRITE },
 139	{ TVP7002_L_FRAME_STAT_LSBS, 0xff, TVP7002_READ },
 140	{ TVP7002_L_FRAME_STAT_MSBS, 0xff, TVP7002_READ },
 141	{ TVP7002_CLK_L_STAT_LSBS, 0xff, TVP7002_READ },
 142	{ TVP7002_CLK_L_STAT_MSBS, 0xff, TVP7002_READ },
 143	{ TVP7002_HSYNC_W, 0xff, TVP7002_READ },
 144	{ TVP7002_VSYNC_W, 0xff, TVP7002_READ },
 145	{ TVP7002_L_LENGTH_TOL, 0x03, TVP7002_WRITE },
 146	{ 0x3e, 0x60, TVP7002_RESERVED },
 147	{ TVP7002_VIDEO_BWTH_CTL, 0x01, TVP7002_WRITE },
 148	{ TVP7002_AVID_START_PIXEL_LSBS, 0x01, TVP7002_WRITE },
 149	{ TVP7002_AVID_START_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
 150	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x06, TVP7002_WRITE },
 151	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x2c, TVP7002_WRITE },
 152	{ TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
 153	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
 154	{ TVP7002_VBLK_F_0_DURATION, 0x1e, TVP7002_WRITE },
 155	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
 156	{ TVP7002_FBIT_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
 157	{ TVP7002_FBIT_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
 158	{ TVP7002_YUV_Y_G_COEF_LSBS, 0xe3, TVP7002_WRITE },
 159	{ TVP7002_YUV_Y_G_COEF_MSBS, 0x16, TVP7002_WRITE },
 160	{ TVP7002_YUV_Y_B_COEF_LSBS, 0x4f, TVP7002_WRITE },
 161	{ TVP7002_YUV_Y_B_COEF_MSBS, 0x02, TVP7002_WRITE },
 162	{ TVP7002_YUV_Y_R_COEF_LSBS, 0xce, TVP7002_WRITE },
 163	{ TVP7002_YUV_Y_R_COEF_MSBS, 0x06, TVP7002_WRITE },
 164	{ TVP7002_YUV_U_G_COEF_LSBS, 0xab, TVP7002_WRITE },
 165	{ TVP7002_YUV_U_G_COEF_MSBS, 0xf3, TVP7002_WRITE },
 166	{ TVP7002_YUV_U_B_COEF_LSBS, 0x00, TVP7002_WRITE },
 167	{ TVP7002_YUV_U_B_COEF_MSBS, 0x10, TVP7002_WRITE },
 168	{ TVP7002_YUV_U_R_COEF_LSBS, 0x55, TVP7002_WRITE },
 169	{ TVP7002_YUV_U_R_COEF_MSBS, 0xfc, TVP7002_WRITE },
 170	{ TVP7002_YUV_V_G_COEF_LSBS, 0x78, TVP7002_WRITE },
 171	{ TVP7002_YUV_V_G_COEF_MSBS, 0xf1, TVP7002_WRITE },
 172	{ TVP7002_YUV_V_B_COEF_LSBS, 0x88, TVP7002_WRITE },
 173	{ TVP7002_YUV_V_B_COEF_MSBS, 0xfe, TVP7002_WRITE },
 174	{ TVP7002_YUV_V_R_COEF_LSBS, 0x00, TVP7002_WRITE },
 175	{ TVP7002_YUV_V_R_COEF_MSBS, 0x10, TVP7002_WRITE },
 176	/* This signals end of register values */
 177	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 178};
 179
 180/* Register parameters for 480P */
 181static const struct i2c_reg_value tvp7002_parms_480P[] = {
 182	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x35, TVP7002_WRITE },
 183	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0xa0, TVP7002_WRITE },
 184	{ TVP7002_HPLL_CRTL, 0x02, TVP7002_WRITE },
 185	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
 186	{ TVP7002_AVID_START_PIXEL_LSBS, 0x91, TVP7002_WRITE },
 187	{ TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
 188	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x0B, TVP7002_WRITE },
 189	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
 190	{ TVP7002_VBLK_F_0_START_L_OFF, 0x03, TVP7002_WRITE },
 191	{ TVP7002_VBLK_F_1_START_L_OFF, 0x01, TVP7002_WRITE },
 192	{ TVP7002_VBLK_F_0_DURATION, 0x13, TVP7002_WRITE },
 193	{ TVP7002_VBLK_F_1_DURATION, 0x13, TVP7002_WRITE },
 194	{ TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
 195	{ TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
 196	{ TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
 197	{ TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
 198	{ TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
 199	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 200};
 201
 202/* Register parameters for 576P */
 203static const struct i2c_reg_value tvp7002_parms_576P[] = {
 204	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x36, TVP7002_WRITE },
 205	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
 206	{ TVP7002_HPLL_CRTL, 0x18, TVP7002_WRITE },
 207	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
 208	{ TVP7002_AVID_START_PIXEL_LSBS, 0x9B, TVP7002_WRITE },
 209	{ TVP7002_AVID_START_PIXEL_MSBS, 0x00, TVP7002_WRITE },
 210	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x0F, TVP7002_WRITE },
 211	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x00, TVP7002_WRITE },
 212	{ TVP7002_VBLK_F_0_START_L_OFF, 0x00, TVP7002_WRITE },
 213	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
 214	{ TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
 215	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
 216	{ TVP7002_ALC_PLACEMENT, 0x18, TVP7002_WRITE },
 217	{ TVP7002_CLAMP_START, 0x06, TVP7002_WRITE },
 218	{ TVP7002_CLAMP_W, 0x10, TVP7002_WRITE },
 219	{ TVP7002_HPLL_PRE_COAST, 0x03, TVP7002_WRITE },
 220	{ TVP7002_HPLL_POST_COAST, 0x03, TVP7002_WRITE },
 221	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 222};
 223
 224/* Register parameters for 1080I60 */
 225static const struct i2c_reg_value tvp7002_parms_1080I60[] = {
 226	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
 227	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x80, TVP7002_WRITE },
 228	{ TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
 229	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
 230	{ TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
 231	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
 232	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
 233	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
 234	{ TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
 235	{ TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
 236	{ TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
 237	{ TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
 238	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
 239	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
 240	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
 241	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
 242	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
 243	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 244};
 245
 246/* Register parameters for 1080P60 */
 247static const struct i2c_reg_value tvp7002_parms_1080P60[] = {
 248	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x89, TVP7002_WRITE },
 249	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x80, TVP7002_WRITE },
 250	{ TVP7002_HPLL_CRTL, 0xE0, TVP7002_WRITE },
 251	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
 252	{ TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
 253	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
 254	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
 255	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
 256	{ TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
 257	{ TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
 258	{ TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
 259	{ TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
 260	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
 261	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
 262	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
 263	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
 264	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
 265	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 266};
 267
 268/* Register parameters for 1080I50 */
 269static const struct i2c_reg_value tvp7002_parms_1080I50[] = {
 270	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0xa5, TVP7002_WRITE },
 271	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x00, TVP7002_WRITE },
 272	{ TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
 273	{ TVP7002_HPLL_PHASE_SEL, 0x14, TVP7002_WRITE },
 274	{ TVP7002_AVID_START_PIXEL_LSBS, 0x06, TVP7002_WRITE },
 275	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
 276	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x8a, TVP7002_WRITE },
 277	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x08, TVP7002_WRITE },
 278	{ TVP7002_VBLK_F_0_START_L_OFF, 0x02, TVP7002_WRITE },
 279	{ TVP7002_VBLK_F_1_START_L_OFF, 0x02, TVP7002_WRITE },
 280	{ TVP7002_VBLK_F_0_DURATION, 0x16, TVP7002_WRITE },
 281	{ TVP7002_VBLK_F_1_DURATION, 0x17, TVP7002_WRITE },
 282	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
 283	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
 284	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
 285	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
 286	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
 287	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 288};
 289
 290/* Register parameters for 720P60 */
 291static const struct i2c_reg_value tvp7002_parms_720P60[] = {
 292	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x67, TVP7002_WRITE },
 293	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0x20, TVP7002_WRITE },
 294	{ TVP7002_HPLL_CRTL, 0xa0, TVP7002_WRITE },
 295	{ TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
 296	{ TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
 297	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
 298	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
 299	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
 300	{ TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
 301	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
 302	{ TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
 303	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
 304	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
 305	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
 306	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
 307	{ TVP7002_HPLL_PRE_COAST, 0x00, TVP7002_WRITE },
 308	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
 309	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 310};
 311
 312/* Register parameters for 720P50 */
 313static const struct i2c_reg_value tvp7002_parms_720P50[] = {
 314	{ TVP7002_HPLL_FDBK_DIV_MSBS, 0x7b, TVP7002_WRITE },
 315	{ TVP7002_HPLL_FDBK_DIV_LSBS, 0xc0, TVP7002_WRITE },
 316	{ TVP7002_HPLL_CRTL, 0x98, TVP7002_WRITE },
 317	{ TVP7002_HPLL_PHASE_SEL, 0x16, TVP7002_WRITE },
 318	{ TVP7002_AVID_START_PIXEL_LSBS, 0x47, TVP7002_WRITE },
 319	{ TVP7002_AVID_START_PIXEL_MSBS, 0x01, TVP7002_WRITE },
 320	{ TVP7002_AVID_STOP_PIXEL_LSBS, 0x4B, TVP7002_WRITE },
 321	{ TVP7002_AVID_STOP_PIXEL_MSBS, 0x06, TVP7002_WRITE },
 322	{ TVP7002_VBLK_F_0_START_L_OFF, 0x05, TVP7002_WRITE },
 323	{ TVP7002_VBLK_F_1_START_L_OFF, 0x00, TVP7002_WRITE },
 324	{ TVP7002_VBLK_F_0_DURATION, 0x2D, TVP7002_WRITE },
 325	{ TVP7002_VBLK_F_1_DURATION, 0x00, TVP7002_WRITE },
 326	{ TVP7002_ALC_PLACEMENT, 0x5a, TVP7002_WRITE },
 327	{ TVP7002_CLAMP_START, 0x32, TVP7002_WRITE },
 328	{ TVP7002_CLAMP_W, 0x20, TVP7002_WRITE },
 329	{ TVP7002_HPLL_PRE_COAST, 0x01, TVP7002_WRITE },
 330	{ TVP7002_HPLL_POST_COAST, 0x00, TVP7002_WRITE },
 331	{ TVP7002_EOR, 0xff, TVP7002_RESERVED }
 332};
 333
 334/* Preset definition for handling device operation */
 335struct tvp7002_preset_definition {
 336	u32 preset;
 337	const struct i2c_reg_value *p_settings;
 338	enum v4l2_colorspace color_space;
 339	enum v4l2_field scanmode;
 340	u16 progressive;
 341	u16 lines_per_frame;
 342	u16 cpl_min;
 343	u16 cpl_max;
 344};
 345
 346/* Struct list for digital video presets */
 347static const struct tvp7002_preset_definition tvp7002_presets[] = {
 348	{
 349		V4L2_DV_720P60,
 350		tvp7002_parms_720P60,
 351		V4L2_COLORSPACE_REC709,
 352		V4L2_FIELD_NONE,
 353		1,
 354		0x2EE,
 355		135,
 356		153
 357	},
 358	{
 359		V4L2_DV_1080I60,
 360		tvp7002_parms_1080I60,
 361		V4L2_COLORSPACE_REC709,
 362		V4L2_FIELD_INTERLACED,
 363		0,
 364		0x465,
 365		181,
 366		205
 367	},
 368	{
 369		V4L2_DV_1080I50,
 370		tvp7002_parms_1080I50,
 371		V4L2_COLORSPACE_REC709,
 372		V4L2_FIELD_INTERLACED,
 373		0,
 374		0x465,
 375		217,
 376		245
 377	},
 378	{
 379		V4L2_DV_720P50,
 380		tvp7002_parms_720P50,
 381		V4L2_COLORSPACE_REC709,
 382		V4L2_FIELD_NONE,
 383		1,
 384		0x2EE,
 385		163,
 386		183
 387	},
 388	{
 389		V4L2_DV_1080P60,
 390		tvp7002_parms_1080P60,
 391		V4L2_COLORSPACE_REC709,
 392		V4L2_FIELD_NONE,
 393		1,
 394		0x465,
 395		90,
 396		102
 397	},
 398	{
 399		V4L2_DV_480P59_94,
 400		tvp7002_parms_480P,
 401		V4L2_COLORSPACE_SMPTE170M,
 402		V4L2_FIELD_NONE,
 403		1,
 404		0x20D,
 405		0xffff,
 406		0xffff
 407	},
 408	{
 409		V4L2_DV_576P50,
 410		tvp7002_parms_576P,
 411		V4L2_COLORSPACE_SMPTE170M,
 412		V4L2_FIELD_NONE,
 413		1,
 414		0x271,
 415		0xffff,
 416		0xffff
 417	}
 418};
 419
 420#define NUM_PRESETS	ARRAY_SIZE(tvp7002_presets)
 421
 422/* Device definition */
 423struct tvp7002 {
 424	struct v4l2_subdev sd;
 425	struct v4l2_ctrl_handler hdl;
 426	const struct tvp7002_config *pdata;
 427
 428	int ver;
 429	int streaming;
 430
 431	const struct tvp7002_preset_definition *current_preset;
 432};
 433
 434/*
 435 * to_tvp7002 - Obtain device handler TVP7002
 436 * @sd: ptr to v4l2_subdev struct
 437 *
 438 * Returns device handler tvp7002.
 439 */
 440static inline struct tvp7002 *to_tvp7002(struct v4l2_subdev *sd)
 441{
 442	return container_of(sd, struct tvp7002, sd);
 443}
 444
 445static inline struct v4l2_subdev *to_sd(struct v4l2_ctrl *ctrl)
 446{
 447	return &container_of(ctrl->handler, struct tvp7002, hdl)->sd;
 448}
 449
 450/*
 451 * tvp7002_read - Read a value from a register in an TVP7002
 452 * @sd: ptr to v4l2_subdev struct
 453 * @addr: TVP7002 register address
 454 * @dst: pointer to 8-bit destination
 455 *
 456 * Returns value read if successful, or non-zero (-1) otherwise.
 457 */
 458static int tvp7002_read(struct v4l2_subdev *sd, u8 addr, u8 *dst)
 459{
 460	struct i2c_client *c = v4l2_get_subdevdata(sd);
 461	int retry;
 462	int error;
 463
 464	for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
 465		error = i2c_smbus_read_byte_data(c, addr);
 466
 467		if (error >= 0) {
 468			*dst = (u8)error;
 469			return 0;
 470		}
 471
 472		msleep_interruptible(10);
 473	}
 474	v4l2_err(sd, "TVP7002 read error %d\n", error);
 475	return error;
 476}
 477
 478/*
 479 * tvp7002_read_err() - Read a register value with error code
 480 * @sd: pointer to standard V4L2 sub-device structure
 481 * @reg: destination register
 482 * @val: value to be read
 483 * @err: pointer to error value
 484 *
 485 * Read a value in a register and save error value in pointer.
 486 * Also update the register table if successful
 487 */
 488static inline void tvp7002_read_err(struct v4l2_subdev *sd, u8 reg,
 489							u8 *dst, int *err)
 490{
 491	if (!*err)
 492		*err = tvp7002_read(sd, reg, dst);
 493}
 494
 495/*
 496 * tvp7002_write() - Write a value to a register in TVP7002
 497 * @sd: ptr to v4l2_subdev struct
 498 * @addr: TVP7002 register address
 499 * @value: value to be written to the register
 500 *
 501 * Write a value to a register in an TVP7002 decoder device.
 502 * Returns zero if successful, or non-zero otherwise.
 503 */
 504static int tvp7002_write(struct v4l2_subdev *sd, u8 addr, u8 value)
 505{
 506	struct i2c_client *c;
 507	int retry;
 508	int error;
 509
 510	c = v4l2_get_subdevdata(sd);
 511
 512	for (retry = 0; retry < I2C_RETRY_COUNT; retry++) {
 513		error = i2c_smbus_write_byte_data(c, addr, value);
 514
 515		if (error >= 0)
 516			return 0;
 517
 518		v4l2_warn(sd, "Write: retry ... %d\n", retry);
 519		msleep_interruptible(10);
 520	}
 521	v4l2_err(sd, "TVP7002 write error %d\n", error);
 522	return error;
 523}
 524
 525/*
 526 * tvp7002_write_err() - Write a register value with error code
 527 * @sd: pointer to standard V4L2 sub-device structure
 528 * @reg: destination register
 529 * @val: value to be written
 530 * @err: pointer to error value
 531 *
 532 * Write a value in a register and save error value in pointer.
 533 * Also update the register table if successful
 534 */
 535static inline void tvp7002_write_err(struct v4l2_subdev *sd, u8 reg,
 536							u8 val, int *err)
 537{
 538	if (!*err)
 539		*err = tvp7002_write(sd, reg, val);
 540}
 541
 542/*
 543 * tvp7002_g_chip_ident() - Get chip identification number
 544 * @sd: ptr to v4l2_subdev struct
 545 * @chip: ptr to v4l2_dbg_chip_ident struct
 546 *
 547 * Obtains the chip's identification number.
 548 * Returns zero or -EINVAL if read operation fails.
 549 */
 550static int tvp7002_g_chip_ident(struct v4l2_subdev *sd,
 551					struct v4l2_dbg_chip_ident *chip)
 552{
 553	u8 rev;
 554	int error;
 555	struct i2c_client *client = v4l2_get_subdevdata(sd);
 556
 557	error = tvp7002_read(sd, TVP7002_CHIP_REV, &rev);
 558
 559	if (error < 0)
 560		return error;
 561
 562	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_TVP7002, rev);
 563}
 564
 565/*
 566 * tvp7002_write_inittab() - Write initialization values
 567 * @sd: ptr to v4l2_subdev struct
 568 * @regs: ptr to i2c_reg_value struct
 569 *
 570 * Write initialization values.
 571 * Returns zero or -EINVAL if read operation fails.
 572 */
 573static int tvp7002_write_inittab(struct v4l2_subdev *sd,
 574					const struct i2c_reg_value *regs)
 575{
 576	int error = 0;
 577
 578	/* Initialize the first (defined) registers */
 579	while (TVP7002_EOR != regs->reg) {
 580		if (TVP7002_WRITE == regs->type)
 581			tvp7002_write_err(sd, regs->reg, regs->value, &error);
 582		regs++;
 583	}
 584
 585	return error;
 586}
 587
 588/*
 589 * tvp7002_s_dv_preset() - Set digital video preset
 590 * @sd: ptr to v4l2_subdev struct
 591 * @dv_preset: ptr to v4l2_dv_preset struct
 592 *
 593 * Set the digital video preset for a TVP7002 decoder device.
 594 * Returns zero when successful or -EINVAL if register access fails.
 595 */
 596static int tvp7002_s_dv_preset(struct v4l2_subdev *sd,
 597					struct v4l2_dv_preset *dv_preset)
 598{
 599	struct tvp7002 *device = to_tvp7002(sd);
 600	u32 preset;
 601	int i;
 602
 603	for (i = 0; i < NUM_PRESETS; i++) {
 604		preset = tvp7002_presets[i].preset;
 605		if (preset == dv_preset->preset) {
 606			device->current_preset = &tvp7002_presets[i];
 607			return tvp7002_write_inittab(sd, tvp7002_presets[i].p_settings);
 608		}
 609	}
 610
 611	return -EINVAL;
 612}
 613
 614/*
 615 * tvp7002_s_ctrl() - Set a control
 616 * @ctrl: ptr to v4l2_ctrl struct
 617 *
 618 * Set a control in TVP7002 decoder device.
 619 * Returns zero when successful or -EINVAL if register access fails.
 620 */
 621static int tvp7002_s_ctrl(struct v4l2_ctrl *ctrl)
 622{
 623	struct v4l2_subdev *sd = to_sd(ctrl);
 624	int error = 0;
 625
 626	switch (ctrl->id) {
 627	case V4L2_CID_GAIN:
 628		tvp7002_write_err(sd, TVP7002_R_FINE_GAIN, ctrl->val, &error);
 629		tvp7002_write_err(sd, TVP7002_G_FINE_GAIN, ctrl->val, &error);
 630		tvp7002_write_err(sd, TVP7002_B_FINE_GAIN, ctrl->val, &error);
 631		return error;
 632	}
 633	return -EINVAL;
 634}
 635
 636/*
 637 * tvp7002_mbus_fmt() - V4L2 decoder interface handler for try/s/g_mbus_fmt
 638 * @sd: pointer to standard V4L2 sub-device structure
 639 * @f: pointer to mediabus format structure
 640 *
 641 * Negotiate the image capture size and mediabus format.
 642 * There is only one possible format, so this single function works for
 643 * get, set and try.
 644 */
 645static int tvp7002_mbus_fmt(struct v4l2_subdev *sd, struct v4l2_mbus_framefmt *f)
 646{
 647	struct tvp7002 *device = to_tvp7002(sd);
 648	struct v4l2_dv_enum_preset e_preset;
 649	int error;
 650
 651	/* Calculate height and width based on current standard */
 652	error = v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset);
 653	if (error)
 654		return error;
 655
 656	f->width = e_preset.width;
 657	f->height = e_preset.height;
 658	f->code = V4L2_MBUS_FMT_YUYV10_1X20;
 659	f->field = device->current_preset->scanmode;
 660	f->colorspace = device->current_preset->color_space;
 661
 662	v4l2_dbg(1, debug, sd, "MBUS_FMT: Width - %d, Height - %d",
 663			f->width, f->height);
 664	return 0;
 665}
 666
 667/*
 668 * tvp7002_query_dv_preset() - query DV preset
 669 * @sd: pointer to standard V4L2 sub-device structure
 670 * @qpreset: standard V4L2 v4l2_dv_preset structure
 671 *
 672 * Returns the current DV preset by TVP7002. If no active input is
 673 * detected, returns -EINVAL
 674 */
 675static int tvp7002_query_dv_preset(struct v4l2_subdev *sd,
 676						struct v4l2_dv_preset *qpreset)
 677{
 678	const struct tvp7002_preset_definition *presets = tvp7002_presets;
 679	struct tvp7002 *device;
 680	u8 progressive;
 681	u32 lpfr;
 682	u32 cpln;
 683	int error = 0;
 684	u8 lpf_lsb;
 685	u8 lpf_msb;
 686	u8 cpl_lsb;
 687	u8 cpl_msb;
 688	int index;
 689
 690	device = to_tvp7002(sd);
 691
 692	/* Read standards from device registers */
 693	tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_LSBS, &lpf_lsb, &error);
 694	tvp7002_read_err(sd, TVP7002_L_FRAME_STAT_MSBS, &lpf_msb, &error);
 695
 696	if (error < 0)
 697		return error;
 698
 699	tvp7002_read_err(sd, TVP7002_CLK_L_STAT_LSBS, &cpl_lsb, &error);
 700	tvp7002_read_err(sd, TVP7002_CLK_L_STAT_MSBS, &cpl_msb, &error);
 701
 702	if (error < 0)
 703		return error;
 704
 705	/* Get lines per frame, clocks per line and interlaced/progresive */
 706	lpfr = lpf_lsb | ((TVP7002_CL_MASK & lpf_msb) << TVP7002_CL_SHIFT);
 707	cpln = cpl_lsb | ((TVP7002_CL_MASK & cpl_msb) << TVP7002_CL_SHIFT);
 708	progressive = (lpf_msb & TVP7002_INPR_MASK) >> TVP7002_IP_SHIFT;
 709
 710	/* Do checking of video modes */
 711	for (index = 0; index < NUM_PRESETS; index++, presets++)
 712		if (lpfr  == presets->lines_per_frame &&
 713			progressive == presets->progressive) {
 714			if (presets->cpl_min == 0xffff)
 715				break;
 716			if (cpln >= presets->cpl_min && cpln <= presets->cpl_max)
 717				break;
 718		}
 719
 720	if (index == NUM_PRESETS) {
 721		v4l2_dbg(1, debug, sd, "detection failed: lpf = %x, cpl = %x\n",
 722								lpfr, cpln);
 723		/* Could not detect a signal, so return the 'invalid' preset */
 724		qpreset->preset = V4L2_DV_INVALID;
 725		return 0;
 726	}
 727
 728	/* Set values in found preset */
 729	qpreset->preset = presets->preset;
 730
 731	/* Update lines per frame and clocks per line info */
 732	v4l2_dbg(1, debug, sd, "detected preset: %d\n", presets->preset);
 733	return 0;
 734}
 735
 736#ifdef CONFIG_VIDEO_ADV_DEBUG
 737/*
 738 * tvp7002_g_register() - Get the value of a register
 739 * @sd: ptr to v4l2_subdev struct
 740 * @reg: ptr to v4l2_dbg_register struct
 741 *
 742 * Get the value of a TVP7002 decoder device register.
 743 * Returns zero when successful, -EINVAL if register read fails or
 744 * access to I2C client fails, -EPERM if the call is not allowed
 745 * by disabled CAP_SYS_ADMIN.
 746 */
 747static int tvp7002_g_register(struct v4l2_subdev *sd,
 748						struct v4l2_dbg_register *reg)
 749{
 750	struct i2c_client *client = v4l2_get_subdevdata(sd);
 751	u8 val;
 752	int ret;
 753
 754	if (!v4l2_chip_match_i2c_client(client, &reg->match))
 755		return -EINVAL;
 756	if (!capable(CAP_SYS_ADMIN))
 757		return -EPERM;
 758
 759	ret = tvp7002_read(sd, reg->reg & 0xff, &val);
 760	reg->val = val;
 761	return ret;
 762}
 763
 764/*
 765 * tvp7002_s_register() - set a control
 766 * @sd: ptr to v4l2_subdev struct
 767 * @reg: ptr to v4l2_dbg_register struct
 768 *
 769 * Get the value of a TVP7002 decoder device register.
 770 * Returns zero when successful, -EINVAL if register read fails or
 771 * -EPERM if call not allowed.
 772 */
 773static int tvp7002_s_register(struct v4l2_subdev *sd,
 774						struct v4l2_dbg_register *reg)
 775{
 776	struct i2c_client *client = v4l2_get_subdevdata(sd);
 777
 778	if (!v4l2_chip_match_i2c_client(client, &reg->match))
 779		return -EINVAL;
 780	if (!capable(CAP_SYS_ADMIN))
 781		return -EPERM;
 782
 783	return tvp7002_write(sd, reg->reg & 0xff, reg->val & 0xff);
 784}
 785#endif
 786
 787/*
 788 * tvp7002_enum_mbus_fmt() - Enum supported mediabus formats
 789 * @sd: pointer to standard V4L2 sub-device structure
 790 * @index: format index
 791 * @code: pointer to mediabus format
 792 *
 793 * Enumerate supported mediabus formats.
 794 */
 795
 796static int tvp7002_enum_mbus_fmt(struct v4l2_subdev *sd, unsigned index,
 797					enum v4l2_mbus_pixelcode *code)
 798{
 799	/* Check requested format index is within range */
 800	if (index)
 801		return -EINVAL;
 802	*code = V4L2_MBUS_FMT_YUYV10_1X20;
 803	return 0;
 804}
 805
 806/*
 807 * tvp7002_s_stream() - V4L2 decoder i/f handler for s_stream
 808 * @sd: pointer to standard V4L2 sub-device structure
 809 * @enable: streaming enable or disable
 810 *
 811 * Sets streaming to enable or disable, if possible.
 812 */
 813static int tvp7002_s_stream(struct v4l2_subdev *sd, int enable)
 814{
 815	struct tvp7002 *device = to_tvp7002(sd);
 816	int error = 0;
 817
 818	if (device->streaming == enable)
 819		return 0;
 820
 821	if (enable) {
 822		/* Set output state on (low impedance means stream on) */
 823		error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x00);
 824		device->streaming = enable;
 825	} else {
 826		/* Set output state off (high impedance means stream off) */
 827		error = tvp7002_write(sd, TVP7002_MISC_CTL_2, 0x03);
 828		if (error)
 829			v4l2_dbg(1, debug, sd, "Unable to stop streaming\n");
 830
 831		device->streaming = enable;
 832	}
 833
 834	return error;
 835}
 836
 837/*
 838 * tvp7002_log_status() - Print information about register settings
 839 * @sd: ptr to v4l2_subdev struct
 840 *
 841 * Log register values of a TVP7002 decoder device.
 842 * Returns zero or -EINVAL if read operation fails.
 843 */
 844static int tvp7002_log_status(struct v4l2_subdev *sd)
 845{
 846	const struct tvp7002_preset_definition *presets = tvp7002_presets;
 847	struct tvp7002 *device = to_tvp7002(sd);
 848	struct v4l2_dv_enum_preset e_preset;
 849	struct v4l2_dv_preset detected;
 850	int i;
 851
 852	detected.preset = V4L2_DV_INVALID;
 853	/* Find my current standard*/
 854	tvp7002_query_dv_preset(sd, &detected);
 855
 856	/* Print standard related code values */
 857	for (i = 0; i < NUM_PRESETS; i++, presets++)
 858		if (presets->preset == detected.preset)
 859			break;
 860
 861	if (v4l_fill_dv_preset_info(device->current_preset->preset, &e_preset))
 862		return -EINVAL;
 863
 864	v4l2_info(sd, "Selected DV Preset: %s\n", e_preset.name);
 865	v4l2_info(sd, "   Pixels per line: %u\n", e_preset.width);
 866	v4l2_info(sd, "   Lines per frame: %u\n\n", e_preset.height);
 867	if (i == NUM_PRESETS) {
 868		v4l2_info(sd, "Detected DV Preset: None\n");
 869	} else {
 870		if (v4l_fill_dv_preset_info(presets->preset, &e_preset))
 871			return -EINVAL;
 872		v4l2_info(sd, "Detected DV Preset: %s\n", e_preset.name);
 873		v4l2_info(sd, "  Pixels per line: %u\n", e_preset.width);
 874		v4l2_info(sd, "  Lines per frame: %u\n\n", e_preset.height);
 875	}
 876	v4l2_info(sd, "Streaming enabled: %s\n",
 877					device->streaming ? "yes" : "no");
 878
 879	/* Print the current value of the gain control */
 880	v4l2_ctrl_handler_log_status(&device->hdl, sd->name);
 881
 882	return 0;
 883}
 884
 885/*
 886 * tvp7002_enum_dv_presets() - Enum supported digital video formats
 887 * @sd: pointer to standard V4L2 sub-device structure
 888 * @preset: pointer to format struct
 889 *
 890 * Enumerate supported digital video formats.
 891 */
 892static int tvp7002_enum_dv_presets(struct v4l2_subdev *sd,
 893		struct v4l2_dv_enum_preset *preset)
 894{
 895	/* Check requested format index is within range */
 896	if (preset->index >= NUM_PRESETS)
 897		return -EINVAL;
 898
 899	return v4l_fill_dv_preset_info(tvp7002_presets[preset->index].preset, preset);
 900}
 901
 902static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
 903	.s_ctrl = tvp7002_s_ctrl,
 904};
 905
 906/* V4L2 core operation handlers */
 907static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
 908	.g_chip_ident = tvp7002_g_chip_ident,
 909	.log_status = tvp7002_log_status,
 910	.g_ext_ctrls = v4l2_subdev_g_ext_ctrls,
 911	.try_ext_ctrls = v4l2_subdev_try_ext_ctrls,
 912	.s_ext_ctrls = v4l2_subdev_s_ext_ctrls,
 913	.g_ctrl = v4l2_subdev_g_ctrl,
 914	.s_ctrl = v4l2_subdev_s_ctrl,
 915	.queryctrl = v4l2_subdev_queryctrl,
 916	.querymenu = v4l2_subdev_querymenu,
 917#ifdef CONFIG_VIDEO_ADV_DEBUG
 918	.g_register = tvp7002_g_register,
 919	.s_register = tvp7002_s_register,
 920#endif
 921};
 922
 923/* Specific video subsystem operation handlers */
 924static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
 925	.enum_dv_presets = tvp7002_enum_dv_presets,
 926	.s_dv_preset = tvp7002_s_dv_preset,
 927	.query_dv_preset = tvp7002_query_dv_preset,
 928	.s_stream = tvp7002_s_stream,
 929	.g_mbus_fmt = tvp7002_mbus_fmt,
 930	.try_mbus_fmt = tvp7002_mbus_fmt,
 931	.s_mbus_fmt = tvp7002_mbus_fmt,
 932	.enum_mbus_fmt = tvp7002_enum_mbus_fmt,
 933};
 934
 935/* V4L2 top level operation handlers */
 936static const struct v4l2_subdev_ops tvp7002_ops = {
 937	.core = &tvp7002_core_ops,
 938	.video = &tvp7002_video_ops,
 939};
 940
 941/*
 942 * tvp7002_probe - Probe a TVP7002 device
 943 * @c: ptr to i2c_client struct
 944 * @id: ptr to i2c_device_id struct
 945 *
 946 * Initialize the TVP7002 device
 947 * Returns zero when successful, -EINVAL if register read fails or
 948 * -EIO if i2c access is not available.
 949 */
 950static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
 951{
 952	struct v4l2_subdev *sd;
 953	struct tvp7002 *device;
 954	struct v4l2_dv_preset preset;
 955	int polarity_a;
 956	int polarity_b;
 957	u8 revision;
 958
 959	int error;
 960
 961	/* Check if the adapter supports the needed features */
 962	if (!i2c_check_functionality(c->adapter,
 963		I2C_FUNC_SMBUS_READ_BYTE | I2C_FUNC_SMBUS_WRITE_BYTE_DATA))
 964		return -EIO;
 965
 966	if (!c->dev.platform_data) {
 967		v4l_err(c, "No platform data!!\n");
 968		return -ENODEV;
 969	}
 970
 971	device = kzalloc(sizeof(struct tvp7002), GFP_KERNEL);
 972
 973	if (!device)
 974		return -ENOMEM;
 975
 976	sd = &device->sd;
 977	device->pdata = c->dev.platform_data;
 978	device->current_preset = tvp7002_presets;
 979
 980	/* Tell v4l2 the device is ready */
 981	v4l2_i2c_subdev_init(sd, c, &tvp7002_ops);
 982	v4l_info(c, "tvp7002 found @ 0x%02x (%s)\n",
 983					c->addr, c->adapter->name);
 984
 985	error = tvp7002_read(sd, TVP7002_CHIP_REV, &revision);
 986	if (error < 0)
 987		goto found_error;
 988
 989	/* Get revision number */
 990	v4l2_info(sd, "Rev. %02x detected.\n", revision);
 991	if (revision != 0x02)
 992		v4l2_info(sd, "Unknown revision detected.\n");
 993
 994	/* Initializes TVP7002 to its default values */
 995	error = tvp7002_write_inittab(sd, tvp7002_init_default);
 996
 997	if (error < 0)
 998		goto found_error;
 999
1000	/* Set polarity information after registers have been set */
1001	polarity_a = 0x20 | device->pdata->hs_polarity << 5
1002			| device->pdata->vs_polarity << 2;
1003	error = tvp7002_write(sd, TVP7002_SYNC_CTL_1, polarity_a);
1004	if (error < 0)
1005		goto found_error;
1006
1007	polarity_b = 0x01  | device->pdata->fid_polarity << 2
1008			| device->pdata->sog_polarity << 1
1009			| device->pdata->clk_polarity;
1010	error = tvp7002_write(sd, TVP7002_MISC_CTL_3, polarity_b);
1011	if (error < 0)
1012		goto found_error;
1013
1014	/* Set registers according to default video mode */
1015	preset.preset = device->current_preset->preset;
1016	error = tvp7002_s_dv_preset(sd, &preset);
1017
1018	v4l2_ctrl_handler_init(&device->hdl, 1);
1019	v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
1020			V4L2_CID_GAIN, 0, 255, 1, 0);
1021	sd->ctrl_handler = &device->hdl;
1022	if (device->hdl.error) {
1023		int err = device->hdl.error;
1024
1025		v4l2_ctrl_handler_free(&device->hdl);
1026		kfree(device);
1027		return err;
1028	}
1029	v4l2_ctrl_handler_setup(&device->hdl);
1030
1031found_error:
1032	if (error < 0)
1033		kfree(device);
1034
1035	return error;
1036}
1037
1038/*
1039 * tvp7002_remove - Remove TVP7002 device support
1040 * @c: ptr to i2c_client struct
1041 *
1042 * Reset the TVP7002 device
1043 * Returns zero.
1044 */
1045static int tvp7002_remove(struct i2c_client *c)
1046{
1047	struct v4l2_subdev *sd = i2c_get_clientdata(c);
1048	struct tvp7002 *device = to_tvp7002(sd);
1049
1050	v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
1051				"on address 0x%x\n", c->addr);
1052
1053	v4l2_device_unregister_subdev(sd);
1054	v4l2_ctrl_handler_free(&device->hdl);
1055	kfree(device);
1056	return 0;
1057}
1058
1059/* I2C Device ID table */
1060static const struct i2c_device_id tvp7002_id[] = {
1061	{ "tvp7002", 0 },
1062	{ }
1063};
1064MODULE_DEVICE_TABLE(i2c, tvp7002_id);
1065
1066/* I2C driver data */
1067static struct i2c_driver tvp7002_driver = {
1068	.driver = {
1069		.owner = THIS_MODULE,
1070		.name = TVP7002_MODULE_NAME,
1071	},
1072	.probe = tvp7002_probe,
1073	.remove = tvp7002_remove,
1074	.id_table = tvp7002_id,
1075};
1076
1077/*
1078 * tvp7002_init - Initialize driver via I2C interface
1079 *
1080 * Register the TVP7002 driver.
1081 * Return 0 on success or error code on failure.
1082 */
1083static int __init tvp7002_init(void)
1084{
1085	return i2c_add_driver(&tvp7002_driver);
1086}
1087
1088/*
1089 * tvp7002_exit - Remove driver via I2C interface
1090 *
1091 * Unregister the TVP7002 driver.
1092 * Returns nothing.
1093 */
1094static void __exit tvp7002_exit(void)
1095{
1096	i2c_del_driver(&tvp7002_driver);
1097}
1098
1099module_init(tvp7002_init);
1100module_exit(tvp7002_exit);