summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-05-27 10:11:39 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-05-27 10:11:39 -0300
commite869f37a082df276cbc412d3f7da04fd3b41fed4 (patch)
treea4067ce193263515f64018aaec0d618fe5864e86 /linux/drivers/media/video
parentfc06889a7cb90e50621ecaaf22f2f575b5ae6a44 (diff)
parentf8a7ff5ce3d73304b156a0ed39d309050c903a82 (diff)
downloadmediapointer-dvb-s2-e869f37a082df276cbc412d3f7da04fd3b41fed4.tar.gz
mediapointer-dvb-s2-e869f37a082df276cbc412d3f7da04fd3b41fed4.tar.bz2
merge: http://linuxtv.org/hg/~awalls/cx18-av-core
From: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media/video')
-rw-r--r--linux/drivers/media/video/Kconfig20
-rw-r--r--linux/drivers/media/video/Makefile2
-rw-r--r--linux/drivers/media/video/adv7343.c534
-rw-r--r--linux/drivers/media/video/adv7343_regs.h185
-rw-r--r--linux/drivers/media/video/au0828/au0828-cards.c4
-rw-r--r--linux/drivers/media/video/au0828/au0828-video.c8
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-driver.c1
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-i2c.c21
-rw-r--r--linux/drivers/media/video/cpia2/cpia2_v4l.c6
-rw-r--r--linux/drivers/media/video/cx18/cx18-driver.c2
-rw-r--r--linux/drivers/media/video/cx231xx/cx231xx-cards.c8
-rw-r--r--linux/drivers/media/video/cx231xx/cx231xx-i2c.c32
-rw-r--r--linux/drivers/media/video/cx231xx/cx231xx-input.c2
-rw-r--r--linux/drivers/media/video/cx231xx/cx231xx.h2
-rw-r--r--linux/drivers/media/video/cx23885/cimax2.c2
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-417.c1
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-cards.c99
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-core.c82
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-dvb.c86
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-i2c.c12
-rw-r--r--linux/drivers/media/video/cx23885/cx23885.h20
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c20
-rw-r--r--linux/drivers/media/video/cx88/cx88-core.c1
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c13
-rw-r--r--linux/drivers/media/video/cx88/cx88-input.c2
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c2
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-cards.c93
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-core.c35
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-dvb.c6
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-i2c.c25
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-input.c8
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-reg.h16
-rw-r--r--linux/drivers/media/video/em28xx/em28xx.h5
-rw-r--r--linux/drivers/media/video/hexium_gemini.c2
-rw-r--r--linux/drivers/media/video/hexium_orion.c2
-rw-r--r--linux/drivers/media/video/ir-kbd-i2c.c222
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-i2c.c36
-rw-r--r--linux/drivers/media/video/ivtv/ivtv-ioctl.c2
-rw-r--r--linux/drivers/media/video/mxb.c4
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c5
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h23
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h3
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c74
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c51
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c22
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c6
-rw-r--r--linux/drivers/media/video/pwc/pwc-v4l.c2
-rw-r--r--linux/drivers/media/video/s2255drv.c63
-rw-r--r--linux/drivers/media/video/saa7134/Kconfig1
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c6
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-core.c1
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-dvb.c26
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-empress.c3
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-i2c.c33
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-input.c103
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-ts.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-video.c9
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h3
-rw-r--r--linux/drivers/media/video/soc_camera.c2
-rw-r--r--linux/drivers/media/video/stk-webcam.c4
-rw-r--r--linux/drivers/media/video/tea6415c.c1
-rw-r--r--linux/drivers/media/video/tea6420.c1
-rw-r--r--linux/drivers/media/video/ths7303.c151
-rw-r--r--linux/drivers/media/video/tuner-core.c4
-rw-r--r--linux/drivers/media/video/tveeprom.c2
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-video.c2
-rw-r--r--linux/drivers/media/video/uvc/uvc_driver.c43
-rw-r--r--linux/drivers/media/video/uvc/uvc_status.c21
-rw-r--r--linux/drivers/media/video/uvc/uvc_v4l2.c14
-rw-r--r--linux/drivers/media/video/uvc/uvc_video.c17
-rw-r--r--linux/drivers/media/video/uvc/uvcvideo.h3
-rw-r--r--linux/drivers/media/video/v4l2-device.c2
-rw-r--r--linux/drivers/media/video/videobuf-core.c5
-rw-r--r--linux/drivers/media/video/videobuf-dma-contig.c14
-rw-r--r--linux/drivers/media/video/videobuf-dma-sg.c17
-rw-r--r--linux/drivers/media/video/zoran/zoran_card.c2
76 files changed, 1852 insertions, 512 deletions
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 9d48da2fb..8de867d30 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -440,6 +440,24 @@ config VIDEO_ADV7175
To compile this driver as a module, choose M here: the
module will be called adv7175.
+config VIDEO_THS7303
+ tristate "THS7303 Video Amplifier"
+ depends on I2C
+ help
+ Support for TI THS7303 video amplifier
+
+ To compile this driver as a module, choose M here: the
+ module will be called ths7303.
+
+config VIDEO_ADV7343
+ tristate "ADV7343 video encoder"
+ depends on I2C
+ help
+ Support for Analog Devices I2C bus based ADV7343 encoder.
+
+ To compile this driver as a module, choose M here: the
+ module will be called adv7343.
+
comment "Video improvement chips"
config VIDEO_UPD64031A
@@ -694,7 +712,7 @@ config VIDEO_CAFE_CCIC
config SOC_CAMERA
tristate "SoC camera support"
- depends on VIDEO_V4L2 && HAS_DMA
+ depends on VIDEO_V4L2 && HAS_DMA && I2C
select VIDEOBUF_GEN
help
SoC Camera is a common API to several cameras, not connecting
diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile
index 7aefac643..f7d9a4c6f 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -49,11 +49,13 @@ obj-$(CONFIG_VIDEO_SAA7185) += saa7185.o
obj-$(CONFIG_VIDEO_SAA7191) += saa7191.o
obj-$(CONFIG_VIDEO_ADV7170) += adv7170.o
obj-$(CONFIG_VIDEO_ADV7175) += adv7175.o
+obj-$(CONFIG_VIDEO_ADV7343) += adv7343.o
obj-$(CONFIG_VIDEO_VPX3220) += vpx3220.o
obj-$(CONFIG_VIDEO_BT819) += bt819.o
obj-$(CONFIG_VIDEO_BT856) += bt856.o
obj-$(CONFIG_VIDEO_BT866) += bt866.o
obj-$(CONFIG_VIDEO_KS0127) += ks0127.o
+obj-$(CONFIG_VIDEO_THS7303) += ths7303.o
obj-$(CONFIG_VIDEO_ZORAN) += zoran/
diff --git a/linux/drivers/media/video/adv7343.c b/linux/drivers/media/video/adv7343.c
new file mode 100644
index 000000000..30f5caf5d
--- /dev/null
+++ b/linux/drivers/media/video/adv7343.c
@@ -0,0 +1,534 @@
+/*
+ * adv7343 - ADV7343 Video Encoder Driver
+ *
+ * The encoder hardware does not support SECAM.
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/videodev2.h>
+#include <linux/uaccess.h>
+#include <linux/version.h>
+
+#include <media/adv7343.h>
+#include <media/v4l2-device.h>
+#include <media/v4l2-chip-ident.h>
+
+#include "adv7343_regs.h"
+
+MODULE_DESCRIPTION("ADV7343 video encoder driver");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+struct adv7343_state {
+ struct v4l2_subdev sd;
+ u8 reg00;
+ u8 reg01;
+ u8 reg02;
+ u8 reg35;
+ u8 reg80;
+ u8 reg82;
+ int bright;
+ int hue;
+ int gain;
+ u32 output;
+ v4l2_std_id std;
+};
+
+static inline struct adv7343_state *to_state(struct v4l2_subdev *sd)
+{
+ return container_of(sd, struct adv7343_state, sd);
+}
+
+static inline int adv7343_write(struct v4l2_subdev *sd, u8 reg, u8 value)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static const u8 adv7343_init_reg_val[] = {
+ ADV7343_SOFT_RESET, ADV7343_SOFT_RESET_DEFAULT,
+ ADV7343_POWER_MODE_REG, ADV7343_POWER_MODE_REG_DEFAULT,
+
+ ADV7343_HD_MODE_REG1, ADV7343_HD_MODE_REG1_DEFAULT,
+ ADV7343_HD_MODE_REG2, ADV7343_HD_MODE_REG2_DEFAULT,
+ ADV7343_HD_MODE_REG3, ADV7343_HD_MODE_REG3_DEFAULT,
+ ADV7343_HD_MODE_REG4, ADV7343_HD_MODE_REG4_DEFAULT,
+ ADV7343_HD_MODE_REG5, ADV7343_HD_MODE_REG5_DEFAULT,
+ ADV7343_HD_MODE_REG6, ADV7343_HD_MODE_REG6_DEFAULT,
+ ADV7343_HD_MODE_REG7, ADV7343_HD_MODE_REG7_DEFAULT,
+
+ ADV7343_SD_MODE_REG1, ADV7343_SD_MODE_REG1_DEFAULT,
+ ADV7343_SD_MODE_REG2, ADV7343_SD_MODE_REG2_DEFAULT,
+ ADV7343_SD_MODE_REG3, ADV7343_SD_MODE_REG3_DEFAULT,
+ ADV7343_SD_MODE_REG4, ADV7343_SD_MODE_REG4_DEFAULT,
+ ADV7343_SD_MODE_REG5, ADV7343_SD_MODE_REG5_DEFAULT,
+ ADV7343_SD_MODE_REG6, ADV7343_SD_MODE_REG6_DEFAULT,
+ ADV7343_SD_MODE_REG7, ADV7343_SD_MODE_REG7_DEFAULT,
+ ADV7343_SD_MODE_REG8, ADV7343_SD_MODE_REG8_DEFAULT,
+
+ ADV7343_SD_HUE_REG, ADV7343_SD_HUE_REG_DEFAULT,
+ ADV7343_SD_CGMS_WSS0, ADV7343_SD_CGMS_WSS0_DEFAULT,
+ ADV7343_SD_BRIGHTNESS_WSS, ADV7343_SD_BRIGHTNESS_WSS_DEFAULT,
+};
+
+/*
+ * 2^32
+ * FSC(reg) = FSC (HZ) * --------
+ * 27000000
+ */
+static const struct adv7343_std_info stdinfo[] = {
+ {
+ /* FSC(Hz) = 3,579,545.45 Hz */
+ SD_STD_NTSC, 569408542, V4L2_STD_NTSC,
+ }, {
+ /* FSC(Hz) = 3,575,611.00 Hz */
+ SD_STD_PAL_M, 568782678, V4L2_STD_PAL_M,
+ }, {
+ /* FSC(Hz) = 3,582,056.00 */
+ SD_STD_PAL_N, 569807903, V4L2_STD_PAL_Nc,
+ }, {
+ /* FSC(Hz) = 4,433,618.75 Hz */
+ SD_STD_PAL_N, 705268427, V4L2_STD_PAL_N,
+ }, {
+ /* FSC(Hz) = 4,433,618.75 Hz */
+ SD_STD_PAL_BDGHI, 705268427, V4L2_STD_PAL,
+ }, {
+ /* FSC(Hz) = 4,433,618.75 Hz */
+ SD_STD_NTSC, 705268427, V4L2_STD_NTSC_443,
+ }, {
+ /* FSC(Hz) = 4,433,618.75 Hz */
+ SD_STD_PAL_M, 705268427, V4L2_STD_PAL_60,
+ },
+};
+
+static int adv7343_setstd(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct adv7343_state *state = to_state(sd);
+ struct adv7343_std_info *std_info;
+ int output_idx, num_std;
+ char *fsc_ptr;
+ u8 reg, val;
+ int err = 0;
+ int i = 0;
+
+ output_idx = state->output;
+
+ std_info = (struct adv7343_std_info *)stdinfo;
+ num_std = ARRAY_SIZE(stdinfo);
+
+ for (i = 0; i < num_std; i++) {
+ if (std_info[i].stdid & std)
+ break;
+ }
+
+ if (i == num_std) {
+ v4l2_dbg(1, debug, sd,
+ "Invalid std or std is not supported: %llx\n",
+ (unsigned long long)std);
+ return -EINVAL;
+ }
+
+ /* Set the standard */
+ val = state->reg80 & (~(SD_STD_MASK));
+ val |= std_info[i].standard_val3;
+ err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
+ if (err < 0)
+ goto setstd_exit;
+
+ state->reg80 = val;
+
+ /* Configure the input mode register */
+ val = state->reg01 & (~((u8) INPUT_MODE_MASK));
+ val |= SD_INPUT_MODE;
+ err = adv7343_write(sd, ADV7343_MODE_SELECT_REG, val);
+ if (err < 0)
+ goto setstd_exit;
+
+ state->reg01 = val;
+
+ /* Program the sub carrier frequency registers */
+ fsc_ptr = (unsigned char *)&std_info[i].fsc_val;
+ reg = ADV7343_FSC_REG0;
+ for (i = 0; i < 4; i++, reg++, fsc_ptr++) {
+ err = adv7343_write(sd, reg, *fsc_ptr);
+ if (err < 0)
+ goto setstd_exit;
+ }
+
+ val = state->reg80;
+
+ /* Filter settings */
+ if (std & (V4L2_STD_NTSC | V4L2_STD_NTSC_443))
+ val &= 0x03;
+ else if (std & ~V4L2_STD_SECAM)
+ val |= 0x04;
+
+ err = adv7343_write(sd, ADV7343_SD_MODE_REG1, val);
+ if (err < 0)
+ goto setstd_exit;
+
+ state->reg80 = val;
+
+setstd_exit:
+ if (err != 0)
+ v4l2_err(sd, "Error setting std, write failed\n");
+
+ return err;
+}
+
+static int adv7343_setoutput(struct v4l2_subdev *sd, u32 output_type)
+{
+ struct adv7343_state *state = to_state(sd);
+ unsigned char val;
+ int err = 0;
+
+ if (output_type > ADV7343_SVIDEO_ID) {
+ v4l2_dbg(1, debug, sd,
+ "Invalid output type or output type not supported:%d\n",
+ output_type);
+ return -EINVAL;
+ }
+
+ /* Enable Appropriate DAC */
+ val = state->reg00 & 0x03;
+
+ if (output_type == ADV7343_COMPOSITE_ID)
+ val |= ADV7343_COMPOSITE_POWER_VALUE;
+ else if (output_type == ADV7343_COMPONENT_ID)
+ val |= ADV7343_COMPONENT_POWER_VALUE;
+ else
+ val |= ADV7343_SVIDEO_POWER_VALUE;
+
+ err = adv7343_write(sd, ADV7343_POWER_MODE_REG, val);
+ if (err < 0)
+ goto setoutput_exit;
+
+ state->reg00 = val;
+
+ /* Enable YUV output */
+ val = state->reg02 | YUV_OUTPUT_SELECT;
+ err = adv7343_write(sd, ADV7343_MODE_REG0, val);
+ if (err < 0)
+ goto setoutput_exit;
+
+ state->reg02 = val;
+
+ /* configure SD DAC Output 2 and SD DAC Output 1 bit to zero */
+ val = state->reg82 & (SD_DAC_1_DI & SD_DAC_2_DI);
+ err = adv7343_write(sd, ADV7343_SD_MODE_REG2, val);
+ if (err < 0)
+ goto setoutput_exit;
+
+ state->reg82 = val;
+
+ /* configure ED/HD Color DAC Swap and ED/HD RGB Input Enable bit to
+ * zero */
+ val = state->reg35 & (HD_RGB_INPUT_DI & HD_DAC_SWAP_DI);
+ err = adv7343_write(sd, ADV7343_HD_MODE_REG6, val);
+ if (err < 0)
+ goto setoutput_exit;
+
+ state->reg35 = val;
+
+setoutput_exit:
+ if (err != 0)
+ v4l2_err(sd, "Error setting output, write failed\n");
+
+ return err;
+}
+
+static int adv7343_log_status(struct v4l2_subdev *sd)
+{
+ struct adv7343_state *state = to_state(sd);
+
+ v4l2_info(sd, "Standard: %llx\n", (unsigned long long)state->std);
+ v4l2_info(sd, "Output: %s\n", (state->output == 0) ? "Composite" :
+ ((state->output == 1) ? "Component" : "S-Video"));
+ return 0;
+}
+
+static int adv7343_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
+{
+ switch (qc->id) {
+ case V4L2_CID_BRIGHTNESS:
+ return v4l2_ctrl_query_fill(qc, ADV7343_BRIGHTNESS_MIN,
+ ADV7343_BRIGHTNESS_MAX, 1,
+ ADV7343_BRIGHTNESS_DEF);
+ case V4L2_CID_HUE:
+ return v4l2_ctrl_query_fill(qc, ADV7343_HUE_MIN,
+ ADV7343_HUE_MAX, 1 ,
+ ADV7343_HUE_DEF);
+ case V4L2_CID_GAIN:
+ return v4l2_ctrl_query_fill(qc, ADV7343_GAIN_MIN,
+ ADV7343_GAIN_MAX, 1,
+ ADV7343_GAIN_DEF);
+ default:
+ break;
+ }
+
+ return 0;
+}
+
+static int adv7343_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct adv7343_state *state = to_state(sd);
+ int err = 0;
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ if (ctrl->value < ADV7343_BRIGHTNESS_MIN ||
+ ctrl->value > ADV7343_BRIGHTNESS_MAX) {
+ v4l2_dbg(1, debug, sd,
+ "invalid brightness settings %d\n",
+ ctrl->value);
+ return -ERANGE;
+ }
+
+ state->bright = ctrl->value;
+ err = adv7343_write(sd, ADV7343_SD_BRIGHTNESS_WSS,
+ state->bright);
+ break;
+
+ case V4L2_CID_HUE:
+ if (ctrl->value < ADV7343_HUE_MIN ||
+ ctrl->value > ADV7343_HUE_MAX) {
+ v4l2_dbg(1, debug, sd, "invalid hue settings %d\n",
+ ctrl->value);
+ return -ERANGE;
+ }
+
+ state->hue = ctrl->value;
+ err = adv7343_write(sd, ADV7343_SD_HUE_REG, state->hue);
+ break;
+
+ case V4L2_CID_GAIN:
+ if (ctrl->value < ADV7343_GAIN_MIN ||
+ ctrl->value > ADV7343_GAIN_MAX) {
+ v4l2_dbg(1, debug, sd, "invalid gain settings %d\n",
+ ctrl->value);
+ return -ERANGE;
+ }
+
+ if ((ctrl->value > POSITIVE_GAIN_MAX) &&
+ (ctrl->value < NEGATIVE_GAIN_MIN)) {
+ v4l2_dbg(1, debug, sd,
+ "gain settings not within the specified range\n");
+ return -ERANGE;
+ }
+
+ state->gain = ctrl->value;
+ err = adv7343_write(sd, ADV7343_DAC2_OUTPUT_LEVEL, state->gain);
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ if (err < 0)
+ v4l2_err(sd, "Failed to set the encoder controls\n");
+
+ return err;
+}
+
+static int adv7343_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct adv7343_state *state = to_state(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_BRIGHTNESS:
+ ctrl->value = state->bright;
+ break;
+
+ case V4L2_CID_HUE:
+ ctrl->value = state->hue;
+ break;
+
+ case V4L2_CID_GAIN:
+ ctrl->value = state->gain;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int adv7343_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_ADV7343, 0);
+}
+
+static const struct v4l2_subdev_core_ops adv7343_core_ops = {
+ .log_status = adv7343_log_status,
+ .g_chip_ident = adv7343_g_chip_ident,
+ .g_ctrl = adv7343_g_ctrl,
+ .s_ctrl = adv7343_s_ctrl,
+ .queryctrl = adv7343_queryctrl,
+};
+
+static int adv7343_s_std_output(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ struct adv7343_state *state = to_state(sd);
+ int err = 0;
+
+ if (state->std == std)
+ return 0;
+
+ err = adv7343_setstd(sd, std);
+ if (!err)
+ state->std = std;
+
+ return err;
+}
+
+static int adv7343_s_routing(struct v4l2_subdev *sd,
+ u32 input, u32 output, u32 config)
+{
+ struct adv7343_state *state = to_state(sd);
+ int err = 0;
+
+ if (state->output == output)
+ return 0;
+
+ err = adv7343_setoutput(sd, output);
+ if (!err)
+ state->output = output;
+
+ return err;
+}
+
+static const struct v4l2_subdev_video_ops adv7343_video_ops = {
+ .s_std_output = adv7343_s_std_output,
+ .s_routing = adv7343_s_routing,
+};
+
+static const struct v4l2_subdev_ops adv7343_ops = {
+ .core = &adv7343_core_ops,
+ .video = &adv7343_video_ops,
+};
+
+static int adv7343_initialize(struct v4l2_subdev *sd)
+{
+ struct adv7343_state *state = to_state(sd);
+ int err = 0;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(adv7343_init_reg_val); i += 2) {
+
+ err = adv7343_write(sd, adv7343_init_reg_val[i],
+ adv7343_init_reg_val[i+1]);
+ if (err) {
+ v4l2_err(sd, "Error initializing\n");
+ return err;
+ }
+ }
+
+ /* Configure for default video standard */
+ err = adv7343_setoutput(sd, state->output);
+ if (err < 0) {
+ v4l2_err(sd, "Error setting output during init\n");
+ return -EINVAL;
+ }
+
+ err = adv7343_setstd(sd, state->std);
+ if (err < 0) {
+ v4l2_err(sd, "Error setting std during init\n");
+ return -EINVAL;
+ }
+
+ return err;
+}
+
+static int adv7343_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct adv7343_state *state;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ state = kzalloc(sizeof(struct adv7343_state), GFP_KERNEL);
+ if (state == NULL)
+ return -ENOMEM;
+
+ state->reg00 = 0x80;
+ state->reg01 = 0x00;
+ state->reg02 = 0x20;
+ state->reg35 = 0x00;
+ state->reg80 = ADV7343_SD_MODE_REG1_DEFAULT;
+ state->reg82 = ADV7343_SD_MODE_REG2_DEFAULT;
+
+ state->output = ADV7343_COMPOSITE_ID;
+ state->std = V4L2_STD_NTSC;
+
+ v4l2_i2c_subdev_init(&state->sd, client, &adv7343_ops);
+ return adv7343_initialize(&state->sd);
+}
+
+static int adv7343_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(to_state(sd));
+
+ return 0;
+}
+
+static const struct i2c_device_id adv7343_id[] = {
+ {"adv7343", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, adv7343_id);
+
+static struct i2c_driver adv7343_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "adv7343",
+ },
+ .probe = adv7343_probe,
+ .remove = adv7343_remove,
+ .id_table = adv7343_id,
+};
+
+static __init int init_adv7343(void)
+{
+ return i2c_add_driver(&adv7343_driver);
+}
+
+static __exit void exit_adv7343(void)
+{
+ i2c_del_driver(&adv7343_driver);
+}
+
+module_init(init_adv7343);
+module_exit(exit_adv7343);
diff --git a/linux/drivers/media/video/adv7343_regs.h b/linux/drivers/media/video/adv7343_regs.h
new file mode 100644
index 000000000..3431045b3
--- /dev/null
+++ b/linux/drivers/media/video/adv7343_regs.h
@@ -0,0 +1,185 @@
+/*
+ * ADV7343 encoder related structure and register definitions
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef ADV7343_REG_H
+#define ADV7343_REGS_H
+
+struct adv7343_std_info {
+ u32 standard_val3;
+ u32 fsc_val;
+ v4l2_std_id stdid;
+};
+
+/* Register offset macros */
+#define ADV7343_POWER_MODE_REG (0x00)
+#define ADV7343_MODE_SELECT_REG (0x01)
+#define ADV7343_MODE_REG0 (0x02)
+
+#define ADV7343_DAC2_OUTPUT_LEVEL (0x0b)
+
+#define ADV7343_SOFT_RESET (0x17)
+
+#define ADV7343_HD_MODE_REG1 (0x30)
+#define ADV7343_HD_MODE_REG2 (0x31)
+#define ADV7343_HD_MODE_REG3 (0x32)
+#define ADV7343_HD_MODE_REG4 (0x33)
+#define ADV7343_HD_MODE_REG5 (0x34)
+#define ADV7343_HD_MODE_REG6 (0x35)
+
+#define ADV7343_HD_MODE_REG7 (0x39)
+
+#define ADV7343_SD_MODE_REG1 (0x80)
+#define ADV7343_SD_MODE_REG2 (0x82)
+#define ADV7343_SD_MODE_REG3 (0x83)
+#define ADV7343_SD_MODE_REG4 (0x84)
+#define ADV7343_SD_MODE_REG5 (0x86)
+#define ADV7343_SD_MODE_REG6 (0x87)
+#define ADV7343_SD_MODE_REG7 (0x88)
+#define ADV7343_SD_MODE_REG8 (0x89)
+
+#define ADV7343_FSC_REG0 (0x8C)
+#define ADV7343_FSC_REG1 (0x8D)
+#define ADV7343_FSC_REG2 (0x8E)
+#define ADV7343_FSC_REG3 (0x8F)
+
+#define ADV7343_SD_CGMS_WSS0 (0x99)
+
+#define ADV7343_SD_HUE_REG (0xA0)
+#define ADV7343_SD_BRIGHTNESS_WSS (0xA1)
+
+/* Default values for the registers */
+#define ADV7343_POWER_MODE_REG_DEFAULT (0x10)
+#define ADV7343_HD_MODE_REG1_DEFAULT (0x3C) /* Changed Default
+ 720p EAVSAV code*/
+#define ADV7343_HD_MODE_REG2_DEFAULT (0x01) /* Changed Pixel data
+ valid */
+#define ADV7343_HD_MODE_REG3_DEFAULT (0x00) /* Color delay 0 clks */
+#define ADV7343_HD_MODE_REG4_DEFAULT (0xE8) /* Changed */
+#define ADV7343_HD_MODE_REG5_DEFAULT (0x08)
+#define ADV7343_HD_MODE_REG6_DEFAULT (0x00)
+#define ADV7343_HD_MODE_REG7_DEFAULT (0x00)
+#define ADV7343_SD_MODE_REG8_DEFAULT (0x00)
+#define ADV7343_SOFT_RESET_DEFAULT (0x02)
+#define ADV7343_COMPOSITE_POWER_VALUE (0x80)
+#define ADV7343_COMPONENT_POWER_VALUE (0x1C)
+#define ADV7343_SVIDEO_POWER_VALUE (0x60)
+#define ADV7343_SD_HUE_REG_DEFAULT (127)
+#define ADV7343_SD_BRIGHTNESS_WSS_DEFAULT (0x03)
+
+#define ADV7343_SD_CGMS_WSS0_DEFAULT (0x10)
+
+#define ADV7343_SD_MODE_REG1_DEFAULT (0x00)
+#define ADV7343_SD_MODE_REG2_DEFAULT (0xC9)
+#define ADV7343_SD_MODE_REG3_DEFAULT (0x10)
+#define ADV7343_SD_MODE_REG4_DEFAULT (0x01)
+#define ADV7343_SD_MODE_REG5_DEFAULT (0x02)
+#define ADV7343_SD_MODE_REG6_DEFAULT (0x0C)
+#define ADV7343_SD_MODE_REG7_DEFAULT (0x04)
+#define ADV7343_SD_MODE_REG8_DEFAULT (0x00)
+
+/* Bit masks for Mode Select Register */
+#define INPUT_MODE_MASK (0x70)
+#define SD_INPUT_MODE (0x00)
+#define HD_720P_INPUT_MODE (0x10)
+#define HD_1080I_INPUT_MODE (0x10)
+
+/* Bit masks for Mode Register 0 */
+#define TEST_PATTERN_BLACK_BAR_EN (0x04)
+#define YUV_OUTPUT_SELECT (0x20)
+#define RGB_OUTPUT_SELECT (0xDF)
+
+/* Bit masks for DAC output levels */
+#define DAC_OUTPUT_LEVEL_MASK (0xFF)
+#define POSITIVE_GAIN_MAX (0x40)
+#define POSITIVE_GAIN_MIN (0x00)
+#define NEGATIVE_GAIN_MAX (0xFF)
+#define NEGATIVE_GAIN_MIN (0xC0)
+
+/* Bit masks for soft reset register */
+#define SOFT_RESET (0x02)
+
+/* Bit masks for HD Mode Register 1 */
+#define OUTPUT_STD_MASK (0x03)
+#define OUTPUT_STD_SHIFT (0)
+#define OUTPUT_STD_EIA0_2 (0x00)
+#define OUTPUT_STD_EIA0_1 (0x01)
+#define OUTPUT_STD_FULL (0x02)
+#define EMBEDDED_SYNC (0x04)
+#define EXTERNAL_SYNC (0xFB)
+#define STD_MODE_SHIFT (3)
+#define STD_MODE_MASK (0x1F)
+#define STD_MODE_720P (0x05)
+#define STD_MODE_720P_25 (0x08)
+#define STD_MODE_720P_30 (0x07)
+#define STD_MODE_720P_50 (0x06)
+#define STD_MODE_1080I (0x0D)
+#define STD_MODE_1080I_25fps (0x0E)
+#define STD_MODE_1080P_24 (0x12)
+#define STD_MODE_1080P_25 (0x10)
+#define STD_MODE_1080P_30 (0x0F)
+#define STD_MODE_525P (0x00)
+#define STD_MODE_625P (0x03)
+
+/* Bit masks for SD Mode Register 1 */
+#define SD_STD_MASK (0x03)
+#define SD_STD_NTSC (0x00)
+#define SD_STD_PAL_BDGHI (0x01)
+#define SD_STD_PAL_M (0x02)
+#define SD_STD_PAL_N (0x03)
+#define SD_LUMA_FLTR_MASK (0x7)
+#define SD_LUMA_FLTR_SHIFT (0x2)
+#define SD_CHROMA_FLTR_MASK (0x7)
+#define SD_CHROMA_FLTR_SHIFT (0x5)
+
+/* Bit masks for SD Mode Register 2 */
+#define SD_PBPR_SSAF_EN (0x01)
+#define SD_PBPR_SSAF_DI (0xFE)
+#define SD_DAC_1_DI (0xFD)
+#define SD_DAC_2_DI (0xFB)
+#define SD_PEDESTAL_EN (0x08)
+#define SD_PEDESTAL_DI (0xF7)
+#define SD_SQUARE_PIXEL_EN (0x10)
+#define SD_SQUARE_PIXEL_DI (0xEF)
+#define SD_PIXEL_DATA_VALID (0x40)
+#define SD_ACTIVE_EDGE_EN (0x80)
+#define SD_ACTIVE_EDGE_DI (0x7F)
+
+/* Bit masks for HD Mode Register 6 */
+#define HD_RGB_INPUT_EN (0x02)
+#define HD_RGB_INPUT_DI (0xFD)
+#define HD_PBPR_SYNC_EN (0x04)
+#define HD_PBPR_SYNC_DI (0xFB)
+#define HD_DAC_SWAP_EN (0x08)
+#define HD_DAC_SWAP_DI (0xF7)
+#define HD_GAMMA_CURVE_A (0xEF)
+#define HD_GAMMA_CURVE_B (0x10)
+#define HD_GAMMA_EN (0x20)
+#define HD_GAMMA_DI (0xDF)
+#define HD_ADPT_FLTR_MODEB (0x40)
+#define HD_ADPT_FLTR_MODEA (0xBF)
+#define HD_ADPT_FLTR_EN (0x80)
+#define HD_ADPT_FLTR_DI (0x7F)
+
+#define ADV7343_BRIGHTNESS_MAX (127)
+#define ADV7343_BRIGHTNESS_MIN (0)
+#define ADV7343_BRIGHTNESS_DEF (3)
+#define ADV7343_HUE_MAX (255)
+#define ADV7343_HUE_MIN (0)
+#define ADV7343_HUE_DEF (127)
+#define ADV7343_GAIN_MAX (255)
+#define ADV7343_GAIN_MIN (0)
+#define ADV7343_GAIN_DEF (0)
+
+#endif
diff --git a/linux/drivers/media/video/au0828/au0828-cards.c b/linux/drivers/media/video/au0828/au0828-cards.c
index 053bbe8c8..830c4a933 100644
--- a/linux/drivers/media/video/au0828/au0828-cards.c
+++ b/linux/drivers/media/video/au0828/au0828-cards.c
@@ -136,9 +136,9 @@ int au0828_tuner_callback(void *priv, int component, int command, int arg)
/* Tuner Reset Command from xc5000 */
/* Drive the tuner into reset and out */
au0828_clear(dev, REG_001, 2);
- mdelay(200);
+ mdelay(10);
au0828_set(dev, REG_001, 2);
- mdelay(50);
+ mdelay(10);
return 0;
} else {
printk(KERN_ERR
diff --git a/linux/drivers/media/video/au0828/au0828-video.c b/linux/drivers/media/video/au0828/au0828-video.c
index 8bc0f0481..ef44aa831 100644
--- a/linux/drivers/media/video/au0828/au0828-video.c
+++ b/linux/drivers/media/video/au0828/au0828-video.c
@@ -834,6 +834,9 @@ static int au0828_v4l2_close(struct file *filp)
au0828_uninit_isoc(dev);
+ /* Save some power by putting tuner to sleep */
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_standby);
+
/* When close the device, set the usb intf0 into alt0 to free
USB bandwidth */
ret = usb_set_interface(dev->usbdev, 0, 0);
@@ -915,11 +918,6 @@ static int au0828_v4l2_mmap(struct file *filp, struct vm_area_struct *vma)
rc = videobuf_mmap_mapper(&fh->vb_vidq, vma);
- dprintk(2, "vma start=0x%08lx, size=%ld, ret=%d\n",
- (unsigned long)vma->vm_start,
- (unsigned long)vma->vm_end-(unsigned long)vma->vm_start,
- rc);
-
return rc;
}
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c
index 622807b54..8d2075186 100644
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c
@@ -4198,7 +4198,6 @@ static struct video_device *vdev_init(struct bttv *btv,
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
vfd->v4l2_dev = &btv->c.v4l2_dev;
vfd->release = video_device_release;
vfd->debug = bttv_debug;
diff --git a/linux/drivers/media/video/bt8xx/bttv-i2c.c b/linux/drivers/media/video/bt8xx/bttv-i2c.c
index bf94551c3..31f2f07d9 100644
--- a/linux/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c
@@ -405,6 +405,27 @@ int __devinit init_bttv_i2c(struct bttv *btv)
}
if (0 == btv->i2c_rc && i2c_scan)
do_i2c_scan(btv->c.v4l2_dev.name, &btv->i2c_client);
+
+ /* Instantiate the IR receiver device, if present */
+ if (0 == btv->i2c_rc) {
+ struct i2c_board_info info;
+ /* The external IR receiver is at i2c address 0x34 (0x35 for
+ reads). Future Hauppauge cards will have an internal
+ receiver at 0x30 (0x31 for reads). In theory, both can be
+ fitted, and Hauppauge suggest an external overrides an
+ internal.
+
+ That's why we probe 0x1a (~0x34) first. CB
+ */
+ const unsigned short addr_list[] = {
+ 0x1a, 0x18, 0x4b, 0x64, 0x30,
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&btv->c.i2c_adap, &info, addr_list);
+ }
return btv->i2c_rc;
}
diff --git a/linux/drivers/media/video/cpia2/cpia2_v4l.c b/linux/drivers/media/video/cpia2/cpia2_v4l.c
index d4099f531..0b4a8f309 100644
--- a/linux/drivers/media/video/cpia2/cpia2_v4l.c
+++ b/linux/drivers/media/video/cpia2/cpia2_v4l.c
@@ -1064,7 +1064,7 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
switch(m->id) {
case CPIA2_CID_FLICKER_MODE:
- if(m->index < 0 || m->index >= NUM_FLICKER_CONTROLS)
+ if (m->index >= NUM_FLICKER_CONTROLS)
return -EINVAL;
strcpy(m->name, flicker_controls[m->index].name);
@@ -1082,14 +1082,14 @@ static int ioctl_querymenu(void *arg,struct camera_data *cam)
maximum = i;
}
}
- if(m->index < 0 || m->index > maximum)
+ if (m->index > maximum)
return -EINVAL;
strcpy(m->name, framerate_controls[m->index].name);
break;
}
case CPIA2_CID_LIGHTS:
- if(m->index < 0 || m->index >= NUM_LIGHTS_CONTROLS)
+ if (m->index >= NUM_LIGHTS_CONTROLS)
return -EINVAL;
strcpy(m->name, lights_controls[m->index].name);
diff --git a/linux/drivers/media/video/cx18/cx18-driver.c b/linux/drivers/media/video/cx18/cx18-driver.c
index 41997dd18..f42a97314 100644
--- a/linux/drivers/media/video/cx18/cx18-driver.c
+++ b/linux/drivers/media/video/cx18/cx18-driver.c
@@ -313,7 +313,7 @@ static void cx18_process_eeprom(struct cx18 *cx)
CX18_INFO("Autodetected %s\n", cx->card_name);
if (tv.tuner_type == TUNER_ABSENT)
- CX18_ERR("tveeprom cannot autodetect tuner!");
+ CX18_ERR("tveeprom cannot autodetect tuner!\n");
if (cx->options.tuner == -1)
cx->options.tuner = tv.tuner_type;
diff --git a/linux/drivers/media/video/cx231xx/cx231xx-cards.c b/linux/drivers/media/video/cx231xx/cx231xx-cards.c
index af6169516..68f92da9e 100644
--- a/linux/drivers/media/video/cx231xx/cx231xx-cards.c
+++ b/linux/drivers/media/video/cx231xx/cx231xx-cards.c
@@ -282,12 +282,12 @@ static void cx231xx_config_tuner(struct cx231xx *dev)
}
/* ----------------------------------------------------------------------- */
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir)
+void cx231xx_register_i2c_ir(struct cx231xx *dev)
{
- if (disable_ir) {
- ir->get_key = NULL;
+ if (disable_ir)
return;
- }
+
+ /* REVISIT: instantiate IR device */
/* detect & configure */
switch (dev->model) {
diff --git a/linux/drivers/media/video/cx231xx/cx231xx-i2c.c b/linux/drivers/media/video/cx231xx/cx231xx-i2c.c
index d196fe666..e71005c59 100644
--- a/linux/drivers/media/video/cx231xx/cx231xx-i2c.c
+++ b/linux/drivers/media/video/cx231xx/cx231xx-i2c.c
@@ -424,34 +424,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
}
-/*
- * attach_inform()
- * gets called when a device attaches to the i2c bus
- * does some basic configuration
- */
-static int attach_inform(struct i2c_client *client)
-{
- struct cx231xx_i2c *bus = i2c_get_adapdata(client->adapter);
- struct cx231xx *dev = bus->dev;
-
- switch (client->addr << 1) {
- case 0x8e:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- dprintk1(1, "attach_inform: IR detected (%s).\n",
- ir->phys);
- cx231xx_set_ir(dev, ir);
- break;
- }
- break;
-
- default:
- break;
- }
-
- return 0;
-}
-
static struct i2c_algorithm cx231xx_algo = {
.master_xfer = cx231xx_i2c_xfer,
.functionality = functionality,
@@ -465,7 +437,6 @@ static struct i2c_adapter cx231xx_adap_template = {
.name = "cx231xx",
.id = I2C_HW_B_CX231XX,
.algo = &cx231xx_algo,
- .client_register = attach_inform,
};
static struct i2c_client cx231xx_client_template = {
@@ -540,6 +511,9 @@ int cx231xx_i2c_register(struct cx231xx_i2c *bus)
if (0 == bus->i2c_rc) {
if (i2c_scan)
cx231xx_do_i2c_scan(dev, &bus->i2c_client);
+
+ /* Instantiate the IR receiver device, if present */
+ cx231xx_register_i2c_ir(dev);
} else
cx231xx_warn("%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
diff --git a/linux/drivers/media/video/cx231xx/cx231xx-input.c b/linux/drivers/media/video/cx231xx/cx231xx-input.c
index 04d954cca..3171b0177 100644
--- a/linux/drivers/media/video/cx231xx/cx231xx-input.c
+++ b/linux/drivers/media/video/cx231xx/cx231xx-input.c
@@ -37,7 +37,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define i2cdprintk(fmt, arg...) \
if (ir_debug) { \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
}
#define dprintk(fmt, arg...) \
diff --git a/linux/drivers/media/video/cx231xx/cx231xx.h b/linux/drivers/media/video/cx231xx/cx231xx.h
index 21b4023dd..d3c05186e 100644
--- a/linux/drivers/media/video/cx231xx/cx231xx.h
+++ b/linux/drivers/media/video/cx231xx/cx231xx.h
@@ -747,7 +747,7 @@ extern void cx231xx_card_setup(struct cx231xx *dev);
extern struct cx231xx_board cx231xx_boards[];
extern struct usb_device_id cx231xx_id_table[];
extern const unsigned int cx231xx_bcount;
-void cx231xx_set_ir(struct cx231xx *dev, struct IR_i2c *ir);
+void cx231xx_register_i2c_ir(struct cx231xx *dev);
int cx231xx_tuner_callback(void *ptr, int component, int command, int arg);
/* Provided by cx231xx-input.c */
diff --git a/linux/drivers/media/video/cx23885/cimax2.c b/linux/drivers/media/video/cx23885/cimax2.c
index 0e29f97f3..fed6d9f9f 100644
--- a/linux/drivers/media/video/cx23885/cimax2.c
+++ b/linux/drivers/media/video/cx23885/cimax2.c
@@ -320,7 +320,7 @@ static void netup_read_ci_status(struct work_struct *work)
"TS config = %02x\n", __func__, state->ci_i2c_addr, 0, buf[0],
buf[32]);
- if (buf[0] && 1)
+ if (buf[0] & 1)
state->status = DVB_CA_EN50221_POLL_CAM_PRESENT |
DVB_CA_EN50221_POLL_CAM_READY;
else
diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c
index 574cdb385..9974d9a78 100644
--- a/linux/drivers/media/video/cx23885/cx23885-417.c
+++ b/linux/drivers/media/video/cx23885/cx23885-417.c
@@ -1749,7 +1749,6 @@ static struct video_device *cx23885_video_dev_alloc(
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)", dev->name,
type, cx23885_boards[tsport->dev->board].name);
vfd->parent = &pci->dev;
diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c
index 28f305dfd..93176fe4b 100644
--- a/linux/drivers/media/video/cx23885/cx23885-cards.c
+++ b/linux/drivers/media/video/cx23885/cx23885-cards.c
@@ -182,6 +182,22 @@ struct cx23885_board cx23885_boards[] = {
.portb = CX23885_MPEG_DVB,
.portc = CX23885_MPEG_DVB,
},
+ [CX23885_BOARD_HAUPPAUGE_HVR1270] = {
+ .name = "Hauppauge WinTV-HVR1270",
+ .portc = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_HAUPPAUGE_HVR1275] = {
+ .name = "Hauppauge WinTV-HVR1275",
+ .portc = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_HAUPPAUGE_HVR1255] = {
+ .name = "Hauppauge WinTV-HVR1255",
+ .portc = CX23885_MPEG_DVB,
+ },
+ [CX23885_BOARD_HAUPPAUGE_HVR1210] = {
+ .name = "Hauppauge WinTV-HVR1210",
+ .portc = CX23885_MPEG_DVB,
+ },
};
const unsigned int cx23885_bcount = ARRAY_SIZE(cx23885_boards);
@@ -281,6 +297,26 @@ struct cx23885_subid cx23885_subids[] = {
.subvendor = 0x1b55,
.subdevice = 0x2a2c,
.card = CX23885_BOARD_NETUP_DUAL_DVBS2_CI,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x2211,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1270,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x2215,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1275,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x2251,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1255,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x2291,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
+ }, {
+ .subvendor = 0x0070,
+ .subdevice = 0x2295,
+ .card = CX23885_BOARD_HAUPPAUGE_HVR1210,
},
};
const unsigned int cx23885_idcount = ARRAY_SIZE(cx23885_subids);
@@ -322,6 +358,42 @@ static void hauppauge_eeprom(struct cx23885_dev *dev, u8 *eeprom_data)
/* Make sure we support the board model */
switch (tv.model) {
+ case 22001:
+ /* WinTV-HVR1270 (PCIe, Retail, half height)
+ * ATSC/QAM and basic analog, IR Blast */
+ case 22009:
+ /* WinTV-HVR1210 (PCIe, Retail, half height)
+ * DVB-T and basic analog, IR Blast */
+ case 22011:
+ /* WinTV-HVR1270 (PCIe, Retail, half height)
+ * ATSC/QAM and basic analog, IR Recv */
+ case 22019:
+ /* WinTV-HVR1210 (PCIe, Retail, half height)
+ * DVB-T and basic analog, IR Recv */
+ case 22021:
+ /* WinTV-HVR1275 (PCIe, Retail, half height)
+ * ATSC/QAM and basic analog, IR Recv */
+ case 22029:
+ /* WinTV-HVR1210 (PCIe, Retail, half height)
+ * DVB-T and basic analog, IR Recv */
+ case 22101:
+ /* WinTV-HVR1270 (PCIe, Retail, full height)
+ * ATSC/QAM and basic analog, IR Blast */
+ case 22109:
+ /* WinTV-HVR1210 (PCIe, Retail, full height)
+ * DVB-T and basic analog, IR Blast */
+ case 22111:
+ /* WinTV-HVR1270 (PCIe, Retail, full height)
+ * ATSC/QAM and basic analog, IR Recv */
+ case 22119:
+ /* WinTV-HVR1210 (PCIe, Retail, full height)
+ * DVB-T and basic analog, IR Recv */
+ case 22121:
+ /* WinTV-HVR1275 (PCIe, Retail, full height)
+ * ATSC/QAM and basic analog, IR Recv */
+ case 22129:
+ /* WinTV-HVR1210 (PCIe, Retail, full height)
+ * DVB-T and basic analog, IR Recv */
case 71009:
/* WinTV-HVR1200 (PCIe, Retail, full height)
* DVB-T and basic analog */
@@ -620,6 +692,21 @@ void cx23885_gpio_setup(struct cx23885_dev *dev)
/* enable irq */
cx_write(GPIO_ISM, 0x00000000);/* INTERRUPTS active low*/
break;
+ case CX23885_BOARD_HAUPPAUGE_HVR1270:
+ case CX23885_BOARD_HAUPPAUGE_HVR1275:
+ case CX23885_BOARD_HAUPPAUGE_HVR1255:
+ case CX23885_BOARD_HAUPPAUGE_HVR1210:
+ /* GPIO-5 RF Control: 0 = RF1 Terrestrial, 1 = RF2 Cable */
+ /* GPIO-6 I2C Gate which can isolate the demod from the bus */
+ /* GPIO-9 Demod reset */
+
+ /* Put the parts into reset and back */
+ cx23885_gpio_enable(dev, GPIO_9 | GPIO_6 | GPIO_5, 1);
+ cx23885_gpio_set(dev, GPIO_9 | GPIO_6 | GPIO_5);
+ cx23885_gpio_clear(dev, GPIO_9);
+ mdelay(20);
+ cx23885_gpio_set(dev, GPIO_9);
+ break;
}
}
@@ -632,6 +719,10 @@ int cx23885_ir_init(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1800:
case CX23885_BOARD_HAUPPAUGE_HVR1200:
case CX23885_BOARD_HAUPPAUGE_HVR1400:
+ case CX23885_BOARD_HAUPPAUGE_HVR1270:
+ case CX23885_BOARD_HAUPPAUGE_HVR1275:
+ case CX23885_BOARD_HAUPPAUGE_HVR1255:
+ case CX23885_BOARD_HAUPPAUGE_HVR1210:
/* FIXME: Implement me */
break;
case CX23885_BOARD_DVICO_FUSIONHDTV_DVB_T_DUAL_EXP:
@@ -667,6 +758,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1800lp:
case CX23885_BOARD_HAUPPAUGE_HVR1200:
case CX23885_BOARD_HAUPPAUGE_HVR1700:
+ case CX23885_BOARD_HAUPPAUGE_HVR1270:
+ case CX23885_BOARD_HAUPPAUGE_HVR1275:
+ case CX23885_BOARD_HAUPPAUGE_HVR1255:
+ case CX23885_BOARD_HAUPPAUGE_HVR1210:
if (dev->i2c_bus[0].i2c_rc == 0)
hauppauge_eeprom(dev, eeprom+0xc0);
break;
@@ -724,6 +819,10 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_HAUPPAUGE_HVR1400:
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
+ case CX23885_BOARD_HAUPPAUGE_HVR1270:
+ case CX23885_BOARD_HAUPPAUGE_HVR1275:
+ case CX23885_BOARD_HAUPPAUGE_HVR1255:
+ case CX23885_BOARD_HAUPPAUGE_HVR1210:
default:
ts2->gen_ctrl_val = 0xc; /* Serial bus + punctured clock */
ts2->ts_clk_en_val = 0x1; /* Enable TS_CLK */
diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c
index 48f777b99..6988361c9 100644
--- a/linux/drivers/media/video/cx23885/cx23885-core.c
+++ b/linux/drivers/media/video/cx23885/cx23885-core.c
@@ -1744,6 +1744,88 @@ out:
return IRQ_RETVAL(handled);
}
+static inline int encoder_on_portb(struct cx23885_dev *dev)
+{
+ return cx23885_boards[dev->board].portb == CX23885_MPEG_ENCODER;
+}
+
+static inline int encoder_on_portc(struct cx23885_dev *dev)
+{
+ return cx23885_boards[dev->board].portc == CX23885_MPEG_ENCODER;
+}
+
+/* Mask represents 32 different GPIOs, GPIO's are split into multiple
+ * registers depending on the board configuration (and whether the
+ * 417 encoder (wi it's own GPIO's) are present. Each GPIO bit will
+ * be pushed into the correct hardware register, regardless of the
+ * physical location. Certain registers are shared so we sanity check
+ * and report errors if we think we're tampering with a GPIo that might
+ * be assigned to the encoder (and used for the host bus).
+ *
+ * GPIO 2 thru 0 - On the cx23885 bridge
+ * GPIO 18 thru 3 - On the cx23417 host bus interface
+ * GPIO 23 thru 19 - On the cx25840 a/v core
+ */
+void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask)
+{
+ if (mask & 0x7)
+ cx_set(GP0_IO, mask & 0x7);
+
+ if (mask & 0x0007fff8) {
+ if (encoder_on_portb(dev) || encoder_on_portc(dev))
+ printk(KERN_ERR
+ "%s: Setting GPIO on encoder ports\n",
+ dev->name);
+ cx_set(MC417_RWD, (mask & 0x0007fff8) >> 3);
+ }
+
+ /* TODO: 23-19 */
+ if (mask & 0x00f80000)
+ printk(KERN_INFO "%s: Unsupported\n", dev->name);
+}
+
+void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask)
+{
+ if (mask & 0x00000007)
+ cx_clear(GP0_IO, mask & 0x7);
+
+ if (mask & 0x0007fff8) {
+ if (encoder_on_portb(dev) || encoder_on_portc(dev))
+ printk(KERN_ERR
+ "%s: Clearing GPIO moving on encoder ports\n",
+ dev->name);
+ cx_clear(MC417_RWD, (mask & 0x7fff8) >> 3);
+ }
+
+ /* TODO: 23-19 */
+ if (mask & 0x00f80000)
+ printk(KERN_INFO "%s: Unsupported\n", dev->name);
+}
+
+void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask, int asoutput)
+{
+ if ((mask & 0x00000007) && asoutput)
+ cx_set(GP0_IO, (mask & 0x7) << 16);
+ else if ((mask & 0x00000007) && !asoutput)
+ cx_clear(GP0_IO, (mask & 0x7) << 16);
+
+ if (mask & 0x0007fff8) {
+ if (encoder_on_portb(dev) || encoder_on_portc(dev))
+ printk(KERN_ERR
+ "%s: Enabling GPIO on encoder ports\n",
+ dev->name);
+ }
+
+ /* MC417_OEN is active low for output, write 1 for an input */
+ if ((mask & 0x0007fff8) && asoutput)
+ cx_clear(MC417_OEN, (mask & 0x7fff8) >> 3);
+
+ else if ((mask & 0x0007fff8) && !asoutput)
+ cx_set(MC417_OEN, (mask & 0x7fff8) >> 3);
+
+ /* TODO: 23-19 */
+}
+
static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
const struct pci_device_id *pci_id)
{
diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c
index eb3293789..4efc7dee1 100644
--- a/linux/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c
@@ -52,6 +52,7 @@
#include "cimax2.h"
#include "netup-eeprom.h"
#include "netup-init.h"
+#include "lgdt3305.h"
static unsigned int debug;
@@ -124,7 +125,20 @@ static struct tda10048_config hauppauge_hvr1200_config = {
.output_mode = TDA10048_SERIAL_OUTPUT,
.fwbulkwritelen = TDA10048_BULKWRITE_200,
.inversion = TDA10048_INVERSION_ON,
- .if_freq_khz = TDA10048_IF_4300,
+ .dtv6_if_freq_khz = TDA10048_IF_3300,
+ .dtv7_if_freq_khz = TDA10048_IF_3800,
+ .dtv8_if_freq_khz = TDA10048_IF_4300,
+ .clk_freq_khz = TDA10048_CLK_16000,
+};
+
+static struct tda10048_config hauppauge_hvr1210_config = {
+ .demod_address = 0x10 >> 1,
+ .output_mode = TDA10048_SERIAL_OUTPUT,
+ .fwbulkwritelen = TDA10048_BULKWRITE_200,
+ .inversion = TDA10048_INVERSION_ON,
+ .dtv6_if_freq_khz = TDA10048_IF_3300,
+ .dtv7_if_freq_khz = TDA10048_IF_3500,
+ .dtv8_if_freq_khz = TDA10048_IF_4000,
.clk_freq_khz = TDA10048_CLK_16000,
};
@@ -197,6 +211,16 @@ static struct s5h1411_config dvico_s5h1411_config = {
.mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
};
+static struct s5h1411_config hcw_s5h1411_config = {
+ .output_mode = S5H1411_SERIAL_OUTPUT,
+ .gpio = S5H1411_GPIO_OFF,
+ .vsb_if = S5H1411_IF_44000,
+ .qam_if = S5H1411_IF_4000,
+ .inversion = S5H1411_INVERSION_ON,
+ .status_mode = S5H1411_DEMODLOCKING,
+ .mpeg_timing = S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
+};
+
static struct xc5000_config hauppauge_hvr1500q_tunerconfig = {
.i2c_address = 0x61,
.if_khz = 5380,
@@ -227,6 +251,32 @@ static struct tda18271_config hauppauge_hvr1200_tuner_config = {
.gate = TDA18271_GATE_ANALOG,
};
+static struct tda18271_config hauppauge_hvr1210_tuner_config = {
+ .gate = TDA18271_GATE_DIGITAL,
+};
+
+static struct tda18271_std_map hauppauge_hvr127x_std_map = {
+ .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
+ .if_lvl = 1, .rfagc_top = 0x58 },
+ .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 5,
+ .if_lvl = 1, .rfagc_top = 0x58 },
+};
+
+static struct tda18271_config hauppauge_hvr127x_config = {
+ .std_map = &hauppauge_hvr127x_std_map,
+};
+
+static struct lgdt3305_config hauppauge_lgdt3305_config = {
+ .i2c_addr = 0x0e,
+ .mpeg_mode = LGDT3305_MPEG_SERIAL,
+ .tpclk_edge = LGDT3305_TPCLK_FALLING_EDGE,
+ .tpvalid_polarity = LGDT3305_TP_VALID_HIGH,
+ .deny_i2c_rptr = 1,
+ .spectral_inversion = 1,
+ .qam_if_khz = 4000,
+ .vsb_if_khz = 3250,
+};
+
static struct dibx000_agc_config xc3028_agc_config = {
BAND_VHF | BAND_UHF, /* band_caps */
@@ -399,6 +449,29 @@ static int dvb_register(struct cx23885_tsport *port)
&hauppauge_generic_tunerconfig, 0);
}
break;
+ case CX23885_BOARD_HAUPPAUGE_HVR1270:
+ case CX23885_BOARD_HAUPPAUGE_HVR1275:
+ i2c_bus = &dev->i2c_bus[0];
+ fe0->dvb.frontend = dvb_attach(lgdt3305_attach,
+ &hauppauge_lgdt3305_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_bus[1].i2c_adap,
+ &hauppauge_hvr127x_config);
+ }
+ break;
+ case CX23885_BOARD_HAUPPAUGE_HVR1255:
+ i2c_bus = &dev->i2c_bus[0];
+ fe0->dvb.frontend = dvb_attach(s5h1411_attach,
+ &hcw_s5h1411_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_bus[1].i2c_adap,
+ &hauppauge_tda18271_config);
+ }
+ break;
case CX23885_BOARD_HAUPPAUGE_HVR1800:
i2c_bus = &dev->i2c_bus[0];
switch (alt_tuner) {
@@ -499,6 +572,17 @@ static int dvb_register(struct cx23885_tsport *port)
&hauppauge_hvr1200_tuner_config);
}
break;
+ case CX23885_BOARD_HAUPPAUGE_HVR1210:
+ i2c_bus = &dev->i2c_bus[0];
+ fe0->dvb.frontend = dvb_attach(tda10048_attach,
+ &hauppauge_hvr1210_config,
+ &i2c_bus->i2c_adap);
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_bus[1].i2c_adap,
+ &hauppauge_hvr1210_tuner_config);
+ }
+ break;
case CX23885_BOARD_HAUPPAUGE_HVR1400:
i2c_bus = &dev->i2c_bus[0];
fe0->dvb.frontend = dvb_attach(dib7000p_attach,
diff --git a/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c
index a5d9f7530..4369470a3 100644
--- a/linux/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c
@@ -364,6 +364,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
+ /* Instantiate the IR receiver device, if present */
+ if (0 == bus->i2c_rc) {
+ struct i2c_board_info info;
+ const unsigned short addr_list[] = {
+ 0x6b, I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&bus->i2c_adap, &info, addr_list);
+ }
+
return bus->i2c_rc;
}
diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h
index 92828c9ce..8dba2fdd6 100644
--- a/linux/drivers/media/video/cx23885/cx23885.h
+++ b/linux/drivers/media/video/cx23885/cx23885.h
@@ -72,6 +72,21 @@
#define CX23885_BOARD_TEVII_S470 15
#define CX23885_BOARD_DVBWORLD_2005 16
#define CX23885_BOARD_NETUP_DUAL_DVBS2_CI 17
+#define CX23885_BOARD_HAUPPAUGE_HVR1270 18
+#define CX23885_BOARD_HAUPPAUGE_HVR1275 19
+#define CX23885_BOARD_HAUPPAUGE_HVR1255 20
+#define CX23885_BOARD_HAUPPAUGE_HVR1210 21
+
+#define GPIO_0 0x00000001
+#define GPIO_1 0x00000002
+#define GPIO_2 0x00000004
+#define GPIO_3 0x00000008
+#define GPIO_4 0x00000010
+#define GPIO_5 0x00000020
+#define GPIO_6 0x00000040
+#define GPIO_7 0x00000080
+#define GPIO_8 0x00000100
+#define GPIO_9 0x00000200
/* Currently unsupported by the driver: PAL/H, NTSC/Kr, SECAM B/G/H/LC */
#define CX23885_NORMS (\
@@ -423,6 +438,11 @@ extern int cx23885_restart_queue(struct cx23885_tsport *port,
extern void cx23885_wakeup(struct cx23885_tsport *port,
struct cx23885_dmaqueue *q, u32 count);
+extern void cx23885_gpio_set(struct cx23885_dev *dev, u32 mask);
+extern void cx23885_gpio_clear(struct cx23885_dev *dev, u32 mask);
+extern void cx23885_gpio_enable(struct cx23885_dev *dev, u32 mask,
+ int asoutput);
+
/* ----------------------------------------------------------- */
/* cx23885-cards.c */
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index c9bfa835e..546793c02 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -2735,10 +2735,22 @@ static int cx88_xc5000_tuner_callback(struct cx88_core *core,
switch (core->boardnr) {
case CX88_BOARD_PINNACLE_PCTV_HD_800i:
if (command == 0) { /* This is the reset command from xc5000 */
- /* Reset XC5000 tuner via SYS_RSTO_pin */
- cx_write(MO_SRST_IO, 0);
- msleep(10);
- cx_write(MO_SRST_IO, 1);
+
+ /* djh - According to the engineer at PCTV Systems,
+ the xc5000 reset pin is supposed to be on GPIO12.
+ However, despite three nights of effort, pulling
+ that GPIO low didn't reset the xc5000. While
+ pulling MO_SRST_IO low does reset the xc5000, this
+ also resets in the s5h1409 being reset as well.
+ This causes tuning to always fail since the internal
+ state of the s5h1409 does not match the driver's
+ state. Given that the only two conditions in which
+ the driver performs a reset is during firmware load
+ and powering down the chip, I am taking out the
+ reset. We know that the chip is being reset
+ when the cx88 comes online, and not being able to
+ do power management for this board is worse than
+ not having any tuning at all. */
return 0;
} else {
err_printk(core, "xc5000: unknown tuner "
diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c
index 39cbd152a..fddba2d51 100644
--- a/linux/drivers/media/video/cx88/cx88-core.c
+++ b/linux/drivers/media/video/cx88/cx88-core.c
@@ -1057,7 +1057,6 @@ struct video_device *cx88_vdev_init(struct cx88_core *core,
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
vfd->v4l2_dev = &core->v4l2_dev;
vfd->parent = &pci->dev;
vfd->release = video_device_release;
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index 680a8c889..dbd629511 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -186,6 +186,19 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
do_i2c_scan(core->name,&core->i2c_client);
} else
printk("%s: i2c register FAILED\n", core->name);
+
+ /* Instantiate the IR receiver device, if present */
+ if (0 == core->i2c_rc) {
+ struct i2c_board_info info;
+ const unsigned short addr_list[] = {
+ 0x18, 0x6b, 0x71,
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&core->i2c_adap, &info, addr_list);
+ }
return core->i2c_rc;
}
diff --git a/linux/drivers/media/video/cx88/cx88-input.c b/linux/drivers/media/video/cx88/cx88-input.c
index facb2e800..dad809335 100644
--- a/linux/drivers/media/video/cx88/cx88-input.c
+++ b/linux/drivers/media/video/cx88/cx88-input.c
@@ -92,6 +92,7 @@ static void cx88_ir_handle_key(struct cx88_IR *ir)
gpio=(gpio & 0x7fd) + (auxgpio & 0xef);
break;
case CX88_BOARD_WINFAST_DTV1000:
+ case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
gpio = (gpio & 0x6ff) | ((cx_read(MO_GP1_IO) << 8) & 0x900);
auxgpio = gpio;
break;
@@ -244,6 +245,7 @@ int cx88_ir_init(struct cx88_core *core, struct pci_dev *pci)
break;
case CX88_BOARD_WINFAST2000XP_EXPERT:
case CX88_BOARD_WINFAST_DTV1000:
+ case CX88_BOARD_WINFAST_TV2000_XP_GLOBAL:
ir_codes = ir_codes_winfast;
ir->gpio_addr = MO_GP0_IO;
ir->mask_keycode = 0x8f8;
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c
index 88a326f61..2dfa4c9c3 100644
--- a/linux/drivers/media/video/cx88/cx88-video.c
+++ b/linux/drivers/media/video/cx88/cx88-video.c
@@ -1152,8 +1152,10 @@ static int video_release(struct file *file)
file->private_data = NULL;
kfree(fh);
+ mutex_lock(&dev->core->lock);
if(atomic_dec_and_test(&dev->core->users))
call_all(dev->core, tuner, s_standby);
+ mutex_unlock(&dev->core->lock);
return 0;
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c
index fb83e4f6e..c765d769b 100644
--- a/linux/drivers/media/video/em28xx/em28xx-cards.c
+++ b/linux/drivers/media/video/em28xx/em28xx-cards.c
@@ -153,6 +153,16 @@ static struct em28xx_reg_seq compro_mute_gpio[] = {
{ -1, -1, -1, -1},
};
+/* Terratec AV350 */
+static struct em28xx_reg_seq terratec_av350_mute_gpio[] = {
+ {EM28XX_R08_GPIO, 0xff, 0x7f, 10},
+ { -1, -1, -1, -1},
+};
+
+static struct em28xx_reg_seq terratec_av350_unmute_gpio[] = {
+ {EM28XX_R08_GPIO, 0xff, 0xff, 10},
+ { -1, -1, -1, -1},
+};
/*
* Board definitions
*/
@@ -1412,6 +1422,42 @@ struct em28xx_board em28xx_boards[] = {
.amux = EM28XX_AMUX_VIDEO,
} },
},
+ [EM2860_BOARD_TERRATEC_GRABBY] = {
+ .name = "Terratec Grabby",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_SAA711X,
+ .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = SAA7115_COMPOSITE0,
+ .amux = EM28XX_AMUX_VIDEO2,
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = SAA7115_SVIDEO3,
+ .amux = EM28XX_AMUX_VIDEO2,
+ } },
+ },
+ [EM2860_BOARD_TERRATEC_AV350] = {
+ .name = "Terratec AV350",
+ .vchannels = 2,
+ .tuner_type = TUNER_ABSENT,
+ .decoder = EM28XX_TVP5150,
+ .xclk = EM28XX_XCLK_FREQUENCY_12MHZ,
+ .mute_gpio = terratec_av350_mute_gpio,
+ .input = { {
+ .type = EM28XX_VMUX_COMPOSITE1,
+ .vmux = TVP5150_COMPOSITE1,
+ .amux = EM28XX_AUDIO_SRC_LINE,
+ .gpio = terratec_av350_unmute_gpio,
+
+ }, {
+ .type = EM28XX_VMUX_SVIDEO,
+ .vmux = TVP5150_SVIDEO,
+ .amux = EM28XX_AUDIO_SRC_LINE,
+ .gpio = terratec_av350_unmute_gpio,
+ } },
+ },
};
const unsigned int em28xx_bcount = ARRAY_SIZE(em28xx_boards);
@@ -1479,6 +1525,10 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2870_BOARD_TERRATEC_XS },
{ USB_DEVICE(0x0ccd, 0x0047),
.driver_info = EM2880_BOARD_TERRATEC_PRODIGY_XS },
+ { USB_DEVICE(0x0ccd, 0x0084),
+ .driver_info = EM2860_BOARD_TERRATEC_AV350 },
+ { USB_DEVICE(0x0ccd, 0x0096),
+ .driver_info = EM2860_BOARD_TERRATEC_GRABBY },
{ USB_DEVICE(0x185b, 0x2870),
.driver_info = EM2870_BOARD_COMPRO_VIDEOMATE },
{ USB_DEVICE(0x185b, 0x2041),
@@ -1931,12 +1981,20 @@ static int em28xx_hint_board(struct em28xx *dev)
}
/* ----------------------------------------------------------------------- */
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
+void em28xx_register_i2c_ir(struct em28xx *dev)
{
- if (disable_ir) {
- ir->get_key = NULL;
- return ;
- }
+ struct i2c_board_info info;
+ struct IR_i2c_init_data init_data;
+ const unsigned short addr_list[] = {
+ 0x30, 0x47, I2C_CLIENT_END
+ };
+
+ if (disable_ir)
+ return;
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
/* detect & configure */
switch (dev->model) {
@@ -1946,22 +2004,19 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
break;
case (EM2800_BOARD_TERRATEC_CINERGY_200):
case (EM2820_BOARD_TERRATEC_CINERGY_250):
- ir->ir_codes = ir_codes_em_terratec;
- ir->get_key = em28xx_get_key_terratec;
- snprintf(ir->c.name, sizeof(ir->c.name),
- "i2c IR (EM28XX Terratec)");
+ init_data.ir_codes = ir_codes_em_terratec;
+ init_data.get_key = em28xx_get_key_terratec;
+ init_data.name = "i2c IR (EM28XX Terratec)";
break;
case (EM2820_BOARD_PINNACLE_USB_2):
- ir->ir_codes = ir_codes_pinnacle_grey;
- ir->get_key = em28xx_get_key_pinnacle_usb_grey;
- snprintf(ir->c.name, sizeof(ir->c.name),
- "i2c IR (EM28XX Pinnacle PCTV)");
+ init_data.ir_codes = ir_codes_pinnacle_grey;
+ init_data.get_key = em28xx_get_key_pinnacle_usb_grey;
+ init_data.name = "i2c IR (EM28XX Pinnacle PCTV)";
break;
case (EM2820_BOARD_HAUPPAUGE_WINTV_USB_2):
- ir->ir_codes = ir_codes_hauppauge_new;
- ir->get_key = em28xx_get_key_em_haup;
- snprintf(ir->c.name, sizeof(ir->c.name),
- "i2c IR (EM2840 Hauppauge)");
+ init_data.ir_codes = ir_codes_hauppauge_new;
+ init_data.get_key = em28xx_get_key_em_haup;
+ init_data.name = "i2c IR (EM2840 Hauppauge)";
break;
case (EM2820_BOARD_MSI_VOX_USB_2):
break;
@@ -1972,6 +2027,10 @@ void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir)
case (EM2800_BOARD_GRABBEEX_USB2800):
break;
}
+
+ if (init_data.name)
+ info.platform_data = &init_data;
+ i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
}
void em28xx_card_setup(struct em28xx *dev)
diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c
index 401dc4e39..02e51af9d 100644
--- a/linux/drivers/media/video/em28xx/em28xx-core.c
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c
@@ -1021,6 +1021,41 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
}
EXPORT_SYMBOL_GPL(em28xx_init_isoc);
+/* Determine the packet size for the DVB stream for the given device
+ (underlying value programmed into the eeprom) */
+int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev)
+{
+ unsigned int chip_cfg2;
+ unsigned int packet_size = 564;
+
+ if (dev->chip_id == CHIP_ID_EM2874) {
+ /* FIXME - for now assume 564 like it was before, but the
+ em2874 code should be added to return the proper value... */
+ packet_size = 564;
+ } else {
+ /* TS max packet size stored in bits 1-0 of R01 */
+ chip_cfg2 = em28xx_read_reg(dev, EM28XX_R01_CHIPCFG2);
+ switch (chip_cfg2 & EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK) {
+ case EM28XX_CHIPCFG2_TS_PACKETSIZE_188:
+ packet_size = 188;
+ break;
+ case EM28XX_CHIPCFG2_TS_PACKETSIZE_376:
+ packet_size = 376;
+ break;
+ case EM28XX_CHIPCFG2_TS_PACKETSIZE_564:
+ packet_size = 564;
+ break;
+ case EM28XX_CHIPCFG2_TS_PACKETSIZE_752:
+ packet_size = 752;
+ break;
+ }
+ }
+
+ em28xx_coredbg("dvb max packet size=%d\n", packet_size);
+ return packet_size;
+}
+EXPORT_SYMBOL_GPL(em28xx_isoc_dvb_max_packetsize);
+
/*
* em28xx_wake_i2c()
* configure i2c attached devices
diff --git a/linux/drivers/media/video/em28xx/em28xx-dvb.c b/linux/drivers/media/video/em28xx/em28xx-dvb.c
index dd749442d..de919504f 100644
--- a/linux/drivers/media/video/em28xx/em28xx-dvb.c
+++ b/linux/drivers/media/video/em28xx/em28xx-dvb.c
@@ -47,7 +47,6 @@ if (debug >= level) \
} while (0)
#define EM28XX_DVB_NUM_BUFS 5
-#define EM28XX_DVB_MAX_PACKETSIZE 564
#define EM28XX_DVB_MAX_PACKETS 64
struct em28xx_dvb {
@@ -143,14 +142,17 @@ static int start_streaming(struct em28xx_dvb *dvb)
{
int rc;
struct em28xx *dev = dvb->adapter.priv;
+ int max_dvb_packet_size;
usb_set_interface(dev->udev, 0, 1);
rc = em28xx_set_mode(dev, EM28XX_DIGITAL_MODE);
if (rc < 0)
return rc;
+ max_dvb_packet_size = em28xx_isoc_dvb_max_packetsize(dev);
+
return em28xx_init_isoc(dev, EM28XX_DVB_MAX_PACKETS,
- EM28XX_DVB_NUM_BUFS, EM28XX_DVB_MAX_PACKETSIZE,
+ EM28XX_DVB_NUM_BUFS, max_dvb_packet_size,
dvb_isoc_copy);
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c
index 24456cebd..fd6be0e2c 100644
--- a/linux/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c
@@ -451,27 +451,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-/*
- * attach_inform()
- * gets called when a device attaches to the i2c bus
- * does some basic configuration
- */
-static int attach_inform(struct i2c_client *client)
-{
- struct em28xx *dev = client->adapter->algo_data;
- struct IR_i2c *ir = i2c_get_clientdata(client);
-
- switch (client->addr << 1) {
- case 0x60:
- case 0x8e:
- dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
- em28xx_set_ir(dev, ir);
- break;
- }
-
- return 0;
-}
-
static struct i2c_algorithm em28xx_algo = {
.master_xfer = em28xx_i2c_xfer,
.functionality = functionality,
@@ -488,7 +467,6 @@ static struct i2c_adapter em28xx_adap_template = {
.name = "em28xx",
.id = I2C_HW_B_EM28XX,
.algo = &em28xx_algo,
- .client_register = attach_inform,
};
static struct i2c_client em28xx_client_template = {
@@ -581,6 +559,9 @@ int em28xx_i2c_register(struct em28xx *dev)
if (i2c_scan)
em28xx_do_i2c_scan(dev);
+ /* Instantiate the IR receiver device, if present */
+ em28xx_register_i2c_ir(dev);
+
return 0;
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-input.c b/linux/drivers/media/video/em28xx/em28xx-input.c
index 5382a6064..bfe2cb8f6 100644
--- a/linux/drivers/media/video/em28xx/em28xx-input.c
+++ b/linux/drivers/media/video/em28xx/em28xx-input.c
@@ -41,7 +41,7 @@ MODULE_PARM_DESC(ir_debug, "enable debug messages [IR]");
#define i2cdprintk(fmt, arg...) \
if (ir_debug) { \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg); \
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg); \
}
#define dprintk(fmt, arg...) \
@@ -86,7 +86,7 @@ int em28xx_get_key_terratec(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -115,7 +115,7 @@ int em28xx_get_key_em_haup(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char code;
/* poll IR chip */
- if (2 != i2c_master_recv(&ir->c, buf, 2))
+ if (2 != i2c_master_recv(ir->c, buf, 2))
return -EIO;
/* Does eliminate repeated parity code */
@@ -153,7 +153,7 @@ int em28xx_get_key_pinnacle_usb_grey(struct IR_i2c *ir, u32 *ir_key,
/* poll IR chip */
- if (3 != i2c_master_recv(&ir->c, buf, 3)) {
+ if (3 != i2c_master_recv(ir->c, buf, 3)) {
i2cdprintk("read error\n");
return -EIO;
}
diff --git a/linux/drivers/media/video/em28xx/em28xx-reg.h b/linux/drivers/media/video/em28xx/em28xx-reg.h
index 24e39c568..a2676d63c 100644
--- a/linux/drivers/media/video/em28xx/em28xx-reg.h
+++ b/linux/drivers/media/video/em28xx/em28xx-reg.h
@@ -27,6 +27,22 @@
#define EM28XX_CHIPCFG_AC97 0x10
#define EM28XX_CHIPCFG_AUDIOMASK 0x30
+#define EM28XX_R01_CHIPCFG2 0x01
+
+/* em28xx Chip Configuration 2 0x01 */
+#define EM28XX_CHIPCFG2_TS_PRESENT 0x10
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_MASK 0x0c /* bits 3-2 */
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_1MF 0x00
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_2MF 0x04
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_4MF 0x08
+#define EM28XX_CHIPCFG2_TS_REQ_INTERVAL_8MF 0x0c
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_MASK 0x03 /* bits 0-1 */
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_188 0x00
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_376 0x01
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_564 0x02
+#define EM28XX_CHIPCFG2_TS_PACKETSIZE_752 0x03
+
+
/* GPIO/GPO registers */
#define EM2880_R04_GPO 0x04 /* em2880-em2883 only */
#define EM28XX_R08_GPIO 0x08 /* em2820 or upper */
diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h
index 966a3b924..e4ddc50c5 100644
--- a/linux/drivers/media/video/em28xx/em28xx.h
+++ b/linux/drivers/media/video/em28xx/em28xx.h
@@ -104,6 +104,8 @@
#define EM2860_BOARD_EASYCAP 64
#define EM2820_BOARD_IODATA_GVMVP_SZ 65
#define EM2880_BOARD_EMPIRE_DUAL_TV 66
+#define EM2860_BOARD_TERRATEC_GRABBY 67
+#define EM2860_BOARD_TERRATEC_AV350 68
/* Limits minimum and default number of buffers */
#define EM28XX_MIN_BUF 4
@@ -625,6 +627,7 @@ int em28xx_init_isoc(struct em28xx *dev, int max_packets,
int num_bufs, int max_pkt_size,
int (*isoc_copy) (struct em28xx *dev, struct urb *urb));
void em28xx_uninit_isoc(struct em28xx *dev);
+int em28xx_isoc_dvb_max_packetsize(struct em28xx *dev);
int em28xx_set_mode(struct em28xx *dev, enum em28xx_mode set_mode);
int em28xx_gpio_set(struct em28xx *dev, struct em28xx_reg_seq *gpio);
void em28xx_wake_i2c(struct em28xx *dev);
@@ -649,7 +652,7 @@ extern void em28xx_card_setup(struct em28xx *dev);
extern struct em28xx_board em28xx_boards[];
extern struct usb_device_id em28xx_id_table[];
extern const unsigned int em28xx_bcount;
-void em28xx_set_ir(struct em28xx *dev, struct IR_i2c *ir);
+void em28xx_register_i2c_ir(struct em28xx *dev);
int em28xx_tuner_callback(void *ptr, int component, int command, int arg);
void em28xx_release_resources(struct em28xx *dev);
diff --git a/linux/drivers/media/video/hexium_gemini.c b/linux/drivers/media/video/hexium_gemini.c
index bcd8144c5..e7dc0aa61 100644
--- a/linux/drivers/media/video/hexium_gemini.c
+++ b/linux/drivers/media/video/hexium_gemini.c
@@ -225,7 +225,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
{
DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
- if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ if (i->index >= HEXIUM_INPUTS)
return -EINVAL;
memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
diff --git a/linux/drivers/media/video/hexium_orion.c b/linux/drivers/media/video/hexium_orion.c
index 4178edcc2..d559c0e0c 100644
--- a/linux/drivers/media/video/hexium_orion.c
+++ b/linux/drivers/media/video/hexium_orion.c
@@ -326,7 +326,7 @@ static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
{
DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
- if (i->index < 0 || i->index >= HEXIUM_INPUTS)
+ if (i->index >= HEXIUM_INPUTS)
return -EINVAL;
memcpy(i, &hexium_inputs[i->index], sizeof(struct v4l2_input));
diff --git a/linux/drivers/media/video/ir-kbd-i2c.c b/linux/drivers/media/video/ir-kbd-i2c.c
index 7bae57ad3..0a18d07c7 100644
--- a/linux/drivers/media/video/ir-kbd-i2c.c
+++ b/linux/drivers/media/video/ir-kbd-i2c.c
@@ -75,7 +75,7 @@ static int get_key_haup_common(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
int start, range, toggle, dev, code, ircode;
/* poll IR chip */
- if (size != i2c_master_recv(&ir->c,buf,size))
+ if (size != i2c_master_recv(ir->c, buf, size))
return -EIO;
/* split rc5 data block ... */
@@ -138,7 +138,7 @@ static int get_key_pixelview(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -152,7 +152,7 @@ static int get_key_pv951(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -172,7 +172,7 @@ static int get_key_fusionhdtv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char buf[4];
/* poll IR chip */
- if (4 != i2c_master_recv(&ir->c,buf,4)) {
+ if (4 != i2c_master_recv(ir->c, buf, 4)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -196,7 +196,7 @@ static int get_key_knc1(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
dprintk(1,"read error\n");
return -EIO;
}
@@ -223,12 +223,12 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
u32 *ir_key, u32 *ir_raw)
{
unsigned char subaddr, key, keygroup;
- struct i2c_msg msg[] = { { .addr = ir->c.addr, .flags = 0,
+ struct i2c_msg msg[] = { { .addr = ir->c->addr, .flags = 0,
.buf = &subaddr, .len = 1},
- { .addr = ir->c.addr, .flags = I2C_M_RD,
+ { .addr = ir->c->addr, .flags = I2C_M_RD,
.buf = &key, .len = 1} };
subaddr = 0x0d;
- if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
dprintk(1, "read error\n");
return -EIO;
}
@@ -238,7 +238,7 @@ static int get_key_avermedia_cardbus(struct IR_i2c *ir,
subaddr = 0x0b;
msg[1].buf = &keygroup;
- if (2 != i2c_transfer(ir->c.adapter, msg, 2)) {
+ if (2 != i2c_transfer(ir->c->adapter, msg, 2)) {
dprintk(1, "read error\n");
return -EIO;
}
@@ -295,7 +295,7 @@ static void ir_work(struct work_struct *work)
/* MSI TV@nywhere Plus requires more frequent polling
otherwise it will miss some keypresses */
- if (ir->c.adapter->id == I2C_HW_SAA7134 && ir->c.addr == 0x30)
+ if (ir->c->adapter->id == I2C_HW_SAA7134 && ir->c->addr == 0x30)
polling_interval = 50;
ir_key_poll(ir);
@@ -304,34 +304,15 @@ static void ir_work(struct work_struct *work)
/* ----------------------------------------------------------------------- */
-static int ir_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind);
-static int ir_detach(struct i2c_client *client);
-static int ir_probe(struct i2c_adapter *adap);
-
-static struct i2c_driver driver = {
- .driver = {
- .name = "ir-kbd-i2c",
- },
- .id = I2C_DRIVERID_INFRARED,
- .attach_adapter = ir_probe,
- .detach_client = ir_detach,
-};
-
-static struct i2c_client client_template =
-{
- .name = "unset",
- .driver = &driver
-};
-
-static int ir_attach(struct i2c_adapter *adap, int addr,
- unsigned short flags, int kind)
+static int ir_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
IR_KEYTAB_TYPE *ir_codes = NULL;
- char *name;
+ const char *name = NULL;
int ir_type;
struct IR_i2c *ir;
struct input_dev *input_dev;
+ struct i2c_adapter *adap = client->adapter;
+ unsigned short addr = client->addr;
int err;
ir = kzalloc(sizeof(struct IR_i2c),GFP_KERNEL);
@@ -341,13 +322,9 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
goto err_out_free;
}
- ir->c = client_template;
+ ir->c = client;
ir->input = input_dev;
-
- ir->c.adapter = adap;
- ir->c.addr = addr;
-
- i2c_set_clientdata(&ir->c, ir);
+ i2c_set_clientdata(client, ir);
switch(addr) {
case 0x64:
@@ -412,44 +389,46 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
ir_codes = ir_codes_avermedia_cardbus;
break;
default:
- /* shouldn't happen */
- printk(DEVNAME ": Huh? unknown i2c address (0x%02x)?\n", addr);
+ dprintk(1, DEVNAME ": Unsupported i2c address 0x%02x\n", addr);
err = -ENODEV;
goto err_out_free;
}
- /* Sets name */
- snprintf(ir->c.name, sizeof(ir->c.name), "i2c IR (%s)", name);
- ir->ir_codes = ir_codes;
+ /* Let the caller override settings */
+ if (client->dev.platform_data) {
+ const struct IR_i2c_init_data *init_data =
+ client->dev.platform_data;
- /* register i2c device
- * At device register, IR codes may be changed to be
- * board dependent.
- */
- err = i2c_attach_client(&ir->c);
- if (err)
- goto err_out_free;
+ ir_codes = init_data->ir_codes;
+ name = init_data->name;
+ ir->get_key = init_data->get_key;
+ }
- /* If IR not supported or disabled, unregisters driver */
- if (ir->get_key == NULL) {
+ /* Make sure we are all setup before going on */
+ if (!name || !ir->get_key || !ir_codes) {
+ dprintk(1, DEVNAME ": Unsupported device at address 0x%02x\n",
+ addr);
err = -ENODEV;
- goto err_out_detach;
+ goto err_out_free;
}
- /* Phys addr can only be set after attaching (for ir->c.dev) */
+ /* Sets name */
+ snprintf(ir->name, sizeof(ir->name), "i2c IR (%s)", name);
+ ir->ir_codes = ir_codes;
+
snprintf(ir->phys, sizeof(ir->phys), "%s/%s/ir0",
- dev_name(&ir->c.adapter->dev),
- dev_name(&ir->c.dev));
+ dev_name(&adap->dev),
+ dev_name(&client->dev));
/* init + register input device */
ir_input_init(input_dev, &ir->ir, ir_type, ir->ir_codes);
input_dev->id.bustype = BUS_I2C;
- input_dev->name = ir->c.name;
+ input_dev->name = ir->name;
input_dev->phys = ir->phys;
err = input_register_device(ir->input);
if (err)
- goto err_out_detach;
+ goto err_out_free;
printk(DEVNAME ": %s detected at %s [%s]\n",
ir->input->name, ir->input->phys, adap->name);
@@ -464,135 +443,42 @@ static int ir_attach(struct i2c_adapter *adap, int addr,
return 0;
- err_out_detach:
- i2c_detach_client(&ir->c);
err_out_free:
input_free_device(input_dev);
kfree(ir);
return err;
}
-static int ir_detach(struct i2c_client *client)
+static int ir_remove(struct i2c_client *client)
{
struct IR_i2c *ir = i2c_get_clientdata(client);
/* kill outstanding polls */
cancel_delayed_work_sync(&ir->work);
- /* unregister devices */
+ /* unregister device */
input_unregister_device(ir->input);
- i2c_detach_client(&ir->c);
/* free memory */
kfree(ir);
return 0;
}
-static int ir_probe(struct i2c_adapter *adap)
-{
-
- /* The external IR receiver is at i2c address 0x34 (0x35 for
- reads). Future Hauppauge cards will have an internal
- receiver at 0x30 (0x31 for reads). In theory, both can be
- fitted, and Hauppauge suggest an external overrides an
- internal.
-
- That's why we probe 0x1a (~0x34) first. CB
- */
-
- static const int probe_bttv[] = { 0x1a, 0x18, 0x4b, 0x64, 0x30, -1};
- static const int probe_saa7134[] = { 0x7a, 0x47, 0x71, 0x2d, -1 };
- static const int probe_em28XX[] = { 0x30, 0x47, -1 };
- static const int probe_cx88[] = { 0x18, 0x6b, 0x71, -1 };
- static const int probe_cx23885[] = { 0x6b, -1 };
- const int *probe;
- struct i2c_msg msg = {
- .flags = I2C_M_RD,
- .len = 0,
- .buf = NULL,
- };
- int i, rc;
-
- switch (adap->id) {
- case I2C_HW_B_BT848:
- probe = probe_bttv;
- break;
- case I2C_HW_B_CX2341X:
- probe = probe_bttv;
- break;
- case I2C_HW_SAA7134:
- probe = probe_saa7134;
- break;
- case I2C_HW_B_EM28XX:
- probe = probe_em28XX;
- break;
- case I2C_HW_B_CX2388x:
- probe = probe_cx88;
- break;
- case I2C_HW_B_CX23885:
- probe = probe_cx23885;
- break;
- default:
- return 0;
- }
-
- for (i = 0; -1 != probe[i]; i++) {
- msg.addr = probe[i];
- rc = i2c_transfer(adap, &msg, 1);
- dprintk(1,"probe 0x%02x @ %s: %s\n",
- probe[i], adap->name,
- (1 == rc) ? "yes" : "no");
- if (1 == rc) {
- ir_attach(adap, probe[i], 0, 0);
- return 0;
- }
- }
-
- /* Special case for MSI TV@nywhere Plus remote */
- if (adap->id == I2C_HW_SAA7134) {
- u8 temp;
-
- /* MSI TV@nywhere Plus controller doesn't seem to
- respond to probes unless we read something from
- an existing device. Weird... */
-
- msg.addr = 0x50;
- rc = i2c_transfer(adap, &msg, 1);
- dprintk(1, "probe 0x%02x @ %s: %s\n",
- msg.addr, adap->name,
- (1 == rc) ? "yes" : "no");
-
- /* Now do the probe. The controller does not respond
- to 0-byte reads, so we use a 1-byte read instead. */
- msg.addr = 0x30;
- msg.len = 1;
- msg.buf = &temp;
- rc = i2c_transfer(adap, &msg, 1);
- dprintk(1, "probe 0x%02x @ %s: %s\n",
- msg.addr, adap->name,
- (1 == rc) ? "yes" : "no");
- if (1 == rc)
- ir_attach(adap, msg.addr, 0, 0);
- }
-
- /* Special case for AVerMedia Cardbus remote */
- if (adap->id == I2C_HW_SAA7134) {
- unsigned char subaddr, data;
- struct i2c_msg msg[] = { { .addr = 0x40, .flags = 0,
- .buf = &subaddr, .len = 1},
- { .addr = 0x40, .flags = I2C_M_RD,
- .buf = &data, .len = 1} };
- subaddr = 0x0d;
- rc = i2c_transfer(adap, msg, 2);
- dprintk(1, "probe 0x%02x/0x%02x @ %s: %s\n",
- msg[0].addr, subaddr, adap->name,
- (2 == rc) ? "yes" : "no");
- if (2 == rc)
- ir_attach(adap, msg[0].addr, 0, 0);
- }
+static const struct i2c_device_id ir_kbd_id[] = {
+ /* Generic entry for any IR receiver */
+ { "ir_video", 0 },
+ /* IR device specific entries could be added here */
+ { }
+};
- return 0;
-}
+static struct i2c_driver driver = {
+ .driver = {
+ .name = "ir-kbd-i2c",
+ },
+ .probe = ir_probe,
+ .remove = ir_remove,
+ .id_table = ir_kbd_id,
+};
/* ----------------------------------------------------------------------- */
diff --git a/linux/drivers/media/video/ivtv/ivtv-i2c.c b/linux/drivers/media/video/ivtv/ivtv-i2c.c
index 984c73b5e..0d18c2220 100644
--- a/linux/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/linux/drivers/media/video/ivtv/ivtv-i2c.c
@@ -592,9 +592,11 @@ static struct i2c_client ivtv_i2c_client_template = {
.name = "ivtv internal",
};
-/* init + register i2c algo-bit adapter */
+/* init + register i2c adapter + instantiate IR receiver */
int init_ivtv_i2c(struct ivtv *itv)
{
+ int retval;
+
IVTV_DEBUG_I2C("i2c init\n");
/* Sanity checks for the I2C hardware arrays. They must be the
@@ -634,9 +636,37 @@ int init_ivtv_i2c(struct ivtv *itv)
ivtv_setsda(itv, 1);
if (itv->options.newi2c > 0)
- return i2c_add_adapter(&itv->i2c_adap);
+ retval = i2c_add_adapter(&itv->i2c_adap);
else
- return i2c_bit_add_bus(&itv->i2c_adap);
+ retval = i2c_bit_add_bus(&itv->i2c_adap);
+
+ /* Instantiate the IR receiver device, if present */
+ if (retval == 0) {
+ struct i2c_board_info info;
+ /* The external IR receiver is at i2c address 0x34 (0x35 for
+ reads). Future Hauppauge cards will have an internal
+ receiver at 0x30 (0x31 for reads). In theory, both can be
+ fitted, and Hauppauge suggest an external overrides an
+ internal.
+
+ That's why we probe 0x1a (~0x34) first. CB
+ */
+ const unsigned short addr_list[] = {
+ 0x1a, /* Hauppauge IR external */
+ 0x18, /* Hauppauge IR internal */
+ 0x71, /* Hauppauge IR (PVR150) */
+ 0x64, /* Pixelview IR */
+ 0x30, /* KNC ONE IR */
+ 0x6b, /* Adaptec IR */
+ I2C_CLIENT_END
+ };
+
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ i2c_new_probed_device(&itv->i2c_adap, &info, addr_list);
+ }
+
+ return retval;
}
void exit_ivtv_i2c(struct ivtv *itv)
diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
index c342a9fe9..99f3c39a1 100644
--- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -709,7 +709,7 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
- else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
+ else if (regs->reg < IVTV_ENCODER_SIZE)
reg_start = itv->enc_mem;
else
return -EINVAL;
diff --git a/linux/drivers/media/video/mxb.c b/linux/drivers/media/video/mxb.c
index 4a50c0e95..411efcd34 100644
--- a/linux/drivers/media/video/mxb.c
+++ b/linux/drivers/media/video/mxb.c
@@ -457,7 +457,7 @@ static int vidioc_s_ctrl(struct file *file, void *fh, struct v4l2_control *vc)
static int vidioc_enum_input(struct file *file, void *fh, struct v4l2_input *i)
{
DEB_EE(("VIDIOC_ENUMINPUT %d.\n", i->index));
- if (i->index < 0 || i->index >= MXB_INPUTS)
+ if (i->index >= MXB_INPUTS)
return -EINVAL;
memcpy(i, &mxb_inputs[i->index], sizeof(struct v4l2_input));
return 0;
@@ -620,7 +620,7 @@ static int vidioc_g_audio(struct file *file, void *fh, struct v4l2_audio *a)
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct mxb *mxb = (struct mxb *)dev->ext_priv;
- if (a->index < 0 || a->index > MXB_INPUTS) {
+ if (a->index > MXB_INPUTS) {
DEB_D(("VIDIOC_G_AUDIO %d out of range.\n", a->index));
return -EINVAL;
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c
index 129de13da..336a20ede 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.c
@@ -71,6 +71,7 @@ static const struct pvr2_device_desc pvr2_device_29xxx = {
.flag_has_svideo = !0,
.signal_routing_scheme = PVR2_ROUTING_SCHEME_HAUPPAUGE,
.led_scheme = PVR2_LED_SCHEME_HAUPPAUGE,
+ .ir_scheme = PVR2_IR_SCHEME_29XXX,
};
@@ -284,7 +285,9 @@ static struct tda10048_config hauppauge_tda10048_config = {
.output_mode = TDA10048_PARALLEL_OUTPUT,
.fwbulkwritelen = TDA10048_BULKWRITE_50,
.inversion = TDA10048_INVERSION_ON,
- .if_freq_khz = TDA10048_IF_4300,
+ .dtv6_if_freq_khz = TDA10048_IF_3300,
+ .dtv7_if_freq_khz = TDA10048_IF_3800,
+ .dtv8_if_freq_khz = TDA10048_IF_4300,
.clk_freq_khz = TDA10048_CLK_16000,
.disable_gate_access = 1,
};
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index 3e553389c..ea04ecf8a 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -69,6 +69,7 @@ struct pvr2_string_table {
#define PVR2_ROUTING_SCHEME_HAUPPAUGE 0
#define PVR2_ROUTING_SCHEME_GOTVIEW 1
#define PVR2_ROUTING_SCHEME_ONAIR 2
+#define PVR2_ROUTING_SCHEME_AV400 3
#define PVR2_DIGITAL_SCHEME_NONE 0
#define PVR2_DIGITAL_SCHEME_HAUPPAUGE 1
@@ -78,8 +79,10 @@ struct pvr2_string_table {
#define PVR2_LED_SCHEME_HAUPPAUGE 1
#define PVR2_IR_SCHEME_NONE 0
-#define PVR2_IR_SCHEME_24XXX 1
-#define PVR2_IR_SCHEME_ZILOG 2
+#define PVR2_IR_SCHEME_24XXX 1 /* FX2-controlled IR */
+#define PVR2_IR_SCHEME_ZILOG 2 /* HVR-1950 style (must be taken out of reset) */
+#define PVR2_IR_SCHEME_24XXX_MCE 3 /* 24xxx MCE device */
+#define PVR2_IR_SCHEME_29XXX 4 /* Original 29xxx device */
/* This describes a particular hardware type (except for the USB device ID
which must live in a separate structure due to environmental
@@ -162,19 +165,9 @@ struct pvr2_device_desc {
ensure that it is found. */
unsigned int flag_has_wm8775:1;
- /* Indicate any specialized IR scheme that might need to be
- supported by this driver. If not set, then it is assumed that
- IR can work without help from the driver (which is frequently
- the case). This is otherwise set to one of
- PVR2_IR_SCHEME_xxxx. For "xxxx", the value "24XXX" indicates a
- Hauppauge 24xxx class device which has an FPGA-hosted IR
- receiver that can only be reached via FX2 command codes. In
- that case the pvrusb2 driver will emulate the behavior of the
- older 29xxx device's IR receiver (a "virtual" I2C chip) in terms
- of those command codes. For the value "ZILOG", we're dealing
- with an IR chip that must be taken out of reset via another FX2
- command code (which is the case for HVR-1950 devices). */
- unsigned int ir_scheme:2;
+ /* Indicate IR scheme of hardware. If not set, then it is assumed
+ that IR can work without any help from the driver. */
+ unsigned int ir_scheme:3;
/* These bits define which kinds of sources the device can handle.
Note: Digital tuner presence is inferred by the
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
index 5d75eb521..5b152ff20 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
@@ -200,6 +200,9 @@ struct pvr2_hdw {
int i2c_cx25840_hack_state;
int i2c_linked;
+ /* IR related */
+ unsigned int ir_scheme_active; /* IR scheme as seen from the outside */
+
/* Frequency table */
unsigned int freqTable[FREQTABLE_SIZE];
unsigned int freqProgSlot;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index c0e1e2cc9..3411cb36a 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -143,6 +143,15 @@ static const unsigned char *module_i2c_addresses[] = {
};
+static const char *ir_scheme_names[] = {
+ [PVR2_IR_SCHEME_NONE] = "none",
+ [PVR2_IR_SCHEME_29XXX] = "29xxx",
+ [PVR2_IR_SCHEME_24XXX] = "24xxx (29xxx emulation)",
+ [PVR2_IR_SCHEME_24XXX_MCE] = "24xxx (MCE device)",
+ [PVR2_IR_SCHEME_ZILOG] = "Zilog",
+};
+
+
/* Define the list of additional controls we'll dynamically construct based
on query of the cx2341x module. */
struct pvr2_mpeg_ids {
@@ -2187,7 +2196,7 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
}
/* Take the IR chip out of reset, if appropriate */
- if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_ZILOG) {
+ if (hdw->ir_scheme_active == PVR2_IR_SCHEME_ZILOG) {
pvr2_issue_simple_cmd(hdw,
FX2CMD_HCW_ZILOG_RESET |
(1 << 8) |
@@ -2468,6 +2477,7 @@ struct pvr2_hdw *pvr2_hdw_create(struct usb_interface *intf,
GFP_KERNEL);
if (!hdw->controls) goto fail;
hdw->hdw_desc = hdw_desc;
+ hdw->ir_scheme_active = hdw->hdw_desc->ir_scheme;
for (idx = 0; idx < hdw->control_cnt; idx++) {
cptr = hdw->controls + idx;
cptr->hdw = hdw;
@@ -4903,6 +4913,12 @@ static unsigned int pvr2_hdw_report_unlocked(struct pvr2_hdw *hdw,int which,
stats.buffers_processed,
stats.buffers_failed);
}
+ case 6: {
+ unsigned int id = hdw->ir_scheme_active;
+ return scnprintf(buf, acnt, "ir scheme: id=%d %s", id,
+ (id >= ARRAY_SIZE(ir_scheme_names) ?
+ "?" : ir_scheme_names[id]));
+ }
default: break;
}
return 0;
@@ -4919,65 +4935,35 @@ static unsigned int pvr2_hdw_report_clients(struct pvr2_hdw *hdw,
unsigned int tcnt = 0;
unsigned int ccnt;
struct i2c_client *client;
- struct list_head *item;
- void *cd;
const char *p;
unsigned int id;
- ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers:");
+ ccnt = scnprintf(buf, acnt, "Associated v4l2-subdev drivers and I2C clients:\n");
tcnt += ccnt;
v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
id = sd->grp_id;
p = NULL;
if (id < ARRAY_SIZE(module_names)) p = module_names[id];
if (p) {
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s", p);
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt, " %s:", p);
tcnt += ccnt;
} else {
ccnt = scnprintf(buf + tcnt, acnt - tcnt,
- " (unknown id=%u)", id);
+ " (unknown id=%u):", id);
tcnt += ccnt;
}
- }
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
- tcnt += ccnt;
-
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, "I2C clients:\n");
- tcnt += ccnt;
-
- mutex_lock(&hdw->i2c_adap.clist_lock);
- list_for_each(item, &hdw->i2c_adap.clients) {
- client = list_entry(item, struct i2c_client, list);
- ccnt = scnprintf(buf + tcnt, acnt - tcnt,
- " %s: i2c=%02x", client->name, client->addr);
- tcnt += ccnt;
- cd = i2c_get_clientdata(client);
- v4l2_device_for_each_subdev(sd, &hdw->v4l2_dev) {
- if (cd == sd) {
- id = sd->grp_id;
- p = NULL;
- if (id < ARRAY_SIZE(module_names)) {
- p = module_names[id];
- }
- if (p) {
- ccnt = scnprintf(buf + tcnt,
- acnt - tcnt,
- " subdev=%s", p);
- tcnt += ccnt;
- } else {
- ccnt = scnprintf(buf + tcnt,
- acnt - tcnt,
- " subdev= id %u)",
- id);
- tcnt += ccnt;
- }
- break;
- }
+ client = v4l2_get_subdevdata(sd);
+ if (client) {
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+ " %s @ %02x\n", client->name,
+ client->addr);
+ tcnt += ccnt;
+ } else {
+ ccnt = scnprintf(buf + tcnt, acnt - tcnt,
+ " no i2c client\n");
+ tcnt += ccnt;
}
- ccnt = scnprintf(buf + tcnt, acnt - tcnt, "\n");
- tcnt += ccnt;
}
- mutex_unlock(&hdw->i2c_adap.clist_lock);
return tcnt;
}
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 919a4f4e1..694e51f58 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -43,6 +43,18 @@ static int ir_mode[PVR_NUM] = { [0 ... PVR_NUM-1] = 1 };
module_param_array(ir_mode, int, NULL, 0444);
MODULE_PARM_DESC(ir_mode,"specify: 0=disable IR reception, 1=normal IR");
+static int pvr2_disable_ir_video;
+module_param_named(disable_autoload_ir_video, pvr2_disable_ir_video,
+ int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(disable_autoload_ir_video,
+ "1=do not try to autoload ir_video IR receiver");
+
+/* Mapping of IR schemes to known I2C addresses - if any */
+static const unsigned char ir_video_addresses[] = {
+ [PVR2_IR_SCHEME_29XXX] = 0x18,
+ [PVR2_IR_SCHEME_24XXX] = 0x18,
+};
+
static int pvr2_i2c_write(struct pvr2_hdw *hdw, /* Context */
u8 i2c_addr, /* I2C address we're talking to */
u8 *data, /* Data to write */
@@ -637,6 +649,31 @@ static void do_i2c_scan(struct pvr2_hdw *hdw)
printk(KERN_INFO "%s: i2c scan done.\n", hdw->name);
}
+static void pvr2_i2c_register_ir(struct pvr2_hdw *hdw)
+{
+ struct i2c_board_info info;
+ unsigned char addr = 0;
+ if (pvr2_disable_ir_video) {
+ pvr2_trace(PVR2_TRACE_INFO,
+ "Automatic binding of ir_video has been disabled.");
+ return;
+ }
+ if (hdw->ir_scheme_active < ARRAY_SIZE(ir_video_addresses)) {
+ addr = ir_video_addresses[hdw->ir_scheme_active];
+ }
+ if (!addr) {
+ /* The device either doesn't support I2C-based IR or we
+ don't know (yet) how to operate IR on the device. */
+ return;
+ }
+ pvr2_trace(PVR2_TRACE_INFO,
+ "Binding ir_video to i2c address 0x%02x.", addr);
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+ info.addr = addr;
+ i2c_new_device(&hdw->i2c_adap, &info);
+}
+
void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
{
unsigned int idx;
@@ -652,7 +689,9 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
printk(KERN_INFO "%s: IR disabled\n",hdw->name);
hdw->i2c_func[0x18] = i2c_black_hole;
} else if (ir_mode[hdw->unit_number] == 1) {
- if (hdw->hdw_desc->ir_scheme == PVR2_IR_SCHEME_24XXX) {
+ if (hdw->ir_scheme_active == PVR2_IR_SCHEME_24XXX) {
+ /* Set up translation so that our IR looks like a
+ 29xxx device */
hdw->i2c_func[0x18] = i2c_24xxx_ir;
}
}
@@ -675,15 +714,23 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
i2c_add_adapter(&hdw->i2c_adap);
if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
/* Probe for a different type of IR receiver on this
- device. If present, disable the emulated IR receiver. */
+ device. This is really the only way to differentiate
+ older 24xxx devices from 24xxx variants that include an
+ IR blaster. If the IR blaster is present, the IR
+ receiver is part of that chip and thus we must disable
+ the emulated IR receiver. */
if (do_i2c_probe(hdw, 0x71)) {
pvr2_trace(PVR2_TRACE_INFO,
"Device has newer IR hardware;"
" disabling unneeded virtual IR device");
hdw->i2c_func[0x18] = NULL;
+ /* Remember that this is a different device... */
+ hdw->ir_scheme_active = PVR2_IR_SCHEME_24XXX_MCE;
}
}
if (i2c_scan) do_i2c_scan(hdw);
+
+ pvr2_i2c_register_ir(hdw);
}
void pvr2_i2c_core_done(struct pvr2_hdw *hdw)
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 7ed3b8453..d8ad83df3 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -548,7 +548,7 @@ static void class_dev_destroy(struct pvr2_sysfs *sfp)
&sfp->attr_unit_number);
}
pvr2_sysfs_trace("Destroying class_dev id=%p",sfp->class_dev);
- sfp->class_dev->driver_data = NULL;
+ dev_set_drvdata(sfp->class_dev, NULL);
device_unregister(sfp->class_dev);
sfp->class_dev = NULL;
}
@@ -558,7 +558,7 @@ static ssize_t v4l_minor_number_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return scnprintf(buf,PAGE_SIZE,"%d\n",
pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -570,7 +570,7 @@ static ssize_t bus_info_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return scnprintf(buf,PAGE_SIZE,"%s\n",
pvr2_hdw_get_bus_info(sfp->channel.hdw));
@@ -581,7 +581,7 @@ static ssize_t hdw_name_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return scnprintf(buf,PAGE_SIZE,"%s\n",
pvr2_hdw_get_type(sfp->channel.hdw));
@@ -592,7 +592,7 @@ static ssize_t hdw_desc_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return scnprintf(buf,PAGE_SIZE,"%s\n",
pvr2_hdw_get_desc(sfp->channel.hdw));
@@ -604,7 +604,7 @@ static ssize_t v4l_radio_minor_number_show(struct device *class_dev,
char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return scnprintf(buf,PAGE_SIZE,"%d\n",
pvr2_hdw_v4l_get_minor_number(sfp->channel.hdw,
@@ -616,7 +616,7 @@ static ssize_t unit_number_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return scnprintf(buf,PAGE_SIZE,"%d\n",
pvr2_hdw_get_unit_number(sfp->channel.hdw));
@@ -644,7 +644,7 @@ static void class_dev_create(struct pvr2_sysfs *sfp,
class_dev->parent = &usb_dev->dev;
sfp->class_dev = class_dev;
- class_dev->driver_data = sfp;
+ dev_set_drvdata(class_dev, sfp);
ret = device_register(class_dev);
if (ret) {
pvr2_trace(PVR2_TRACE_ERROR_LEGS,
@@ -817,7 +817,7 @@ static ssize_t debuginfo_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
pvr2_hdw_trigger_module_log(sfp->channel.hdw);
return pvr2_debugifc_print_info(sfp->channel.hdw,buf,PAGE_SIZE);
@@ -828,7 +828,7 @@ static ssize_t debugcmd_show(struct device *class_dev,
struct device_attribute *attr, char *buf)
{
struct pvr2_sysfs *sfp;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
return pvr2_debugifc_print_status(sfp->channel.hdw,buf,PAGE_SIZE);
}
@@ -841,7 +841,7 @@ static ssize_t debugcmd_store(struct device *class_dev,
struct pvr2_sysfs *sfp;
int ret;
- sfp = (struct pvr2_sysfs *)class_dev->driver_data;
+ sfp = dev_get_drvdata(class_dev);
if (!sfp) return -EINVAL;
ret = pvr2_debugifc_docmd(sfp->channel.hdw,buf,count);
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
index c7fc605f8..a19ad36e5 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-v4l2.c
@@ -91,7 +91,7 @@ static struct v4l2_capability pvr_capability ={
.driver = "pvrusb2",
.card = "Hauppauge WinTV pvr-usb2",
.bus_info = "usb",
- .version = KERNEL_VERSION(0,8,0),
+ .version = KERNEL_VERSION(0, 9, 0),
.capabilities = (V4L2_CAP_VIDEO_CAPTURE |
V4L2_CAP_TUNER | V4L2_CAP_AUDIO | V4L2_CAP_RADIO |
V4L2_CAP_READWRITE),
@@ -268,7 +268,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
memset(&tmp,0,sizeof(tmp));
tmp.index = vi->index;
ret = 0;
- if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
+ if (vi->index >= fh->input_cnt) {
ret = -EINVAL;
break;
}
@@ -332,7 +332,7 @@ static long pvr2_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
case VIDIOC_S_INPUT:
{
struct v4l2_input *vi = (struct v4l2_input *)arg;
- if ((vi->index < 0) || (vi->index >= fh->input_cnt)) {
+ if (vi->index >= fh->input_cnt) {
ret = -ERANGE;
break;
}
diff --git a/linux/drivers/media/video/pwc/pwc-v4l.c b/linux/drivers/media/video/pwc/pwc-v4l.c
index bc0a46429..2876ce084 100644
--- a/linux/drivers/media/video/pwc/pwc-v4l.c
+++ b/linux/drivers/media/video/pwc/pwc-v4l.c
@@ -1107,7 +1107,7 @@ long pwc_video_do_ioctl(struct file *file, unsigned int cmd, void *arg)
return -EINVAL;
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- if (buf->index < 0 || buf->index >= pwc_mbufs)
+ if (buf->index >= pwc_mbufs)
return -EINVAL;
buf->flags |= V4L2_BUF_FLAG_QUEUED;
diff --git a/linux/drivers/media/video/s2255drv.c b/linux/drivers/media/video/s2255drv.c
index 12ced841e..203f6e3ff 100644
--- a/linux/drivers/media/video/s2255drv.c
+++ b/linux/drivers/media/video/s2255drv.c
@@ -110,6 +110,8 @@
#define SCALE_4CIFS 1 /* 640x480(NTSC) or 704x576(PAL) */
#define SCALE_2CIFS 2 /* 640x240(NTSC) or 704x288(PAL) */
#define SCALE_1CIFS 3 /* 320x240(NTSC) or 352x288(PAL) */
+/* SCALE_4CIFSI is the 2 fields interpolated into one */
+#define SCALE_4CIFSI 4 /* 640x480(NTSC) or 704x576(PAL) high quality */
#define COLOR_YUVPL 1 /* YUV planar */
#define COLOR_YUVPK 2 /* YUV packed */
@@ -239,6 +241,8 @@ struct s2255_dev {
struct s2255_mode mode[MAX_CHANNELS];
/* jpeg compression */
struct v4l2_jpegcompression jc[MAX_CHANNELS];
+ /* capture parameters (for high quality mode full size) */
+ struct v4l2_captureparm cap_parm[MAX_CHANNELS];
const struct s2255_fmt *cur_fmt[MAX_CHANNELS];
int cur_frame[MAX_CHANNELS];
int last_frame[MAX_CHANNELS];
@@ -1021,9 +1025,16 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fh->type = f->type;
norm = norm_minw(fh->dev->vdev[fh->channel]);
if (fh->width > norm_minw(fh->dev->vdev[fh->channel])) {
- if (fh->height > norm_minh(fh->dev->vdev[fh->channel]))
- fh->mode.scale = SCALE_4CIFS;
- else
+ if (fh->height > norm_minh(fh->dev->vdev[fh->channel])) {
+ if (fh->dev->cap_parm[fh->channel].capturemode &
+ V4L2_MODE_HIGHQUALITY) {
+ fh->mode.scale = SCALE_4CIFSI;
+ dprintk(2, "scale 4CIFSI\n");
+ } else {
+ fh->mode.scale = SCALE_4CIFS;
+ dprintk(2, "scale 4CIFS\n");
+ }
+ } else
fh->mode.scale = SCALE_2CIFS;
} else {
@@ -1124,6 +1135,7 @@ static u32 get_transfer_size(struct s2255_mode *mode)
if (mode->format == FORMAT_NTSC) {
switch (mode->scale) {
case SCALE_4CIFS:
+ case SCALE_4CIFSI:
linesPerFrame = NUM_LINES_4CIFS_NTSC * 2;
pixelsPerLine = LINE_SZ_4CIFS_NTSC;
break;
@@ -1141,6 +1153,7 @@ static u32 get_transfer_size(struct s2255_mode *mode)
} else if (mode->format == FORMAT_PAL) {
switch (mode->scale) {
case SCALE_4CIFS:
+ case SCALE_4CIFSI:
linesPerFrame = NUM_LINES_4CIFS_PAL * 2;
pixelsPerLine = LINE_SZ_4CIFS_PAL;
break;
@@ -1496,6 +1509,33 @@ static int vidioc_s_jpegcomp(struct file *file, void *priv,
dprintk(2, "setting jpeg quality %d\n", jc->quality);
return 0;
}
+
+static int vidioc_g_parm(struct file *file, void *priv,
+ struct v4l2_streamparm *sp)
+{
+ struct s2255_fh *fh = priv;
+ struct s2255_dev *dev = fh->dev;
+ if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+ sp->parm.capture.capturemode = dev->cap_parm[fh->channel].capturemode;
+ dprintk(2, "getting parm %d\n", sp->parm.capture.capturemode);
+ return 0;
+}
+
+static int vidioc_s_parm(struct file *file, void *priv,
+ struct v4l2_streamparm *sp)
+{
+ struct s2255_fh *fh = priv;
+ struct s2255_dev *dev = fh->dev;
+
+ if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
+ return -EINVAL;
+
+ dev->cap_parm[fh->channel].capturemode = sp->parm.capture.capturemode;
+ dprintk(2, "setting param capture mode %d\n",
+ sp->parm.capture.capturemode);
+ return 0;
+}
static int s2255_open(struct file *file)
{
int minor = video_devdata(file)->minor;
@@ -1787,6 +1827,8 @@ static const struct v4l2_ioctl_ops s2255_ioctl_ops = {
#endif
.vidioc_s_jpegcomp = vidioc_s_jpegcomp,
.vidioc_g_jpegcomp = vidioc_g_jpegcomp,
+ .vidioc_s_parm = vidioc_s_parm,
+ .vidioc_g_parm = vidioc_g_parm,
};
static struct video_device template = {
@@ -2240,8 +2282,10 @@ static void read_pipe_completion(struct urb *purb)
return;
}
status = purb->status;
- if (status != 0) {
- dprintk(2, "read_pipe_completion: err\n");
+ /* if shutting down, do not resubmit, exit immediately */
+ if (status == -ESHUTDOWN) {
+ dprintk(2, "read_pipe_completion: err shutdown\n");
+ pipe_info->err_count++;
return;
}
@@ -2250,9 +2294,13 @@ static void read_pipe_completion(struct urb *purb)
return;
}
- s2255_read_video_callback(dev, pipe_info);
+ if (status == 0)
+ s2255_read_video_callback(dev, pipe_info);
+ else {
+ pipe_info->err_count++;
+ dprintk(1, "s2255drv: failed URB %d\n", status);
+ }
- pipe_info->err_count = 0;
pipe = usb_rcvbulkpipe(dev->udev, dev->read_endpoint);
/* reuse urb */
usb_fill_bulk_urb(pipe_info->stream_urb, dev->udev,
@@ -2264,7 +2312,6 @@ static void read_pipe_completion(struct urb *purb)
if (pipe_info->state != 0) {
if (usb_submit_urb(pipe_info->stream_urb, GFP_KERNEL)) {
dev_err(&dev->udev->dev, "error submitting urb\n");
- usb_free_urb(pipe_info->stream_urb);
}
} else {
dprintk(2, "read pipe complete state 0\n");
diff --git a/linux/drivers/media/video/saa7134/Kconfig b/linux/drivers/media/video/saa7134/Kconfig
index 0ba68987b..5bcce092e 100644
--- a/linux/drivers/media/video/saa7134/Kconfig
+++ b/linux/drivers/media/video/saa7134/Kconfig
@@ -44,6 +44,7 @@ config VIDEO_SAA7134_DVB
select DVB_LNBP21 if !DVB_FE_CUSTOMISE
select DVB_ZL10353 if !DVB_FE_CUSTOMISE
select DVB_LGDT3305 if !DVB_FE_CUSTOMISE
+ select DVB_TDA10048 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
---help---
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index 582a56c07..587209fdd 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -3403,13 +3403,15 @@ struct saa7134_board saa7134_boards[] = {
},
},
[SAA7134_BOARD_HAUPPAUGE_HVR1110R3] = {
- .name = "Hauppauge WinTV-HVR1110r3",
+ .name = "Hauppauge WinTV-HVR1110r3 DVB-T/Hybrid",
.audio_clock = 0x00187de7,
.tuner_type = TUNER_PHILIPS_TDA8290,
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
.tuner_config = 3,
+ .mpeg = SAA7134_MPEG_DVB,
+ .ts_type = SAA7134_MPEG_TS_SERIAL,
.gpiomask = 0x0800100, /* GPIO 21 is an INPUT */
.inputs = {{
.name = name_tv,
@@ -4826,7 +4828,6 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
- .mpeg = SAA7134_MPEG_DVB,
.inputs = {{
.name = name_tv,
.vmux = 3,
@@ -6580,7 +6581,6 @@ int saa7134_board_init1(struct saa7134_dev *dev)
case SAA7134_BOARD_VIDEOMATE_DVBT_300:
case SAA7134_BOARD_VIDEOMATE_DVBT_200:
case SAA7134_BOARD_VIDEOMATE_DVBT_200A:
- case SAA7134_BOARD_VIDEOMATE_T750:
case SAA7134_BOARD_MANLI_MTV001:
case SAA7134_BOARD_MANLI_MTV002:
case SAA7134_BOARD_BEHOLD_409FM:
diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c
index 69a214417..dc692d7a7 100644
--- a/linux/drivers/media/video/saa7134/saa7134-core.c
+++ b/linux/drivers/media/video/saa7134/saa7134-core.c
@@ -836,7 +836,6 @@ static struct video_device *vdev_init(struct saa7134_dev *dev,
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
vfd->debug = video_debug;
diff --git a/linux/drivers/media/video/saa7134/saa7134-dvb.c b/linux/drivers/media/video/saa7134/saa7134-dvb.c
index 2e1344ecf..360fbdf19 100644
--- a/linux/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/linux/drivers/media/video/saa7134/saa7134-dvb.c
@@ -48,6 +48,7 @@
#include "isl6405.h"
#include "lnbp21.h"
#include "tuner-simple.h"
+#include "tda10048.h"
#include "tda18271.h"
#include "lgdt3305.h"
#include "tda8290.h"
@@ -978,6 +979,18 @@ static struct lgdt3305_config hcw_lgdt3305_config = {
.vsb_if_khz = 3250,
};
+static struct tda10048_config hcw_tda10048_config = {
+ .demod_address = 0x10 >> 1,
+ .output_mode = TDA10048_SERIAL_OUTPUT,
+ .fwbulkwritelen = TDA10048_BULKWRITE_200,
+ .inversion = TDA10048_INVERSION_ON,
+ .dtv6_if_freq_khz = TDA10048_IF_3300,
+ .dtv7_if_freq_khz = TDA10048_IF_3500,
+ .dtv8_if_freq_khz = TDA10048_IF_4000,
+ .clk_freq_khz = TDA10048_CLK_16000,
+ .disable_gate_access = 1,
+};
+
static struct tda18271_std_map hauppauge_tda18271_std_map = {
.atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 4,
.if_lvl = 1, .rfagc_top = 0x58, },
@@ -1106,6 +1119,19 @@ static int dvb_init(struct saa7134_dev *dev)
&tda827x_cfg_2) < 0)
goto dettach_frontend;
break;
+ case SAA7134_BOARD_HAUPPAUGE_HVR1110R3:
+ fe0->dvb.frontend = dvb_attach(tda10048_attach,
+ &hcw_tda10048_config,
+ &dev->i2c_adap);
+ if (fe0->dvb.frontend != NULL) {
+ dvb_attach(tda829x_attach, fe0->dvb.frontend,
+ &dev->i2c_adap, 0x4b,
+ &tda829x_no_probe);
+ dvb_attach(tda18271_attach, fe0->dvb.frontend,
+ 0x60, &dev->i2c_adap,
+ &hcw_tda18271_config);
+ }
+ break;
case SAA7134_BOARD_PHILIPS_TIGER:
if (configure_tda827x_fe(dev, &philips_tiger_config,
&tda827x_cfg_0) < 0)
diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c
index bab6b56c8..dd22a5215 100644
--- a/linux/drivers/media/video/saa7134/saa7134-empress.c
+++ b/linux/drivers/media/video/saa7134/saa7134-empress.c
@@ -499,11 +499,8 @@ static void empress_signal_update(struct work_struct *work)
if (dev->nosignal) {
dprintk("no video signal\n");
- ts_reset_encoder(dev);
} else {
dprintk("video signal acquired\n");
- if (atomic_read(&dev->empress_users))
- ts_init_encoder(dev);
}
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c
index 3eb60aabe..a8185693f 100644
--- a/linux/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c
@@ -264,7 +264,7 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
/* workaround for a saa7134 i2c bug
* needed to talk to the mt352 demux
* thanks to pinnacle for the hint */
- int quirk = 0xfd;
+ int quirk = 0xfe;
d1printk(" [%02x quirk]",quirk);
i2c_send_byte(dev,START,quirk);
i2c_recv_byte(dev);
@@ -326,33 +326,6 @@ static u32 functionality(struct i2c_adapter *adap)
return I2C_FUNC_SMBUS_EMUL;
}
-static int attach_inform(struct i2c_client *client)
-{
- struct saa7134_dev *dev = client->adapter->algo_data;
-
- d1printk( "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- /* Am I an i2c remote control? */
-
- switch (client->addr) {
- case 0x7a:
- case 0x47:
- case 0x71:
- case 0x2d:
- case 0x30:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- d1printk("%s i2c IR detected (%s).\n",
- client->driver->driver.name, ir->phys);
- saa7134_set_i2c_ir(dev,ir);
- break;
- }
- }
-
- return 0;
-}
-
static struct i2c_algorithm saa7134_algo = {
.master_xfer = saa7134_i2c_xfer,
.functionality = functionality,
@@ -369,7 +342,6 @@ static struct i2c_adapter saa7134_adap_template = {
.name = "saa7134",
.id = I2C_HW_SAA7134,
.algo = &saa7134_algo,
- .client_register = attach_inform,
};
static struct i2c_client saa7134_client_template = {
@@ -444,6 +416,9 @@ int saa7134_i2c_register(struct saa7134_dev *dev)
saa7134_i2c_eeprom(dev,dev->eedata,sizeof(dev->eedata));
if (i2c_scan)
do_i2c_scan(dev->name,&dev->i2c_client);
+
+ /* Instantiate the IR receiver device, if present */
+ saa7134_probe_i2c_ir(dev);
return 0;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-input.c b/linux/drivers/media/video/saa7134/saa7134-input.c
index 80a4cc23d..36913d22b 100644
--- a/linux/drivers/media/video/saa7134/saa7134-input.c
+++ b/linux/drivers/media/video/saa7134/saa7134-input.c
@@ -60,7 +60,7 @@ MODULE_PARM_DESC(disable_other_ir, "disable full codes of "
#define dprintk(fmt, arg...) if (ir_debug) \
printk(KERN_DEBUG "%s/ir: " fmt, dev->name , ## arg)
#define i2cdprintk(fmt, arg...) if (ir_debug) \
- printk(KERN_DEBUG "%s/ir: " fmt, ir->c.name , ## arg)
+ printk(KERN_DEBUG "%s/ir: " fmt, ir->name , ## arg)
/* Helper functions for RC5 and NEC decoding at GPIO16 or GPIO18 */
static int saa7134_rc5_irq(struct saa7134_dev *dev);
@@ -134,10 +134,10 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
int gpio;
/* <dev> is needed to access GPIO. Used by the saa_readl macro. */
- struct saa7134_dev *dev = ir->c.adapter->algo_data;
+ struct saa7134_dev *dev = ir->c->adapter->algo_data;
if (dev == NULL) {
dprintk("get_key_msi_tvanywhere_plus: "
- "gir->c.adapter->algo_data is NULL!\n");
+ "gir->c->adapter->algo_data is NULL!\n");
return -EIO;
}
@@ -156,7 +156,7 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
/* GPIO says there is a button press. Get it. */
- if (1 != i2c_master_recv(&ir->c, &b, 1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -179,7 +179,7 @@ static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char b;
/* poll IR chip */
- if (1 != i2c_master_recv(&ir->c,&b,1)) {
+ if (1 != i2c_master_recv(ir->c, &b, 1)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -202,7 +202,7 @@ static int get_key_hvr1110(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char buf[5], cod4, code3, code4;
/* poll IR chip */
- if (5 != i2c_master_recv(&ir->c,buf,5))
+ if (5 != i2c_master_recv(ir->c, buf, 5))
return -EIO;
cod4 = buf[4];
@@ -224,7 +224,7 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
unsigned char data[12];
u32 gpio;
- struct saa7134_dev *dev = ir->c.adapter->algo_data;
+ struct saa7134_dev *dev = ir->c->adapter->algo_data;
/* rising SAA7134_GPIO_GPRESCAN reads the status */
saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
@@ -235,9 +235,9 @@ static int get_key_beholdm6xx(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
if (0x400000 & ~gpio)
return 0; /* No button press */
- ir->c.addr = 0x5a >> 1;
+ ir->c->addr = 0x5a >> 1;
- if (12 != i2c_master_recv(&ir->c, data, 12)) {
+ if (12 != i2c_master_recv(ir->c, data, 12)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -267,7 +267,7 @@ static int get_key_pinnacle(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw,
unsigned int start = 0,parity = 0,code = 0;
/* poll IR chip */
- if (4 != i2c_master_recv(&ir->c, b, 4)) {
+ if (4 != i2c_master_recv(ir->c, b, 4)) {
i2cdprintk("read error\n");
return -EIO;
}
@@ -686,40 +686,68 @@ void saa7134_input_fini(struct saa7134_dev *dev)
dev->remote = NULL;
}
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
{
+ struct i2c_board_info info;
+ struct IR_i2c_init_data init_data;
+ const unsigned short addr_list[] = {
+ 0x7a, 0x47, 0x71, 0x2d,
+ I2C_CLIENT_END
+ };
+
+ struct i2c_msg msg_msi = {
+ .addr = 0x50,
+ .flags = I2C_M_RD,
+ .len = 0,
+ .buf = NULL,
+ };
+
+ int rc;
+
if (disable_ir) {
- dprintk("Found supported i2c remote, but IR has been disabled\n");
- ir->get_key=NULL;
+ dprintk("IR has been disabled, not probing for i2c remote\n");
return;
}
+ memset(&info, 0, sizeof(struct i2c_board_info));
+ memset(&init_data, 0, sizeof(struct IR_i2c_init_data));
+ strlcpy(info.type, "ir_video", I2C_NAME_SIZE);
+
switch (dev->board) {
case SAA7134_BOARD_PINNACLE_PCTV_110i:
case SAA7134_BOARD_PINNACLE_PCTV_310i:
- snprintf(ir->c.name, sizeof(ir->c.name), "Pinnacle PCTV");
+ init_data.name = "Pinnacle PCTV";
if (pinnacle_remote == 0) {
- ir->get_key = get_key_pinnacle_color;
- ir->ir_codes = ir_codes_pinnacle_color;
+ init_data.get_key = get_key_pinnacle_color;
+ init_data.ir_codes = ir_codes_pinnacle_color;
} else {
- ir->get_key = get_key_pinnacle_grey;
- ir->ir_codes = ir_codes_pinnacle_grey;
+ init_data.get_key = get_key_pinnacle_grey;
+ init_data.ir_codes = ir_codes_pinnacle_grey;
}
break;
case SAA7134_BOARD_UPMOST_PURPLE_TV:
- snprintf(ir->c.name, sizeof(ir->c.name), "Purple TV");
- ir->get_key = get_key_purpletv;
- ir->ir_codes = ir_codes_purpletv;
+ init_data.name = "Purple TV";
+ init_data.get_key = get_key_purpletv;
+ init_data.ir_codes = ir_codes_purpletv;
break;
case SAA7134_BOARD_MSI_TVATANYWHERE_PLUS:
- snprintf(ir->c.name, sizeof(ir->c.name), "MSI TV@nywhere Plus");
- ir->get_key = get_key_msi_tvanywhere_plus;
- ir->ir_codes = ir_codes_msi_tvanywhere_plus;
+ init_data.name = "MSI TV@nywhere Plus";
+ init_data.get_key = get_key_msi_tvanywhere_plus;
+ init_data.ir_codes = ir_codes_msi_tvanywhere_plus;
+ info.addr = 0x30;
+ /* MSI TV@nywhere Plus controller doesn't seem to
+ respond to probes unless we read something from
+ an existing device. Weird...
+ REVISIT: might no longer be needed */
+ rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
+ dprintk(KERN_DEBUG "probe 0x%02x @ %s: %s\n",
+ msg_msi.addr, dev->i2c_adap.name,
+ (1 == rc) ? "yes" : "no");
break;
case SAA7134_BOARD_HAUPPAUGE_HVR1110:
- snprintf(ir->c.name, sizeof(ir->c.name), "HVR 1110");
- ir->get_key = get_key_hvr1110;
- ir->ir_codes = ir_codes_hauppauge_new;
+ init_data.name = "HVR 1110";
+ init_data.get_key = get_key_hvr1110;
+ init_data.ir_codes = ir_codes_hauppauge_new;
break;
case SAA7134_BOARD_BEHOLD_607FM_MK3:
case SAA7134_BOARD_BEHOLD_607FM_MK5:
@@ -733,15 +761,26 @@ void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir)
case SAA7134_BOARD_BEHOLD_M63:
case SAA7134_BOARD_BEHOLD_M6_EXTRA:
case SAA7134_BOARD_BEHOLD_H6:
- snprintf(ir->c.name, sizeof(ir->c.name), "BeholdTV");
- ir->get_key = get_key_beholdm6xx;
- ir->ir_codes = ir_codes_behold;
+ init_data.name = "BeholdTV";
+ init_data.get_key = get_key_beholdm6xx;
+ init_data.ir_codes = ir_codes_behold;
break;
- default:
- dprintk("Shouldn't get here: Unknown board %x for I2C IR?\n",dev->board);
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_501:
+ case SAA7134_BOARD_AVERMEDIA_CARDBUS_506:
+ info.addr = 0x40;
break;
}
+ if (init_data.name)
+ info.platform_data = &init_data;
+ /* No need to probe if address is known */
+ if (info.addr) {
+ i2c_new_device(&dev->i2c_adap, &info);
+ return;
+ }
+
+ /* Address not known, fallback to probing */
+ i2c_new_probed_device(&dev->i2c_adap, &info, addr_list);
}
static int saa7134_rc5_irq(struct saa7134_dev *dev)
diff --git a/linux/drivers/media/video/saa7134/saa7134-ts.c b/linux/drivers/media/video/saa7134/saa7134-ts.c
index cc8b923af..b8ff459d0 100644
--- a/linux/drivers/media/video/saa7134/saa7134-ts.c
+++ b/linux/drivers/media/video/saa7134/saa7134-ts.c
@@ -65,7 +65,7 @@ static int buffer_activate(struct saa7134_dev *dev,
/* start DMA */
saa7134_set_dmabits(dev);
- mod_timer(&dev->ts_q.timeout, jiffies+BUFFER_TIMEOUT);
+ mod_timer(&dev->ts_q.timeout, jiffies+TS_BUFFER_TIMEOUT);
if (dev->ts_state == SAA7134_TS_BUFF_DONE) {
/* Clear TS cache */
diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c
index 5f68bed54..26f1727e6 100644
--- a/linux/drivers/media/video/saa7134/saa7134-video.c
+++ b/linux/drivers/media/video/saa7134/saa7134-video.c
@@ -1423,11 +1423,13 @@ video_poll(struct file *file, struct poll_table_struct *wait)
{
struct saa7134_fh *fh = file->private_data;
struct videobuf_buffer *buf = NULL;
+ unsigned int rc = 0;
if (V4L2_BUF_TYPE_VBI_CAPTURE == fh->type)
return videobuf_poll_stream(file, &fh->vbi, wait);
if (res_check(fh,RESOURCE_VIDEO)) {
+ mutex_lock(&fh->cap.vb_lock);
if (!list_empty(&fh->cap.stream))
buf = list_entry(fh->cap.stream.next, struct videobuf_buffer, stream);
} else {
@@ -1446,13 +1448,14 @@ video_poll(struct file *file, struct poll_table_struct *wait)
}
if (!buf)
- return POLLERR;
+ rc = POLLERR;
poll_wait(file, &buf->done, wait);
if (buf->state == VIDEOBUF_DONE ||
buf->state == VIDEOBUF_ERROR)
- return POLLIN|POLLRDNORM;
- return 0;
+ rc = POLLIN|POLLRDNORM;
+ mutex_unlock(&fh->cap.vb_lock);
+ return rc;
err:
mutex_unlock(&fh->cap.vb_lock);
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index d961e0861..be6763dde 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -377,6 +377,7 @@ struct saa7134_board {
#define INTERLACE_OFF 2
#define BUFFER_TIMEOUT msecs_to_jiffies(500) /* 0.5 seconds */
+#define TS_BUFFER_TIMEOUT msecs_to_jiffies(1000) /* 1 second */
struct saa7134_dev;
struct saa7134_dma;
@@ -803,7 +804,7 @@ void saa7134_irq_oss_done(struct saa7134_dev *dev, unsigned long status);
int saa7134_input_init1(struct saa7134_dev *dev);
void saa7134_input_fini(struct saa7134_dev *dev);
void saa7134_input_irq(struct saa7134_dev *dev);
-void saa7134_set_i2c_ir(struct saa7134_dev *dev, struct IR_i2c *ir);
+void saa7134_probe_i2c_ir(struct saa7134_dev *dev);
void saa7134_ir_start(struct saa7134_dev *dev, struct card_ir *ir);
void saa7134_ir_stop(struct saa7134_dev *dev);
diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c
index f792ab2e5..822052b25 100644
--- a/linux/drivers/media/video/soc_camera.c
+++ b/linux/drivers/media/video/soc_camera.c
@@ -1204,7 +1204,7 @@ static int __devexit soc_camera_pdrv_remove(struct platform_device *pdev)
return 0;
}
-static struct platform_driver soc_camera_pdrv = {
+static struct platform_driver __refdata soc_camera_pdrv = {
.probe = soc_camera_pdrv_probe,
.remove = __exit_p(soc_camera_pdrv_remove),
.driver = {
diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c
index 7cbc4f736..886caf736 100644
--- a/linux/drivers/media/video/stk-webcam.c
+++ b/linux/drivers/media/video/stk-webcam.c
@@ -1138,7 +1138,7 @@ static int stk_vidioc_querybuf(struct file *filp,
struct stk_camera *dev = priv;
struct stk_sio_buffer *sbuf;
- if (buf->index < 0 || buf->index >= dev->n_sbufs)
+ if (buf->index >= dev->n_sbufs)
return -EINVAL;
sbuf = dev->sio_bufs + buf->index;
*buf = sbuf->v4lbuf;
@@ -1155,7 +1155,7 @@ static int stk_vidioc_qbuf(struct file *filp,
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- if (buf->index < 0 || buf->index >= dev->n_sbufs)
+ if (buf->index >= dev->n_sbufs)
return -EINVAL;
sbuf = dev->sio_bufs + buf->index;
if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED)
diff --git a/linux/drivers/media/video/tea6415c.c b/linux/drivers/media/video/tea6415c.c
index de866798b..910e156f4 100644
--- a/linux/drivers/media/video/tea6415c.c
+++ b/linux/drivers/media/video/tea6415c.c
@@ -147,7 +147,6 @@ static const struct v4l2_subdev_ops tea6415c_ops = {
.video = &tea6415c_video_ops,
};
-/* this function is called by i2c_probe */
static int tea6415c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
diff --git a/linux/drivers/media/video/tea6420.c b/linux/drivers/media/video/tea6420.c
index 90054dfbe..0e7bb8d6a 100644
--- a/linux/drivers/media/video/tea6420.c
+++ b/linux/drivers/media/video/tea6420.c
@@ -118,7 +118,6 @@ static const struct v4l2_subdev_ops tea6420_ops = {
.audio = &tea6420_audio_ops,
};
-/* this function is called by i2c_probe */
static int tea6420_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
diff --git a/linux/drivers/media/video/ths7303.c b/linux/drivers/media/video/ths7303.c
new file mode 100644
index 000000000..21781f8a0
--- /dev/null
+++ b/linux/drivers/media/video/ths7303.c
@@ -0,0 +1,151 @@
+/*
+ * ths7303- THS7303 Video Amplifier driver
+ *
+ * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * 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 version 2.
+ *
+ * This program is distributed .as is. WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/ctype.h>
+#include <linux/i2c.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/videodev2.h>
+
+#include <media/v4l2-device.h>
+#include <media/v4l2-subdev.h>
+#include <media/v4l2-chip-ident.h>
+
+MODULE_DESCRIPTION("TI THS7303 video amplifier driver");
+MODULE_AUTHOR("Chaithrika U S");
+MODULE_LICENSE("GPL");
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Debug level 0-1");
+
+/* following function is used to set ths7303 */
+static int ths7303_setvalue(struct v4l2_subdev *sd, v4l2_std_id std)
+{
+ int err = 0;
+ u8 val;
+ struct i2c_client *client;
+
+ client = v4l2_get_subdevdata(sd);
+
+ if (std & (V4L2_STD_ALL & ~V4L2_STD_SECAM)) {
+ val = 0x02;
+ v4l2_dbg(1, debug, sd, "setting value for SDTV format\n");
+ } else {
+ val = 0x00;
+ v4l2_dbg(1, debug, sd, "disabling all channels\n");
+ }
+
+ err |= i2c_smbus_write_byte_data(client, 0x01, val);
+ err |= i2c_smbus_write_byte_data(client, 0x02, val);
+ err |= i2c_smbus_write_byte_data(client, 0x03, val);
+
+ if (err)
+ v4l2_err(sd, "write failed\n");
+
+ return err;
+}
+
+static int ths7303_s_std_output(struct v4l2_subdev *sd, v4l2_std_id norm)
+{
+ return ths7303_setvalue(sd, norm);
+}
+
+static int ths7303_g_chip_ident(struct v4l2_subdev *sd,
+ struct v4l2_dbg_chip_ident *chip)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_THS7303, 0);
+}
+
+static const struct v4l2_subdev_video_ops ths7303_video_ops = {
+ .s_std_output = ths7303_s_std_output,
+};
+
+static const struct v4l2_subdev_core_ops ths7303_core_ops = {
+ .g_chip_ident = ths7303_g_chip_ident,
+};
+
+static const struct v4l2_subdev_ops ths7303_ops = {
+ .core = &ths7303_core_ops,
+ .video = &ths7303_video_ops,
+};
+
+static int ths7303_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct v4l2_subdev *sd;
+ v4l2_std_id std_id = V4L2_STD_NTSC;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+ return -ENODEV;
+
+ v4l_info(client, "chip found @ 0x%x (%s)\n",
+ client->addr << 1, client->adapter->name);
+
+ sd = kzalloc(sizeof(struct v4l2_subdev), GFP_KERNEL);
+ if (sd == NULL)
+ return -ENOMEM;
+
+ v4l2_i2c_subdev_init(sd, client, &ths7303_ops);
+
+ return ths7303_setvalue(sd, std_id);
+}
+
+static int ths7303_remove(struct i2c_client *client)
+{
+ struct v4l2_subdev *sd = i2c_get_clientdata(client);
+
+ v4l2_device_unregister_subdev(sd);
+ kfree(sd);
+
+ return 0;
+}
+
+static const struct i2c_device_id ths7303_id[] = {
+ {"ths7303", 0},
+ {},
+};
+
+MODULE_DEVICE_TABLE(i2c, ths7303_id);
+
+static struct i2c_driver ths7303_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ths7303",
+ },
+ .probe = ths7303_probe,
+ .remove = ths7303_remove,
+ .id_table = ths7303_id,
+};
+
+static int __init ths7303_init(void)
+{
+ return i2c_add_driver(&ths7303_driver);
+}
+
+static void __exit ths7303_exit(void)
+{
+ i2c_del_driver(&ths7303_driver);
+}
+
+module_init(ths7303_init);
+module_exit(ths7303_exit);
+
diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c
index bb60c910e..cb715f143 100644
--- a/linux/drivers/media/video/tuner-core.c
+++ b/linux/drivers/media/video/tuner-core.c
@@ -434,10 +434,6 @@ static void set_type(struct i2c_client *c, unsigned int type,
if (!dvb_attach(xc5000_attach,
&t->fe, t->i2c->adapter, &xc5000_cfg))
goto attach_failed;
-
- xc_tuner_ops = &t->fe.ops.tuner_ops;
- if (xc_tuner_ops->init)
- xc_tuner_ops->init(&t->fe);
break;
}
default:
diff --git a/linux/drivers/media/video/tveeprom.c b/linux/drivers/media/video/tveeprom.c
index cdea91aae..7d6459dd2 100644
--- a/linux/drivers/media/video/tveeprom.c
+++ b/linux/drivers/media/video/tveeprom.c
@@ -211,7 +211,7 @@ hauppauge_tuner[] =
{ TUNER_TEA5767, "Philips TEA5768HL FM Radio"},
{ TUNER_ABSENT, "Panasonic ENV57H12D5"},
{ TUNER_PHILIPS_FM1236_MK3, "TCL MFNM05-4"},
- { TUNER_ABSENT, "TCL MNM05-4"},
+ { TUNER_PHILIPS_FM1236_MK3, "TCL MNM05-4"},
{ TUNER_PHILIPS_FM1216ME_MK3, "TCL MPE05-2"},
{ TUNER_ABSENT, "TCL MQNM05-4"},
{ TUNER_ABSENT, "LG TAPC-W701D"},
diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c
index d7056a5b7..d03e5922d 100644
--- a/linux/drivers/media/video/usbvision/usbvision-video.c
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c
@@ -541,7 +541,7 @@ static int vidioc_enum_input (struct file *file, void *priv,
struct usb_usbvision *usbvision = video_drvdata(file);
int chan;
- if ((vi->index >= usbvision->video_inputs) || (vi->index < 0) )
+ if (vi->index >= usbvision->video_inputs)
return -EINVAL;
if (usbvision->have_tuner) {
chan = vi->index;
diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c
index 4a69a3af6..8d193376c 100644
--- a/linux/drivers/media/video/uvc/uvc_driver.c
+++ b/linux/drivers/media/video/uvc/uvc_driver.c
@@ -289,10 +289,8 @@ static int uvc_parse_format(struct uvc_device *dev,
struct uvc_format_desc *fmtdesc;
struct uvc_frame *frame;
const unsigned char *start = buffer;
- unsigned char *_buffer;
unsigned int interval;
unsigned int i, n;
- int _buflen;
__u8 ftype;
format->type = buffer[2];
@@ -303,7 +301,7 @@ static int uvc_parse_format(struct uvc_device *dev,
case VS_FORMAT_FRAME_BASED:
n = buffer[2] == VS_FORMAT_UNCOMPRESSED ? 27 : 28;
if (buflen < n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d FORMAT error\n",
dev->udev->devnum,
alts->desc.bInterfaceNumber);
@@ -338,7 +336,7 @@ static int uvc_parse_format(struct uvc_device *dev,
case VS_FORMAT_MJPEG:
if (buflen < 11) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d FORMAT error\n",
dev->udev->devnum,
alts->desc.bInterfaceNumber);
@@ -354,7 +352,7 @@ static int uvc_parse_format(struct uvc_device *dev,
case VS_FORMAT_DV:
if (buflen < 9) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d FORMAT error\n",
dev->udev->devnum,
alts->desc.bInterfaceNumber);
@@ -372,7 +370,7 @@ static int uvc_parse_format(struct uvc_device *dev,
strlcpy(format->name, "HD-DV", sizeof format->name);
break;
default:
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d: unknown DV format %u\n",
dev->udev->devnum,
alts->desc.bInterfaceNumber, buffer[8]);
@@ -401,7 +399,7 @@ static int uvc_parse_format(struct uvc_device *dev,
case VS_FORMAT_STREAM_BASED:
/* Not supported yet. */
default:
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d unsupported format %u\n",
dev->udev->devnum, alts->desc.bInterfaceNumber,
buffer[2]);
@@ -413,20 +411,11 @@ static int uvc_parse_format(struct uvc_device *dev,
buflen -= buffer[0];
buffer += buffer[0];
- /* Count the number of frame descriptors to test the bFrameIndex
- * field when parsing the descriptors. We can't rely on the
- * bNumFrameDescriptors field as some cameras don't initialize it
- * properly.
- */
- for (_buflen = buflen, _buffer = buffer;
- _buflen > 2 && _buffer[2] == ftype;
- _buflen -= _buffer[0], _buffer += _buffer[0])
- format->nframes++;
-
/* Parse the frame descriptors. Only uncompressed, MJPEG and frame
* based formats have frame descriptors.
*/
while (buflen > 2 && buffer[2] == ftype) {
+ frame = &format->frame[format->nframes];
if (ftype != VS_FRAME_FRAME_BASED)
n = buflen > 25 ? buffer[25] : 0;
else
@@ -435,22 +424,12 @@ static int uvc_parse_format(struct uvc_device *dev,
n = n ? n : 3;
if (buflen < 26 + 4*n) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d FRAME error\n", dev->udev->devnum,
alts->desc.bInterfaceNumber);
return -EINVAL;
}
- if (buffer[3] - 1 >= format->nframes) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
- "interface %d frame index %u out of range\n",
- dev->udev->devnum, alts->desc.bInterfaceNumber,
- buffer[3]);
- return -EINVAL;
- }
-
- frame = &format->frame[buffer[3] - 1];
-
frame->bFrameIndex = buffer[3];
frame->bmCapabilities = buffer[4];
frame->wWidth = get_unaligned_le16(&buffer[5]);
@@ -507,6 +486,7 @@ static int uvc_parse_format(struct uvc_device *dev,
10000000/frame->dwDefaultFrameInterval,
(100000000/frame->dwDefaultFrameInterval)%10);
+ format->nframes++;
buflen -= buffer[0];
buffer += buffer[0];
}
@@ -518,7 +498,7 @@ static int uvc_parse_format(struct uvc_device *dev,
if (buflen > 2 && buffer[2] == VS_COLORFORMAT) {
if (buflen < 6) {
- uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming"
+ uvc_trace(UVC_TRACE_DESCR, "device %d videostreaming "
"interface %d COLORFORMAT error\n",
dev->udev->devnum,
alts->desc.bInterfaceNumber);
@@ -1316,7 +1296,7 @@ static int uvc_scan_chain_forward(struct uvc_video_device *video,
continue;
if (forward->extension.bNrInPins != 1) {
- uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has"
+ uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has "
"more than 1 input pin.\n", entity->id);
return -1;
}
@@ -1614,6 +1594,7 @@ static int uvc_probe(struct usb_interface *intf,
INIT_LIST_HEAD(&dev->entities);
INIT_LIST_HEAD(&dev->streaming);
kref_init(&dev->kref);
+ atomic_set(&dev->users, 0);
dev->udev = usb_get_dev(udev);
dev->intf = usb_get_intf(intf);
@@ -1929,7 +1910,7 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
- /* Lenovo Thinkpad SL500 */
+ /* Lenovo Thinkpad SL400/SL500 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
.idVendor = 0x17ef,
diff --git a/linux/drivers/media/video/uvc/uvc_status.c b/linux/drivers/media/video/uvc/uvc_status.c
index 1e1bda413..b05df63b4 100644
--- a/linux/drivers/media/video/uvc/uvc_status.c
+++ b/linux/drivers/media/video/uvc/uvc_status.c
@@ -206,7 +206,7 @@ int uvc_status_init(struct uvc_device *dev)
dev->status, UVC_MAX_STATUS_SIZE, uvc_status_complete,
dev, interval);
- return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+ return 0;
}
void uvc_status_cleanup(struct uvc_device *dev)
@@ -217,15 +217,30 @@ void uvc_status_cleanup(struct uvc_device *dev)
uvc_input_cleanup(dev);
}
-int uvc_status_suspend(struct uvc_device *dev)
+int uvc_status_start(struct uvc_device *dev)
+{
+ if (dev->int_urb == NULL)
+ return 0;
+
+ return usb_submit_urb(dev->int_urb, GFP_KERNEL);
+}
+
+void uvc_status_stop(struct uvc_device *dev)
{
usb_kill_urb(dev->int_urb);
+}
+
+int uvc_status_suspend(struct uvc_device *dev)
+{
+ if (atomic_read(&dev->users))
+ usb_kill_urb(dev->int_urb);
+
return 0;
}
int uvc_status_resume(struct uvc_device *dev)
{
- if (dev->int_urb == NULL)
+ if (dev->int_urb == NULL || atomic_read(&dev->users) == 0)
return 0;
return usb_submit_urb(dev->int_urb, GFP_NOIO);
diff --git a/linux/drivers/media/video/uvc/uvc_v4l2.c b/linux/drivers/media/video/uvc/uvc_v4l2.c
index bc13dbf05..160c01314 100644
--- a/linux/drivers/media/video/uvc/uvc_v4l2.c
+++ b/linux/drivers/media/video/uvc/uvc_v4l2.c
@@ -443,6 +443,17 @@ static int uvc_v4l2_open(struct file *file)
goto done;
}
+ if (atomic_inc_return(&video->dev->users) == 1) {
+ if ((ret = uvc_status_start(video->dev)) < 0) {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
+ usb_autopm_put_interface(video->dev->intf);
+#endif
+ atomic_dec(&video->dev->users);
+ kfree(handle);
+ goto done;
+ }
+ }
+
handle->device = video;
handle->state = UVC_HANDLE_PASSIVE;
file->private_data = handle;
@@ -477,6 +488,9 @@ static int uvc_v4l2_release(struct file *file)
kfree(handle);
file->private_data = NULL;
+ if (atomic_dec_return(&video->dev->users) == 0)
+ uvc_status_stop(video->dev);
+
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 19)
usb_autopm_put_interface(video->dev->intf);
#endif
diff --git a/linux/drivers/media/video/uvc/uvc_video.c b/linux/drivers/media/video/uvc/uvc_video.c
index c5df33de9..07e755ba7 100644
--- a/linux/drivers/media/video/uvc/uvc_video.c
+++ b/linux/drivers/media/video/uvc/uvc_video.c
@@ -65,7 +65,8 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
struct uvc_streaming_control *ctrl)
{
struct uvc_format *format;
- struct uvc_frame *frame;
+ struct uvc_frame *frame = NULL;
+ unsigned int i;
if (ctrl->bFormatIndex <= 0 ||
ctrl->bFormatIndex > video->streaming->nformats)
@@ -73,11 +74,15 @@ static void uvc_fixup_video_ctrl(struct uvc_video_device *video,
format = &video->streaming->format[ctrl->bFormatIndex - 1];
- if (ctrl->bFrameIndex <= 0 ||
- ctrl->bFrameIndex > format->nframes)
- return;
+ for (i = 0; i < format->nframes; ++i) {
+ if (format->frame[i].bFrameIndex == ctrl->bFrameIndex) {
+ frame = &format->frame[i];
+ break;
+ }
+ }
- frame = &format->frame[ctrl->bFrameIndex - 1];
+ if (frame == NULL)
+ return;
if (!(format->flags & UVC_FMT_FLAG_COMPRESSED) ||
(ctrl->dwMaxVideoFrameSize == 0 &&
@@ -1093,7 +1098,7 @@ int uvc_video_init(struct uvc_video_device *video)
/* Zero bFrameIndex might be correct. Stream-based formats (including
* MPEG-2 TS and DV) do not support frames but have a dummy frame
* descriptor with bFrameIndex set to zero. If the default frame
- * descriptor is not found, use the first avalable frame.
+ * descriptor is not found, use the first available frame.
*/
for (i = format->nframes; i > 0; --i) {
frame = &format->frame[i-1];
diff --git a/linux/drivers/media/video/uvc/uvcvideo.h b/linux/drivers/media/video/uvc/uvcvideo.h
index 53d5c9e0c..6b254fd39 100644
--- a/linux/drivers/media/video/uvc/uvcvideo.h
+++ b/linux/drivers/media/video/uvc/uvcvideo.h
@@ -635,6 +635,7 @@ struct uvc_device {
enum uvc_device_state state;
struct kref kref;
struct list_head list;
+ atomic_t users;
/* Video control interface */
__u16 uvc_version;
@@ -771,6 +772,8 @@ extern int uvc_query_ctrl(struct uvc_device *dev, __u8 query, __u8 unit,
/* Status */
extern int uvc_status_init(struct uvc_device *dev);
extern void uvc_status_cleanup(struct uvc_device *dev);
+extern int uvc_status_start(struct uvc_device *dev);
+extern void uvc_status_stop(struct uvc_device *dev);
extern int uvc_status_suspend(struct uvc_device *dev);
extern int uvc_status_resume(struct uvc_device *dev);
diff --git a/linux/drivers/media/video/v4l2-device.c b/linux/drivers/media/video/v4l2-device.c
index c76f83840..b962862fe 100644
--- a/linux/drivers/media/video/v4l2-device.c
+++ b/linux/drivers/media/video/v4l2-device.c
@@ -86,6 +86,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
/* Unregister subdevs */
list_for_each_entry_safe(sd, next, &v4l2_dev->subdevs, list) {
v4l2_device_unregister_subdev(sd);
+#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)
if (sd->flags & V4L2_SUBDEV_FL_IS_I2C) {
struct i2c_client *client = v4l2_get_subdevdata(sd);
@@ -96,6 +97,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev)
if (client)
i2c_unregister_device(client);
}
+#endif
}
}
EXPORT_SYMBOL_GPL(v4l2_device_unregister);
diff --git a/linux/drivers/media/video/videobuf-core.c b/linux/drivers/media/video/videobuf-core.c
index b104cd593..e9696385d 100644
--- a/linux/drivers/media/video/videobuf-core.c
+++ b/linux/drivers/media/video/videobuf-core.c
@@ -440,6 +440,7 @@ int videobuf_reqbufs(struct videobuf_queue *q,
}
req->count = retval;
+ retval = 0;
done:
mutex_unlock(&q->vb_lock);
@@ -455,7 +456,7 @@ int videobuf_querybuf(struct videobuf_queue *q, struct v4l2_buffer *b)
dprintk(1, "querybuf: Wrong type.\n");
goto done;
}
- if (unlikely(b->index < 0 || b->index >= VIDEO_MAX_FRAME)) {
+ if (unlikely(b->index >= VIDEO_MAX_FRAME)) {
dprintk(1, "querybuf: index out of range.\n");
goto done;
}
@@ -496,7 +497,7 @@ int videobuf_qbuf(struct videobuf_queue *q,
dprintk(1, "qbuf: Wrong type.\n");
goto done;
}
- if (b->index < 0 || b->index >= VIDEO_MAX_FRAME) {
+ if (b->index >= VIDEO_MAX_FRAME) {
dprintk(1, "qbuf: index out of range.\n");
goto done;
}
diff --git a/linux/drivers/media/video/videobuf-dma-contig.c b/linux/drivers/media/video/videobuf-dma-contig.c
index 6db1398fd..633a124cf 100644
--- a/linux/drivers/media/video/videobuf-dma-contig.c
+++ b/linux/drivers/media/video/videobuf-dma-contig.c
@@ -183,19 +183,6 @@ static int __videobuf_iolock(struct videobuf_queue *q,
return 0;
}
-static int __videobuf_sync(struct videobuf_queue *q,
- struct videobuf_buffer *buf)
-{
- struct videobuf_dma_contig_memory *mem = buf->priv;
-
- BUG_ON(!mem);
- MAGIC_CHECK(mem->magic, MAGIC_DC_MEM);
-
- dma_sync_single_for_cpu(q->dev, mem->dma_handle, mem->size,
- DMA_FROM_DEVICE);
- return 0;
-}
-
static int __videobuf_mmap_free(struct videobuf_queue *q)
{
unsigned int i;
@@ -357,7 +344,6 @@ static struct videobuf_qtype_ops qops = {
.alloc = __videobuf_alloc,
.iolock = __videobuf_iolock,
- .sync = __videobuf_sync,
.mmap_free = __videobuf_mmap_free,
.mmap_mapper = __videobuf_mmap_mapper,
.video_copy_to_user = __videobuf_copy_to_user,
diff --git a/linux/drivers/media/video/videobuf-dma-sg.c b/linux/drivers/media/video/videobuf-dma-sg.c
index ed38145e1..623e2fc12 100644
--- a/linux/drivers/media/video/videobuf-dma-sg.c
+++ b/linux/drivers/media/video/videobuf-dma-sg.c
@@ -59,9 +59,10 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
struct page *pg;
int i;
- sglist = kcalloc(nr_pages, sizeof(struct scatterlist), GFP_KERNEL);
+ sglist = vmalloc(nr_pages * sizeof(*sglist));
if (NULL == sglist)
return NULL;
+ memset(sglist, 0, nr_pages * sizeof(*sglist));
sg_init_table(sglist, nr_pages);
for (i = 0; i < nr_pages; i++, virt += PAGE_SIZE) {
pg = vmalloc_to_page(virt);
@@ -73,7 +74,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
return sglist;
err:
- kfree(sglist);
+ vfree(sglist);
return NULL;
}
@@ -85,7 +86,7 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
if (NULL == pages[0])
return NULL;
- sglist = kmalloc(nr_pages * sizeof(*sglist), GFP_KERNEL);
+ sglist = vmalloc(nr_pages * sizeof(*sglist));
if (NULL == sglist)
return NULL;
sg_init_table(sglist, nr_pages);
@@ -105,12 +106,12 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
nopage:
dprintk(2,"sgl: oops - no page\n");
- kfree(sglist);
+ vfree(sglist);
return NULL;
highmem:
dprintk(2,"sgl: oops - highmem page\n");
- kfree(sglist);
+ vfree(sglist);
return NULL;
}
@@ -231,7 +232,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
(dma->vmalloc,dma->nr_pages);
}
if (dma->bus_addr) {
- dma->sglist = kmalloc(sizeof(struct scatterlist), GFP_KERNEL);
+ dma->sglist = vmalloc(sizeof(*dma->sglist));
if (NULL != dma->sglist) {
dma->sglen = 1;
sg_dma_address(&dma->sglist[0]) = dma->bus_addr & PAGE_MASK;
@@ -249,7 +250,7 @@ int videobuf_dma_map(struct videobuf_queue* q, struct videobuf_dmabuf *dma)
if (0 == dma->sglen) {
printk(KERN_WARNING
"%s: videobuf_map_sg failed\n",__func__);
- kfree(dma->sglist);
+ vfree(dma->sglist);
dma->sglist = NULL;
dma->sglen = 0;
return -EIO;
@@ -275,7 +276,7 @@ int videobuf_dma_unmap(struct videobuf_queue* q,struct videobuf_dmabuf *dma)
dma_unmap_sg(q->dev, dma->sglist, dma->nr_pages, dma->direction);
- kfree(dma->sglist);
+ vfree(dma->sglist);
dma->sglist = NULL;
dma->sglen = 0;
return 0;
diff --git a/linux/drivers/media/video/zoran/zoran_card.c b/linux/drivers/media/video/zoran/zoran_card.c
index 733db7690..67ab10878 100644
--- a/linux/drivers/media/video/zoran/zoran_card.c
+++ b/linux/drivers/media/video/zoran/zoran_card.c
@@ -1023,7 +1023,7 @@ zr36057_init (struct zoran *zr)
zr->vbuf_bytesperline = 0;
/* Avoid nonsense settings from user for default input/norm */
- if (default_norm < 0 && default_norm > 2)
+ if (default_norm < 0 || default_norm > 2)
default_norm = 0;
if (default_norm == 0) {
zr->norm = V4L2_STD_PAL;