saa7191.c 15.9 KB
Newer Older
R
Ralf Baechle 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14
/*
 *  saa7191.c - Philips SAA7191 video decoder driver
 *
 *  Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
 *  Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License version 2 as
 *  published by the Free Software Foundation.
 */

#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/fs.h>
15
#include <linux/init.h>
R
Ralf Baechle 已提交
16 17
#include <linux/kernel.h>
#include <linux/major.h>
18
#include <linux/module.h>
R
Ralf Baechle 已提交
19
#include <linux/mm.h>
20
#include <linux/slab.h>
R
Ralf Baechle 已提交
21

22
#include <linux/videodev2.h>
R
Ralf Baechle 已提交
23
#include <linux/i2c.h>
24 25
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
26
#include <media/v4l2-i2c-drv-legacy.h>
R
Ralf Baechle 已提交
27 28 29

#include "saa7191.h"

L
Ladislav Michl 已提交
30
#define SAA7191_MODULE_VERSION	"0.0.5"
R
Ralf Baechle 已提交
31 32 33 34 35 36

MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
MODULE_VERSION(SAA7191_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");

37 38 39 40
static unsigned short normal_i2c[] = { 0x8a >> 1, 0x8e >> 1, I2C_CLIENT_END };

I2C_CLIENT_INSMOD;

L
Ladislav Michl 已提交
41 42 43 44 45 46 47 48 49 50 51
// #define SAA7191_DEBUG

#ifdef SAA7191_DEBUG
#define dprintk(x...) printk("SAA7191: " x);
#else
#define dprintk(x...)
#endif

#define SAA7191_SYNC_COUNT	30
#define SAA7191_SYNC_DELAY	100	/* milliseconds */

R
Ralf Baechle 已提交
52
struct saa7191 {
53
	struct v4l2_subdev sd;
R
Ralf Baechle 已提交
54 55 56

	/* the register values are stored here as the actual
	 * I2C-registers are write-only */
L
Ladislav Michl 已提交
57
	u8 reg[25];
R
Ralf Baechle 已提交
58

L
Ladislav Michl 已提交
59
	int input;
60
	v4l2_std_id norm;
R
Ralf Baechle 已提交
61 62
};

63 64 65 66 67
static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd)
{
	return container_of(sd, struct saa7191, sd);
}

L
Ladislav Michl 已提交
68
static const u8 initseq[] = {
R
Ralf Baechle 已提交
69
	0,	/* Subaddress */
L
Ladislav Michl 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98

	0x50,	/* (0x50) SAA7191_REG_IDEL */

	/* 50 Hz signal timing */
	0x30,	/* (0x30) SAA7191_REG_HSYB */
	0x00,	/* (0x00) SAA7191_REG_HSYS */
	0xe8,	/* (0xe8) SAA7191_REG_HCLB */
	0xb6,	/* (0xb6) SAA7191_REG_HCLS */
	0xf4,	/* (0xf4) SAA7191_REG_HPHI */

	/* control */
	SAA7191_LUMA_APER_1,	/* (0x01) SAA7191_REG_LUMA - CVBS mode */
	0x00,	/* (0x00) SAA7191_REG_HUEC */
	0xf8,	/* (0xf8) SAA7191_REG_CKTQ */
	0xf8,	/* (0xf8) SAA7191_REG_CKTS */
	0x90,	/* (0x90) SAA7191_REG_PLSE */
	0x90,	/* (0x90) SAA7191_REG_SESE */
	0x00,	/* (0x00) SAA7191_REG_GAIN */
	SAA7191_STDC_NFEN | SAA7191_STDC_HRMV,	/* (0x0c) SAA7191_REG_STDC
						 * - not SECAM,
						 * slow time constant */
	SAA7191_IOCK_OEDC | SAA7191_IOCK_OEHS | SAA7191_IOCK_OEVS
	| SAA7191_IOCK_OEDY,	/* (0x78) SAA7191_REG_IOCK
				 * - chroma from CVBS, GPSW1 & 2 off */
	SAA7191_CTL3_AUFD | SAA7191_CTL3_SCEN | SAA7191_CTL3_OFTS
	| SAA7191_CTL3_YDEL0,	/* (0x99) SAA7191_REG_CTL3
				 * - automatic field detection */
	0x00,	/* (0x00) SAA7191_REG_CTL4 */
	0x2c,	/* (0x2c) SAA7191_REG_CHCV - PAL nominal value */
R
Ralf Baechle 已提交
99 100
	0x00,	/* unused */
	0x00,	/* unused */
L
Ladislav Michl 已提交
101 102 103 104 105 106 107

	/* 60 Hz signal timing */
	0x34,	/* (0x34) SAA7191_REG_HS6B */
	0x0a,	/* (0x0a) SAA7191_REG_HS6S */
	0xf4,	/* (0xf4) SAA7191_REG_HC6B */
	0xce,	/* (0xce) SAA7191_REG_HC6S */
	0xf4,	/* (0xf4) SAA7191_REG_HP6I */
R
Ralf Baechle 已提交
108 109 110 111
};

/* SAA7191 register handling */

112
static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg)
R
Ralf Baechle 已提交
113
{
114
	return to_saa7191(sd)->reg[reg];
R
Ralf Baechle 已提交
115 116
}

117
static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value)
R
Ralf Baechle 已提交
118
{
119
	struct i2c_client *client = v4l2_get_subdevdata(sd);
R
Ralf Baechle 已提交
120 121 122 123
	int ret;

	ret = i2c_master_recv(client, value, 1);
	if (ret < 0) {
L
Ladislav Michl 已提交
124
		printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
R
Ralf Baechle 已提交
125 126 127 128 129 130 131
		return ret;
	}

	return 0;
}


132
static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
R
Ralf Baechle 已提交
133
{
134 135 136
	struct i2c_client *client = v4l2_get_subdevdata(sd);

	to_saa7191(sd)->reg[reg] = value;
R
Ralf Baechle 已提交
137 138 139 140
	return i2c_smbus_write_byte_data(client, reg, value);
}

/* the first byte of data must be the first subaddress number (register) */
141
static int saa7191_write_block(struct v4l2_subdev *sd,
142
			       u8 length, const u8 *data)
R
Ralf Baechle 已提交
143
{
144 145
	struct i2c_client *client = v4l2_get_subdevdata(sd);
	struct saa7191 *decoder = to_saa7191(sd);
R
Ralf Baechle 已提交
146 147 148 149 150 151 152 153 154 155
	int i;
	int ret;

	for (i = 0; i < (length - 1); i++) {
		decoder->reg[data[0] + i] = data[i + 1];
	}

	ret = i2c_master_send(client, data, length);
	if (ret < 0) {
		printk(KERN_ERR "SAA7191: saa7191_write_block(): "
L
Ladislav Michl 已提交
156
		       "write failed\n");
R
Ralf Baechle 已提交
157 158 159 160 161 162 163 164
		return ret;
	}

	return 0;
}

/* Helper functions */

165 166
static int saa7191_s_routing(struct v4l2_subdev *sd,
				const struct v4l2_routing *route)
R
Ralf Baechle 已提交
167
{
168 169 170
	struct saa7191 *decoder = to_saa7191(sd);
	u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
	u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
R
Ralf Baechle 已提交
171 172
	int err;

173
	switch (route->input) {
R
Ralf Baechle 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
	case SAA7191_INPUT_COMPOSITE: /* Set Composite input */
		iock &= ~(SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW1
			  | SAA7191_IOCK_GPSW2);
		/* Chrominance trap active */
		luma &= ~SAA7191_LUMA_BYPS;
		break;
	case SAA7191_INPUT_SVIDEO: /* Set S-Video input */
		iock |= SAA7191_IOCK_CHRS | SAA7191_IOCK_GPSW2;
		/* Chrominance trap bypassed */
		luma |= SAA7191_LUMA_BYPS;
		break;
	default:
		return -EINVAL;
	}

189
	err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma);
R
Ralf Baechle 已提交
190 191
	if (err)
		return -EIO;
192
	err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock);
R
Ralf Baechle 已提交
193 194 195
	if (err)
		return -EIO;

196
	decoder->input = route->input;
L
Ladislav Michl 已提交
197

R
Ralf Baechle 已提交
198 199 200
	return 0;
}

201
static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
R
Ralf Baechle 已提交
202
{
203 204 205 206
	struct saa7191 *decoder = to_saa7191(sd);
	u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
	u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
	u8 chcv = saa7191_read_reg(sd, SAA7191_REG_CHCV);
R
Ralf Baechle 已提交
207 208
	int err;

209
	if (norm & V4L2_STD_PAL) {
R
Ralf Baechle 已提交
210 211 212
		stdc &= ~SAA7191_STDC_SECS;
		ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
		chcv = SAA7191_CHCV_PAL;
213
	} else if (norm & V4L2_STD_NTSC) {
R
Ralf Baechle 已提交
214 215 216 217
		stdc &= ~SAA7191_STDC_SECS;
		ctl3 &= ~SAA7191_CTL3_AUFD;
		ctl3 |= SAA7191_CTL3_FSEL;
		chcv = SAA7191_CHCV_NTSC;
218
	} else if (norm & V4L2_STD_SECAM) {
R
Ralf Baechle 已提交
219 220 221
		stdc |= SAA7191_STDC_SECS;
		ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
		chcv = SAA7191_CHCV_PAL;
222
	} else {
R
Ralf Baechle 已提交
223 224 225
		return -EINVAL;
	}

226
	err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
R
Ralf Baechle 已提交
227 228
	if (err)
		return -EIO;
229
	err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
R
Ralf Baechle 已提交
230 231
	if (err)
		return -EIO;
232
	err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv);
R
Ralf Baechle 已提交
233 234 235 236 237
	if (err)
		return -EIO;

	decoder->norm = norm;

L
Ladislav Michl 已提交
238 239
	dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
		stdc, chcv);
240
	dprintk("norm: %llx\n", norm);
L
Ladislav Michl 已提交
241

R
Ralf Baechle 已提交
242 243 244
	return 0;
}

245
static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status)
R
Ralf Baechle 已提交
246
{
L
Ladislav Michl 已提交
247
	int i = 0;
R
Ralf Baechle 已提交
248

L
Ladislav Michl 已提交
249 250 251
	dprintk("Checking for signal...\n");

	for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
252
		if (saa7191_read_status(sd, status))
L
Ladislav Michl 已提交
253 254 255 256 257 258 259 260
			return -EIO;

		if (((*status) & SAA7191_STATUS_HLCK) == 0) {
			dprintk("Signal found\n");
			return 0;
		}

		msleep(SAA7191_SYNC_DELAY);
R
Ralf Baechle 已提交
261 262
	}

L
Ladislav Michl 已提交
263
	dprintk("No signal\n");
R
Ralf Baechle 已提交
264

L
Ladislav Michl 已提交
265
	return -EBUSY;
R
Ralf Baechle 已提交
266 267
}

268
static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm)
R
Ralf Baechle 已提交
269
{
270 271 272
	struct saa7191 *decoder = to_saa7191(sd);
	u8 stdc = saa7191_read_reg(sd, SAA7191_REG_STDC);
	u8 ctl3 = saa7191_read_reg(sd, SAA7191_REG_CTL3);
L
Ladislav Michl 已提交
273
	u8 status;
274
	v4l2_std_id old_norm = decoder->norm;
L
Ladislav Michl 已提交
275
	int err = 0;
R
Ralf Baechle 已提交
276

L
Ladislav Michl 已提交
277 278
	dprintk("SAA7191 extended signal auto-detection...\n");

279
	*norm = V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
L
Ladislav Michl 已提交
280 281 282
	stdc &= ~SAA7191_STDC_SECS;
	ctl3 &= ~(SAA7191_CTL3_FSEL);

283
	err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
L
Ladislav Michl 已提交
284 285 286 287
	if (err) {
		err = -EIO;
		goto out;
	}
288
	err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
L
Ladislav Michl 已提交
289 290 291 292 293 294
	if (err) {
		err = -EIO;
		goto out;
	}

	ctl3 |= SAA7191_CTL3_AUFD;
295
	err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
L
Ladislav Michl 已提交
296 297 298 299 300 301 302
	if (err) {
		err = -EIO;
		goto out;
	}

	msleep(SAA7191_SYNC_DELAY);

303
	err = saa7191_wait_for_signal(sd, &status);
L
Ladislav Michl 已提交
304 305 306 307 308 309
	if (err)
		goto out;

	if (status & SAA7191_STATUS_FIDT) {
		/* 60Hz signal -> NTSC */
		dprintk("60Hz signal: NTSC\n");
310 311
		*norm = V4L2_STD_NTSC;
		return 0;
L
Ladislav Michl 已提交
312 313 314 315 316 317
	}

	/* 50Hz signal */
	dprintk("50Hz signal: Trying PAL...\n");

	/* try PAL first */
318
	err = saa7191_s_std(sd, V4L2_STD_PAL);
L
Ladislav Michl 已提交
319 320 321 322 323
	if (err)
		goto out;

	msleep(SAA7191_SYNC_DELAY);

324
	err = saa7191_wait_for_signal(sd, &status);
L
Ladislav Michl 已提交
325 326 327 328 329 330
	if (err)
		goto out;

	/* not 50Hz ? */
	if (status & SAA7191_STATUS_FIDT) {
		dprintk("No 50Hz signal\n");
331
		saa7191_s_std(sd, old_norm);
332
		return -EAGAIN;
L
Ladislav Michl 已提交
333 334 335 336
	}

	if (status & SAA7191_STATUS_CODE) {
		dprintk("PAL\n");
337
		*norm = V4L2_STD_PAL;
338
		return saa7191_s_std(sd, old_norm);
L
Ladislav Michl 已提交
339 340 341 342 343
	}

	dprintk("No color detected with PAL - Trying SECAM...\n");

	/* no color detected ? -> try SECAM */
344
	err = saa7191_s_std(sd, V4L2_STD_SECAM);
L
Ladislav Michl 已提交
345 346 347 348 349
	if (err)
		goto out;

	msleep(SAA7191_SYNC_DELAY);

350
	err = saa7191_wait_for_signal(sd, &status);
L
Ladislav Michl 已提交
351 352 353 354 355 356 357 358 359 360 361 362 363
	if (err)
		goto out;

	/* not 50Hz ? */
	if (status & SAA7191_STATUS_FIDT) {
		dprintk("No 50Hz signal\n");
		err = -EAGAIN;
		goto out;
	}

	if (status & SAA7191_STATUS_CODE) {
		/* Color detected -> SECAM */
		dprintk("SECAM\n");
364
		*norm = V4L2_STD_SECAM;
365
		return saa7191_s_std(sd, old_norm);
L
Ladislav Michl 已提交
366 367 368 369 370
	}

	dprintk("No color detected with SECAM - Going back to PAL.\n");

out:
371
	return saa7191_s_std(sd, old_norm);
L
Ladislav Michl 已提交
372 373
}

374
static int saa7191_autodetect_norm(struct v4l2_subdev *sd)
L
Ladislav Michl 已提交
375 376 377 378 379 380 381
{
	u8 status;

	dprintk("SAA7191 signal auto-detection...\n");

	dprintk("Reading status...\n");

382
	if (saa7191_read_status(sd, &status))
L
Ladislav Michl 已提交
383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
		return -EIO;

	dprintk("Checking for signal...\n");

	/* no signal ? */
	if (status & SAA7191_STATUS_HLCK) {
		dprintk("No signal\n");
		return -EBUSY;
	}

	dprintk("Signal found\n");

	if (status & SAA7191_STATUS_FIDT) {
		/* 60hz signal -> NTSC */
		dprintk("NTSC\n");
398
		return saa7191_s_std(sd, V4L2_STD_NTSC);
L
Ladislav Michl 已提交
399 400 401
	} else {
		/* 50hz signal -> PAL */
		dprintk("PAL\n");
402
		return saa7191_s_std(sd, V4L2_STD_PAL);
L
Ladislav Michl 已提交
403 404 405
	}
}

406
static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
L
Ladislav Michl 已提交
407 408 409 410
{
	u8 reg;
	int ret = 0;

411
	switch (ctrl->id) {
L
Ladislav Michl 已提交
412 413 414
	case SAA7191_CONTROL_BANDPASS:
	case SAA7191_CONTROL_BANDPASS_WEIGHT:
	case SAA7191_CONTROL_CORING:
415
		reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
416
		switch (ctrl->id) {
L
Ladislav Michl 已提交
417 418 419 420 421 422 423 424 425 426 427 428
		case SAA7191_CONTROL_BANDPASS:
			ctrl->value = ((s32)reg & SAA7191_LUMA_BPSS_MASK)
				>> SAA7191_LUMA_BPSS_SHIFT;
			break;
		case SAA7191_CONTROL_BANDPASS_WEIGHT:
			ctrl->value = ((s32)reg & SAA7191_LUMA_APER_MASK)
				>> SAA7191_LUMA_APER_SHIFT;
			break;
		case SAA7191_CONTROL_CORING:
			ctrl->value = ((s32)reg & SAA7191_LUMA_CORI_MASK)
				>> SAA7191_LUMA_CORI_SHIFT;
			break;
R
Ralf Baechle 已提交
429
		}
L
Ladislav Michl 已提交
430 431 432
		break;
	case SAA7191_CONTROL_FORCE_COLOUR:
	case SAA7191_CONTROL_CHROMA_GAIN:
433
		reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
434
		if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
L
Ladislav Michl 已提交
435 436 437 438 439
			ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
		else
			ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
				>> SAA7191_GAIN_LFIS_SHIFT;
		break;
440
	case V4L2_CID_HUE:
441
		reg = saa7191_read_reg(sd, SAA7191_REG_HUEC);
L
Ladislav Michl 已提交
442 443 444 445 446 447 448
		if (reg < 0x80)
			reg += 0x80;
		else
			reg -= 0x80;
		ctrl->value = (s32)reg;
		break;
	case SAA7191_CONTROL_VTRC:
449
		reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
L
Ladislav Michl 已提交
450 451 452
		ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
		break;
	case SAA7191_CONTROL_LUMA_DELAY:
453
		reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
L
Ladislav Michl 已提交
454 455 456 457 458 459
		ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
			>> SAA7191_CTL3_YDEL_SHIFT;
		if (ctrl->value >= 4)
			ctrl->value -= 8;
		break;
	case SAA7191_CONTROL_VNR:
460
		reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
L
Ladislav Michl 已提交
461 462 463 464 465 466
		ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
			>> SAA7191_CTL4_VNOI_SHIFT;
		break;
	default:
		ret = -EINVAL;
	}
R
Ralf Baechle 已提交
467

L
Ladislav Michl 已提交
468 469 470
	return ret;
}

471
static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
L
Ladislav Michl 已提交
472 473 474 475
{
	u8 reg;
	int ret = 0;

476
	switch (ctrl->id) {
L
Ladislav Michl 已提交
477 478 479
	case SAA7191_CONTROL_BANDPASS:
	case SAA7191_CONTROL_BANDPASS_WEIGHT:
	case SAA7191_CONTROL_CORING:
480
		reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
481
		switch (ctrl->id) {
L
Ladislav Michl 已提交
482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497
		case SAA7191_CONTROL_BANDPASS:
			reg &= ~SAA7191_LUMA_BPSS_MASK;
			reg |= (ctrl->value << SAA7191_LUMA_BPSS_SHIFT)
				& SAA7191_LUMA_BPSS_MASK;
			break;
		case SAA7191_CONTROL_BANDPASS_WEIGHT:
			reg &= ~SAA7191_LUMA_APER_MASK;
			reg |= (ctrl->value << SAA7191_LUMA_APER_SHIFT)
				& SAA7191_LUMA_APER_MASK;
			break;
		case SAA7191_CONTROL_CORING:
			reg &= ~SAA7191_LUMA_CORI_MASK;
			reg |= (ctrl->value << SAA7191_LUMA_CORI_SHIFT)
				& SAA7191_LUMA_CORI_MASK;
			break;
		}
498
		ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg);
L
Ladislav Michl 已提交
499 500 501
		break;
	case SAA7191_CONTROL_FORCE_COLOUR:
	case SAA7191_CONTROL_CHROMA_GAIN:
502
		reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
503
		if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
L
Ladislav Michl 已提交
504 505 506 507 508 509 510 511 512
			if (ctrl->value)
				reg |= SAA7191_GAIN_COLO;
			else
				reg &= ~SAA7191_GAIN_COLO;
		} else {
			reg &= ~SAA7191_GAIN_LFIS_MASK;
			reg |= (ctrl->value << SAA7191_GAIN_LFIS_SHIFT)
				& SAA7191_GAIN_LFIS_MASK;
		}
513
		ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg);
L
Ladislav Michl 已提交
514
		break;
515
	case V4L2_CID_HUE:
L
Ladislav Michl 已提交
516 517 518 519 520
		reg = ctrl->value & 0xff;
		if (reg < 0x80)
			reg += 0x80;
		else
			reg -= 0x80;
521
		ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg);
L
Ladislav Michl 已提交
522 523
		break;
	case SAA7191_CONTROL_VTRC:
524
		reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
L
Ladislav Michl 已提交
525 526 527 528
		if (ctrl->value)
			reg |= SAA7191_STDC_VTRC;
		else
			reg &= ~SAA7191_STDC_VTRC;
529
		ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg);
L
Ladislav Michl 已提交
530 531 532 533 534
		break;
	case SAA7191_CONTROL_LUMA_DELAY: {
		s32 value = ctrl->value;
		if (value < 0)
			value += 8;
535
		reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
L
Ladislav Michl 已提交
536 537 538
		reg &= ~SAA7191_CTL3_YDEL_MASK;
		reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
			& SAA7191_CTL3_YDEL_MASK;
539
		ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg);
L
Ladislav Michl 已提交
540 541 542
		break;
	}
	case SAA7191_CONTROL_VNR:
543
		reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
L
Ladislav Michl 已提交
544 545 546
		reg &= ~SAA7191_CTL4_VNOI_MASK;
		reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
			& SAA7191_CTL4_VNOI_MASK;
547
		ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg);
L
Ladislav Michl 已提交
548 549 550
		break;
	default:
		ret = -EINVAL;
R
Ralf Baechle 已提交
551 552
	}

L
Ladislav Michl 已提交
553
	return ret;
R
Ralf Baechle 已提交
554 555 556 557
}

/* I2C-interface */

558
static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
R
Ralf Baechle 已提交
559
{
560 561
	u8 status_reg;
	int res = V4L2_IN_ST_NO_SIGNAL;
R
Ralf Baechle 已提交
562

563 564 565 566 567 568 569 570 571
	if (saa7191_read_status(sd, &status_reg))
		return -EIO;
	if ((status_reg & SAA7191_STATUS_HLCK) == 0)
		res = 0;
	if (!(status_reg & SAA7191_STATUS_CODE))
		res |= V4L2_IN_ST_NO_COLOR;
	*status = res;
	return 0;
}
R
Ralf Baechle 已提交
572

L
Ladislav Michl 已提交
573

574 575 576 577
static int saa7191_g_chip_ident(struct v4l2_subdev *sd,
		struct v4l2_dbg_chip_ident *chip)
{
	struct i2c_client *client = v4l2_get_subdevdata(sd);
L
Ladislav Michl 已提交
578

579 580
	return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA7191, 0);
}
R
Ralf Baechle 已提交
581

582 583 584 585
static int saa7191_command(struct i2c_client *client, unsigned cmd, void *arg)
{
	return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
}
586

587
/* ----------------------------------------------------------------------- */
588

589 590 591 592 593
static const struct v4l2_subdev_core_ops saa7191_core_ops = {
	.g_chip_ident = saa7191_g_chip_ident,
	.g_ctrl = saa7191_g_ctrl,
	.s_ctrl = saa7191_s_ctrl,
};
594

595 596 597
static const struct v4l2_subdev_tuner_ops saa7191_tuner_ops = {
	.s_std = saa7191_s_std,
};
R
Ralf Baechle 已提交
598

599 600 601 602 603 604 605 606 607 608
static const struct v4l2_subdev_video_ops saa7191_video_ops = {
	.s_routing = saa7191_s_routing,
	.querystd = saa7191_querystd,
	.g_input_status = saa7191_g_input_status,
};

static const struct v4l2_subdev_ops saa7191_ops = {
	.core = &saa7191_core_ops,
	.video = &saa7191_video_ops,
};
R
Ralf Baechle 已提交
609

610 611 612 613 614
static int saa7191_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	int err = 0;
	struct saa7191 *decoder;
615
	struct v4l2_subdev *sd;
R
Ralf Baechle 已提交
616

617 618 619 620 621 622 623
	v4l_info(client, "chip found @ 0x%x (%s)\n",
			client->addr << 1, client->adapter->name);

	decoder = kzalloc(sizeof(*decoder), GFP_KERNEL);
	if (!decoder)
		return -ENOMEM;

624 625
	sd = &decoder->sd;
	v4l2_i2c_subdev_init(sd, client, &saa7191_ops);
626

627
	err = saa7191_write_block(sd, sizeof(initseq), initseq);
628 629 630 631 632 633 634 635 636
	if (err) {
		printk(KERN_ERR "SAA7191 initialization failed\n");
		kfree(decoder);
		return err;
	}

	printk(KERN_INFO "SAA7191 initialized\n");

	decoder->input = SAA7191_INPUT_COMPOSITE;
637
	decoder->norm = V4L2_STD_PAL;
638

639
	err = saa7191_autodetect_norm(sd);
640 641 642 643 644 645 646
	if (err && (err != -EBUSY))
		printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");

	return 0;
}

static int saa7191_remove(struct i2c_client *client)
R
Ralf Baechle 已提交
647
{
648
	struct v4l2_subdev *sd = i2c_get_clientdata(client);
649

650 651
	v4l2_device_unregister_subdev(sd);
	kfree(to_saa7191(sd));
652
	return 0;
R
Ralf Baechle 已提交
653 654
}

655
static int saa7191_legacy_probe(struct i2c_adapter *adapter)
R
Ralf Baechle 已提交
656
{
657
	return adapter->id == I2C_HW_SGI_VINO;
R
Ralf Baechle 已提交
658 659
}

660 661 662 663 664 665 666 667 668 669 670 671 672 673 674
static const struct i2c_device_id saa7191_id[] = {
	{ "saa7191", 0 },
	{ }
};
MODULE_DEVICE_TABLE(i2c, saa7191_id);

static struct v4l2_i2c_driver_data v4l2_i2c_data = {
	.name = "saa7191",
	.driverid = I2C_DRIVERID_SAA7191,
	.command = saa7191_command,
	.probe = saa7191_probe,
	.remove = saa7191_remove,
	.legacy_probe = saa7191_legacy_probe,
	.id_table = saa7191_id,
};