Commit 43b6594e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] v4l: use saa7111 i2c module in V4L MXB driver

From: Michael Hunold <hunold@convergence.de>

The attached patch changes my "Multimedia eXtension Board" (MXB)
Video4Linux-driver to use the standard saa7111 video decoder infrastructure
(to which I recently submitted changes through Ronald Bultje) instead of
some home-brewn direct-access stuff.

Nothing serious, but it removes code duplication and makes the code use the
video decoder api.
parent 385b866c
...@@ -24,42 +24,15 @@ ...@@ -24,42 +24,15 @@
#define DEBUG_VARIABLE debug #define DEBUG_VARIABLE debug
#include <media/saa7146_vv.h> #include <media/saa7146_vv.h>
#include <linux/video_decoder.h> /* for saa7111a */ #include <media/tuner.h>
#include <linux/video_decoder.h>
#include "mxb.h" #include "mxb.h"
#include "tea6415c.h" #include "tea6415c.h"
#include "tea6420.h" #include "tea6420.h"
#include "tda9840.h" #include "tda9840.h"
#include <media/tuner.h>
#define I2C_SAA7111A 0x24 #define I2C_SAA7111 0x24
/* All unused bytes are reserverd. */
#define SAA711X_CHIP_VERSION 0x00
#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02
#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03
#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04
#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05
#define SAA711X_HORIZONTAL_SYNC_START 0x06
#define SAA711X_HORIZONTAL_SYNC_STOP 0x07
#define SAA711X_SYNC_CONTROL 0x08
#define SAA711X_LUMINANCE_CONTROL 0x09
#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A
#define SAA711X_LUMINANCE_CONTRAST 0x0B
#define SAA711X_CHROMA_SATURATION 0x0C
#define SAA711X_CHROMA_HUE_CONTROL 0x0D
#define SAA711X_CHROMA_CONTROL 0x0E
#define SAA711X_FORMAT_DELAY_CONTROL 0x10
#define SAA711X_OUTPUT_CONTROL_1 0x11
#define SAA711X_OUTPUT_CONTROL_2 0x12
#define SAA711X_OUTPUT_CONTROL_3 0x13
#define SAA711X_V_GATE_1_START 0x15
#define SAA711X_V_GATE_1_STOP 0x16
#define SAA711X_V_GATE_1_MSB 0x17
#define SAA711X_TEXT_SLICER_STATUS 0x1A
#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B
#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C
#define SAA711X_STATUS_BYTE 0x1F
#define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) #define MXB_BOARD_CAN_DO_VBI(dev) (dev->revision != 0)
...@@ -175,42 +148,33 @@ struct mxb ...@@ -175,42 +148,33 @@ struct mxb
static struct saa7146_extension extension; static struct saa7146_extension extension;
static int mxb_vbi_bypass(struct saa7146_dev* dev)
{
struct mxb* mxb = (struct mxb*)dev->ext_priv;
s32 byte = 0x0;
int result = 0;
DEB_EE(("dev:%p\n",dev));
/* switch bypass in saa7111a, this should be done in the
saa7111a driver of course... */
if ( -1 == (result = i2c_smbus_read_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_3))) {
DEB_D(("could not read from saa7111a.\n"));
return -EFAULT;
}
byte = result;
byte &= 0xf0;
byte |= 0x0a;
if ( 0 != (result = i2c_smbus_write_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_3, byte))) {
DEB_D(("could not write to saa7111a.\n"));
return -EFAULT;
}
return 0;
}
static int mxb_probe(struct saa7146_dev* dev) static int mxb_probe(struct saa7146_dev* dev)
{ {
struct mxb* mxb = 0; struct mxb* mxb = 0;
struct i2c_client *client; struct i2c_client *client;
struct list_head *item; struct list_head *item;
int result;
request_module("tuner"); if ((result = request_module("saa7111")) < 0) {
request_module("tea6420"); printk("mxb: saa7111 i2c module not available.\n");
request_module("tea6415c"); return -ENODEV;
request_module("tda9840"); }
request_module("saa7111"); if ((result = request_module("tuner")) < 0) {
printk("mxb: tuner i2c module not available.\n");
return -ENODEV;
}
if ((result = request_module("tea6420")) < 0) {
printk("mxb: tea6420 i2c module not available.\n");
return -ENODEV;
}
if ((result = request_module("tea6415c")) < 0) {
printk("mxb: tea6415c i2c module not available.\n");
return -ENODEV;
}
if ((result = request_module("tda9840")) < 0) {
printk("mxb: tda9840 i2c module not available.\n");
return -ENODEV;
}
mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL); mxb = (struct mxb*)kmalloc(sizeof(struct mxb), GFP_KERNEL);
if( NULL == mxb ) { if( NULL == mxb ) {
...@@ -219,10 +183,6 @@ static int mxb_probe(struct saa7146_dev* dev) ...@@ -219,10 +183,6 @@ static int mxb_probe(struct saa7146_dev* dev)
} }
memset(mxb, 0x0, sizeof(struct mxb)); memset(mxb, 0x0, sizeof(struct mxb));
/* FIXME: enable i2c-port pins, video-port-pins
video port pins should be enabled here ?! */
saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26));
saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480); saa7146_i2c_adapter_prepare(dev, &mxb->i2c_adapter, I2C_CLASS_TV_ANALOG, SAA7146_I2C_BUS_BIT_RATE_480);
if(i2c_add_adapter(&mxb->i2c_adapter) < 0) { if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
DEB_S(("cannot register i2c-device. skipping.\n")); DEB_S(("cannot register i2c-device. skipping.\n"));
...@@ -241,7 +201,7 @@ static int mxb_probe(struct saa7146_dev* dev) ...@@ -241,7 +201,7 @@ static int mxb_probe(struct saa7146_dev* dev)
mxb->tea6415c = client; mxb->tea6415c = client;
if( I2C_TDA9840 == client->addr ) if( I2C_TDA9840 == client->addr )
mxb->tda9840 = client; mxb->tda9840 = client;
if( I2C_SAA7111A == client->addr ) if( I2C_SAA7111 == client->addr )
mxb->saa7111a = client; mxb->saa7111a = client;
if( 0x60 == client->addr ) if( 0x60 == client->addr )
mxb->tuner = client; mxb->tuner = client;
...@@ -251,8 +211,7 @@ static int mxb_probe(struct saa7146_dev* dev) ...@@ -251,8 +211,7 @@ static int mxb_probe(struct saa7146_dev* dev)
if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c if( 0 == mxb->tea6420_1 || 0 == mxb->tea6420_2 || 0 == mxb->tea6415c
|| 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) { || 0 == mxb->tda9840 || 0 == mxb->saa7111a || 0 == mxb->tuner ) {
printk("mxb: did not find all i2c devices. are you sure you\n"); printk("mxb: did not find all i2c devices. aborting\n");
printk("mxb: insmod'ed tea6420, tea6415c, saa7111, tea6415c and tuner?\n");
i2c_del_adapter(&mxb->i2c_adapter); i2c_del_adapter(&mxb->i2c_adapter);
kfree(mxb); kfree(mxb);
return -ENODEV; return -ENODEV;
...@@ -322,37 +281,35 @@ static struct { ...@@ -322,37 +281,35 @@ static struct {
{-1, { 0} } {-1, { 0} }
}; };
static unsigned char mxb_saa7111_init[25] = { static const unsigned char mxb_saa7111_init[] = {
0x00, 0x00, 0x00, /* 00 - ID byte */
0x01, 0x00, /* 01 - reserved */
0x00, /* 00 - ID byte */
0x00, /* 01 - reserved */
/*front end */ /*front end */
0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */ 0x02, 0xd8, /* 02 - FUSE=x, GUDL=x, MODE=x */
0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */ 0x03, 0x23, /* 03 - HLNRS=0, VBSL=1, WPOFF=0, HOLDG=0, GAFIX=0, GAI1=256, GAI2=256 */
0x00, /* 04 - GAI1=256 */ 0x04, 0x00, /* 04 - GAI1=256 */
0x00, /* 05 - GAI2=256 */ 0x05, 0x00, /* 05 - GAI2=256 */
/* decoder */ /* decoder */
0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */ 0x06, 0xf0, /* 06 - HSB at xx(50Hz) / xx(60Hz) pixels after end of last line */
0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */ 0x07, 0x30, /* 07 - HSS at xx(50Hz) / xx(60Hz) pixels after end of last line */
0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */ 0x08, 0xa8, /* 08 - AUFD=x, FSEL=x, EXFIL=x, VTRC=x, HPLL=x, VNOI=x */
0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */ 0x09, 0x02, /* 09 - BYPS=x, PREF=x, BPSS=x, VBLB=x, UPTCV=x, APER=x */
0x80, /* 0a - BRIG=128 */ 0x0a, 0x80, /* 0a - BRIG=128 */
0x47, /* 0b - CONT=1.109 */ 0x0b, 0x47, /* 0b - CONT=1.109 */
0x40, /* 0c - SATN=1.0 */ 0x0c, 0x40, /* 0c - SATN=1.0 */
0x00, /* 0d - HUE=0 */ 0x0d, 0x00, /* 0d - HUE=0 */
0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */ 0x0e, 0x01, /* 0e - CDTO=0, CSTD=0, DCCF=0, FCTC=0, CHBW=1 */
0x00, /* 0f - reserved */ 0x0f, 0x00, /* 0f - reserved */
0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */ 0x10, 0xd0, /* 10 - OFTS=x, HDEL=x, VRLN=x, YDEL=x */
0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */ 0x11, 0x8c, /* 11 - GPSW=x, CM99=x, FECO=x, COMPO=x, OEYC=1, OEHV=1, VIPB=0, COLO=0 */
0x80, /* 12 - xx output control 2 */ 0x12, 0x80, /* 12 - xx output control 2 */
0x30, /* 13 - xx output control 3 */ 0x13, 0x30, /* 13 - xx output control 3 */
0x00, /* 14 - reserved */ 0x14, 0x00, /* 14 - reserved */
0x15, /* 15 - VBI */ 0x15, 0x15, /* 15 - VBI */
0x04, /* 16 - VBI */ 0x16, 0x04, /* 16 - VBI */
0x00, /* 17 - VBI */ 0x17, 0x00, /* 17 - VBI */
}; };
/* bring hardware to a sane state. this has to be done, just in case someone /* bring hardware to a sane state. this has to be done, just in case someone
...@@ -362,25 +319,29 @@ static unsigned char mxb_saa7111_init[25] = { ...@@ -362,25 +319,29 @@ static unsigned char mxb_saa7111_init[25] = {
static int mxb_init_done(struct saa7146_dev* dev) static int mxb_init_done(struct saa7146_dev* dev)
{ {
struct mxb* mxb = (struct mxb*)dev->ext_priv; struct mxb* mxb = (struct mxb*)dev->ext_priv;
struct video_decoder_init init;
struct i2c_msg msg; struct i2c_msg msg;
int i = 0, err = 0; int i = 0, err = 0;
struct tea6415c_multiplex vm; struct tea6415c_multiplex vm;
/* select video mode in saa7111a */
i = VIDEO_MODE_PAL;
/* fixme: currently pointless: gets overwritten by configuration below */
mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
/* write configuration to saa7111a */ /* write configuration to saa7111a */
i = i2c_master_send(mxb->saa7111a, mxb_saa7111_init, sizeof(mxb_saa7111_init)); init.data = mxb_saa7111_init;
if (i < 0) { init.len = sizeof(mxb_saa7111_init);
printk("failed to initialize saa7111a. this should never happen.\n"); mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_INIT, &init);
}
/* select tuner-output on saa7111a */ /* select tuner-output on saa7111a */
i = 0; i = 0;
mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i); mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_INPUT, &i);
// i = VIDEO_MODE_PAL;
// mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_NORM, &i);
mxb_vbi_bypass(dev); /* enable vbi bypass */
i = 1;
mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_VBI_BYPASS, &i);
/* select a tuner type */ /* select a tuner type */
i = 5; i = 5;
...@@ -538,36 +499,6 @@ static int mxb_detach(struct saa7146_dev* dev) ...@@ -538,36 +499,6 @@ static int mxb_detach(struct saa7146_dev* dev)
return 0; return 0;
} }
/* hack: this should go into saa711x */
static int saa7111_set_gpio(struct saa7146_dev *dev, int bl)
{
struct mxb* mxb = (struct mxb*)dev->ext_priv;
s32 byte = 0x0;
int result = 0;
DEB_EE(("dev:%p\n",dev));
/* get the old register contents */
if ( -1 == (byte = i2c_smbus_read_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_1))) {
DEB_D(("could not read from saa711x\n"));
return -EFAULT;
}
if( 0 == bl ) {
byte &= 0x7f;
} else {
byte |= 0x80;
}
/* write register contents back */
if ( 0 != (result = i2c_smbus_write_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_1, byte))) {
DEB_D(("could not write to saa711x\n"));
return -EFAULT;
}
return 0;
}
static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
{ {
struct saa7146_dev *dev = fh->dev; struct saa7146_dev *dev = fh->dev;
...@@ -988,18 +919,22 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) ...@@ -988,18 +919,22 @@ static int mxb_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg)
static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std)
{ {
struct mxb* mxb = (struct mxb*)dev->ext_priv;
int zero = 0;
int one = 1;
if(V4L2_STD_PAL_I == std->id ) { if(V4L2_STD_PAL_I == std->id ) {
DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n")); DEB_D(("VIDIOC_S_STD: setting mxb for PAL_I.\n"));
/* set the 7146 gpio register -- I don't know what this does exactly */ /* set the 7146 gpio register -- I don't know what this does exactly */
saa7146_write(dev, GPIO_CTRL, 0x00404050); saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* unset the 7111 gpio register -- I don't know what this does exactly */ /* unset the 7111 gpio register -- I don't know what this does exactly */
saa7111_set_gpio(dev,0); mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &zero);
} else { } else {
DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n")); DEB_D(("VIDIOC_S_STD: setting mxb for PAL/NTSC/SECAM.\n"));
/* set the 7146 gpio register -- I don't know what this does exactly */ /* set the 7146 gpio register -- I don't know what this does exactly */
saa7146_write(dev, GPIO_CTRL, 0x00404050); saa7146_write(dev, GPIO_CTRL, 0x00404050);
/* set the 7111 gpio register -- I don't know what this does exactly */ /* set the 7111 gpio register -- I don't know what this does exactly */
saa7111_set_gpio(dev,1); mxb->saa7111a->driver->command(mxb->saa7111a,DECODER_SET_GPIO, &one);
} }
return 0; return 0;
} }
......
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