summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/mxb.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/video/mxb.c')
-rw-r--r--linux/drivers/media/video/mxb.c108
1 files changed, 87 insertions, 21 deletions
diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c
index 5b3c4b824..ce8a4d9b4 100644
--- a/linux/drivers/media/video/mxb.c
+++ b/linux/drivers/media/video/mxb.c
@@ -33,6 +33,35 @@
#define I2C_SAA7111A 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)
+
/* global variable */
static int mxb_num = 0;
@@ -129,6 +158,9 @@ static struct saa7146_extension_ioctls ioctls[] = {
struct mxb
{
+ struct video_device video_dev;
+ struct video_device vbi_dev;
+
struct i2c_adapter i2c_adapter;
struct i2c_client* saa7111a;
@@ -169,6 +201,10 @@ static int mxb_probe(struct saa7146_dev* dev, unsigned int subvendor, unsigned i
}
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, SAA7146_I2C_BUS_BIT_RATE_480);
if(i2c_add_adapter(&mxb->i2c_adapter) < 0) {
DEB_S(("cannot register i2c-device. skipping.\n"));
@@ -396,7 +432,7 @@ err:
return 0;
}
-/* interrupt bh-handler. this gets called when irq_mask is != 0.
+/* interrupt-handler. this gets called when irq_mask is != 0.
it must clear the interrupt-bits in irq_mask it has handled */
/*
void mxb_irq_bh(struct saa7146_dev* dev, u32* irq_mask)
@@ -410,11 +446,26 @@ static int mxb_attach(struct saa7146_dev* dev)
{
struct mxb* mxb = (struct mxb*)dev->ext_priv;
+ DEB_EE(("dev:%p\n",dev));
+
/* checking for i2c-devices can be omitted here, because we
already did this in "mxb_vl42_probe" */
- mxb_num++;
+ saa7146_video_uops.init(dev);
+ if( 0 != saa7146_register_device(&mxb->video_dev, dev, "mxb", VFL_TYPE_GRABBER)) {
+ ERR(("cannot register capture v4l2 device. skipping.\n"));
+ return -1;
+ }
+ /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/
+ if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
+ saa7146_vbi_uops.init(dev);
+ if( 0 != saa7146_register_device(&mxb->vbi_dev, dev, "mxb", VFL_TYPE_VBI)) {
+ ERR(("cannot register vbi v4l2 device. skipping.\n"));
+ return -1;
+ }
+ }
+
i2c_inc_use_client(mxb->tea6420_1);
i2c_inc_use_client(mxb->tea6420_2);
i2c_inc_use_client(mxb->tea6415c);
@@ -422,6 +473,7 @@ static int mxb_attach(struct saa7146_dev* dev)
i2c_inc_use_client(mxb->saa7111a);
i2c_inc_use_client(mxb->tuner);
+ mxb_num++;
return mxb_init_done(dev);
}
@@ -429,6 +481,8 @@ static int mxb_detach(struct saa7146_dev* dev)
{
struct mxb* mxb = (struct mxb*)dev->ext_priv;
+ DEB_EE(("dev:%p\n",dev));
+
i2c_dec_use_client(mxb->tea6420_1);
i2c_dec_use_client(mxb->tea6420_2);
i2c_dec_use_client(mxb->tea6415c);
@@ -436,6 +490,11 @@ static int mxb_detach(struct saa7146_dev* dev)
i2c_dec_use_client(mxb->saa7111a);
i2c_dec_use_client(mxb->tuner);
+ saa7146_unregister_device(&mxb->video_dev,dev);
+ if( 0 != MXB_BOARD_CAN_DO_VBI(dev)) {
+ saa7146_unregister_device(&mxb->vbi_dev,dev);
+ }
+
mxb_num--;
i2c_del_adapter(&mxb->i2c_adapter);
@@ -447,16 +506,25 @@ static int mxb_detach(struct saa7146_dev* dev)
static int mxb_vbi_bypass(struct saa7146_dev* dev)
{
struct mxb* mxb = (struct mxb*)dev->ext_priv;
- int i = 1;
+ s32 byte = 0x0;
+ int result = 0;
- /* switch bypass in saa7111a */
- /* fixme saa
- if ( 0 != mxb->saa7111a->driver->command(mxb->saa7111a,SAA711X_VBI_BYPASS, &i)) {
- DEB_D(("could not address saa7111a.\n"));
- return -1;
- }
- */
-
+ 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;
}
@@ -464,12 +532,13 @@ static int mxb_vbi_bypass(struct saa7146_dev* dev)
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, 0x11))) {
+ if ( -1 == (byte = i2c_smbus_read_byte_data(mxb->saa7111a, SAA711X_OUTPUT_CONTROL_1))) {
DEB_D(("could not read from saa711x\n"));
return -EFAULT;
}
@@ -481,7 +550,7 @@ static int saa7111_set_gpio(struct saa7146_dev *dev, int bl)
}
/* write register contents back */
- if ( 0 != (result = i2c_smbus_write_byte_data(mxb->saa7111a, 0x11, byte))) {
+ 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;
}
@@ -707,11 +776,10 @@ static int mxb_ioctl(struct saa7146_dev *dev, unsigned int cmd, void *arg)
strcpy(t->name, "Television");
t->type = V4L2_TUNER_ANALOG_TV;
- /* fixme: _CAP_NORM needed? */
t->capability = V4L2_TUNER_CAP_NORM | V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2 | V4L2_TUNER_CAP_SAP;
t->rangelow = 772; /* 48.25 MHZ / 62.5 kHz = 772, see fi1216mk2-specs, page 2 */
t->rangehigh = 13684; /* 855.25 MHz / 62.5 kHz = 13684 */
- /* fixme: add the real signal strength here */
+ /* FIXME: add the real signal strength here */
t->signal = 0xffff;
t->afc = 0;
@@ -953,10 +1021,10 @@ struct saa7146_extension extension = {
.name = MXB_IDENTIFIER,
.inputs = MXB_INPUTS,
.audios = MXB_AUDIOS,
- .capabilities = V4L2_CAP_TUNER,
+ .capabilities = V4L2_CAP_TUNER | V4L2_CAP_VBI_CAPTURE,
+
+ .flags = 0,
- .flags = SAA7146_EXT_PROVIDES_VIDEO|SAA7146_EXT_PROVIDES_VBI,
-
.devices = &sub_data[0],
.module = THIS_MODULE,
@@ -969,8 +1037,6 @@ struct saa7146_extension extension = {
.num_stds = sizeof(standard)/sizeof(struct saa7146_standard),
.std_callback = &std_callback,
- .vbi = mxb_vbi_bypass,
-
.ioctls = &ioctls[0],
.preinit = mxb_preinit,