summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2007-10-31 09:10:50 -0200
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-10-31 09:10:50 -0200
commitf1ff79eafc9d2ff01fbec2eaee2f81bcf9544f86 (patch)
tree44efbb99651f24cb3a75c29bc3c0c33ef25b1c3e /linux/drivers/media
parente77871b7c84f213b57e7f34d30e2d9e45f59d8b5 (diff)
parent67da9a2a1f4c26fb835d42f1ba1a2c9b7542bf54 (diff)
downloadmediapointer-dvb-s2-f1ff79eafc9d2ff01fbec2eaee2f81bcf9544f86.tar.gz
mediapointer-dvb-s2-f1ff79eafc9d2ff01fbec2eaee2f81bcf9544f86.tar.bz2
merge: http://linuxtv.org/hg/~mkrufky/tuner
From: Mauro Carvalho Chehab <mchehab@infradead.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/video/Kconfig23
-rw-r--r--linux/drivers/media/video/Makefile1
-rw-r--r--linux/drivers/media/video/ivtv/Kconfig1
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-cards.c79
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-cards.h8
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-driver.c6
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-i2c.c3
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-routing.c25
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-streams.c2
-rw-r--r--linux/drivers/media/video/m52790.c183
10 files changed, 308 insertions, 23 deletions
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 20f7c57bb..8a164bd1c 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -111,7 +111,7 @@ config VIDEO_MSP3400
config VIDEO_CS53L32A
tristate "Cirrus Logic CS53L32A audio ADC"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Cirrus Logic CS53L32A low voltage
stereo A/D converter.
@@ -119,6 +119,15 @@ config VIDEO_CS53L32A
To compile this driver as a module, choose M here: the
module will be called cs53l32a.
+config VIDEO_M52790
+ tristate "Mitsubishi M52790 A/V switch"
+ depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ ---help---
+ Support for the Mitsubishi M52790 A/V switch.
+
+ To compile this driver as a module, choose M here: the
+ module will be called m52790.
+
config VIDEO_TLV320AIC23B
tristate "Texas Instruments TLV320AIC23B audio codec"
depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
@@ -130,7 +139,7 @@ config VIDEO_TLV320AIC23B
config VIDEO_WM8775
tristate "Wolfson Microelectronics WM8775 audio ADC with input mixer"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Wolfson Microelectronics WM8775 high
performance stereo A/D Converter with a 4 channel input mixer.
@@ -140,7 +149,7 @@ config VIDEO_WM8775
config VIDEO_WM8739
tristate "Wolfson Microelectronics WM8739 stereo audio ADC"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Wolfson Microelectronics WM8739
stereo A/D Converter.
@@ -244,7 +253,7 @@ config VIDEO_SAA7114
config VIDEO_SAA711X
tristate "Philips SAA7113/4/5 video decoders"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7113/4/5 video decoders.
@@ -300,7 +309,7 @@ comment "Video encoders"
config VIDEO_SAA7127
tristate "Philips SAA7127/9 digital video encoders"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the Philips SAA7127/9 digital video encoders.
@@ -338,7 +347,7 @@ comment "Video improvement chips"
config VIDEO_UPD64031A
tristate "NEC Electronics uPD64031A Ghost Reduction"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the NEC Electronics uPD64031A Ghost Reduction
video chip. It is most often found in NTSC TV cards made for
@@ -350,7 +359,7 @@ config VIDEO_UPD64031A
config VIDEO_UPD64083
tristate "NEC Electronics uPD64083 3-Dimensional Y/C separation"
- depends on VIDEO_V4L2 && I2C && EXPERIMENTAL
+ depends on VIDEO_V4L2 && I2C
---help---
Support for the NEC Electronics uPD64083 3-Dimensional Y/C
separation video chip. It is used to improve the quality of
diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile
index 8a2781821..d8910d87a 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -67,6 +67,7 @@ obj-$(CONFIG_VIDEO_TVP5150) += tvp5150.o
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
obj-$(CONFIG_VIDEO_MSP3400) += msp3400.o
obj-$(CONFIG_VIDEO_CS53L32A) += cs53l32a.o
+obj-$(CONFIG_VIDEO_M52790) += m52790.o
obj-$(CONFIG_VIDEO_TLV320AIC23B) += tlv320aic23b.o
obj-$(CONFIG_VIDEO_WM8775) += wm8775.o
obj-$(CONFIG_VIDEO_WM8739) += wm8739.o
diff --git a/linux/drivers/media/video/ivtv/Kconfig b/linux/drivers/media/video/ivtv/Kconfig
index 854cc9c30..6e5eed5e2 100644
--- a/linux/drivers/media/video/ivtv/Kconfig
+++ b/linux/drivers/media/video/ivtv/Kconfig
@@ -12,6 +12,7 @@ config VIDEO_IVTV
select VIDEO_SAA7127
select VIDEO_TVAUDIO
select VIDEO_CS53L32A
+ select VIDEO_M52790
select VIDEO_WM8775
select VIDEO_WM8739
select VIDEO_VP27SMPX
diff --git a/linux/drivers/media/video/ivtv/ivtv-cards.c b/linux/drivers/media/video/ivtv/ivtv-cards.c
index bf6948eda..664fdbca5 100644
--- a/linux/drivers/media/video/ivtv/ivtv-cards.c
+++ b/linux/drivers/media/video/ivtv/ivtv-cards.c
@@ -23,6 +23,7 @@
#include "ivtv-i2c.h"
#include <media/msp3400.h>
+#include <media/m52790.h>
#include <media/wm8775.h>
#include <media/cs53l32a.h>
#include <media/cx25840.h>
@@ -959,6 +960,82 @@ static const struct ivtv_card ivtv_card_avertv_mce116 = {
.pci_list = ivtv_pci_avertv_mce116,
};
+/* ------------------------------------------------------------------------- */
+
+/* AVerMedia PVR-150 Plus (M113) card */
+
+static const struct ivtv_card_pci_info ivtv_pci_aver_pvr150[] = {
+ { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_AVERMEDIA, 0xc035 },
+ { 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_aver_pvr150 = {
+ .type = IVTV_CARD_AVER_PVR150PLUS,
+ .name = "AVerMedia PVR-150 Plus",
+ .v4l2_capabilities = IVTV_CAP_ENCODER,
+ .hw_video = IVTV_HW_CX25840,
+ .hw_audio = IVTV_HW_CX25840,
+ .hw_audio_ctrl = IVTV_HW_CX25840,
+ .hw_muxer = IVTV_HW_GPIO,
+ .hw_all = IVTV_HW_CX25840 | IVTV_HW_TUNER,
+ .video_inputs = {
+ { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
+ { IVTV_CARD_INPUT_SVIDEO1, 1,
+ CX25840_SVIDEO_LUMA3 | CX25840_SVIDEO_CHROMA4 },
+ { IVTV_CARD_INPUT_COMPOSITE1, 1, CX25840_COMPOSITE1 },
+ },
+ .audio_inputs = {
+ { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, 0 },
+ { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, 1 },
+ },
+ .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, 2 },
+ .gpio_init = { .direction = 0x0800, .initial_value = 0 },
+ .gpio_audio_input = { .mask = 0x0800, .tuner = 0, .linein = 0, .radio = 0x0800 },
+ .tuners = {
+ /* This card has a Partsnic PTI-5NF05 tuner */
+ { .std = V4L2_STD_525_60, .tuner = TUNER_TCL_2002N },
+ },
+ .pci_list = ivtv_pci_aver_pvr150,
+};
+
+/* ------------------------------------------------------------------------- */
+
+/* ASUS Falcon2 */
+
+static const struct ivtv_card_pci_info ivtv_pci_asus_falcon2[] = {
+ { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b66 },
+ { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x462e },
+ { PCI_DEVICE_ID_IVTV16, IVTV_PCI_ID_ASUSTEK, 0x4b2e },
+ { 0, 0, 0 }
+};
+
+static const struct ivtv_card ivtv_card_asus_falcon2 = {
+ .type = IVTV_CARD_ASUS_FALCON2,
+ .name = "ASUS Falcon2",
+ .v4l2_capabilities = IVTV_CAP_ENCODER,
+ .hw_video = IVTV_HW_CX25840,
+ .hw_audio = IVTV_HW_CX25840,
+ .hw_audio_ctrl = IVTV_HW_CX25840,
+ .hw_muxer = IVTV_HW_M52790,
+ .hw_all = IVTV_HW_CX25840 | IVTV_HW_M52790 | IVTV_HW_TUNER,
+ .video_inputs = {
+ { IVTV_CARD_INPUT_VID_TUNER, 0, CX25840_COMPOSITE2 },
+ { IVTV_CARD_INPUT_SVIDEO1, 1, CX25840_SVIDEO3 },
+ { IVTV_CARD_INPUT_COMPOSITE1, 2, CX25840_COMPOSITE2 },
+ },
+ .audio_inputs = {
+ { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO5, M52790_IN_TUNER },
+ { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL,
+ M52790_IN_V2 | M52790_SW1_YCMIX | M52790_SW2_YCMIX },
+ { IVTV_CARD_INPUT_LINE_IN1, CX25840_AUDIO_SERIAL, M52790_IN_V2 },
+ },
+ .radio_input = { IVTV_CARD_INPUT_AUD_TUNER, CX25840_AUDIO_SERIAL, M52790_IN_TUNER },
+ .tuners = {
+ { .std = V4L2_STD_525_60, .tuner = TUNER_PHILIPS_FM1236_MK3 },
+ },
+ .pci_list = ivtv_pci_asus_falcon2,
+};
+
static const struct ivtv_card *ivtv_card_list[] = {
&ivtv_card_pvr250,
&ivtv_card_pvr350,
@@ -981,6 +1058,8 @@ static const struct ivtv_card *ivtv_card_list[] = {
&ivtv_card_pg600v2,
&ivtv_card_club3d,
&ivtv_card_avertv_mce116,
+ &ivtv_card_asus_falcon2,
+ &ivtv_card_aver_pvr150,
/* Variations of standard cards but with the same PCI IDs.
These cards must come last in this list. */
diff --git a/linux/drivers/media/video/ivtv/ivtv-cards.h b/linux/drivers/media/video/ivtv/ivtv-cards.h
index ff46e5ae8..881b04473 100644
--- a/linux/drivers/media/video/ivtv/ivtv-cards.h
+++ b/linux/drivers/media/video/ivtv/ivtv-cards.h
@@ -45,7 +45,9 @@
#define IVTV_CARD_PG600V2 18 /* Yuan PG600V2/GotView PCI DVD Lite */
#define IVTV_CARD_CLUB3D 19 /* Club3D ZAP-TV1x01 */
#define IVTV_CARD_AVERTV_MCE116 20 /* AVerTV MCE 116 Plus */
-#define IVTV_CARD_LAST 20
+#define IVTV_CARD_ASUS_FALCON2 21 /* ASUS Falcon2 */
+#define IVTV_CARD_AVER_PVR150PLUS 22 /* AVerMedia PVR-150 Plus */
+#define IVTV_CARD_LAST 22
/* Variants of existing cards but with the same PCI IDs. The driver
detects these based on other device information.
@@ -69,6 +71,7 @@
#define IVTV_PCI_ID_HAUPPAUGE_ALT1 0x0270
#define IVTV_PCI_ID_HAUPPAUGE_ALT2 0x4070
#define IVTV_PCI_ID_ADAPTEC 0x9005
+#define IVTV_PCI_ID_ASUSTEK 0x1043
#define IVTV_PCI_ID_AVERMEDIA 0x1461
#define IVTV_PCI_ID_YUAN1 0x12ab
#define IVTV_PCI_ID_YUAN2 0xff01
@@ -96,7 +99,8 @@
#define IVTV_HW_SAA717X (1 << 12)
#define IVTV_HW_WM8739 (1 << 13)
#define IVTV_HW_VP27SMPX (1 << 14)
-#define IVTV_HW_GPIO (1 << 15)
+#define IVTV_HW_M52790 (1 << 15)
+#define IVTV_HW_GPIO (1 << 16)
#define IVTV_HW_SAA711X (IVTV_HW_SAA7115 | IVTV_HW_SAA7114)
diff --git a/linux/drivers/media/video/ivtv/ivtv-driver.c b/linux/drivers/media/video/ivtv/ivtv-driver.c
index 051593a17..0a00c023c 100644
--- a/linux/drivers/media/video/ivtv/ivtv-driver.c
+++ b/linux/drivers/media/video/ivtv/ivtv-driver.c
@@ -185,6 +185,8 @@ MODULE_PARM_DESC(cardtype,
"\t\t\t19 = Yuan PG600V2/GotView PCI DVD Lite\n"
"\t\t\t20 = Club3D ZAP-TV1x01\n"
"\t\t\t21 = AverTV MCE 116 Plus\n"
+ "\t\t\t22 = ASUS Falcon2\n"
+ "\t\t\t23 = AverMedia PVR-150 Plus\n"
"\t\t\t 0 = Autodetect (default)\n"
"\t\t\t-1 = Ignore this card\n\t\t");
MODULE_PARM_DESC(pal, "Set PAL standard: B, G, H, D, K, I, M, N, Nc, 60");
@@ -886,6 +888,10 @@ static void ivtv_load_and_init_modules(struct ivtv *itv)
if (hw & IVTV_HW_CS53L32A)
ivtv_request_module(itv, "cs53l32a");
#endif
+#ifndef CONFIG_VIDEO_M52790
+ if (hw & IVTV_HW_M52790)
+ ivtv_request_module(itv, "m52790");
+#endif
/* check which i2c devices are actually found */
for (i = 0; i < 32; i++) {
diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c
index 02b520060..d78f2f7fd 100644
--- a/linux/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c
@@ -80,6 +80,7 @@
#endif /* I2C_ADAP_CLASS_TV_ANALOG */
#define IVTV_CS53L32A_I2C_ADDR 0x11
+#define IVTV_M52790_I2C_ADDR 0x48
#define IVTV_CX25840_I2C_ADDR 0x44
#define IVTV_SAA7115_I2C_ADDR 0x21
#define IVTV_SAA7127_I2C_ADDR 0x44
@@ -110,6 +111,7 @@ static const u8 hw_driverids[] = {
I2C_DRIVERID_SAA717X,
I2C_DRIVERID_WM8739,
I2C_DRIVERID_VP27SMPX,
+ I2C_DRIVERID_M52790,
0 /* IVTV_HW_GPIO dummy driver ID */
};
@@ -130,6 +132,7 @@ static const char * const hw_drivernames[] = {
"saa717x",
"wm8739",
"vp27smpx",
+ "m52790",
"gpio",
};
diff --git a/linux/drivers/media/video/ivtv/ivtv-routing.c b/linux/drivers/media/video/ivtv/ivtv-routing.c
index 398bd3303..05564919b 100644
--- a/linux/drivers/media/video/ivtv/ivtv-routing.c
+++ b/linux/drivers/media/video/ivtv/ivtv-routing.c
@@ -25,6 +25,7 @@
#include "ivtv-routing.h"
#include <media/msp3400.h>
+#include <media/m52790.h>
#include <media/upd64031a.h>
#include <media/upd64083.h>
@@ -32,28 +33,26 @@
settings. */
void ivtv_audio_set_io(struct ivtv *itv)
{
+ const struct ivtv_card_audio_input *in;
struct v4l2_routing route;
- u32 audio_input;
- int mux_input;
/* Determine which input to use */
- if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
- audio_input = itv->card->radio_input.audio_input;
- mux_input = itv->card->radio_input.muxer_input;
- } else {
- audio_input = itv->card->audio_inputs[itv->audio_input].audio_input;
- mux_input = itv->card->audio_inputs[itv->audio_input].muxer_input;
- }
+ if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags))
+ in = &itv->card->radio_input;
+ else
+ in = &itv->card->audio_inputs[itv->audio_input];
/* handle muxer chips */
- route.input = mux_input;
+ route.input = in->muxer_input;
route.output = 0;
+ if (itv->card->hw_muxer & IVTV_HW_M52790)
+ route.output = M52790_OUT_STEREO;
ivtv_i2c_hw(itv, itv->card->hw_muxer, VIDIOC_INT_S_AUDIO_ROUTING, &route);
- route.input = audio_input;
- if (itv->card->hw_audio & IVTV_HW_MSP34XX) {
+ route.input = in->audio_input;
+ route.output = 0;
+ if (itv->card->hw_audio & IVTV_HW_MSP34XX)
route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
- }
ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, &route);
}
diff --git a/linux/drivers/media/video/ivtv/ivtv-streams.c b/linux/drivers/media/video/ivtv/ivtv-streams.c
index cc1efd63e..a5bfbd98a 100644
--- a/linux/drivers/media/video/ivtv/ivtv-streams.c
+++ b/linux/drivers/media/video/ivtv/ivtv-streams.c
@@ -76,7 +76,7 @@ static struct {
int minor_offset;
int dma, pio;
enum v4l2_buf_type buf_type;
- struct file_operations *fops;
+ const struct file_operations *fops;
} ivtv_stream_info[] = {
{ /* IVTV_ENC_STREAM_TYPE_MPG */
"encoder MPG",
diff --git a/linux/drivers/media/video/m52790.c b/linux/drivers/media/video/m52790.c
new file mode 100644
index 000000000..ebe089c6d
--- /dev/null
+++ b/linux/drivers/media/video/m52790.c
@@ -0,0 +1,183 @@
+/*
+ * m52790 i2c ivtv driver.
+ * Copyright (C) 2007 Hans Verkuil
+ *
+ * A/V source switching Mitsubishi M52790SP/FP
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/ioctl.h>
+#include <asm/uaccess.h>
+#include <linux/i2c.h>
+#include <linux/i2c-id.h>
+#include <linux/videodev.h>
+#include <media/m52790.h>
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/v4l2-i2c-drv-legacy.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
+#include "i2c-compat.h"
+#include <linux/slab.h>
+#endif
+#include "compat.h"
+
+MODULE_DESCRIPTION("i2c device driver for m52790 A/V switch");
+MODULE_AUTHOR("Hans Verkuil");
+MODULE_LICENSE("GPL");
+
+static unsigned short normal_i2c[] = { 0x90 >> 1, I2C_CLIENT_END };
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 13)
+static unsigned short normal_i2c_range[] = { I2C_CLIENT_END };
+#endif
+
+I2C_CLIENT_INSMOD;
+
+struct m52790_state {
+ u16 input;
+ u16 output;
+};
+
+/* ----------------------------------------------------------------------- */
+
+static int m52790_write(struct i2c_client *client)
+{
+ struct m52790_state *state = i2c_get_clientdata(client);
+ u8 sw1 = (state->input | state->output) & 0xff;
+ u8 sw2 = (state->input | state->output) >> 8;
+
+ return i2c_smbus_write_byte_data(client, sw1, sw2);
+}
+
+static int m52790_command(struct i2c_client *client, unsigned int cmd,
+ void *arg)
+{
+ struct m52790_state *state = i2c_get_clientdata(client);
+ struct v4l2_routing *route = arg;
+
+ /* Note: audio and video are linked and cannot be switched separately.
+ So audio and video routing commands are identical for this chip.
+ In theory the video amplifier and audio modes could be handled
+ separately for the output, but that seems to be overkill right now.
+ The same holds for implementing an audio mute control, this is now
+ part of the audio output routing. The normal case is that another
+ chip takes care of the actual muting so making it part of the
+ output routing seems to be the right thing to do for now. */
+ switch (cmd) {
+ case VIDIOC_INT_G_AUDIO_ROUTING:
+ case VIDIOC_INT_G_VIDEO_ROUTING:
+ route->input = state->input;
+ route->output = state->output;
+ break;
+
+ case VIDIOC_INT_S_AUDIO_ROUTING:
+ case VIDIOC_INT_S_VIDEO_ROUTING:
+ state->input = route->input;
+ state->output = route->output;
+ m52790_write(client);
+ break;
+
+#ifdef CONFIG_VIDEO_ADV_DEBUG
+ case VIDIOC_DBG_G_REGISTER:
+ case VIDIOC_DBG_S_REGISTER:
+ {
+ struct v4l2_register *reg = arg;
+
+ if (!v4l2_chip_match_i2c_client(client,
+ reg->match_type, reg->match_chip))
+ return -EINVAL;
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+ if (reg->reg != 0)
+ return -EINVAL;
+ if (cmd == VIDIOC_DBG_G_REGISTER)
+ reg->val = state->input | state->output;
+ else {
+ state->input = reg->val & 0x0303;
+ state->output = reg->val & ~0x0303;
+ m52790_write(client);
+ }
+ break;
+ }
+#endif
+
+ case VIDIOC_G_CHIP_IDENT:
+ return v4l2_chip_ident_i2c_client(client, arg,
+ V4L2_IDENT_M52790, 0);
+
+ case VIDIOC_LOG_STATUS:
+ v4l_info(client, "Switch 1: %02x\n",
+ (state->input | state->output) & 0xff);
+ v4l_info(client, "Switch 2: %02x\n",
+ (state->input | state->output) >> 8);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+/* i2c implementation */
+
+static int m52790_probe(struct i2c_client *client)
+{
+ struct m52790_state *state;
+
+ /* Check if the adapter supports the needed features */
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -EIO;
+
+ snprintf(client->name, sizeof(client->name) - 1, "m52790");
+
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ state = kmalloc(sizeof(struct m52790_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ state->input = M52790_IN_TUNER;
+ state->output = M52790_OUT_STEREO;
+ i2c_set_clientdata(client, state);
+ m52790_write(client);
+ return 0;
+}
+
+static int m52790_remove(struct i2c_client *client)
+{
+ kfree(i2c_get_clientdata(client));
+ return 0;
+}
+
+/* ----------------------------------------------------------------------- */
+
+static struct v4l2_i2c_driver_data v4l2_i2c_data = {
+ .name = "m52790",
+ .driverid = I2C_DRIVERID_M52790,
+ .command = m52790_command,
+ .probe = m52790_probe,
+ .remove = m52790_remove,
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0)
+EXPORT_NO_SYMBOLS;
+#endif