Commit 8f32df45 authored by Hans Verkuil's avatar Hans Verkuil Committed by Mauro Carvalho Chehab

[media] vino/saa7191: remove deprecated drivers

These drivers haven't been tested in a long, long time. The hardware is
ancient and hopelessly obsolete. These drivers also need to be converted
to newer media frameworks but due to the lack of hardware that's going
to be impossible.

So these drivers are a prime candidate for removal. If someone is
interested in working on these drivers to prevent their removal, then
please contact the linux-media mailinglist.

These drivers are already deprecated, so now remove them altogether.
Signed-off-by: default avatarHans Verkuil <hans.verkuil@cisco.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@osg.samsung.com>
parent 3f7a3f6e
......@@ -35,8 +35,6 @@ source "drivers/staging/media/omap4iss/Kconfig"
source "drivers/staging/media/parport/Kconfig"
source "drivers/staging/media/vino/Kconfig"
# Keep LIRC at the end, as it has sub-menus
source "drivers/staging/media/lirc/Kconfig"
......
......@@ -7,5 +7,3 @@ obj-$(CONFIG_VIDEO_OMAP4) += omap4iss/
obj-$(CONFIG_DVB_MN88472) += mn88472/
obj-$(CONFIG_DVB_MN88473) += mn88473/
obj-y += parport/
obj-y += vino/
config VIDEO_VINO
tristate "SGI Vino Video For Linux (Deprecated)"
depends on I2C && SGI_IP22 && VIDEO_V4L2
select VIDEO_SAA7191 if MEDIA_SUBDRV_AUTOSELECT
help
Say Y here to build in support for the Vino video input system found
on SGI Indy machines.
This driver is deprecated and will be removed soon. If you have
hardware for this and you want to work on this driver, then contact
the linux-media mailinglist.
config VIDEO_SAA7191
tristate "Philips SAA7191 video decoder (Deprecated)"
depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7191 video decoder.
This driver is deprecated and will be removed soon. If you have
hardware for this and you want to work on this driver, then contact
the linux-media mailinglist.
To compile this driver as a module, choose M here: the
module will be called saa7191.
obj-$(CONFIG_VIDEO_VINO) += indycam.o
obj-$(CONFIG_VIDEO_VINO) += vino.o
obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
/*
* indycam.c - Silicon Graphics IndyCam digital camera 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>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
/* IndyCam decodes stream of photons into digital image representation ;-) */
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
#include "indycam.h"
#define INDYCAM_MODULE_VERSION "0.0.5"
MODULE_DESCRIPTION("SGI IndyCam driver");
MODULE_VERSION(INDYCAM_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
// #define INDYCAM_DEBUG
#ifdef INDYCAM_DEBUG
#define dprintk(x...) printk("IndyCam: " x);
#define indycam_regdump(client) indycam_regdump_debug(client)
#else
#define dprintk(x...)
#define indycam_regdump(client)
#endif
struct indycam {
struct v4l2_subdev sd;
u8 version;
};
static inline struct indycam *to_indycam(struct v4l2_subdev *sd)
{
return container_of(sd, struct indycam, sd);
}
static const u8 initseq[] = {
INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */
INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */
INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */
0x00, /* INDYCAM_BRIGHTNESS (read-only) */
INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */
INDYCAM_BLUE_BALANCE_DEFAULT, /* INDYCAM_BLUE_BALANCE */
INDYCAM_RED_SATURATION_DEFAULT, /* INDYCAM_RED_SATURATION */
INDYCAM_BLUE_SATURATION_DEFAULT,/* INDYCAM_BLUE_SATURATION */
};
/* IndyCam register handling */
static int indycam_read_reg(struct v4l2_subdev *sd, u8 reg, u8 *value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
if (reg == INDYCAM_REG_RESET) {
dprintk("indycam_read_reg(): "
"skipping write-only register %d\n", reg);
*value = 0;
return 0;
}
ret = i2c_smbus_read_byte_data(client, reg);
if (ret < 0) {
printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
"register = 0x%02x\n", reg);
return ret;
}
*value = (u8)ret;
return 0;
}
static int indycam_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
int err;
if (reg == INDYCAM_REG_BRIGHTNESS || reg == INDYCAM_REG_VERSION) {
dprintk("indycam_write_reg(): "
"skipping read-only register %d\n", reg);
return 0;
}
dprintk("Writing Reg %d = 0x%02x\n", reg, value);
err = i2c_smbus_write_byte_data(client, reg, value);
if (err) {
printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
"register = 0x%02x, value = 0x%02x\n", reg, value);
}
return err;
}
static int indycam_write_block(struct v4l2_subdev *sd, u8 reg,
u8 length, u8 *data)
{
int i, err;
for (i = 0; i < length; i++) {
err = indycam_write_reg(sd, reg + i, data[i]);
if (err)
return err;
}
return 0;
}
/* Helper functions */
#ifdef INDYCAM_DEBUG
static void indycam_regdump_debug(struct v4l2_subdev *sd)
{
int i;
u8 val;
for (i = 0; i < 9; i++) {
indycam_read_reg(sd, i, &val);
dprintk("Reg %d = 0x%02x\n", i, val);
}
}
#endif
static int indycam_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct indycam *camera = to_indycam(sd);
u8 reg;
int ret = 0;
switch (ctrl->id) {
case V4L2_CID_AUTOGAIN:
case V4L2_CID_AUTO_WHITE_BALANCE:
ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
if (ret)
return -EIO;
if (ctrl->id == V4L2_CID_AUTOGAIN)
ctrl->value = (reg & INDYCAM_CONTROL_AGCENA)
? 1 : 0;
else
ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL)
? 1 : 0;
break;
case V4L2_CID_EXPOSURE:
ret = indycam_read_reg(sd, INDYCAM_REG_SHUTTER, &reg);
if (ret)
return -EIO;
ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1);
break;
case V4L2_CID_GAIN:
ret = indycam_read_reg(sd, INDYCAM_REG_GAIN, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case V4L2_CID_RED_BALANCE:
ret = indycam_read_reg(sd, INDYCAM_REG_RED_BALANCE, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case V4L2_CID_BLUE_BALANCE:
ret = indycam_read_reg(sd, INDYCAM_REG_BLUE_BALANCE, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case INDYCAM_CONTROL_RED_SATURATION:
ret = indycam_read_reg(sd,
INDYCAM_REG_RED_SATURATION, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case INDYCAM_CONTROL_BLUE_SATURATION:
ret = indycam_read_reg(sd,
INDYCAM_REG_BLUE_SATURATION, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
break;
case V4L2_CID_GAMMA:
if (camera->version == CAMERA_VERSION_MOOSE) {
ret = indycam_read_reg(sd,
INDYCAM_REG_GAMMA, &reg);
if (ret)
return -EIO;
ctrl->value = (s32)reg;
} else {
ctrl->value = INDYCAM_GAMMA_DEFAULT;
}
break;
default:
ret = -EINVAL;
}
return ret;
}
static int indycam_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
struct indycam *camera = to_indycam(sd);
u8 reg;
int ret = 0;
switch (ctrl->id) {
case V4L2_CID_AUTOGAIN:
case V4L2_CID_AUTO_WHITE_BALANCE:
ret = indycam_read_reg(sd, INDYCAM_REG_CONTROL, &reg);
if (ret)
break;
if (ctrl->id == V4L2_CID_AUTOGAIN) {
if (ctrl->value)
reg |= INDYCAM_CONTROL_AGCENA;
else
reg &= ~INDYCAM_CONTROL_AGCENA;
} else {
if (ctrl->value)
reg |= INDYCAM_CONTROL_AWBCTL;
else
reg &= ~INDYCAM_CONTROL_AWBCTL;
}
ret = indycam_write_reg(sd, INDYCAM_REG_CONTROL, reg);
break;
case V4L2_CID_EXPOSURE:
reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1);
ret = indycam_write_reg(sd, INDYCAM_REG_SHUTTER, reg);
break;
case V4L2_CID_GAIN:
ret = indycam_write_reg(sd, INDYCAM_REG_GAIN, ctrl->value);
break;
case V4L2_CID_RED_BALANCE:
ret = indycam_write_reg(sd, INDYCAM_REG_RED_BALANCE,
ctrl->value);
break;
case V4L2_CID_BLUE_BALANCE:
ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_BALANCE,
ctrl->value);
break;
case INDYCAM_CONTROL_RED_SATURATION:
ret = indycam_write_reg(sd, INDYCAM_REG_RED_SATURATION,
ctrl->value);
break;
case INDYCAM_CONTROL_BLUE_SATURATION:
ret = indycam_write_reg(sd, INDYCAM_REG_BLUE_SATURATION,
ctrl->value);
break;
case V4L2_CID_GAMMA:
if (camera->version == CAMERA_VERSION_MOOSE) {
ret = indycam_write_reg(sd, INDYCAM_REG_GAMMA,
ctrl->value);
}
break;
default:
ret = -EINVAL;
}
return ret;
}
/* I2C-interface */
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops indycam_core_ops = {
.g_ctrl = indycam_g_ctrl,
.s_ctrl = indycam_s_ctrl,
};
static const struct v4l2_subdev_ops indycam_ops = {
.core = &indycam_core_ops,
};
static int indycam_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err = 0;
struct indycam *camera;
struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
camera = kzalloc(sizeof(struct indycam), GFP_KERNEL);
if (!camera)
return -ENOMEM;
sd = &camera->sd;
v4l2_i2c_subdev_init(sd, client, &indycam_ops);
camera->version = i2c_smbus_read_byte_data(client,
INDYCAM_REG_VERSION);
if (camera->version != CAMERA_VERSION_INDY &&
camera->version != CAMERA_VERSION_MOOSE) {
kfree(camera);
return -ENODEV;
}
printk(KERN_INFO "IndyCam v%d.%d detected\n",
INDYCAM_VERSION_MAJOR(camera->version),
INDYCAM_VERSION_MINOR(camera->version));
indycam_regdump(sd);
// initialize
err = indycam_write_block(sd, 0, sizeof(initseq), (u8 *)&initseq);
if (err) {
printk(KERN_ERR "IndyCam initialization failed\n");
kfree(camera);
return -EIO;
}
indycam_regdump(sd);
// white balance
err = indycam_write_reg(sd, INDYCAM_REG_CONTROL,
INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL);
if (err) {
printk(KERN_ERR "IndyCam: White balancing camera failed\n");
kfree(camera);
return -EIO;
}
indycam_regdump(sd);
printk(KERN_INFO "IndyCam initialized\n");
return 0;
}
static int indycam_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
kfree(to_indycam(sd));
return 0;
}
static const struct i2c_device_id indycam_id[] = {
{ "indycam", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, indycam_id);
static struct i2c_driver indycam_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "indycam",
},
.probe = indycam_probe,
.remove = indycam_remove,
.id_table = indycam_id,
};
module_i2c_driver(indycam_driver);
/*
* indycam.h - Silicon Graphics IndyCam digital camera 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.
*/
#ifndef _INDYCAM_H_
#define _INDYCAM_H_
/* I2C address for the Guinness Camera */
#define INDYCAM_ADDR 0x56
/* Camera version */
#define CAMERA_VERSION_INDY 0x10 /* v1.0 */
#define CAMERA_VERSION_MOOSE 0x12 /* v1.2 */
#define INDYCAM_VERSION_MAJOR(x) (((x) & 0xf0) >> 4)
#define INDYCAM_VERSION_MINOR(x) ((x) & 0x0f)
/* Register bus addresses */
#define INDYCAM_REG_CONTROL 0x00
#define INDYCAM_REG_SHUTTER 0x01
#define INDYCAM_REG_GAIN 0x02
#define INDYCAM_REG_BRIGHTNESS 0x03 /* read-only */
#define INDYCAM_REG_RED_BALANCE 0x04
#define INDYCAM_REG_BLUE_BALANCE 0x05
#define INDYCAM_REG_RED_SATURATION 0x06
#define INDYCAM_REG_BLUE_SATURATION 0x07
#define INDYCAM_REG_GAMMA 0x08
#define INDYCAM_REG_VERSION 0x0e /* read-only */
#define INDYCAM_REG_RESET 0x0f /* write-only */
#define INDYCAM_REG_LED 0x46
#define INDYCAM_REG_ORIENTATION 0x47
#define INDYCAM_REG_BUTTON 0x48
/* Field definitions of registers */
#define INDYCAM_CONTROL_AGCENA (1<<0) /* automatic gain control */
#define INDYCAM_CONTROL_AWBCTL (1<<1) /* automatic white balance */
/* 2-3 are reserved */
#define INDYCAM_CONTROL_EVNFLD (1<<4) /* read-only */
#define INDYCAM_SHUTTER_10000 0x02 /* 1/10000 second */
#define INDYCAM_SHUTTER_4000 0x04 /* 1/4000 second */
#define INDYCAM_SHUTTER_2000 0x08 /* 1/2000 second */
#define INDYCAM_SHUTTER_1000 0x10 /* 1/1000 second */
#define INDYCAM_SHUTTER_500 0x20 /* 1/500 second */
#define INDYCAM_SHUTTER_250 0x3f /* 1/250 second */
#define INDYCAM_SHUTTER_125 0x7e /* 1/125 second */
#define INDYCAM_SHUTTER_100 0x9e /* 1/100 second */
#define INDYCAM_SHUTTER_60 0x00 /* 1/60 second */
#define INDYCAM_LED_ACTIVE 0x10
#define INDYCAM_LED_INACTIVE 0x30
#define INDYCAM_ORIENTATION_BOTTOM_TO_TOP 0x40
#define INDYCAM_BUTTON_RELEASED 0x10
/* Values for controls */
#define INDYCAM_SHUTTER_MIN 0x00
#define INDYCAM_SHUTTER_MAX 0xff
#define INDYCAM_GAIN_MIN 0x00
#define INDYCAM_GAIN_MAX 0xff
#define INDYCAM_RED_BALANCE_MIN 0x00
#define INDYCAM_RED_BALANCE_MAX 0xff
#define INDYCAM_BLUE_BALANCE_MIN 0x00
#define INDYCAM_BLUE_BALANCE_MAX 0xff
#define INDYCAM_RED_SATURATION_MIN 0x00
#define INDYCAM_RED_SATURATION_MAX 0xff
#define INDYCAM_BLUE_SATURATION_MIN 0x00
#define INDYCAM_BLUE_SATURATION_MAX 0xff
#define INDYCAM_GAMMA_MIN 0x00
#define INDYCAM_GAMMA_MAX 0xff
#define INDYCAM_AGC_DEFAULT 1
#define INDYCAM_AWB_DEFAULT 0
#define INDYCAM_SHUTTER_DEFAULT 0xff
#define INDYCAM_GAIN_DEFAULT 0x80
#define INDYCAM_RED_BALANCE_DEFAULT 0x18
#define INDYCAM_BLUE_BALANCE_DEFAULT 0xa4
#define INDYCAM_RED_SATURATION_DEFAULT 0x80
#define INDYCAM_BLUE_SATURATION_DEFAULT 0xc0
#define INDYCAM_GAMMA_DEFAULT 0x80
/* Driver interface definitions */
#define INDYCAM_CONTROL_RED_SATURATION (V4L2_CID_PRIVATE_BASE + 0)
#define INDYCAM_CONTROL_BLUE_SATURATION (V4L2_CID_PRIVATE_BASE + 1)
#endif
/*
* 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>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <linux/i2c.h>
#include <media/v4l2-device.h>
#include "saa7191.h"
#define SAA7191_MODULE_VERSION "0.0.5"
MODULE_DESCRIPTION("Philips SAA7191 video decoder driver");
MODULE_VERSION(SAA7191_MODULE_VERSION);
MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>");
MODULE_LICENSE("GPL");
// #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 */
struct saa7191 {
struct v4l2_subdev sd;
/* the register values are stored here as the actual
* I2C-registers are write-only */
u8 reg[25];
int input;
v4l2_std_id norm;
};
static inline struct saa7191 *to_saa7191(struct v4l2_subdev *sd)
{
return container_of(sd, struct saa7191, sd);
}
static const u8 initseq[] = {
0, /* Subaddress */
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 */
0x00, /* unused */
0x00, /* unused */
/* 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 */
};
/* SAA7191 register handling */
static u8 saa7191_read_reg(struct v4l2_subdev *sd, u8 reg)
{
return to_saa7191(sd)->reg[reg];
}
static int saa7191_read_status(struct v4l2_subdev *sd, u8 *value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
int ret;
ret = i2c_master_recv(client, value, 1);
if (ret < 0) {
printk(KERN_ERR "SAA7191: saa7191_read_status(): read failed\n");
return ret;
}
return 0;
}
static int saa7191_write_reg(struct v4l2_subdev *sd, u8 reg, u8 value)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
to_saa7191(sd)->reg[reg] = value;
return i2c_smbus_write_byte_data(client, reg, value);
}
/* the first byte of data must be the first subaddress number (register) */
static int saa7191_write_block(struct v4l2_subdev *sd,
u8 length, const u8 *data)
{
struct i2c_client *client = v4l2_get_subdevdata(sd);
struct saa7191 *decoder = to_saa7191(sd);
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(): "
"write failed\n");
return ret;
}
return 0;
}
/* Helper functions */
static int saa7191_s_routing(struct v4l2_subdev *sd,
u32 input, u32 output, u32 config)
{
struct saa7191 *decoder = to_saa7191(sd);
u8 luma = saa7191_read_reg(sd, SAA7191_REG_LUMA);
u8 iock = saa7191_read_reg(sd, SAA7191_REG_IOCK);
int err;
switch (input) {
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;
}
err = saa7191_write_reg(sd, SAA7191_REG_LUMA, luma);
if (err)
return -EIO;
err = saa7191_write_reg(sd, SAA7191_REG_IOCK, iock);
if (err)
return -EIO;
decoder->input = input;
return 0;
}
static int saa7191_s_std(struct v4l2_subdev *sd, v4l2_std_id norm)
{
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);
int err;
if (norm & V4L2_STD_PAL) {
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
chcv = SAA7191_CHCV_PAL;
} else if (norm & V4L2_STD_NTSC) {
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~SAA7191_CTL3_AUFD;
ctl3 |= SAA7191_CTL3_FSEL;
chcv = SAA7191_CHCV_NTSC;
} else if (norm & V4L2_STD_SECAM) {
stdc |= SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_AUFD | SAA7191_CTL3_FSEL);
chcv = SAA7191_CHCV_PAL;
} else {
return -EINVAL;
}
err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err)
return -EIO;
err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
if (err)
return -EIO;
err = saa7191_write_reg(sd, SAA7191_REG_CHCV, chcv);
if (err)
return -EIO;
decoder->norm = norm;
dprintk("ctl3: %02x stdc: %02x chcv: %02x\n", ctl3,
stdc, chcv);
dprintk("norm: %llx\n", norm);
return 0;
}
static int saa7191_wait_for_signal(struct v4l2_subdev *sd, u8 *status)
{
int i = 0;
dprintk("Checking for signal...\n");
for (i = 0; i < SAA7191_SYNC_COUNT; i++) {
if (saa7191_read_status(sd, status))
return -EIO;
if (((*status) & SAA7191_STATUS_HLCK) == 0) {
dprintk("Signal found\n");
return 0;
}
msleep(SAA7191_SYNC_DELAY);
}
dprintk("No signal\n");
return -EBUSY;
}
static int saa7191_querystd(struct v4l2_subdev *sd, v4l2_std_id *norm)
{
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 status;
v4l2_std_id old_norm = decoder->norm;
int err = 0;
dprintk("SAA7191 extended signal auto-detection...\n");
*norm &= V4L2_STD_NTSC | V4L2_STD_PAL | V4L2_STD_SECAM;
stdc &= ~SAA7191_STDC_SECS;
ctl3 &= ~(SAA7191_CTL3_FSEL);
err = saa7191_write_reg(sd, SAA7191_REG_STDC, stdc);
if (err) {
err = -EIO;
goto out;
}
err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err) {
err = -EIO;
goto out;
}
ctl3 |= SAA7191_CTL3_AUFD;
err = saa7191_write_reg(sd, SAA7191_REG_CTL3, ctl3);
if (err) {
err = -EIO;
goto out;
}
msleep(SAA7191_SYNC_DELAY);
err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
if (status & SAA7191_STATUS_FIDT) {
/* 60Hz signal -> NTSC */
dprintk("60Hz signal: NTSC\n");
*norm &= V4L2_STD_NTSC;
return 0;
}
/* 50Hz signal */
dprintk("50Hz signal: Trying PAL...\n");
/* try PAL first */
err = saa7191_s_std(sd, V4L2_STD_PAL);
if (err)
goto out;
msleep(SAA7191_SYNC_DELAY);
err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
/* not 50Hz ? */
if (status & SAA7191_STATUS_FIDT) {
dprintk("No 50Hz signal\n");
saa7191_s_std(sd, old_norm);
*norm = V4L2_STD_UNKNOWN;
return 0;
}
if (status & SAA7191_STATUS_CODE) {
dprintk("PAL\n");
*norm &= V4L2_STD_PAL;
return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with PAL - Trying SECAM...\n");
/* no color detected ? -> try SECAM */
err = saa7191_s_std(sd, V4L2_STD_SECAM);
if (err)
goto out;
msleep(SAA7191_SYNC_DELAY);
err = saa7191_wait_for_signal(sd, &status);
if (err)
goto out;
/* not 50Hz ? */
if (status & SAA7191_STATUS_FIDT) {
dprintk("No 50Hz signal\n");
*norm = V4L2_STD_UNKNOWN;
goto out;
}
if (status & SAA7191_STATUS_CODE) {
/* Color detected -> SECAM */
dprintk("SECAM\n");
*norm &= V4L2_STD_SECAM;
return saa7191_s_std(sd, old_norm);
}
dprintk("No color detected with SECAM - Going back to PAL.\n");
*norm = V4L2_STD_UNKNOWN;
out:
return saa7191_s_std(sd, old_norm);
}
static int saa7191_autodetect_norm(struct v4l2_subdev *sd)
{
u8 status;
dprintk("SAA7191 signal auto-detection...\n");
dprintk("Reading status...\n");
if (saa7191_read_status(sd, &status))
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");
return saa7191_s_std(sd, V4L2_STD_NTSC);
} else {
/* 50hz signal -> PAL */
dprintk("PAL\n");
return saa7191_s_std(sd, V4L2_STD_PAL);
}
}
static int saa7191_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
u8 reg;
int ret = 0;
switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
case SAA7191_CONTROL_BANDPASS_WEIGHT:
case SAA7191_CONTROL_CORING:
reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
switch (ctrl->id) {
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;
}
break;
case SAA7191_CONTROL_FORCE_COLOUR:
case SAA7191_CONTROL_CHROMA_GAIN:
reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR)
ctrl->value = ((s32)reg & SAA7191_GAIN_COLO) ? 1 : 0;
else
ctrl->value = ((s32)reg & SAA7191_GAIN_LFIS_MASK)
>> SAA7191_GAIN_LFIS_SHIFT;
break;
case V4L2_CID_HUE:
reg = saa7191_read_reg(sd, SAA7191_REG_HUEC);
if (reg < 0x80)
reg += 0x80;
else
reg -= 0x80;
ctrl->value = (s32)reg;
break;
case SAA7191_CONTROL_VTRC:
reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
ctrl->value = ((s32)reg & SAA7191_STDC_VTRC) ? 1 : 0;
break;
case SAA7191_CONTROL_LUMA_DELAY:
reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
ctrl->value = ((s32)reg & SAA7191_CTL3_YDEL_MASK)
>> SAA7191_CTL3_YDEL_SHIFT;
if (ctrl->value >= 4)
ctrl->value -= 8;
break;
case SAA7191_CONTROL_VNR:
reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
ctrl->value = ((s32)reg & SAA7191_CTL4_VNOI_MASK)
>> SAA7191_CTL4_VNOI_SHIFT;
break;
default:
ret = -EINVAL;
}
return ret;
}
static int saa7191_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
u8 reg;
int ret = 0;
switch (ctrl->id) {
case SAA7191_CONTROL_BANDPASS:
case SAA7191_CONTROL_BANDPASS_WEIGHT:
case SAA7191_CONTROL_CORING:
reg = saa7191_read_reg(sd, SAA7191_REG_LUMA);
switch (ctrl->id) {
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;
}
ret = saa7191_write_reg(sd, SAA7191_REG_LUMA, reg);
break;
case SAA7191_CONTROL_FORCE_COLOUR:
case SAA7191_CONTROL_CHROMA_GAIN:
reg = saa7191_read_reg(sd, SAA7191_REG_GAIN);
if (ctrl->id == SAA7191_CONTROL_FORCE_COLOUR) {
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;
}
ret = saa7191_write_reg(sd, SAA7191_REG_GAIN, reg);
break;
case V4L2_CID_HUE:
reg = ctrl->value & 0xff;
if (reg < 0x80)
reg += 0x80;
else
reg -= 0x80;
ret = saa7191_write_reg(sd, SAA7191_REG_HUEC, reg);
break;
case SAA7191_CONTROL_VTRC:
reg = saa7191_read_reg(sd, SAA7191_REG_STDC);
if (ctrl->value)
reg |= SAA7191_STDC_VTRC;
else
reg &= ~SAA7191_STDC_VTRC;
ret = saa7191_write_reg(sd, SAA7191_REG_STDC, reg);
break;
case SAA7191_CONTROL_LUMA_DELAY: {
s32 value = ctrl->value;
if (value < 0)
value += 8;
reg = saa7191_read_reg(sd, SAA7191_REG_CTL3);
reg &= ~SAA7191_CTL3_YDEL_MASK;
reg |= (value << SAA7191_CTL3_YDEL_SHIFT)
& SAA7191_CTL3_YDEL_MASK;
ret = saa7191_write_reg(sd, SAA7191_REG_CTL3, reg);
break;
}
case SAA7191_CONTROL_VNR:
reg = saa7191_read_reg(sd, SAA7191_REG_CTL4);
reg &= ~SAA7191_CTL4_VNOI_MASK;
reg |= (ctrl->value << SAA7191_CTL4_VNOI_SHIFT)
& SAA7191_CTL4_VNOI_MASK;
ret = saa7191_write_reg(sd, SAA7191_REG_CTL4, reg);
break;
default:
ret = -EINVAL;
}
return ret;
}
/* I2C-interface */
static int saa7191_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
u8 status_reg;
int res = V4L2_IN_ST_NO_SIGNAL;
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;
}
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa7191_core_ops = {
.g_ctrl = saa7191_g_ctrl,
.s_ctrl = saa7191_s_ctrl,
};
static const struct v4l2_subdev_video_ops saa7191_video_ops = {
.s_std = saa7191_s_std,
.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,
};
static int saa7191_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int err = 0;
struct saa7191 *decoder;
struct v4l2_subdev *sd;
v4l_info(client, "chip found @ 0x%x (%s)\n",
client->addr << 1, client->adapter->name);
decoder = devm_kzalloc(&client->dev, sizeof(*decoder), GFP_KERNEL);
if (!decoder)
return -ENOMEM;
sd = &decoder->sd;
v4l2_i2c_subdev_init(sd, client, &saa7191_ops);
err = saa7191_write_block(sd, sizeof(initseq), initseq);
if (err) {
printk(KERN_ERR "SAA7191 initialization failed\n");
return err;
}
printk(KERN_INFO "SAA7191 initialized\n");
decoder->input = SAA7191_INPUT_COMPOSITE;
decoder->norm = V4L2_STD_PAL;
err = saa7191_autodetect_norm(sd);
if (err && (err != -EBUSY))
printk(KERN_ERR "SAA7191: Signal auto-detection failed\n");
return 0;
}
static int saa7191_remove(struct i2c_client *client)
{
struct v4l2_subdev *sd = i2c_get_clientdata(client);
v4l2_device_unregister_subdev(sd);
return 0;
}
static const struct i2c_device_id saa7191_id[] = {
{ "saa7191", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, saa7191_id);
static struct i2c_driver saa7191_driver = {
.driver = {
.owner = THIS_MODULE,
.name = "saa7191",
},
.probe = saa7191_probe,
.remove = saa7191_remove,
.id_table = saa7191_id,
};
module_i2c_driver(saa7191_driver);
/*
* saa7191.h - 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.
*/
#ifndef _SAA7191_H_
#define _SAA7191_H_
/* Philips SAA7191 DMSD I2C bus address */
#define SAA7191_ADDR 0x8a
/* Register subaddresses. */
#define SAA7191_REG_IDEL 0x00
#define SAA7191_REG_HSYB 0x01
#define SAA7191_REG_HSYS 0x02
#define SAA7191_REG_HCLB 0x03
#define SAA7191_REG_HCLS 0x04
#define SAA7191_REG_HPHI 0x05
#define SAA7191_REG_LUMA 0x06
#define SAA7191_REG_HUEC 0x07
#define SAA7191_REG_CKTQ 0x08 /* bits 3-7 */
#define SAA7191_REG_CKTS 0x09 /* bits 3-7 */
#define SAA7191_REG_PLSE 0x0a
#define SAA7191_REG_SESE 0x0b
#define SAA7191_REG_GAIN 0x0c
#define SAA7191_REG_STDC 0x0d
#define SAA7191_REG_IOCK 0x0e
#define SAA7191_REG_CTL3 0x0f
#define SAA7191_REG_CTL4 0x10
#define SAA7191_REG_CHCV 0x11
#define SAA7191_REG_HS6B 0x14
#define SAA7191_REG_HS6S 0x15
#define SAA7191_REG_HC6B 0x16
#define SAA7191_REG_HC6S 0x17
#define SAA7191_REG_HP6I 0x18
#define SAA7191_REG_STATUS 0xff /* not really a subaddress */
/* Status Register definitions */
#define SAA7191_STATUS_CODE 0x01 /* color detected flag */
#define SAA7191_STATUS_FIDT 0x20 /* signal type 50/60 Hz */
#define SAA7191_STATUS_HLCK 0x40 /* PLL unlocked(1)/locked(0) */
#define SAA7191_STATUS_STTC 0x80 /* tv/vtr time constant */
/* Luminance Control Register definitions */
/* input mode select bit:
* 0=CVBS (chrominance trap active), 1=S-Video (trap bypassed) */
#define SAA7191_LUMA_BYPS 0x80
/* pre-filter (only when chrominance trap is active) */
#define SAA7191_LUMA_PREF 0x40
/* aperture bandpass to select different characteristics with maximums
* (bits 4-5) */
#define SAA7191_LUMA_BPSS_MASK 0x30
#define SAA7191_LUMA_BPSS_SHIFT 4
#define SAA7191_LUMA_BPSS_3 0x30
#define SAA7191_LUMA_BPSS_2 0x20
#define SAA7191_LUMA_BPSS_1 0x10
#define SAA7191_LUMA_BPSS_0 0x00
/* coring range for high frequency components according to 8-bit luminance
* (bits 2-3)
* 0=coring off, n= (+-)n LSB */
#define SAA7191_LUMA_CORI_MASK 0x0c
#define SAA7191_LUMA_CORI_SHIFT 2
#define SAA7191_LUMA_CORI_3 0x0c
#define SAA7191_LUMA_CORI_2 0x08
#define SAA7191_LUMA_CORI_1 0x04
#define SAA7191_LUMA_CORI_0 0x00
/* aperture bandpass filter weights high frequency components of luminance
* signal (bits 0-1)
* 0=factor 0, 1=0.25, 2=0.5, 3=1 */
#define SAA7191_LUMA_APER_MASK 0x03
#define SAA7191_LUMA_APER_SHIFT 0
#define SAA7191_LUMA_APER_3 0x03
#define SAA7191_LUMA_APER_2 0x02
#define SAA7191_LUMA_APER_1 0x01
#define SAA7191_LUMA_APER_0 0x00
/* Chrominance Gain Control Settings Register definitions */
/* colour on: 0=automatic colour-killer enabled, 1=forced colour on */
#define SAA7191_GAIN_COLO 0x80
/* chrominance gain control (AGC filter)
* 0=loop filter time constant slow, 1=medium, 2=fast, 3=actual gain */
#define SAA7191_GAIN_LFIS_MASK 0x60
#define SAA7191_GAIN_LFIS_SHIFT 5
#define SAA7191_GAIN_LFIS_3 0x60
#define SAA7191_GAIN_LFIS_2 0x40
#define SAA7191_GAIN_LFIS_1 0x20
#define SAA7191_GAIN_LFIS_0 0x00
/* Standard/Mode Control Register definitions */
/* tv/vtr mode bit: 0=TV mode (slow time constant),
* 1=VTR mode (fast time constant) */
#define SAA7191_STDC_VTRC 0x80
/* SAA7191B-specific functions enable (RTCO, ODD and GPSW0 outputs)
* 0=outputs set to high-impedance (circuit equals SAA7191), 1=enabled */
#define SAA7191_STDC_NFEN 0x08
/* HREF generation: 0=like SAA7191, 1=HREF is 8xLLC2 clocks earlier */
#define SAA7191_STDC_HRMV 0x04
/* general purpose switch 0
* (not used with VINO afaik) */
#define SAA7191_STDC_GPSW0 0x02
/* SECAM mode bit: 0=other standards, 1=SECAM */
#define SAA7191_STDC_SECS 0x01
/* I/O and Clock Control Register definitions */
/* horizontal clock PLL: 0=PLL closed,
* 1=PLL circuit open and horizontal freq fixed */
#define SAA7191_IOCK_HPLL 0x80
/* colour-difference output enable (outputs UV0-UV7) */
#define SAA7191_IOCK_OEDC 0x40
/* H-sync output enable */
#define SAA7191_IOCK_OEHS 0x20
/* V-sync output enable */
#define SAA7191_IOCK_OEVS 0x10
/* luminance output enable (outputs Y0-Y7) */
#define SAA7191_IOCK_OEDY 0x08
/* S-VHS bit (chrominance from CVBS or from chrominance input):
* 0=controlled by BYPS-bit, 1=from chrominance input */
#define SAA7191_IOCK_CHRS 0x04
/* general purpose switch 2
* VINO-specific: 0=used with CVBS, 1=used with S-Video */
#define SAA7191_IOCK_GPSW2 0x02
/* general purpose switch 1 */
/* VINO-specific: 0=always, 1=not used!*/
#define SAA7191_IOCK_GPSW1 0x01
/* Miscellaneous Control #1 Register definitions */
/* automatic field detection (50/60Hz standard) */
#define SAA7191_CTL3_AUFD 0x80
/* field select: (if AUFD=0)
* 0=50Hz (625 lines), 1=60Hz (525 lines) */
#define SAA7191_CTL3_FSEL 0x40
/* SECAM cross-colour reduction enable */
#define SAA7191_CTL3_SXCR 0x20
/* sync and clamping pulse enable (HCL and HSY outputs) */
#define SAA7191_CTL3_SCEN 0x10
/* output format: 0=4:1:1, 1=4:2:2 (4:2:2 for VINO) */
#define SAA7191_CTL3_OFTS 0x08
/* luminance delay compensation
* 0=0*2/LLC, 1=+1*2/LLC, 2=+2*2/LLC, 3=+3*2/LLC,
* 4=-4*2/LLC, 5=-3*2/LLC, 6=-2*2/LLC, 7=-1*2/LLC
* step size = 2/LLC = 67.8ns for 50Hz, 81.5ns for 60Hz */
#define SAA7191_CTL3_YDEL_MASK 0x07
#define SAA7191_CTL3_YDEL_SHIFT 0
#define SAA7191_CTL3_YDEL2 0x04
#define SAA7191_CTL3_YDEL1 0x02
#define SAA7191_CTL3_YDEL0 0x01
/* Miscellaneous Control #2 Register definitions */
/* select HREF position
* 0=normal, HREF is matched to YUV output port,
* 1=HREF is matched to CVBS input port */
#define SAA7191_CTL4_HRFS 0x04
/* vertical noise reduction
* 0=normal, 1=searching window, 2=auto-deflection, 3=reduction bypassed */
#define SAA7191_CTL4_VNOI_MASK 0x03
#define SAA7191_CTL4_VNOI_SHIFT 0
#define SAA7191_CTL4_VNOI_3 0x03
#define SAA7191_CTL4_VNOI_2 0x02
#define SAA7191_CTL4_VNOI_1 0x01
#define SAA7191_CTL4_VNOI_0 0x00
/* Chrominance Gain Control Register definitions
* - for QAM-modulated input signals, effects output amplitude
* (SECAM gain fixed)
* (nominal values for UV CCIR level) */
#define SAA7191_CHCV_NTSC 0x2c
#define SAA7191_CHCV_PAL 0x59
/* Driver interface definitions */
#define SAA7191_INPUT_COMPOSITE 0
#define SAA7191_INPUT_SVIDEO 1
#define SAA7191_NORM_PAL 1
#define SAA7191_NORM_NTSC 2
#define SAA7191_NORM_SECAM 3
struct saa7191_status {
/* 0=no signal, 1=signal detected */
int signal;
/* 0=50hz (pal) signal, 1=60hz (ntsc) signal */
int signal_60hz;
/* 0=no color detected, 1=color detected */
int color;
/* current SAA7191_INPUT_ */
int input;
/* current SAA7191_NORM_ */
int norm;
};
#define SAA7191_BANDPASS_MIN 0x00
#define SAA7191_BANDPASS_MAX 0x03
#define SAA7191_BANDPASS_DEFAULT 0x00
#define SAA7191_BANDPASS_WEIGHT_MIN 0x00
#define SAA7191_BANDPASS_WEIGHT_MAX 0x03
#define SAA7191_BANDPASS_WEIGHT_DEFAULT 0x01
#define SAA7191_CORING_MIN 0x00
#define SAA7191_CORING_MAX 0x03
#define SAA7191_CORING_DEFAULT 0x00
#define SAA7191_HUE_MIN 0x00
#define SAA7191_HUE_MAX 0xff
#define SAA7191_HUE_DEFAULT 0x80
#define SAA7191_VTRC_MIN 0x00
#define SAA7191_VTRC_MAX 0x01
#define SAA7191_VTRC_DEFAULT 0x00
#define SAA7191_FORCE_COLOUR_MIN 0x00
#define SAA7191_FORCE_COLOUR_MAX 0x01
#define SAA7191_FORCE_COLOUR_DEFAULT 0x00
#define SAA7191_CHROMA_GAIN_MIN 0x00
#define SAA7191_CHROMA_GAIN_MAX 0x03
#define SAA7191_CHROMA_GAIN_DEFAULT 0x00
#define SAA7191_LUMA_DELAY_MIN -0x04
#define SAA7191_LUMA_DELAY_MAX 0x03
#define SAA7191_LUMA_DELAY_DEFAULT 0x01
#define SAA7191_VNR_MIN 0x00
#define SAA7191_VNR_MAX 0x03
#define SAA7191_VNR_DEFAULT 0x00
#define SAA7191_CONTROL_BANDPASS (V4L2_CID_PRIVATE_BASE + 0)
#define SAA7191_CONTROL_BANDPASS_WEIGHT (V4L2_CID_PRIVATE_BASE + 1)
#define SAA7191_CONTROL_CORING (V4L2_CID_PRIVATE_BASE + 2)
#define SAA7191_CONTROL_FORCE_COLOUR (V4L2_CID_PRIVATE_BASE + 3)
#define SAA7191_CONTROL_CHROMA_GAIN (V4L2_CID_PRIVATE_BASE + 4)
#define SAA7191_CONTROL_VTRC (V4L2_CID_PRIVATE_BASE + 5)
#define SAA7191_CONTROL_LUMA_DELAY (V4L2_CID_PRIVATE_BASE + 6)
#define SAA7191_CONTROL_VNR (V4L2_CID_PRIVATE_BASE + 7)
#define DECODER_SAA7191_GET_STATUS _IOR('d', 195, struct saa7191_status)
#define DECODER_SAA7191_SET_NORM _IOW('d', 196, int)
#endif
This source diff could not be displayed because it is too large. You can view the blob instead.
/*
* Driver for the VINO (Video In No Out) system found in SGI Indys.
*
* This file is subject to the terms and conditions of the GNU General Public
* License version 2 as published by the Free Software Foundation.
*
* Copyright (C) 1999 Ulf Karlsson <ulfc@bun.falkenberg.se>
* Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org>
*/
#ifndef _VINO_H_
#define _VINO_H_
#define VINO_BASE 0x00080000 /* Vino is in the EISA address space,
* but it is not an EISA bus card */
#define VINO_PAGE_SIZE 4096
struct sgi_vino_channel {
u32 _pad_alpha;
volatile u32 alpha;
#define VINO_CLIP_X(x) ((x) & 0x3ff) /* bits 0:9 */
#define VINO_CLIP_ODD(x) (((x) & 0x1ff) << 10) /* bits 10:18 */
#define VINO_CLIP_EVEN(x) (((x) & 0x1ff) << 19) /* bits 19:27 */
u32 _pad_clip_start;
volatile u32 clip_start;
u32 _pad_clip_end;
volatile u32 clip_end;
#define VINO_FRAMERT_FULL 0xfff
#define VINO_FRAMERT_PAL (1<<0) /* 0=NTSC 1=PAL */
#define VINO_FRAMERT_RT(x) (((x) & 0xfff) << 1) /* bits 1:12 */
u32 _pad_frame_rate;
volatile u32 frame_rate;
u32 _pad_field_counter;
volatile u32 field_counter;
u32 _pad_line_size;
volatile u32 line_size;
u32 _pad_line_count;
volatile u32 line_count;
u32 _pad_page_index;
volatile u32 page_index;
u32 _pad_next_4_desc;
volatile u32 next_4_desc;
u32 _pad_start_desc_tbl;
volatile u32 start_desc_tbl;
#define VINO_DESC_JUMP (1<<30)
#define VINO_DESC_STOP (1<<31)
#define VINO_DESC_VALID (1<<32)
u32 _pad_desc_0;
volatile u32 desc_0;
u32 _pad_desc_1;
volatile u32 desc_1;
u32 _pad_desc_2;
volatile u32 desc_2;
u32 _pad_Bdesc_3;
volatile u32 desc_3;
u32 _pad_fifo_thres;
volatile u32 fifo_thres;
u32 _pad_fifo_read;
volatile u32 fifo_read;
u32 _pad_fifo_write;
volatile u32 fifo_write;
};
struct sgi_vino {
#define VINO_CHIP_ID 0xb
#define VINO_REV_NUM(x) ((x) & 0x0f)
#define VINO_ID_VALUE(x) (((x) & 0xf0) >> 4)
u32 _pad_rev_id;
volatile u32 rev_id;
#define VINO_CTRL_LITTLE_ENDIAN (1<<0)
#define VINO_CTRL_A_EOF_INT (1<<1) /* Field transferred int */
#define VINO_CTRL_A_FIFO_INT (1<<2) /* FIFO overflow int */
#define VINO_CTRL_A_EOD_INT (1<<3) /* End of desc table int */
#define VINO_CTRL_A_INT (VINO_CTRL_A_EOF_INT | \
VINO_CTRL_A_FIFO_INT | \
VINO_CTRL_A_EOD_INT)
#define VINO_CTRL_B_EOF_INT (1<<4) /* Field transferred int */
#define VINO_CTRL_B_FIFO_INT (1<<5) /* FIFO overflow int */
#define VINO_CTRL_B_EOD_INT (1<<6) /* End of desc table int */
#define VINO_CTRL_B_INT (VINO_CTRL_B_EOF_INT | \
VINO_CTRL_B_FIFO_INT | \
VINO_CTRL_B_EOD_INT)
#define VINO_CTRL_A_DMA_ENBL (1<<7)
#define VINO_CTRL_A_INTERLEAVE_ENBL (1<<8)
#define VINO_CTRL_A_SYNC_ENBL (1<<9)
#define VINO_CTRL_A_SELECT (1<<10) /* 1=D1 0=Philips */
#define VINO_CTRL_A_RGB (1<<11) /* 1=RGB 0=YUV */
#define VINO_CTRL_A_LUMA_ONLY (1<<12)
#define VINO_CTRL_A_DEC_ENBL (1<<13) /* Decimation */
#define VINO_CTRL_A_DEC_SCALE_MASK 0x1c000 /* bits 14:17 */
#define VINO_CTRL_A_DEC_SCALE_SHIFT (14)
#define VINO_CTRL_A_DEC_HOR_ONLY (1<<17) /* Horizontal only */
#define VINO_CTRL_A_DITHER (1<<18) /* 24 -> 8 bit dither */
#define VINO_CTRL_B_DMA_ENBL (1<<19)
#define VINO_CTRL_B_INTERLEAVE_ENBL (1<<20)
#define VINO_CTRL_B_SYNC_ENBL (1<<21)
#define VINO_CTRL_B_SELECT (1<<22) /* 1=D1 0=Philips */
#define VINO_CTRL_B_RGB (1<<23) /* 1=RGB 0=YUV */
#define VINO_CTRL_B_LUMA_ONLY (1<<24)
#define VINO_CTRL_B_DEC_ENBL (1<<25) /* Decimation */
#define VINO_CTRL_B_DEC_SCALE_MASK 0x1c000000 /* bits 26:28 */
#define VINO_CTRL_B_DEC_SCALE_SHIFT (26)
#define VINO_CTRL_B_DEC_HOR_ONLY (1<<29) /* Decimation horizontal only */
#define VINO_CTRL_B_DITHER (1<<30) /* ChanB 24 -> 8 bit dither */
u32 _pad_control;
volatile u32 control;
#define VINO_INTSTAT_A_EOF (1<<0) /* Field transferred int */
#define VINO_INTSTAT_A_FIFO (1<<1) /* FIFO overflow int */
#define VINO_INTSTAT_A_EOD (1<<2) /* End of desc table int */
#define VINO_INTSTAT_A (VINO_INTSTAT_A_EOF | \
VINO_INTSTAT_A_FIFO | \
VINO_INTSTAT_A_EOD)
#define VINO_INTSTAT_B_EOF (1<<3) /* Field transferred int */
#define VINO_INTSTAT_B_FIFO (1<<4) /* FIFO overflow int */
#define VINO_INTSTAT_B_EOD (1<<5) /* End of desc table int */
#define VINO_INTSTAT_B (VINO_INTSTAT_B_EOF | \
VINO_INTSTAT_B_FIFO | \
VINO_INTSTAT_B_EOD)
u32 _pad_intr_status;
volatile u32 intr_status;
u32 _pad_i2c_control;
volatile u32 i2c_control;
u32 _pad_i2c_data;
volatile u32 i2c_data;
struct sgi_vino_channel a;
struct sgi_vino_channel b;
};
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment