summaryrefslogtreecommitdiff
path: root/linux/drivers/media
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2009-04-01 07:36:31 -0300
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-04-01 07:36:31 -0300
commite149dc20dba1c192f28fbeab92aac7f004a41273 (patch)
tree18aaa82ffabd3790e47ef35e2f631932ef5c46e8 /linux/drivers/media
parentfdab553be22b01acd8124650ed75da649169596f (diff)
parente8b1f94e600957e27366e37a729126388c705c7d (diff)
downloadmediapointer-dvb-s2-e149dc20dba1c192f28fbeab92aac7f004a41273.tar.gz
mediapointer-dvb-s2-e149dc20dba1c192f28fbeab92aac7f004a41273.tar.bz2
merge: http://linuxtv.org/hg/~anttip/af9015/
From: Mauro Carvalho Chehab <mchehab@redhat.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'linux/drivers/media')
-rw-r--r--linux/drivers/media/common/saa7146_video.c2
-rw-r--r--linux/drivers/media/common/tuners/mxl5005s.c7
-rw-r--r--linux/drivers/media/common/tuners/tda827x.c54
-rw-r--r--linux/drivers/media/dvb/b2c2/Makefile1
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-common.h64
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-dma.c27
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-eeprom.c47
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c6
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c171
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-i2c.c61
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-misc.c68
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-pci.c180
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-reg.h21
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-sram.c112
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-usb.c368
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop-usb.h62
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop.c86
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop.h20
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h7
-rw-r--r--linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h7
-rw-r--r--linux/drivers/media/dvb/bt8xx/dst_ca.c12
-rw-r--r--linux/drivers/media/dvb/dvb-usb/Kconfig2
-rw-r--r--linux/drivers/media/dvb/dvb-usb/ce6230.c10
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dib0700_devices.c14
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h6
-rw-r--r--linux/drivers/media/dvb/dvb-usb/dvb-usb.h2
-rw-r--r--linux/drivers/media/dvb/frontends/au8522_decoder.c1
-rw-r--r--linux/drivers/media/dvb/frontends/itd1000_priv.h2
-rw-r--r--linux/drivers/media/dvb/frontends/stb6100_cfg.h4
-rw-r--r--linux/drivers/media/dvb/pluto2/pluto2.c7
-rw-r--r--linux/drivers/media/dvb/siano/smssdio.c356
-rw-r--r--linux/drivers/media/dvb/ttpci/budget-ci.c6
-rw-r--r--linux/drivers/media/video/Kconfig26
-rw-r--r--linux/drivers/media/video/bt8xx/Kconfig2
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-cards.c179
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-driver.c43
-rw-r--r--linux/drivers/media/video/bt8xx/bttv-i2c.c52
-rw-r--r--linux/drivers/media/video/bt8xx/bttv.h7
-rw-r--r--linux/drivers/media/video/bt8xx/bttvp.h5
-rw-r--r--linux/drivers/media/video/cafe_ccic.c14
-rw-r--r--linux/drivers/media/video/cs5345.c7
-rw-r--r--linux/drivers/media/video/cs53l32a.c10
-rw-r--r--linux/drivers/media/video/cx18/cx18-av-audio.c120
-rw-r--r--linux/drivers/media/video/cx18/cx18-av-core.c29
-rw-r--r--linux/drivers/media/video/cx18/cx18-av-core.h9
-rw-r--r--linux/drivers/media/video/cx18/cx18-av-vbi.c325
-rw-r--r--linux/drivers/media/video/cx231xx/Kconfig8
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-417.c52
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-cards.c4
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-core.c19
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-dvb.c2
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-i2c.c87
-rw-r--r--linux/drivers/media/video/cx23885/cx23885-video.c66
-rw-r--r--linux/drivers/media/video/cx23885/cx23885.h14
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-audio.c121
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.c49
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-core.h8
-rw-r--r--linux/drivers/media/video/cx25840/cx25840-vbi.c314
-rw-r--r--linux/drivers/media/video/cx88/cx88-blackbird.c8
-rw-r--r--linux/drivers/media/video/cx88/cx88-cards.c53
-rw-r--r--linux/drivers/media/video/cx88/cx88-core.c9
-rw-r--r--linux/drivers/media/video/cx88/cx88-dvb.c2
-rw-r--r--linux/drivers/media/video/cx88/cx88-i2c.c39
-rw-r--r--linux/drivers/media/video/cx88/cx88-video.c44
-rw-r--r--linux/drivers/media/video/cx88/cx88.h14
-rw-r--r--linux/drivers/media/video/dabusb.c13
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-cards.c145
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-core.c9
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-i2c.c72
-rw-r--r--linux/drivers/media/video/em28xx/em28xx-video.c78
-rw-r--r--linux/drivers/media/video/em28xx/em28xx.h10
-rw-r--r--linux/drivers/media/video/gspca/gspca.c4
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr-control.c22
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr-core.c69
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr-video.c133
-rw-r--r--linux/drivers/media/video/hdpvr/hdpvr.h7
-rw-r--r--linux/drivers/media/video/ks0127.c23
-rw-r--r--linux/drivers/media/video/m52790.c6
-rw-r--r--linux/drivers/media/video/meye.c29
-rw-r--r--linux/drivers/media/video/msp3400-driver.c2
-rw-r--r--linux/drivers/media/video/mt9m001.c2
-rw-r--r--linux/drivers/media/video/omap24xxcam.c6
-rw-r--r--linux/drivers/media/video/ov772x.c65
-rw-r--r--linux/drivers/media/video/ovcamchip/ovcamchip_core.c6
-rw-r--r--linux/drivers/media/video/pvrusb2/Makefile1
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c12
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c1
-rw-r--r--linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c14
-rw-r--r--linux/drivers/media/video/pxa_camera.c511
-rw-r--r--linux/drivers/media/video/saa6588.c10
-rw-r--r--linux/drivers/media/video/saa7115.c4
-rw-r--r--linux/drivers/media/video/saa7134/Kconfig1
-rw-r--r--linux/drivers/media/video/saa7134/saa6752hs.c2
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-cards.c9
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-core.c16
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-empress.c3
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-video.c37
-rw-r--r--linux/drivers/media/video/saa7134/saa7134.h2
-rw-r--r--linux/drivers/media/video/saa717x.c7
-rw-r--r--linux/drivers/media/video/saa7191.c1
-rw-r--r--linux/drivers/media/video/soc_camera.c6
-rw-r--r--linux/drivers/media/video/stk-webcam.c10
-rw-r--r--linux/drivers/media/video/tda7432.c10
-rw-r--r--linux/drivers/media/video/tda9875.c10
-rw-r--r--linux/drivers/media/video/tlv320aic23b.c6
-rw-r--r--linux/drivers/media/video/tuner-core.c149
-rw-r--r--linux/drivers/media/video/tvaudio.c158
-rw-r--r--linux/drivers/media/video/tvp5150.c8
-rw-r--r--linux/drivers/media/video/upd64031a.c6
-rw-r--r--linux/drivers/media/video/upd64083.c6
-rw-r--r--linux/drivers/media/video/usbvideo/vicam.c2
-rw-r--r--linux/drivers/media/video/usbvision/usbvision-video.c10
-rw-r--r--linux/drivers/media/video/uvc/uvc_driver.c9
-rw-r--r--linux/drivers/media/video/uvc/uvc_v4l2.c6
-rw-r--r--linux/drivers/media/video/v4l1-compat.c9
-rw-r--r--linux/drivers/media/video/v4l2-dev.c19
-rw-r--r--linux/drivers/media/video/v4l2-ioctl.c7
-rw-r--r--linux/drivers/media/video/vino.c290
-rw-r--r--linux/drivers/media/video/vp27smpx.c6
-rw-r--r--linux/drivers/media/video/vpx3220.c8
-rw-r--r--linux/drivers/media/video/wm8739.c6
-rw-r--r--linux/drivers/media/video/wm8775.c11
-rw-r--r--linux/drivers/media/video/zoran/zoran_driver.c4
-rw-r--r--linux/drivers/media/video/zr364xx.c16
124 files changed, 3111 insertions, 2527 deletions
diff --git a/linux/drivers/media/common/saa7146_video.c b/linux/drivers/media/common/saa7146_video.c
index ace925134..46c59da56 100644
--- a/linux/drivers/media/common/saa7146_video.c
+++ b/linux/drivers/media/common/saa7146_video.c
@@ -724,8 +724,6 @@ static int vidioc_g_parm(struct file *file, void *fh,
struct saa7146_dev *dev = ((struct saa7146_fh *)fh)->dev;
struct saa7146_vv *vv = dev->vv_data;
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
parm->parm.capture.readbuffers = 1;
v4l2_video_std_frame_period(vv->standard->id,
&parm->parm.capture.timeperframe);
diff --git a/linux/drivers/media/common/tuners/mxl5005s.c b/linux/drivers/media/common/tuners/mxl5005s.c
index 58418277a..bea599fbc 100644
--- a/linux/drivers/media/common/tuners/mxl5005s.c
+++ b/linux/drivers/media/common/tuners/mxl5005s.c
@@ -4005,12 +4005,11 @@ static int mxl5005s_set_params(struct dvb_frontend *fe,
/* Change tuner for new modulation type if reqd */
if (req_mode != state->current_mode) {
switch (req_mode) {
- case VSB_8:
- case QAM_64:
- case QAM_256:
- case QAM_AUTO:
+ case MXL_ATSC:
+ case MXL_QAM:
req_bw = MXL5005S_BANDWIDTH_6MHZ;
break;
+ case MXL_DVBT:
default:
/* Assume DVB-T */
switch (params->u.ofdm.bandwidth) {
diff --git a/linux/drivers/media/common/tuners/tda827x.c b/linux/drivers/media/common/tuners/tda827x.c
index eb989c241..6653ebcdf 100644
--- a/linux/drivers/media/common/tuners/tda827x.c
+++ b/linux/drivers/media/common/tuners/tda827x.c
@@ -352,7 +352,7 @@ struct tda827xa_data {
u8 gc3;
};
-static const struct tda827xa_data tda827xa_dvbt[] = {
+static struct tda827xa_data tda827xa_dvbt[] = {
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
{ .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
@@ -382,6 +382,36 @@ static const struct tda827xa_data tda827xa_dvbt[] = {
{ .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
};
+static struct tda827xa_data tda827xa_dvbc[] = {
+ { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
+ { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
+ { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
+ { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
+ { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
+ { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
+ { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+ { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
+ { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
+ { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
+ { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
+ { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
+ { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
+ { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
+};
+
static struct tda827xa_data tda827xa_analog[] = {
{ .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
{ .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
@@ -485,6 +515,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
+ struct tda827xa_data *frequency_map = tda827xa_dvbt;
u8 buf[11];
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
@@ -511,22 +542,27 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
}
tuner_freq = params->frequency + if_freq;
+ if (fe->ops.info.type == FE_QAM) {
+ dprintk("%s select tda827xa_dvbc\n", __func__);
+ frequency_map = tda827xa_dvbc;
+ }
+
i = 0;
- while (tda827xa_dvbt[i].lomax < tuner_freq) {
- if(tda827xa_dvbt[i + 1].lomax == 0)
+ while (frequency_map[i].lomax < tuner_freq) {
+ if (frequency_map[i + 1].lomax == 0)
break;
i++;
}
- N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
+ N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
buf[0] = 0; // subaddress
buf[1] = N >> 8;
buf[2] = N & 0xff;
buf[3] = 0;
buf[4] = 0x16;
- buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
- tda827xa_dvbt[i].sbs;
- buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
+ buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
+ frequency_map[i].sbs;
+ buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
buf[7] = 0x1c;
buf[8] = 0x06;
buf[9] = 0x24;
@@ -585,7 +621,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
/* correct CP value */
buf[0] = 0x30;
- buf[1] = 0x10 + tda827xa_dvbt[i].scr;
+ buf[1] = 0x10 + frequency_map[i].scr;
rc = tuner_transfer(fe, &msg, 1);
if (rc < 0)
goto err;
@@ -600,7 +636,7 @@ static int tda827xa_set_params(struct dvb_frontend *fe,
msleep(3);
/* freeze AGC1 */
buf[0] = 0x50;
- buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
+ buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
rc = tuner_transfer(fe, &msg, 1);
if (rc < 0)
goto err;
diff --git a/linux/drivers/media/dvb/b2c2/Makefile b/linux/drivers/media/dvb/b2c2/Makefile
index d9db066f9..b97cf7208 100644
--- a/linux/drivers/media/dvb/b2c2/Makefile
+++ b/linux/drivers/media/dvb/b2c2/Makefile
@@ -2,7 +2,6 @@ b2c2-flexcop-objs = flexcop.o flexcop-fe-tuner.o flexcop-i2c.o \
flexcop-sram.o flexcop-eeprom.o flexcop-misc.o flexcop-hw-filter.o
obj-$(CONFIG_DVB_B2C2_FLEXCOP) += b2c2-flexcop.o
-
ifneq ($(CONFIG_DVB_B2C2_FLEXCOP_PCI),)
b2c2-flexcop-objs += flexcop-dma.o
endif
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-common.h b/linux/drivers/media/dvb/b2c2/flexcop-common.h
index 166f0fb09..cee2956cb 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-common.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop-common.h
@@ -29,11 +29,14 @@
/* Steal from usb.h */
#undef err
-#define err(format, arg...) printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define err(format, arg...) \
+ printk(KERN_ERR FC_LOG_PREFIX ": " format "\n" , ## arg)
#undef info
-#define info(format, arg...) printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO FC_LOG_PREFIX ": " format "\n" , ## arg)
#undef warn
-#define warn(format, arg...) printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING FC_LOG_PREFIX ": " format "\n" , ## arg)
struct flexcop_dma {
struct pci_dev *pdev;
@@ -92,16 +95,14 @@ struct flexcop_device {
int fullts_streaming_state;
/* bus specific callbacks */
- flexcop_ibi_value (*read_ibi_reg) (struct flexcop_device *, flexcop_ibi_register);
- int (*write_ibi_reg) (struct flexcop_device *, flexcop_ibi_register, flexcop_ibi_value);
-
-
- int (*i2c_request) (struct flexcop_i2c_adapter*,
+ flexcop_ibi_value(*read_ibi_reg) (struct flexcop_device *,
+ flexcop_ibi_register);
+ int (*write_ibi_reg) (struct flexcop_device *,
+ flexcop_ibi_register, flexcop_ibi_value);
+ int (*i2c_request) (struct flexcop_i2c_adapter *,
flexcop_access_op_t, u8 chipaddr, u8 addr, u8 *buf, u16 len);
- int (*stream_control) (struct flexcop_device*, int);
-
+ int (*stream_control) (struct flexcop_device *, int);
int (*get_mac_addr) (struct flexcop_device *fc, int extended);
-
void *bus_specific;
};
@@ -112,22 +113,28 @@ void flexcop_pass_dmx_data(struct flexcop_device *fc, u8 *buf, u32 len);
void flexcop_pass_dmx_packets(struct flexcop_device *fc, u8 *buf, u32 no);
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len);
-void flexcop_device_kfree(struct flexcop_device*);
+void flexcop_device_kfree(struct flexcop_device *);
-int flexcop_device_initialize(struct flexcop_device*);
+int flexcop_device_initialize(struct flexcop_device *);
void flexcop_device_exit(struct flexcop_device *fc);
-
void flexcop_reset_block_300(struct flexcop_device *fc);
/* from flexcop-dma.c */
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size);
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size);
void flexcop_dma_free(struct flexcop_dma *dma);
-int flexcop_dma_control_timer_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_control_size_irq(struct flexcop_device *fc, flexcop_dma_index_t no, int onoff);
-int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma, flexcop_dma_index_t dma_idx);
-int flexcop_dma_xfer_control(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index, int onoff);
-int flexcop_dma_config_timer(struct flexcop_device *fc, flexcop_dma_index_t dma_idx, u8 cycles);
+int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no, int onoff);
+int flexcop_dma_control_size_irq(struct flexcop_device *fc,
+ flexcop_dma_index_t no, int onoff);
+int flexcop_dma_config(struct flexcop_device *fc, struct flexcop_dma *dma,
+ flexcop_dma_index_t dma_idx);
+int flexcop_dma_xfer_control(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx, flexcop_dma_addr_index_t index,
+ int onoff);
+int flexcop_dma_config_timer(struct flexcop_device *fc,
+ flexcop_dma_index_t dma_idx, u8 cycles);
/* from flexcop-eeprom.c */
/* the PCI part uses this call to get the MAC address, the USB part has its own */
@@ -142,13 +149,15 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter*, flexcop_access_op_t,
u8 chipaddr, u8 addr, u8 *buf, u16 len);
/* from flexcop-sram.c */
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target);
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+ flexcop_sram_dest_target_t target);
void flexcop_wan_set_speed(struct flexcop_device *fc, flexcop_wan_speed_t s);
-void flexcop_sram_ctrl(struct flexcop_device *fc, int usb_wan, int sramdma, int maximumfill);
+void flexcop_sram_ctrl(struct flexcop_device *fc,
+ int usb_wan, int sramdma, int maximumfill);
/* global prototypes for the flexcop-chip */
/* from flexcop-fe-tuner.c */
-int flexcop_frontend_init(struct flexcop_device *card);
+int flexcop_frontend_init(struct flexcop_device *fc);
void flexcop_frontend_exit(struct flexcop_device *fc);
/* from flexcop-i2c.c */
@@ -160,11 +169,14 @@ int flexcop_sram_init(struct flexcop_device *fc);
/* from flexcop-misc.c */
void flexcop_determine_revision(struct flexcop_device *fc);
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const char *suffix);
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num);
+void flexcop_device_name(struct flexcop_device *fc,
+ const char *prefix, const char *suffix);
+void flexcop_dump_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, int num);
/* from flexcop-hw-filter.c */
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff);
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+ struct dvb_demux_feed *dvbdmxfeed, int onoff);
void flexcop_hw_filter_init(struct flexcop_device *fc);
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff);
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-dma.c b/linux/drivers/media/dvb/b2c2/flexcop-dma.c
index 02a0f07a1..2c0eab398 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-dma.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-dma.c
@@ -1,13 +1,12 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-dma.c - methods for configuring and controlling the DMA of the FlexCop.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
-int flexcop_dma_allocate(struct pci_dev *pdev, struct flexcop_dma *dma, u32 size)
+int flexcop_dma_allocate(struct pci_dev *pdev,
+ struct flexcop_dma *dma, u32 size)
{
u8 *tcpu;
dma_addr_t tdma = 0;
@@ -32,7 +31,8 @@ EXPORT_SYMBOL(flexcop_dma_allocate);
void flexcop_dma_free(struct flexcop_dma *dma)
{
- pci_free_consistent(dma->pdev, dma->size*2,dma->cpu_addr0, dma->dma_addr0);
+ pci_free_consistent(dma->pdev, dma->size*2,
+ dma->cpu_addr0, dma->dma_addr0);
memset(dma,0,sizeof(struct flexcop_dma));
}
EXPORT_SYMBOL(flexcop_dma_free);
@@ -44,8 +44,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
flexcop_ibi_value v0x0,v0x4,v0xc;
v0x0.raw = v0x4.raw = v0xc.raw = 0;
- v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
- v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
+ v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
+ v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
if ((dma_idx & FC_DMA_1) == dma_idx) {
@@ -57,7 +57,8 @@ int flexcop_dma_config(struct flexcop_device *fc,
fc->write_ibi_reg(fc,dma2_014,v0x4);
fc->write_ibi_reg(fc,dma2_01c,v0xc);
} else {
- err("either DMA1 or DMA2 can be configured at the within one flexcop_dma_config call.");
+ err("either DMA1 or DMA2 can be configured within one "
+ "flexcop_dma_config call.");
return -EINVAL;
}
@@ -81,7 +82,8 @@ int flexcop_dma_xfer_control(struct flexcop_device *fc,
r0x0 = dma2_010;
r0xc = dma2_01c;
} else {
- err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
+ err("either transfer DMA1 or DMA2 can be started within one "
+ "flexcop_dma_xfer_control call.");
return -EINVAL;
}
@@ -154,8 +156,7 @@ EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
/* 1 cycles = 1.97 msec */
int flexcop_dma_config_timer(struct flexcop_device *fc,
- flexcop_dma_index_t dma_idx,
- u8 cycles)
+ flexcop_dma_index_t dma_idx, u8 cycles)
{
flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
flexcop_ibi_value v = fc->read_ibi_reg(fc,r);
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c b/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c
index 5d563fbc7..4f42efa26 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-eeprom.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading is used)
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-eeprom.c - eeprom access methods (currently only MAC address reading)
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -14,17 +12,17 @@ static int eeprom_write(struct adapter *adapter, u16 addr, u8 *buf, u16 len)
return flex_i2c_write(adapter, 0x20000000, 0x50, addr, buf, len);
}
-static int eeprom_lrc_write(struct adapter *adapter, u32 addr, u32 len, u8 *wbuf, u8 *rbuf, int retries)
+static int eeprom_lrc_write(struct adapter *adapter, u32 addr,
+ u32 len, u8 *wbuf, u8 *rbuf, int retries)
{
- int i;
+int i;
- for (i = 0; i < retries; i++) {
- if (eeprom_write(adapter, addr, wbuf, len) == len) {
- if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
- return 1;
+for (i = 0; i < retries; i++) {
+ if (eeprom_write(adapter, addr, wbuf, len) == len) {
+ if (eeprom_lrc_read(adapter, addr, len, rbuf, retries) == 1)
+ return 1;
}
}
-
return 0;
}
@@ -39,12 +37,10 @@ static int eeprom_writeKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(wbuf, key, len);
-
wbuf[16] = 0;
wbuf[17] = 0;
wbuf[18] = 0;
wbuf[19] = calc_lrc(wbuf, 19);
-
return eeprom_lrc_write(adapter, 0x3e4, 20, wbuf, rbuf, 4);
}
@@ -59,7 +55,6 @@ static int eeprom_readKey(struct adapter *adapter, u8 *key, u32 len)
return 0;
memcpy(key, buf, len);
-
return 1;
}
@@ -74,9 +69,7 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
tmp[3] = mac[5];
tmp[4] = mac[6];
tmp[5] = mac[7];
-
} else {
-
tmp[0] = mac[0];
tmp[1] = mac[1];
tmp[2] = mac[2];
@@ -90,11 +83,11 @@ static char eeprom_set_mac_addr(struct adapter *adapter, char type, u8 *mac)
if (eeprom_write(adapter, 0x3f8, tmp, 8) == 8)
return 1;
-
return 0;
}
-static int flexcop_eeprom_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len)
+static int flexcop_eeprom_read(struct flexcop_device *fc,
+ u16 addr, u8 *buf, u16 len)
{
return fc->i2c_request(fc,FC_READ,FC_I2C_PORT_EEPROM,0x50,addr,buf,len);
}
@@ -110,7 +103,8 @@ static u8 calc_lrc(u8 *buf, int len)
return sum;
}
-static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_request(struct flexcop_device *fc,
+ flexcop_access_op_t op, u16 addr, u8 *buf, u16 len, int retries)
{
int i,ret = 0;
u8 chipaddr = 0x50 | ((addr >> 8) & 3);
@@ -123,7 +117,8 @@ static int flexcop_eeprom_request(struct flexcop_device *fc, flexcop_access_op_t
return ret;
}
-static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf, u16 len, int retries)
+static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr,
+ u8 *buf, u16 len, int retries)
{
int ret = flexcop_eeprom_request(fc, FC_READ, addr, buf, len, retries);
if (ret == 0)
@@ -133,8 +128,7 @@ static int flexcop_eeprom_lrc_read(struct flexcop_device *fc, u16 addr, u8 *buf,
}
/* JJ's comment about extended == 1: it is not presently used anywhere but was
- * added to the low-level functions for possible support of EUI64
- */
+ * added to the low-level functions for possible support of EUI64 */
int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
{
u8 buf[8];
@@ -142,12 +136,9 @@ int flexcop_eeprom_check_mac_addr(struct flexcop_device *fc, int extended)
if ((ret = flexcop_eeprom_lrc_read(fc,0x3f8,buf,8,4)) == 0) {
if (extended != 0) {
- err("TODO: extended (EUI64) MAC addresses aren't completely supported yet");
+ err("TODO: extended (EUI64) MAC addresses aren't "
+ "completely supported yet");
ret = -EINVAL;
-/* memcpy(fc->dvb_adapter.proposed_mac,buf,3);
- mac[3] = 0xfe;
- mac[4] = 0xff;
- memcpy(&fc->dvb_adapter.proposed_mac[3],&buf[5],3); */
} else
memcpy(fc->dvb_adapter.proposed_mac,buf,6);
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
index 5cded3708..f7afab594 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-fe-tuner.c
@@ -592,14 +592,14 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY;
+ fc->dev_type = FC_SKY_REV26;
goto fe_found;
}
/* try the air dvb-t (mt352/Samsung tdtc9251dh0(??)) */
fc->fe = dvb_attach(mt352_attach, &samsung_tdtc9251dh0_config, i2c);
if (fc->fe != NULL) {
- fc->dev_type = FC_AIR_DVB;
+ fc->dev_type = FC_AIR_DVBT;
fc->fe->ops.tuner_ops.calc_regs = samsung_tdtc9251dh0_calc_regs;
goto fe_found;
}
@@ -653,7 +653,7 @@ int flexcop_frontend_init(struct flexcop_device *fc)
fc->fe_sleep = ops->sleep;
ops->sleep = flexcop_sleep;
- fc->dev_type = FC_SKY_OLD;
+ fc->dev_type = FC_SKY_REV23;
goto fe_found;
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c b/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c
index 451974ba3..77e45475f 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-hw-filter.c
@@ -1,33 +1,30 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-hw-filter.c - pid and mac address filtering and corresponding control functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-hw-filter.c - pid and mac address filtering and control functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
static void flexcop_rcv_data_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Rcv_Data_sig,onoff);
-
- deb_ts("rcv_data is now: '%s'\n",onoff ? "on" : "off");
+ flexcop_set_ibi_value(ctrl_208, Rcv_Data_sig, onoff);
+ deb_ts("rcv_data is now: '%s'\n", onoff ? "on" : "off");
}
void flexcop_smc_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,SMC_Enable_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, SMC_Enable_sig, onoff);
}
static void flexcop_null_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Null_filter_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, Null_filter_sig, onoff);
}
void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
{
- flexcop_ibi_value v418,v41c;
- v41c = fc->read_ibi_reg(fc,mac_address_41c);
+ flexcop_ibi_value v418, v41c;
+ v41c = fc->read_ibi_reg(fc, mac_address_41c);
v418.mac_address_418.MAC1 = mac[0];
v418.mac_address_418.MAC2 = mac[1];
@@ -36,27 +33,28 @@ void flexcop_set_mac_filter(struct flexcop_device *fc, u8 mac[6])
v41c.mac_address_41c.MAC7 = mac[4];
v41c.mac_address_41c.MAC8 = mac[5];
- fc->write_ibi_reg(fc,mac_address_418,v418);
- fc->write_ibi_reg(fc,mac_address_41c,v41c);
+ fc->write_ibi_reg(fc, mac_address_418, v418);
+ fc->write_ibi_reg(fc, mac_address_41c, v41c);
}
void flexcop_mac_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,MAC_filter_Mode_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, MAC_filter_Mode_sig, onoff);
}
-static void flexcop_pid_group_filter(struct flexcop_device *fc, u16 pid, u16 mask)
+static void flexcop_pid_group_filter(struct flexcop_device *fc,
+ u16 pid, u16 mask)
{
/* index_reg_310.extra_index_reg need to 0 or 7 to work */
flexcop_ibi_value v30c;
v30c.pid_filter_30c_ext_ind_0_7.Group_PID = pid;
v30c.pid_filter_30c_ext_ind_0_7.Group_mask = mask;
- fc->write_ibi_reg(fc,pid_filter_30c,v30c);
+ fc->write_ibi_reg(fc, pid_filter_30c, v30c);
}
static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
{
- flexcop_set_ibi_value(ctrl_208,Mask_filter_sig,onoff);
+ flexcop_set_ibi_value(ctrl_208, Mask_filter_sig, onoff);
}
/* this fancy define reduces the code size of the quite similar PID controlling of
@@ -65,91 +63,112 @@ static void flexcop_pid_group_filter_ctrl(struct flexcop_device *fc, int onoff)
#define pid_ctrl(vregname,field,enablefield,trans_field,transval) \
flexcop_ibi_value vpid = fc->read_ibi_reg(fc, vregname), \
- v208 = fc->read_ibi_reg(fc, ctrl_208); \
-\
- vpid.vregname.field = onoff ? pid : 0x1fff; \
- vpid.vregname.trans_field = transval; \
- v208.ctrl_208.enablefield = onoff; \
-\
- fc->write_ibi_reg(fc,vregname,vpid); \
- fc->write_ibi_reg(fc,ctrl_208,v208);
+v208 = fc->read_ibi_reg(fc, ctrl_208); \
+vpid.vregname.field = onoff ? pid : 0x1fff; \
+vpid.vregname.trans_field = transval; \
+v208.ctrl_208.enablefield = onoff; \
+fc->write_ibi_reg(fc, vregname, vpid); \
+fc->write_ibi_reg(fc, ctrl_208, v208);
-static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream1_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_300,Stream1_PID,Stream1_filter_sig,Stream1_trans,0);
+ pid_ctrl(pid_filter_300, Stream1_PID, Stream1_filter_sig,
+ Stream1_trans, 0);
}
-static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_Stream2_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_300,Stream2_PID,Stream2_filter_sig,Stream2_trans,0);
+ pid_ctrl(pid_filter_300, Stream2_PID, Stream2_filter_sig,
+ Stream2_trans, 0);
}
-static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PCR_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_304,PCR_PID,PCR_filter_sig,PCR_trans,0);
+ pid_ctrl(pid_filter_304, PCR_PID, PCR_filter_sig, PCR_trans, 0);
}
-static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_PMT_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_304,PMT_PID,PMT_filter_sig,PMT_trans,0);
+ pid_ctrl(pid_filter_304, PMT_PID, PMT_filter_sig, PMT_trans, 0);
}
-static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_EMM_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_308,EMM_PID,EMM_filter_sig,EMM_trans,0);
+ pid_ctrl(pid_filter_308, EMM_PID, EMM_filter_sig, EMM_trans, 0);
}
-static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc, u16 pid, int onoff)
+static void flexcop_pid_ECM_PID_ctrl(struct flexcop_device *fc,
+ u16 pid, int onoff)
{
- pid_ctrl(pid_filter_308,ECM_PID,ECM_filter_sig,ECM_trans,0);
+ pid_ctrl(pid_filter_308, ECM_PID, ECM_filter_sig, ECM_trans, 0);
}
-static void flexcop_pid_control(struct flexcop_device *fc, int index, u16 pid,int onoff)
+static void flexcop_pid_control(struct flexcop_device *fc,
+ int index, u16 pid, int onoff)
{
if (pid == 0x2000)
return;
- deb_ts("setting pid: %5d %04x at index %d '%s'\n",pid,pid,index,onoff ? "on" : "off");
+ deb_ts("setting pid: %5d %04x at index %d '%s'\n",
+ pid, pid, index, onoff ? "on" : "off");
/* We could use bit magic here to reduce source code size.
* I decided against it, but to use the real register names */
switch (index) {
- case 0: flexcop_pid_Stream1_PID_ctrl(fc,pid,onoff); break;
- case 1: flexcop_pid_Stream2_PID_ctrl(fc,pid,onoff); break;
- case 2: flexcop_pid_PCR_PID_ctrl(fc,pid,onoff); break;
- case 3: flexcop_pid_PMT_PID_ctrl(fc,pid,onoff); break;
- case 4: flexcop_pid_EMM_PID_ctrl(fc,pid,onoff); break;
- case 5: flexcop_pid_ECM_PID_ctrl(fc,pid,onoff); break;
- default:
- if (fc->has_32_hw_pid_filter && index < 38) {
- flexcop_ibi_value vpid,vid;
-
- /* set the index */
- vid = fc->read_ibi_reg(fc,index_reg_310);
- vid.index_reg_310.index_reg = index - 6;
- fc->write_ibi_reg(fc,index_reg_310, vid);
-
- vpid = fc->read_ibi_reg(fc,pid_n_reg_314);
- vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
- vpid.pid_n_reg_314.PID_enable_bit = onoff;
- fc->write_ibi_reg(fc,pid_n_reg_314, vpid);
- }
- break;
+ case 0:
+ flexcop_pid_Stream1_PID_ctrl(fc, pid, onoff);
+ break;
+ case 1:
+ flexcop_pid_Stream2_PID_ctrl(fc, pid, onoff);
+ break;
+ case 2:
+ flexcop_pid_PCR_PID_ctrl(fc, pid, onoff);
+ break;
+ case 3:
+ flexcop_pid_PMT_PID_ctrl(fc, pid, onoff);
+ break;
+ case 4:
+ flexcop_pid_EMM_PID_ctrl(fc, pid, onoff);
+ break;
+ case 5:
+ flexcop_pid_ECM_PID_ctrl(fc, pid, onoff);
+ break;
+ default:
+ if (fc->has_32_hw_pid_filter && index < 38) {
+ flexcop_ibi_value vpid, vid;
+
+ /* set the index */
+ vid = fc->read_ibi_reg(fc, index_reg_310);
+ vid.index_reg_310.index_reg = index - 6;
+ fc->write_ibi_reg(fc, index_reg_310, vid);
+
+ vpid = fc->read_ibi_reg(fc, pid_n_reg_314);
+ vpid.pid_n_reg_314.PID = onoff ? pid : 0x1fff;
+ vpid.pid_n_reg_314.PID_enable_bit = onoff;
+ fc->write_ibi_reg(fc, pid_n_reg_314, vpid);
+ }
+ break;
}
}
-static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc,int onoff)
+static int flexcop_toggle_fullts_streaming(struct flexcop_device *fc, int onoff)
{
if (fc->fullts_streaming_state != onoff) {
deb_ts("%s full TS transfer\n",onoff ? "enabling" : "disabling");
flexcop_pid_group_filter(fc, 0, 0x1fe0 * (!onoff));
- flexcop_pid_group_filter_ctrl(fc,onoff);
+ flexcop_pid_group_filter_ctrl(fc, onoff);
fc->fullts_streaming_state = onoff;
}
return 0;
}
-int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *dvbdmxfeed, int onoff)
+int flexcop_pid_feed_control(struct flexcop_device *fc,
+ struct dvb_demux_feed *dvbdmxfeed, int onoff)
{
int max_pid_filter = 6 + fc->has_32_hw_pid_filter*32;
@@ -164,24 +183,25 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
* - or the requested pid is 0x2000 */
if (!fc->pid_filtering && fc->feedcount == onoff)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
if (fc->pid_filtering) {
- flexcop_pid_control(fc,dvbdmxfeed->index,dvbdmxfeed->pid,onoff);
+ flexcop_pid_control \
+ (fc, dvbdmxfeed->index, dvbdmxfeed->pid, onoff);
if (fc->extra_feedcount > 0)
- flexcop_toggle_fullts_streaming(fc,1);
+ flexcop_toggle_fullts_streaming(fc, 1);
else if (dvbdmxfeed->pid == 0x2000)
- flexcop_toggle_fullts_streaming(fc,onoff);
+ flexcop_toggle_fullts_streaming(fc, onoff);
else
- flexcop_toggle_fullts_streaming(fc,0);
+ flexcop_toggle_fullts_streaming(fc, 0);
}
/* if it was the first or last feed request change the stream-status */
if (fc->feedcount == onoff) {
- flexcop_rcv_data_ctrl(fc,onoff);
+ flexcop_rcv_data_ctrl(fc, onoff);
if (fc->stream_control) /* device specific stream control */
- fc->stream_control(fc,onoff);
+ fc->stream_control(fc, onoff);
/* feeding stopped -> reset the flexcop filter*/
if (onoff == 0) {
@@ -189,7 +209,6 @@ int flexcop_pid_feed_control(struct flexcop_device *fc, struct dvb_demux_feed *d
flexcop_hw_filter_init(fc);
}
}
-
return 0;
}
EXPORT_SYMBOL(flexcop_pid_feed_control);
@@ -199,15 +218,15 @@ void flexcop_hw_filter_init(struct flexcop_device *fc)
int i;
flexcop_ibi_value v;
for (i = 0; i < 6 + 32*fc->has_32_hw_pid_filter; i++)
- flexcop_pid_control(fc,i,0x1fff,0);
+ flexcop_pid_control(fc, i, 0x1fff, 0);
flexcop_pid_group_filter(fc, 0, 0x1fe0);
- flexcop_pid_group_filter_ctrl(fc,0);
+ flexcop_pid_group_filter_ctrl(fc, 0);
- v = fc->read_ibi_reg(fc,pid_filter_308);
+ v = fc->read_ibi_reg(fc, pid_filter_308);
v.pid_filter_308.EMM_filter_4 = 1;
v.pid_filter_308.EMM_filter_6 = 0;
- fc->write_ibi_reg(fc,pid_filter_308,v);
+ fc->write_ibi_reg(fc, pid_filter_308, v);
flexcop_null_filter_ctrl(fc, 1);
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c
index 01d27613f..06a90f67e 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-i2c.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-i2c.c
@@ -1,17 +1,14 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-i2c.c - flexcop internal 2Wire bus (I2C) and dvb i2c initialization
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
#define FC_MAX_I2C_RETRIES 100000
-/* #define DUMP_I2C_MESSAGES */
-
-static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r100)
+static int flexcop_i2c_operation(struct flexcop_device *fc,
+ flexcop_ibi_value *r100)
{
int i;
flexcop_ibi_value r;
@@ -26,7 +23,7 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
r = fc->read_ibi_reg(fc, tw_sm_c_100);
if (!r.tw_sm_c_100.no_base_addr_ack_error) {
- if (r.tw_sm_c_100.st_done) { /* && !r.tw_sm_c_100.working_start */
+ if (r.tw_sm_c_100.st_done) {
*r100 = r;
deb_i2c("i2c success\n");
return 0;
@@ -36,17 +33,31 @@ static int flexcop_i2c_operation(struct flexcop_device *fc, flexcop_ibi_value *r
return -EREMOTEIO;
}
}
- deb_i2c("tried %d times i2c operation, never finished or too many ack errors.\n",i);
+ deb_i2c("tried %d times i2c operation, "
+ "never finished or too many ack errors.\n", i);
return -EREMOTEIO;
}
static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
- flexcop_ibi_value r100, u8 *buf)
+ flexcop_ibi_value r100, u8 *buf)
{
flexcop_ibi_value r104;
- int len = r100.tw_sm_c_100.total_bytes, /* remember total_bytes is buflen-1 */
+ int len = r100.tw_sm_c_100.total_bytes,
+ /* remember total_bytes is buflen-1 */
ret;
+ /* work-around to have CableStar2 and SkyStar2 rev 2.7 work
+ * correctly:
+ *
+ * the ITD1000 is behind an i2c-gate which closes automatically
+ * after an i2c-transaction the STV0297 needs 2 consecutive reads
+ * one with no_base_addr = 0 and one with 1
+ *
+ * those two work-arounds are conflictin: we check for the card
+ * type, it is set when probing the ITD1000 */
+ if (i2c->fc->dev_type == FC_SKY_REV27)
+ r100.tw_sm_c_100.no_base_addr_ack_error = i2c->no_base_addr;
+
ret = flexcop_i2c_operation(i2c->fc, &r100);
if (ret != 0) {
deb_i2c("Retrying operation\n");
@@ -69,11 +80,11 @@ static int flexcop_i2c_read4(struct flexcop_i2c_adapter *i2c,
if (len > 1) buf[2] = r104.tw_sm_c_104.data3_reg;
if (len > 2) buf[3] = r104.tw_sm_c_104.data4_reg;
}
-
return 0;
}
-static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100, u8 *buf)
+static int flexcop_i2c_write4(struct flexcop_device *fc,
+ flexcop_ibi_value r100, u8 *buf)
{
flexcop_ibi_value r104;
int len = r100.tw_sm_c_100.total_bytes; /* remember total_bytes is buflen-1 */
@@ -81,7 +92,6 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
/* there is at least one byte, otherwise we wouldn't be here */
r100.tw_sm_c_100.data1_reg = buf[0];
-
r104.tw_sm_c_104.data2_reg = len > 0 ? buf[1] : 0;
r104.tw_sm_c_104.data3_reg = len > 1 ? buf[2] : 0;
r104.tw_sm_c_104.data4_reg = len > 2 ? buf[3] : 0;
@@ -94,7 +104,7 @@ static int flexcop_i2c_write4(struct flexcop_device *fc, flexcop_ibi_value r100,
}
int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
int ret;
@@ -117,7 +127,6 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
printk("rd(");
else
printk("wr(");
-
printk("%02x): %02x ", chipaddr, addr);
#endif
@@ -163,7 +172,8 @@ int flexcop_i2c_request(struct flexcop_i2c_adapter *i2c,
EXPORT_SYMBOL(flexcop_i2c_request);
/* master xfer callback for demodulator */
-static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs[], int num)
+static int flexcop_master_xfer(struct i2c_adapter *i2c_adap,
+ struct i2c_msg msgs[], int num)
{
struct flexcop_i2c_adapter *i2c = i2c_get_adapdata(i2c_adap);
int i, ret = 0;
@@ -182,12 +192,13 @@ static int flexcop_master_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msgs
/* reading */
if (i+1 < num && (msgs[i+1].flags == I2C_M_RD)) {
ret = i2c->fc->i2c_request(i2c, FC_READ, msgs[i].addr,
- msgs[i].buf[0], msgs[i+1].buf, msgs[i+1].len);
+ msgs[i].buf[0], msgs[i+1].buf,
+ msgs[i+1].len);
i++; /* skip the following message */
} else /* writing */
ret = i2c->fc->i2c_request(i2c, FC_WRITE, msgs[i].addr,
- msgs[i].buf[0], &msgs[i].buf[1],
- msgs[i].len - 1);
+ msgs[i].buf[0], &msgs[i].buf[1],
+ msgs[i].len - 1);
if (ret < 0) {
err("i2c master_xfer failed");
break;
@@ -217,23 +228,21 @@ static struct i2c_algorithm flexcop_algo = {
int flexcop_i2c_init(struct flexcop_device *fc)
{
int ret;
-
mutex_init(&fc->i2c_mutex);
fc->fc_i2c_adap[0].fc = fc;
fc->fc_i2c_adap[1].fc = fc;
fc->fc_i2c_adap[2].fc = fc;
-
fc->fc_i2c_adap[0].port = FC_I2C_PORT_DEMOD;
fc->fc_i2c_adap[1].port = FC_I2C_PORT_EEPROM;
fc->fc_i2c_adap[2].port = FC_I2C_PORT_TUNER;
strlcpy(fc->fc_i2c_adap[0].i2c_adap.name, "B2C2 FlexCop I2C to demod",
- sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[0].i2c_adap.name));
strlcpy(fc->fc_i2c_adap[1].i2c_adap.name, "B2C2 FlexCop I2C to eeprom",
- sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[1].i2c_adap.name));
strlcpy(fc->fc_i2c_adap[2].i2c_adap.name, "B2C2 FlexCop I2C to tuner",
- sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
+ sizeof(fc->fc_i2c_adap[2].i2c_adap.name));
i2c_set_adapdata(&fc->fc_i2c_adap[0].i2c_adap, &fc->fc_i2c_adap[0]);
i2c_set_adapdata(&fc->fc_i2c_adap[1].i2c_adap, &fc->fc_i2c_adap[1]);
@@ -271,7 +280,6 @@ adap_2_failed:
i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
adap_1_failed:
i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
-
return ret;
}
@@ -282,6 +290,5 @@ void flexcop_i2c_exit(struct flexcop_device *fc)
i2c_del_adapter(&fc->fc_i2c_adap[1].i2c_adap);
i2c_del_adapter(&fc->fc_i2c_adap[0].i2c_adap);
}
-
fc->init_state &= ~FC_STATE_I2C_INIT;
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-misc.c b/linux/drivers/media/dvb/b2c2/flexcop-misc.c
index 93d20e56f..e56627d2f 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-misc.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-misc.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-misc.c - miscellaneous functions.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-misc.c - miscellaneous functions
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
@@ -12,39 +10,43 @@ void flexcop_determine_revision(struct flexcop_device *fc)
flexcop_ibi_value v = fc->read_ibi_reg(fc,misc_204);
switch (v.misc_204.Rev_N_sig_revision_hi) {
- case 0x2:
- deb_info("found a FlexCopII.\n");
- fc->rev = FLEXCOP_II;
- break;
- case 0x3:
- deb_info("found a FlexCopIIb.\n");
- fc->rev = FLEXCOP_IIB;
- break;
- case 0x0:
- deb_info("found a FlexCopIII.\n");
- fc->rev = FLEXCOP_III;
- break;
- default:
- err("unkown FlexCop Revision: %x. Please report the linux-dvb@linuxtv.org.",v.misc_204.Rev_N_sig_revision_hi);
- break;
+ case 0x2:
+ deb_info("found a FlexCopII.\n");
+ fc->rev = FLEXCOP_II;
+ break;
+ case 0x3:
+ deb_info("found a FlexCopIIb.\n");
+ fc->rev = FLEXCOP_IIB;
+ break;
+ case 0x0:
+ deb_info("found a FlexCopIII.\n");
+ fc->rev = FLEXCOP_III;
+ break;
+ default:
+ err("unknown FlexCop Revision: %x. Please report this to "
+ "linux-dvb@linuxtv.org.",
+ v.misc_204.Rev_N_sig_revision_hi);
+ break;
}
if ((fc->has_32_hw_pid_filter = v.misc_204.Rev_N_sig_caps))
- deb_info("this FlexCop has the additional 32 hardware pid filter.\n");
+ deb_info("this FlexCop has "
+ "the additional 32 hardware pid filter.\n");
else
- deb_info("this FlexCop has only the 6 basic main hardware pid filter.\n");
+ deb_info("this FlexCop has "
+ "the 6 basic main hardware pid filter.\n");
/* bus parts have to decide if hw pid filtering is used or not. */
}
static const char *flexcop_revision_names[] = {
- "Unkown chip",
+ "Unknown chip",
"FlexCopII",
"FlexCopIIb",
"FlexCopIII",
};
static const char *flexcop_device_names[] = {
- "Unkown device",
+ "Unknown device",
"Air2PC/AirStar 2 DVB-T",
"Air2PC/AirStar 2 ATSC 1st generation",
"Air2PC/AirStar 2 ATSC 2nd generation",
@@ -61,21 +63,23 @@ static const char *flexcop_bus_names[] = {
"PCI",
};
-void flexcop_device_name(struct flexcop_device *fc,const char *prefix,const
- char *suffix)
+void flexcop_device_name(struct flexcop_device *fc,
+ const char *prefix, const char *suffix)
{
- info("%s '%s' at the '%s' bus controlled by a '%s' %s",prefix,
- flexcop_device_names[fc->dev_type],flexcop_bus_names[fc->bus_type],
- flexcop_revision_names[fc->rev],suffix);
+ info("%s '%s' at the '%s' bus controlled by a '%s' %s",
+ prefix, flexcop_device_names[fc->dev_type],
+ flexcop_bus_names[fc->bus_type],
+ flexcop_revision_names[fc->rev], suffix);
}
-void flexcop_dump_reg(struct flexcop_device *fc, flexcop_ibi_register reg, int num)
+void flexcop_dump_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, int num)
{
flexcop_ibi_value v;
int i;
for (i = 0; i < num; i++) {
- v = fc->read_ibi_reg(fc,reg+4*i);
- deb_rdump("0x%03x: %08x, ",reg+4*i, v.raw);
+ v = fc->read_ibi_reg(fc, reg+4*i);
+ deb_rdump("0x%03x: %08x, ", reg+4*i, v.raw);
}
deb_rdump("\n");
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-pci.c b/linux/drivers/media/dvb/b2c2/flexcop-pci.c
index 72710fee2..e3ee05d98 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-pci.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-pci.c
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-pci.c - covers the PCI part including DMA transfers.
- *
- * see flexcop.c for copyright information.
+ * Linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-pci.c - covers the PCI part including DMA transfers
+ * see flexcop.c for copyright information
*/
#define FC_LOG_PREFIX "flexcop-pci"
@@ -11,7 +9,8 @@
static int enable_pid_filtering = 1;
module_param(enable_pid_filtering, int, 0444);
-MODULE_PARM_DESC(enable_pid_filtering, "enable hardware pid filtering: supported values: 0 (fullts), 1");
+MODULE_PARM_DESC(enable_pid_filtering,
+ "enable hardware pid filtering: supported values: 0 (fullts), 1");
static int irq_chk_intv = 100;
module_param(irq_chk_intv, int, 0644);
@@ -26,17 +25,17 @@ MODULE_PARM_DESC(irq_chk_intv, "set the interval for IRQ streaming watchdog.");
#define DEBSTATUS " (debugging is not enabled)"
#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_reg(args...) dprintk(0x02,args)
-#define deb_ts(args...) dprintk(0x04,args)
-#define deb_irq(args...) dprintk(0x08,args)
-#define deb_chk(args...) dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_reg(args...) dprintk(0x02, args)
+#define deb_ts(args...) dprintk(0x04, args)
+#define deb_irq(args...) dprintk(0x08, args)
+#define deb_chk(args...) dprintk(0x10, args)
static int debug;
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug,
"set debug level (1=info,2=regs,4=TS,8=irqdma,16=check (|-able))."
- DEBSTATUS);
+ DEBSTATUS);
#define DRIVER_VERSION "0.1"
#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
@@ -51,30 +50,30 @@ struct flexcop_pci {
void __iomem *io_mem;
u32 irq;
-/* buffersize (at least for DMA1, need to be % 188 == 0,
- * this logic is required */
+ /* buffersize (at least for DMA1, need to be % 188 == 0,
+ * this logic is required */
#define FC_DEFAULT_DMA1_BUFSIZE (1280 * 188)
#define FC_DEFAULT_DMA2_BUFSIZE (10 * 188)
struct flexcop_dma dma[2];
int active_dma1_addr; /* 0 = addr0 of dma1; 1 = addr1 of dma1 */
- u32 last_dma1_cur_pos; /* position of the pointer last time the timer/packet irq occured */
+ u32 last_dma1_cur_pos;
+ /* position of the pointer last time the timer/packet irq occured */
int count;
int count_prev;
int stream_problem;
spinlock_t irq_lock;
-
unsigned long last_irq;
struct delayed_work irq_check_work;
-
struct flexcop_device *fc_dev;
};
-static int lastwreg,lastwval,lastrreg,lastrval;
+static int lastwreg, lastwval, lastrreg, lastrval;
-static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, flexcop_ibi_register r)
+static flexcop_ibi_value flexcop_pci_read_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register r)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
flexcop_ibi_value v;
@@ -82,19 +81,20 @@ static flexcop_ibi_value flexcop_pci_read_ibi_reg (struct flexcop_device *fc, fl
if (lastrreg != r || lastrval != v.raw) {
lastrreg = r; lastrval = v.raw;
- deb_reg("new rd: %3x: %08x\n",r,v.raw);
+ deb_reg("new rd: %3x: %08x\n", r, v.raw);
}
return v;
}
-static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register r, flexcop_ibi_value v)
+static int flexcop_pci_write_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register r, flexcop_ibi_value v)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (lastwreg != r || lastwval != v.raw) {
lastwreg = r; lastwval = v.raw;
- deb_reg("new wr: %3x: %08x\n",r,v.raw);
+ deb_reg("new wr: %3x: %08x\n", r, v.raw);
}
writel(v.raw, fc_pci->io_mem + r);
@@ -119,14 +119,14 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
#if 0
flexcop_ibi_value v = fc->read_ibi_reg(fc, sram_dest_reg_714);
deb_chk("net_ovflow_error: %d, media_ovflow_error: %d,"
- "cai_ovflow_error: %d, cao_ovflow_error: %d, "
- "sram_dma: %d, maximumfill: %d\n",
- v.sram_dest_reg_714.net_ovflow_error,
- v.sram_dest_reg_714.media_ovflow_error,
- v.sram_dest_reg_714.cai_ovflow_error,
- v.sram_dest_reg_714.cao_ovflow_error,
- v.sram_dest_reg_714.ctrl_sramdma,
- v.sram_dest_reg_714.ctrl_maximumfill);
+ "cai_ovflow_error: %d, cao_ovflow_error: %d, "
+ "sram_dma: %d, maximumfill: %d\n",
+ v.sram_dest_reg_714.net_ovflow_error,
+ v.sram_dest_reg_714.media_ovflow_error,
+ v.sram_dest_reg_714.cai_ovflow_error,
+ v.sram_dest_reg_714.cao_ovflow_error,
+ v.sram_dest_reg_714.ctrl_sramdma,
+ v.sram_dest_reg_714.ctrl_maximumfill);
#endif
if (fc_pci->count == fc_pci->count_prev) {
@@ -137,12 +137,12 @@ static void flexcop_pci_irq_check_work(struct work_struct *work)
spin_lock_irq(&fc->demux.lock);
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 0);
}
list_for_each_entry(feed, &fc->demux.feed_list,
- list_head) {
+ list_head) {
flexcop_pid_feed_control(fc, feed, 1);
}
spin_unlock_irq(&fc->demux.lock);
@@ -174,11 +174,10 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
flexcop_ibi_value v;
irqreturn_t ret = IRQ_HANDLED;
- spin_lock_irqsave(&fc_pci->irq_lock,flags);
-
- v = fc->read_ibi_reg(fc,irq_20c);
+ spin_lock_irqsave(&fc_pci->irq_lock, flags);
+ v = fc->read_ibi_reg(fc, irq_20c);
- /* errors */
+ /* errors */
if (v.irq_20c.Data_receiver_error)
deb_chk("data receiver error\n");
if (v.irq_20c.Continuity_error_flag)
@@ -189,24 +188,29 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
deb_chk("Transport error\n");
if ((fc_pci->count % 1000) == 0)
- deb_chk("%d valid irq took place so far\n",fc_pci->count);
+ deb_chk("%d valid irq took place so far\n", fc_pci->count);
if (v.irq_20c.DMA1_IRQ_Status == 1) {
if (fc_pci->active_dma1_addr == 0)
- flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr0,fc_pci->dma[0].size / 188);
+ flexcop_pass_dmx_packets(fc_pci->fc_dev,
+ fc_pci->dma[0].cpu_addr0,
+ fc_pci->dma[0].size / 188);
else
- flexcop_pass_dmx_packets(fc_pci->fc_dev,fc_pci->dma[0].cpu_addr1,fc_pci->dma[0].size / 188);
+ flexcop_pass_dmx_packets(fc_pci->fc_dev,
+ fc_pci->dma[0].cpu_addr1,
+ fc_pci->dma[0].size / 188);
deb_irq("page change to page: %d\n",!fc_pci->active_dma1_addr);
fc_pci->active_dma1_addr = !fc_pci->active_dma1_addr;
- } else if (v.irq_20c.DMA1_Timer_Status == 1) {
/* for the timer IRQ we only can use buffer dmx feeding, because we don't have
* complete TS packets when reading from the DMA memory */
+ } else if (v.irq_20c.DMA1_Timer_Status == 1) {
dma_addr_t cur_addr =
fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2;
u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0;
- deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ",
+ deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, "
+ "last_cur_pos: %08x ",
jiffies_to_usecs(jiffies - fc_pci->last_irq),
v.raw, (unsigned long long)cur_addr, cur_pos,
fc_pci->last_dma1_cur_pos);
@@ -216,30 +220,36 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id)
* pass the data from last_cur_pos to the buffer end to the demux
*/
if (cur_pos < fc_pci->last_dma1_cur_pos) {
- deb_irq(" end was reached: passing %d bytes ",(fc_pci->dma[0].size*2 - 1) - fc_pci->last_dma1_cur_pos);
+ deb_irq(" end was reached: passing %d bytes ",
+ (fc_pci->dma[0].size*2 - 1) -
+ fc_pci->last_dma1_cur_pos);
flexcop_pass_dmx_data(fc_pci->fc_dev,
- fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
- (fc_pci->dma[0].size*2) - fc_pci->last_dma1_cur_pos);
+ fc_pci->dma[0].cpu_addr0 +
+ fc_pci->last_dma1_cur_pos,
+ (fc_pci->dma[0].size*2) -
+ fc_pci->last_dma1_cur_pos);
fc_pci->last_dma1_cur_pos = 0;
}
if (cur_pos > fc_pci->last_dma1_cur_pos) {
- deb_irq(" passing %d bytes ",cur_pos - fc_pci->last_dma1_cur_pos);
+ deb_irq(" passing %d bytes ",
+ cur_pos - fc_pci->last_dma1_cur_pos);
flexcop_pass_dmx_data(fc_pci->fc_dev,
- fc_pci->dma[0].cpu_addr0 + fc_pci->last_dma1_cur_pos,
- cur_pos - fc_pci->last_dma1_cur_pos);
+ fc_pci->dma[0].cpu_addr0 +
+ fc_pci->last_dma1_cur_pos,
+ cur_pos - fc_pci->last_dma1_cur_pos);
}
deb_irq("\n");
fc_pci->last_dma1_cur_pos = cur_pos;
fc_pci->count++;
} else {
- deb_irq("isr for flexcop called, apparently without reason (%08x)\n",v.raw);
+ deb_irq("isr for flexcop called, "
+ "apparently without reason (%08x)\n", v.raw);
ret = IRQ_NONE;
}
- spin_unlock_irqrestore(&fc_pci->irq_lock,flags);
-
+ spin_unlock_irqrestore(&fc_pci->irq_lock, flags);
return ret;
}
@@ -247,52 +257,48 @@ static int flexcop_pci_stream_control(struct flexcop_device *fc, int onoff)
{
struct flexcop_pci *fc_pci = fc->bus_specific;
if (onoff) {
- flexcop_dma_config(fc,&fc_pci->dma[0],FC_DMA_1);
- flexcop_dma_config(fc,&fc_pci->dma[1],FC_DMA_2);
-
- flexcop_dma_config_timer(fc,FC_DMA_1,0);
-
- flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,1);
+ flexcop_dma_config(fc, &fc_pci->dma[0], FC_DMA_1);
+ flexcop_dma_config(fc, &fc_pci->dma[1], FC_DMA_2);
+ flexcop_dma_config_timer(fc, FC_DMA_1, 0);
+ flexcop_dma_xfer_control(fc, FC_DMA_1,
+ FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 1);
deb_irq("DMA xfer enabled\n");
fc_pci->last_dma1_cur_pos = 0;
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,1);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 1);
deb_irq("IRQ enabled\n");
-
fc_pci->count_prev = fc_pci->count;
-
-// fc_pci->active_dma1_addr = 0;
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,1);
-
} else {
- flexcop_dma_control_timer_irq(fc,FC_DMA_1,0);
+ flexcop_dma_control_timer_irq(fc, FC_DMA_1, 0);
deb_irq("IRQ disabled\n");
-// flexcop_dma_control_size_irq(fc,FC_DMA_1,0);
-
- flexcop_dma_xfer_control(fc,FC_DMA_1,FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1,0);
+ flexcop_dma_xfer_control(fc, FC_DMA_1,
+ FC_DMA_SUBADDR_0 | FC_DMA_SUBADDR_1, 0);
deb_irq("DMA xfer disabled\n");
}
-
return 0;
}
static int flexcop_pci_dma_init(struct flexcop_pci *fc_pci)
{
int ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[0],FC_DEFAULT_DMA1_BUFSIZE)) != 0)
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[0],
+ FC_DEFAULT_DMA1_BUFSIZE);
+ if (ret != 0)
return ret;
- if ((ret = flexcop_dma_allocate(fc_pci->pdev,&fc_pci->dma[1],FC_DEFAULT_DMA2_BUFSIZE)) != 0) {
+ ret = flexcop_dma_allocate(fc_pci->pdev, &fc_pci->dma[1],
+ FC_DEFAULT_DMA2_BUFSIZE);
+ if (ret != 0) {
flexcop_dma_free(&fc_pci->dma[0]);
return ret;
}
- flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
- flexcop_sram_set_dest(fc_pci->fc_dev,FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
-
+ flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_MEDIA |
+ FC_SRAM_DEST_NET, FC_SRAM_DEST_TARGET_DMA1);
+ flexcop_sram_set_dest(fc_pci->fc_dev, FC_SRAM_DEST_CAO |
+ FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_DMA2);
fc_pci->init_state |= FC_PCI_DMA_INIT;
-
return ret;
}
@@ -315,12 +321,8 @@ static int flexcop_pci_init(struct flexcop_pci *fc_pci)
if ((ret = pci_enable_device(fc_pci->pdev)) != 0)
return ret;
-
pci_set_master(fc_pci->pdev);
- /* enable interrupts */
- // pci_write_config_dword(pdev, 0x6c, 0x8000);
-
if ((ret = pci_request_regions(fc_pci->pdev, DRIVER_NAME)) != 0)
goto err_pci_disable_device;
@@ -363,8 +365,8 @@ static void flexcop_pci_exit(struct flexcop_pci *fc_pci)
fc_pci->init_state &= ~FC_PCI_INIT;
}
-
-static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int flexcop_pci_probe(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
{
struct flexcop_device *fc;
struct flexcop_pci *fc_pci;
@@ -375,7 +377,7 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_pci = fc->bus_specific;
fc_pci->fc_dev = fc;
@@ -383,7 +385,6 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->write_ibi_reg = flexcop_pci_write_ibi_reg;
fc->i2c_request = flexcop_i2c_request;
fc->get_mac_addr = flexcop_eeprom_check_mac_addr;
-
fc->stream_control = flexcop_pci_stream_control;
if (enable_pid_filtering)
@@ -393,20 +394,19 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
fc->pid_filtering = enable_pid_filtering;
fc->bus_type = FC_PCI;
-
fc->dev = &pdev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_pci->pdev = pdev;
if ((ret = flexcop_pci_init(fc_pci)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_pci_exit;
-/* init dma */
+ /* init dma */
if ((ret = flexcop_pci_dma_init(fc_pci)) != 0)
goto err_fc_exit;
@@ -416,10 +416,11 @@ static int flexcop_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
INIT_DELAYED_WORK(&fc_pci->irq_check_work, flexcop_pci_irq_check_work);
#endif
- if (irq_chk_intv > 0)
- schedule_delayed_work(&fc_pci->irq_check_work,
- msecs_to_jiffies(irq_chk_intv < 100 ? 100 : irq_chk_intv));
-
+ if (irq_chk_intv > 0)
+ schedule_delayed_work(&fc_pci->irq_check_work,
+ msecs_to_jiffies(irq_chk_intv < 100 ?
+ 100 :
+ irq_chk_intv));
return ret;
err_fc_exit:
@@ -449,7 +450,6 @@ static void flexcop_pci_remove(struct pci_dev *pdev)
static struct pci_device_id flexcop_pci_tbl[] = {
{ PCI_DEVICE(0x13d0, 0x2103) },
-/* { PCI_DEVICE(0x13d0, 0x2200) }, ? */
{ },
};
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-reg.h b/linux/drivers/media/dvb/b2c2/flexcop-reg.h
index 7599fccc1..dc4528dcb 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-reg.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop-reg.h
@@ -1,14 +1,11 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* flexcop-reg.h - register abstraction for FlexCopII, FlexCopIIb and FlexCopIII
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_REG_H__
#define __FLEXCOP_REG_H__
-
typedef enum {
FLEXCOP_UNK = 0,
FLEXCOP_II,
@@ -18,13 +15,13 @@ typedef enum {
typedef enum {
FC_UNK = 0,
- FC_AIR_DVB,
+ FC_CABLE,
+ FC_AIR_DVBT,
FC_AIR_ATSC1,
FC_AIR_ATSC2,
- FC_SKY,
- FC_SKY_OLD,
- FC_CABLE,
FC_AIR_ATSC3,
+ FC_SKY_REV23,
+ FC_SKY_REV26,
FC_SKY_REV27,
FC_SKY_REV28,
} flexcop_device_type_t;
@@ -36,12 +33,12 @@ typedef enum {
/* FlexCop IBI Registers */
#if defined(__LITTLE_ENDIAN)
- #include "flexcop_ibi_value_le.h"
+#include "flexcop_ibi_value_le.h"
#else
#if defined(__BIG_ENDIAN)
- #include "flexcop_ibi_value_be.h"
+#include "flexcop_ibi_value_be.h"
#else
- #error no endian defined
+#error no endian defined
#endif
#endif
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-sram.c b/linux/drivers/media/dvb/b2c2/flexcop-sram.c
index cfb196ef7..d0e82a360 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-sram.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-sram.c
@@ -1,45 +1,43 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-sram.c - functions for controlling the SRAM.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-sram.c - functions for controlling the SRAM
+ * see flexcop.c for copyright information
*/
#include "flexcop.h"
-static void flexcop_sram_set_chip (struct flexcop_device *fc, flexcop_sram_type_t type)
+static void flexcop_sram_set_chip(struct flexcop_device *fc,
+ flexcop_sram_type_t type)
{
- flexcop_set_ibi_value(wan_ctrl_reg_71c,sram_chip,type);
+ flexcop_set_ibi_value(wan_ctrl_reg_71c, sram_chip, type);
}
int flexcop_sram_init(struct flexcop_device *fc)
{
switch (fc->rev) {
- case FLEXCOP_II:
- case FLEXCOP_IIB:
- flexcop_sram_set_chip(fc,FC_SRAM_1_32KB);
- break;
- case FLEXCOP_III:
- flexcop_sram_set_chip(fc,FC_SRAM_1_48KB);
- break;
- default:
- return -EINVAL;
+ case FLEXCOP_II:
+ case FLEXCOP_IIB:
+ flexcop_sram_set_chip(fc, FC_SRAM_1_32KB);
+ break;
+ case FLEXCOP_III:
+ flexcop_sram_set_chip(fc, FC_SRAM_1_48KB);
+ break;
+ default:
+ return -EINVAL;
}
return 0;
}
-int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest, flexcop_sram_dest_target_t target)
+int flexcop_sram_set_dest(struct flexcop_device *fc, flexcop_sram_dest_t dest,
+ flexcop_sram_dest_target_t target)
{
flexcop_ibi_value v;
-
- v = fc->read_ibi_reg(fc,sram_dest_reg_714);
+ v = fc->read_ibi_reg(fc, sram_dest_reg_714);
if (fc->rev != FLEXCOP_III && target == FC_SRAM_DEST_TARGET_FC3_CA) {
err("SRAM destination target to available on FlexCopII(b)\n");
return -EINVAL;
}
-
- deb_sram("sram dest: %x target: %x\n",dest, target);
+ deb_sram("sram dest: %x target: %x\n", dest, target);
if (dest & FC_SRAM_DEST_NET)
v.sram_dest_reg_714.NET_Dest = target;
@@ -154,14 +152,12 @@ static void sram_write_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len
else
bank = 0x10000000;
}
-
flex_sram_write(adapter, bank, addr & 0x7fff, buf, len);
}
static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
{
u32 bank;
-
bank = 0;
if (adapter->dw_sram_type == 0x20000) {
@@ -174,26 +170,22 @@ static void sram_read_chunk(struct adapter *adapter, u32 addr, u8 *buf, u16 len)
else
bank = 0x10000000;
}
-
flex_sram_read(adapter, bank, addr & 0x7fff, buf, len);
}
static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
{
u32 length;
-
while (len != 0) {
length = len;
-
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is read from
- // one chip at a time.
+ /* check if the address range belongs to the same
+ * 32K memory chip. If not, the data is read
+ * from one chip at a time */
if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
}
sram_read_chunk(adapter, addr, buf, length);
-
addr = addr + length;
buf = buf + length;
len = len - length;
@@ -203,19 +195,17 @@ static void sram_read(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
{
u32 length;
-
while (len != 0) {
length = len;
- // check if the address range belongs to the same
- // 32K memory chip. If not, the data is written to
- // one chip at a time.
+ /* check if the address range belongs to the same
+ * 32K memory chip. If not, the data is
+ * written to one chip at a time */
if ((addr >> 0x0f) != ((addr + len - 1) >> 0x0f)) {
length = (((addr >> 0x0f) + 1) << 0x0f) - addr;
}
sram_write_chunk(adapter, addr, buf, length);
-
addr = addr + length;
buf = buf + length;
len = len - length;
@@ -224,39 +214,29 @@ static void sram_write(struct adapter *adapter, u32 addr, u8 *buf, u32 len)
static void sram_set_size(struct adapter *adapter, u32 mask)
{
- write_reg_dw(adapter, 0x71c, (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
+ write_reg_dw(adapter, 0x71c,
+ (mask | (~0x30000 & read_reg_dw(adapter, 0x71c))));
}
static void sram_init(struct adapter *adapter)
{
u32 tmp;
-
tmp = read_reg_dw(adapter, 0x71c);
-
write_reg_dw(adapter, 0x71c, 1);
if (read_reg_dw(adapter, 0x71c) != 0) {
write_reg_dw(adapter, 0x71c, tmp);
-
adapter->dw_sram_type = tmp & 0x30000;
-
ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
-
} else {
-
adapter->dw_sram_type = 0x10000;
-
ddprintk("%s: dw_sram_type = %x\n", __func__, adapter->dw_sram_type);
}
-
- /* return value is never used? */
-/* return adapter->dw_sram_type; */
}
static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
{
u8 tmp1, tmp2;
-
dprintk("%s: mask = %x, addr = %x\n", __func__, mask, addr);
sram_set_size(adapter, mask);
@@ -269,7 +249,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -287,7 +266,6 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
sram_write(adapter, addr + 4, &tmp1, 1);
tmp2 = 0;
-
mdelay(20);
sram_read(adapter, addr, &tmp2, 1);
@@ -297,26 +275,24 @@ static int sram_test_location(struct adapter *adapter, u32 mask, u32 addr)
if (tmp2 != 0x5a)
return 0;
-
return 1;
}
static u32 sram_length(struct adapter *adapter)
{
if (adapter->dw_sram_type == 0x10000)
- return 32768; // 32K
+ return 32768; /* 32K */
if (adapter->dw_sram_type == 0x00000)
- return 65536; // 64K
+ return 65536; /* 64K */
if (adapter->dw_sram_type == 0x20000)
- return 131072; // 128K
-
- return 32768; // 32K
+ return 131072; /* 128K */
+ return 32768; /* 32K */
}
/* FlexcopII can work with 32K, 64K or 128K of external SRAM memory.
- - for 128K there are 4x32K chips at bank 0,1,2,3.
- - for 64K there are 2x32K chips at bank 1,2.
- - for 32K there is one 32K chip at bank 0.
+ - for 128K there are 4x32K chips at bank 0,1,2,3.
+ - for 64K there are 2x32K chips at bank 1,2.
+ - for 32K there is one 32K chip at bank 0.
FlexCop works only with one bank at a time. The bank is selected
by bits 28-29 of the 0x700 register.
@@ -324,24 +300,18 @@ static u32 sram_length(struct adapter *adapter)
bank 0 covers addresses 0x00000-0x07fff
bank 1 covers addresses 0x08000-0x0ffff
bank 2 covers addresses 0x10000-0x17fff
- bank 3 covers addresses 0x18000-0x1ffff
-*/
+ bank 3 covers addresses 0x18000-0x1ffff */
static int flexcop_sram_detect(struct flexcop_device *fc)
{
- flexcop_ibi_value r208,r71c_0,vr71c_1;
-
+ flexcop_ibi_value r208, r71c_0, vr71c_1;
r208 = fc->read_ibi_reg(fc, ctrl_208);
fc->write_ibi_reg(fc, ctrl_208, ibi_zero);
r71c_0 = fc->read_ibi_reg(fc, wan_ctrl_reg_71c);
-
write_reg_dw(adapter, 0x71c, 1);
-
tmp3 = read_reg_dw(adapter, 0x71c);
-
dprintk("%s: tmp3 = %x\n", __func__, tmp3);
-
write_reg_dw(adapter, 0x71c, tmp2);
// check for internal SRAM ???
@@ -350,9 +320,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
@@ -360,9 +328,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x20000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 128K\n", __func__);
-
return 128;
}
@@ -370,9 +336,7 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x00000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 64K\n", __func__);
-
return 64;
}
@@ -380,18 +344,14 @@ static int flexcop_sram_detect(struct flexcop_device *fc)
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: sram size = 32K\n", __func__);
-
return 32;
}
sram_set_size(adapter, 0x10000);
sram_init(adapter);
write_reg_dw(adapter, 0x208, tmp);
-
dprintk("%s: SRAM detection failed. Set to 32K \n", __func__);
-
return 0;
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.c b/linux/drivers/media/dvb/b2c2/flexcop-usb.c
index 4be298e90..65206b656 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-usb.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.c
@@ -1,11 +1,8 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop-usb.c - covers the USB part.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.c - covers the USB part
+ * see flexcop.c for copyright information
*/
-
#define FC_LOG_PREFIX "flexcop_usb"
#include "flexcop-usb.h"
#include "flexcop-common.h"
@@ -18,42 +15,47 @@
/* debug */
#ifdef CONFIG_DVB_B2C2_FLEXCOP_DEBUG
#define dprintk(level,args...) \
- do { if ((debug & level)) { printk(args); } } while (0)
-#define debug_dump(b,l,method) {\
+ do { if ((debug & level)) printk(args); } while (0)
+
+#define debug_dump(b, l, method) do {\
int i; \
- for (i = 0; i < l; i++) method("%02x ", b[i]); \
- method("\n");\
-}
+ for (i = 0; i < l; i++) \
+ method("%02x ", b[i]); \
+ method("\n"); \
+} while (0)
#define DEBSTATUS ""
#else
-#define dprintk(level,args...)
-#define debug_dump(b,l,method)
+#define dprintk(level, args...)
+#define debug_dump(b, l, method)
#define DEBSTATUS " (debugging is not enabled)"
#endif
static int debug;
module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,ts=2,"
+ "ctrl=4,i2c=8,v8mem=16 (or-able))." DEBSTATUS);
#undef DEBSTATUS
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_ts(args...) dprintk(0x02,args)
-#define deb_ctrl(args...) dprintk(0x04,args)
-#define deb_i2c(args...) dprintk(0x08,args)
-#define deb_v8(args...) dprintk(0x10,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_ts(args...) dprintk(0x02, args)
+#define deb_ctrl(args...) dprintk(0x04, args)
+#define deb_i2c(args...) dprintk(0x08, args)
+#define deb_v8(args...) dprintk(0x10, args)
/* JLP 111700: we will include the 1 bit gap between the upper and lower 3 bits
* in the IBI address, to make the V8 code simpler.
- * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (these are the six bits used)
+ * PCI ADDRESS FORMAT: 0x71C -> 0000 0111 0001 1100 (the six bits used)
* in general: 0000 0HHH 000L LL00
* IBI ADDRESS FORMAT: RHHH BLLL
*
* where R is the read(1)/write(0) bit, B is the busy bit
* and HHH and LLL are the two sets of three bits from the PCI address.
*/
-#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
-#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
+#define B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(usPCI) (u8) \
+ (((usPCI >> 2) & 0x07) + ((usPCI >> 4) & 0x70))
+#define B2C2_FLEX_INTERNALADDR_TO_PCIOFFSET(ucAddr) (u16) \
+ (((ucAddr & 0x07) << 2) + ((ucAddr & 0x70) << 4))
/*
* DKT 020228
@@ -69,12 +71,13 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
struct flexcop_usb *fc_usb = fc->bus_specific;
u8 request = read ? B2C2_USB_READ_REG : B2C2_USB_WRITE_REG;
u8 request_type = (read ? USB_DIR_IN : USB_DIR_OUT) | USB_TYPE_VENDOR;
- u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) | (read ? 0x80 : 0);
+ u8 wAddress = B2C2_FLEX_PCIOFFSET_TO_INTERNALADDR(wRegOffsPCI) |
+ (read ? 0x80 : 0);
int len = usb_control_msg(fc_usb->udev,
read ? B2C2_USB_CTRL_PIPE_IN : B2C2_USB_CTRL_PIPE_OUT,
request,
- request_type, /* 0xc0 read or 0x40 write*/
+ request_type, /* 0xc0 read or 0x40 write */
wAddress,
0,
val,
@@ -82,55 +85,49 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI,
B2C2_WAIT_FOR_OPERATION_RDW * HZ);
if (len != sizeof(u32)) {
- err("error while %s dword from %d (%d).",read ? "reading" : "writing",
- wAddress,wRegOffsPCI);
+ err("error while %s dword from %d (%d).", read ? "reading" :
+ "writing", wAddress, wRegOffsPCI);
return -EIO;
}
return 0;
}
-
/*
* DKT 010817 - add support for V8 memory read/write and flash update
*/
static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
flexcop_usb_request_t req, u8 page, u16 wAddress,
- u8 *pbBuffer,u32 buflen)
+ u8 *pbBuffer, u32 buflen)
{
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
u16 wIndex;
- int nWaitTime,pipe,len;
-
+ int nWaitTime, pipe, len;
wIndex = page << 8;
switch (req) {
- case B2C2_USB_READ_V8_MEM:
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
- request_type |= USB_DIR_IN;
-// dwRequestType = (u8) RTYPE_READ_V8_MEMORY;
- pipe = B2C2_USB_CTRL_PIPE_IN;
+ case B2C2_USB_READ_V8_MEM:
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8READ;
+ request_type |= USB_DIR_IN;
+ pipe = B2C2_USB_CTRL_PIPE_IN;
break;
- case B2C2_USB_WRITE_V8_MEM:
- wIndex |= pbBuffer[0];
- request_type |= USB_DIR_OUT;
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
-// dwRequestType = (u8) RTYPE_WRITE_V8_MEMORY;
- pipe = B2C2_USB_CTRL_PIPE_OUT;
+ case B2C2_USB_WRITE_V8_MEM:
+ wIndex |= pbBuffer[0];
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8WRITE;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- case B2C2_USB_FLASH_BLOCK:
- request_type |= USB_DIR_OUT;
- nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
-// dwRequestType = (u8) RTYPE_WRITE_V8_FLASH;
- pipe = B2C2_USB_CTRL_PIPE_OUT;
+ case B2C2_USB_FLASH_BLOCK:
+ request_type |= USB_DIR_OUT;
+ nWaitTime = B2C2_WAIT_FOR_OPERATION_V8FLASH;
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
break;
- default:
- deb_info("unsupported request for v8_mem_req %x.\n",req);
+ default:
+ deb_info("unsupported request for v8_mem_req %x.\n", req);
return -EINVAL;
}
- deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n",request_type,req,
- wAddress,wIndex,buflen);
+ deb_v8("v8mem: %02x %02x %04x %04x, len: %d\n", request_type, req,
+ wAddress, wIndex, buflen);
- len = usb_control_msg(fc_usb->udev,pipe,
+ len = usb_control_msg(fc_usb->udev, pipe,
req,
request_type,
wAddress,
@@ -139,39 +136,53 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb,
buflen,
nWaitTime * HZ);
- debug_dump(pbBuffer,len,deb_v8);
-
+ debug_dump(pbBuffer, len, deb_v8);
return len == buflen ? 0 : -EIO;
}
#define bytes_left_to_read_on_page(paddr,buflen) \
- ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
- ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
+ ((V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)) > buflen \
+ ? buflen : (V8_MEMORY_PAGE_SIZE - (paddr & V8_MEMORY_PAGE_MASK)))
-static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request_t req,
- flexcop_usb_mem_page_t page_start, u32 addr, int extended, u8 *buf, u32 len)
+static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,
+ flexcop_usb_request_t req, flexcop_usb_mem_page_t page_start,
+ u32 addr, int extended, u8 *buf, u32 len)
{
int i,ret = 0;
u16 wMax;
u32 pagechunk = 0;
switch(req) {
- case B2C2_USB_READ_V8_MEM: wMax = USB_MEM_READ_MAX; break;
- case B2C2_USB_WRITE_V8_MEM: wMax = USB_MEM_WRITE_MAX; break;
- case B2C2_USB_FLASH_BLOCK: wMax = USB_FLASH_MAX; break;
- default:
- return -EINVAL;
+ case B2C2_USB_READ_V8_MEM:
+ wMax = USB_MEM_READ_MAX;
+ break;
+ case B2C2_USB_WRITE_V8_MEM:
+ wMax = USB_MEM_WRITE_MAX;
+ break;
+ case B2C2_USB_FLASH_BLOCK:
+ wMax = USB_FLASH_MAX;
+ break;
+ default:
+ return -EINVAL;
break;
}
for (i = 0; i < len;) {
- pagechunk = wMax < bytes_left_to_read_on_page(addr,len) ? wMax : bytes_left_to_read_on_page(addr,len);
- deb_info("%x\n",(addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended));
- if ((ret = flexcop_usb_v8_memory_req(fc_usb,req,
- page_start + (addr / V8_MEMORY_PAGE_SIZE), /* actual page */
- (addr & V8_MEMORY_PAGE_MASK) | (V8_MEMORY_EXTENDED*extended),
- &buf[i],pagechunk)) < 0)
+ pagechunk =
+ wMax < bytes_left_to_read_on_page(addr, len) ?
+ wMax :
+ bytes_left_to_read_on_page(addr, len);
+ deb_info("%x\n",
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended));
+
+ ret = flexcop_usb_v8_memory_req(fc_usb, req,
+ page_start + (addr / V8_MEMORY_PAGE_SIZE),
+ (addr & V8_MEMORY_PAGE_MASK) |
+ (V8_MEMORY_EXTENDED*extended),
+ &buf[i], pagechunk);
+
+ if (ret < 0)
return ret;
-
addr += pagechunk;
len -= pagechunk;
}
@@ -180,8 +191,9 @@ static int flexcop_usb_memory_req(struct flexcop_usb *fc_usb,flexcop_usb_request
static int flexcop_usb_get_mac_addr(struct flexcop_device *fc, int extended)
{
- return flexcop_usb_memory_req(fc->bus_specific,B2C2_USB_READ_V8_MEM,
- V8_MEMORY_PAGE_FLASH,0x1f010,1,fc->dvb_adapter.proposed_mac,6);
+ return flexcop_usb_memory_req(fc->bus_specific, B2C2_USB_READ_V8_MEM,
+ V8_MEMORY_PAGE_FLASH, 0x1f010, 1,
+ fc->dvb_adapter.proposed_mac, 6);
}
#if 0 /* keep */
@@ -191,11 +203,8 @@ static int flexcop_usb_utility_req(struct flexcop_usb *fc_usb, int set,
{
u16 wValue;
u8 request_type = (set ? USB_DIR_OUT : USB_DIR_IN) | USB_TYPE_VENDOR;
-// u8 dwRequestType = (u8) RTYPE_GENERIC,
int nWaitTime = 2,
- pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN,
- len;
-
+ pipe = set ? B2C2_USB_CTRL_PIPE_OUT : B2C2_USB_CTRL_PIPE_IN, len;
wValue = (func << 8) | extra;
len = usb_control_msg(fc_usb->udev,pipe,
@@ -218,36 +227,35 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
struct flexcop_usb *fc_usb = i2c->fc->bus_specific;
u16 wValue, wIndex;
int nWaitTime,pipe,len;
-// u8 dwRequestType;
u8 request_type = USB_TYPE_VENDOR;
switch (func) {
- case USB_FUNC_I2C_WRITE:
- case USB_FUNC_I2C_MULTIWRITE:
- case USB_FUNC_I2C_REPEATWRITE:
+ case USB_FUNC_I2C_WRITE:
+ case USB_FUNC_I2C_MULTIWRITE:
+ case USB_FUNC_I2C_REPEATWRITE:
/* DKT 020208 - add this to support special case of DiSEqC */
- case USB_FUNC_I2C_CHECKWRITE:
- pipe = B2C2_USB_CTRL_PIPE_OUT;
- nWaitTime = 2;
-// dwRequestType = (u8) RTYPE_GENERIC;
- request_type |= USB_DIR_OUT;
+ case USB_FUNC_I2C_CHECKWRITE:
+ pipe = B2C2_USB_CTRL_PIPE_OUT;
+ nWaitTime = 2;
+ request_type |= USB_DIR_OUT;
break;
- case USB_FUNC_I2C_READ:
- case USB_FUNC_I2C_REPEATREAD:
- pipe = B2C2_USB_CTRL_PIPE_IN;
- nWaitTime = 2;
-// dwRequestType = (u8) RTYPE_GENERIC;
- request_type |= USB_DIR_IN;
+ case USB_FUNC_I2C_READ:
+ case USB_FUNC_I2C_REPEATREAD:
+ pipe = B2C2_USB_CTRL_PIPE_IN;
+ nWaitTime = 2;
+ request_type |= USB_DIR_IN;
break;
- default:
- deb_info("unsupported function for i2c_req %x\n",func);
- return -EINVAL;
+ default:
+ deb_info("unsupported function for i2c_req %x\n", func);
+ return -EINVAL;
}
wValue = (func << 8) | (i2c->port << 4);
wIndex = (chipaddr << 8 ) | addr;
- deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",func,request_type,req,
- wValue & 0xff, wValue >> 8, wIndex & 0xff, wIndex >> 8);
+ deb_i2c("i2c %2d: %02x %02x %02x %02x %02x %02x\n",
+ func, request_type, req,
+ wValue & 0xff, wValue >> 8,
+ wIndex & 0xff, wIndex >> 8);
len = usb_control_msg(fc_usb->udev,pipe,
req,
@@ -257,44 +265,49 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c,
buf,
buflen,
nWaitTime * HZ);
-
return len == buflen ? 0 : -EREMOTEIO;
}
-/* actual bus specific access functions, make sure prototype are/will be equal to pci */
-static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg)
+/* actual bus specific access functions,
+ make sure prototype are/will be equal to pci */
+static flexcop_ibi_value flexcop_usb_read_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg)
{
flexcop_ibi_value val;
val.raw = 0;
- flexcop_usb_readwrite_dw(fc,reg, &val.raw, 1);
+ flexcop_usb_readwrite_dw(fc, reg, &val.raw, 1);
return val;
}
-static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc, flexcop_ibi_register reg, flexcop_ibi_value val)
+static int flexcop_usb_write_ibi_reg(struct flexcop_device *fc,
+ flexcop_ibi_register reg, flexcop_ibi_value val)
{
- return flexcop_usb_readwrite_dw(fc,reg, &val.raw, 0);
+ return flexcop_usb_readwrite_dw(fc, reg, &val.raw, 0);
}
static int flexcop_usb_i2c_request(struct flexcop_i2c_adapter *i2c,
- flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
+ flexcop_access_op_t op, u8 chipaddr, u8 addr, u8 *buf, u16 len)
{
if (op == FC_READ)
return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
- USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
+ USB_FUNC_I2C_READ, chipaddr, addr, buf, len);
else
return flexcop_usb_i2c_req(i2c, B2C2_USB_I2C_REQUEST,
- USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
+ USB_FUNC_I2C_WRITE, chipaddr, addr, buf, len);
}
-static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, int buffer_length)
+static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb,
+ u8 *buffer, int buffer_length)
{
u8 *b;
int l;
- deb_ts("tmp_buffer_length=%d, buffer_length=%d\n", fc_usb->tmp_buffer_length, buffer_length);
+ deb_ts("tmp_buffer_length=%d, buffer_length=%d\n",
+ fc_usb->tmp_buffer_length, buffer_length);
if (fc_usb->tmp_buffer_length > 0) {
- memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer, buffer_length);
+ memcpy(fc_usb->tmp_buffer+fc_usb->tmp_buffer_length, buffer,
+ buffer_length);
fc_usb->tmp_buffer_length += buffer_length;
b = fc_usb->tmp_buffer;
l = fc_usb->tmp_buffer_length;
@@ -304,23 +317,26 @@ static void flexcop_usb_process_frame(struct flexcop_usb *fc_usb, u8 *buffer, in
}
while (l >= 190) {
- if (*b == 0xff)
+ if (*b == 0xff) {
switch (*(b+1) & 0x03) {
- case 0x01: /* media packet */
- if ( *(b+2) == 0x47 )
- flexcop_pass_dmx_packets(fc_usb->fc_dev, b+2, 1);
- else
- deb_ts("not ts packet %02x %02x %02x %02x \n", *(b+2), *(b+3), *(b+4), *(b+5) );
-
- b += 190;
- l -= 190;
+ case 0x01: /* media packet */
+ if (*(b+2) == 0x47)
+ flexcop_pass_dmx_packets(
+ fc_usb->fc_dev, b+2, 1);
+ else
+ deb_ts(
+ "not ts packet %02x %02x %02x %02x \n",
+ *(b+2), *(b+3),
+ *(b+4), *(b+5));
+ b += 190;
+ l -= 190;
break;
- default:
- deb_ts("wrong packet type\n");
- l = 0;
+ default:
+ deb_ts("wrong packet type\n");
+ l = 0;
break;
}
- else {
+ } else {
deb_ts("wrong header\n");
l = 0;
}
@@ -341,23 +357,26 @@ static void flexcop_usb_urb_complete(struct urb *urb)
int i;
if (urb->actual_length > 0)
- deb_ts("urb completed, bufsize: %d actlen; %d\n",urb->transfer_buffer_length, urb->actual_length);
+ deb_ts("urb completed, bufsize: %d actlen; %d\n",
+ urb->transfer_buffer_length, urb->actual_length);
for (i = 0; i < urb->number_of_packets; i++) {
if (urb->iso_frame_desc[i].status < 0) {
- err("iso frame descriptor %d has an error: %d\n",i,urb->iso_frame_desc[i].status);
+ err("iso frame descriptor %d has an error: %d\n", i,
+ urb->iso_frame_desc[i].status);
} else
if (urb->iso_frame_desc[i].actual_length > 0) {
- deb_ts("passed %d bytes to the demux\n",urb->iso_frame_desc[i].actual_length);
+ deb_ts("passed %d bytes to the demux\n",
+ urb->iso_frame_desc[i].actual_length);
flexcop_usb_process_frame(fc_usb,
- urb->transfer_buffer + urb->iso_frame_desc[i].offset,
+ urb->transfer_buffer +
+ urb->iso_frame_desc[i].offset,
urb->iso_frame_desc[i].actual_length);
- }
+ }
urb->iso_frame_desc[i].status = 0;
urb->iso_frame_desc[i].actual_length = 0;
}
-
usb_submit_urb(urb,GFP_ATOMIC);
}
@@ -378,35 +397,47 @@ static void flexcop_usb_transfer_exit(struct flexcop_usb *fc_usb)
}
if (fc_usb->iso_buffer != NULL)
- pci_free_consistent(NULL,fc_usb->buffer_size, fc_usb->iso_buffer, fc_usb->dma_addr);
+ pci_free_consistent(NULL,
+ fc_usb->buffer_size, fc_usb->iso_buffer,
+ fc_usb->dma_addr);
}
static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
{
- u16 frame_size = le16_to_cpu(fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
- int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO * frame_size,i,j,ret;
+ u16 frame_size = le16_to_cpu(
+ fc_usb->uintf->cur_altsetting->endpoint[0].desc.wMaxPacketSize);
+ int bufsize = B2C2_USB_NUM_ISO_URB * B2C2_USB_FRAMES_PER_ISO *
+ frame_size, i, j, ret;
int buffer_offset = 0;
- deb_ts("creating %d iso-urbs with %d frames each of %d bytes size = %d.\n",
- B2C2_USB_NUM_ISO_URB, B2C2_USB_FRAMES_PER_ISO, frame_size,bufsize);
+ deb_ts("creating %d iso-urbs with %d frames "
+ "each of %d bytes size = %d.\n", B2C2_USB_NUM_ISO_URB,
+ B2C2_USB_FRAMES_PER_ISO, frame_size, bufsize);
- fc_usb->iso_buffer = pci_alloc_consistent(NULL,bufsize,&fc_usb->dma_addr);
+ fc_usb->iso_buffer = pci_alloc_consistent(NULL,
+ bufsize, &fc_usb->dma_addr);
if (fc_usb->iso_buffer == NULL)
return -ENOMEM;
+
memset(fc_usb->iso_buffer, 0, bufsize);
fc_usb->buffer_size = bufsize;
/* creating iso urbs */
- for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++)
- if (!(fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,GFP_ATOMIC))) {
+ for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
+ fc_usb->iso_urb[i] = usb_alloc_urb(B2C2_USB_FRAMES_PER_ISO,
+ GFP_ATOMIC);
+ if (fc_usb->iso_urb[i] == NULL) {
ret = -ENOMEM;
goto urb_error;
}
+ }
+
/* initialising and submitting iso urbs */
for (i = 0; i < B2C2_USB_NUM_ISO_URB; i++) {
int frame_offset = 0;
struct urb *urb = fc_usb->iso_urb[i];
- deb_ts("initializing and submitting urb no. %d (buf_offset: %d).\n",i,buffer_offset);
+ deb_ts("initializing and submitting urb no. %d "
+ "(buf_offset: %d).\n", i, buffer_offset);
urb->dev = fc_usb->udev;
urb->context = fc_usb;
@@ -420,26 +451,26 @@ static int flexcop_usb_transfer_init(struct flexcop_usb *fc_usb)
buffer_offset += frame_size * B2C2_USB_FRAMES_PER_ISO;
for (j = 0; j < B2C2_USB_FRAMES_PER_ISO; j++) {
- deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",i,j,frame_offset);
+ deb_ts("urb no: %d, frame: %d, frame_offset: %d\n",
+ i, j, frame_offset);
urb->iso_frame_desc[j].offset = frame_offset;
urb->iso_frame_desc[j].length = frame_size;
frame_offset += frame_size;
}
if ((ret = usb_submit_urb(fc_usb->iso_urb[i],GFP_ATOMIC))) {
- err("submitting urb %d failed with %d.",i,ret);
+ err("submitting urb %d failed with %d.", i, ret);
goto urb_error;
}
deb_ts("submitted urb no. %d.\n",i);
}
-/* SRAM */
-
- flexcop_sram_set_dest(fc_usb->fc_dev,FC_SRAM_DEST_MEDIA | FC_SRAM_DEST_NET |
- FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI, FC_SRAM_DEST_TARGET_WAN_USB);
- flexcop_wan_set_speed(fc_usb->fc_dev,FC_WAN_SPEED_8MBITS);
- flexcop_sram_ctrl(fc_usb->fc_dev,1,1,1);
-
+ /* SRAM */
+ flexcop_sram_set_dest(fc_usb->fc_dev, FC_SRAM_DEST_MEDIA |
+ FC_SRAM_DEST_NET | FC_SRAM_DEST_CAO | FC_SRAM_DEST_CAI,
+ FC_SRAM_DEST_TARGET_WAN_USB);
+ flexcop_wan_set_speed(fc_usb->fc_dev, FC_WAN_SPEED_8MBITS);
+ flexcop_sram_ctrl(fc_usb->fc_dev, 1, 1, 1);
return 0;
urb_error:
@@ -452,20 +483,20 @@ static int flexcop_usb_init(struct flexcop_usb *fc_usb)
/* use the alternate setting with the larges buffer */
usb_set_interface(fc_usb->udev,0,1);
switch (fc_usb->udev->speed) {
- case USB_SPEED_LOW:
- err("cannot handle USB speed because it is to sLOW.");
- return -ENODEV;
- break;
- case USB_SPEED_FULL:
- info("running at FULL speed.");
- break;
- case USB_SPEED_HIGH:
- info("running at HIGH speed.");
- break;
- case USB_SPEED_UNKNOWN: /* fall through */
- default:
- err("cannot handle USB speed because it is unkown.");
- return -ENODEV;
+ case USB_SPEED_LOW:
+ err("cannot handle USB speed because it is too slow.");
+ return -ENODEV;
+ break;
+ case USB_SPEED_FULL:
+ info("running at FULL speed.");
+ break;
+ case USB_SPEED_HIGH:
+ info("running at HIGH speed.");
+ break;
+ case USB_SPEED_UNKNOWN: /* fall through */
+ default:
+ err("cannot handle USB speed because it is unknown.");
+ return -ENODEV;
}
usb_set_intfdata(fc_usb->uintf, fc_usb);
return 0;
@@ -489,7 +520,7 @@ static int flexcop_usb_probe(struct usb_interface *intf,
return -ENOMEM;
}
-/* general flexcop init */
+ /* general flexcop init */
fc_usb = fc->bus_specific;
fc_usb->fc_dev = fc;
@@ -506,21 +537,21 @@ static int flexcop_usb_probe(struct usb_interface *intf,
fc->dev = &udev->dev;
fc->owner = THIS_MODULE;
-/* bus specific part */
+ /* bus specific part */
fc_usb->udev = udev;
fc_usb->uintf = intf;
if ((ret = flexcop_usb_init(fc_usb)) != 0)
goto err_kfree;
-/* init flexcop */
+ /* init flexcop */
if ((ret = flexcop_device_initialize(fc)) != 0)
goto err_usb_exit;
-/* xfer init */
+ /* xfer init */
if ((ret = flexcop_usb_transfer_init(fc_usb)) != 0)
goto err_fc_exit;
- info("%s successfully initialized and connected.",DRIVER_NAME);
+ info("%s successfully initialized and connected.", DRIVER_NAME);
return 0;
err_fc_exit:
@@ -539,12 +570,12 @@ static void flexcop_usb_disconnect(struct usb_interface *intf)
flexcop_device_exit(fc_usb->fc_dev);
flexcop_usb_exit(fc_usb);
flexcop_device_kfree(fc_usb->fc_dev);
- info("%s successfully deinitialized and disconnected.",DRIVER_NAME);
+ info("%s successfully deinitialized and disconnected.", DRIVER_NAME);
}
static struct usb_device_id flexcop_usb_table [] = {
- { USB_DEVICE(0x0af7, 0x0101) },
- { }
+ { USB_DEVICE(0x0af7, 0x0101) },
+ { }
};
MODULE_DEVICE_TABLE (usb, flexcop_usb_table);
@@ -561,10 +592,9 @@ static int __init flexcop_usb_module_init(void)
{
int result;
if ((result = usb_register(&flexcop_usb_driver))) {
- err("usb_register failed. (%d)",result);
+ err("usb_register failed. (%d)", result);
return result;
}
-
return 0;
}
diff --git a/linux/drivers/media/dvb/b2c2/flexcop-usb.h b/linux/drivers/media/dvb/b2c2/flexcop-usb.h
index 0e31b9881..5fa250e33 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop-usb.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop-usb.h
@@ -1,15 +1,20 @@
+/*
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop-usb.h - header file for the USB part
+ * see flexcop.c for copyright information
+ */
#ifndef __FLEXCOP_USB_H_INCLUDED__
#define __FLEXCOP_USB_H_INCLUDED__
#include <linux/usb.h>
/* transfer parameters */
-#define B2C2_USB_FRAMES_PER_ISO 4
-#define B2C2_USB_NUM_ISO_URB 4
+#define B2C2_USB_FRAMES_PER_ISO 4
+#define B2C2_USB_NUM_ISO_URB 4
-#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev,0)
-#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev,0x81)
+#define B2C2_USB_CTRL_PIPE_IN usb_rcvctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_CTRL_PIPE_OUT usb_sndctrlpipe(fc_usb->udev, 0)
+#define B2C2_USB_DATA_PIPE usb_rcvisocpipe(fc_usb->udev, 0x81)
struct flexcop_usb {
struct usb_device *udev;
@@ -18,8 +23,8 @@ struct flexcop_usb {
u8 *iso_buffer;
int buffer_size;
dma_addr_t dma_addr;
- struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
+ struct urb *iso_urb[B2C2_USB_NUM_ISO_URB];
struct flexcop_device *fc_dev;
u8 tmp_buffer[1023+190];
@@ -30,14 +35,6 @@ struct flexcop_usb {
/* request types TODO What is its use?*/
typedef enum {
-/* something is wrong with this part
- RTYPE_READ_DW = (1 << 6),
- RTYPE_WRITE_DW_1 = (3 << 6),
- RTYPE_READ_V8_MEMORY = (6 << 6),
- RTYPE_WRITE_V8_MEMORY = (7 << 6),
- RTYPE_WRITE_V8_FLASH = (8 << 6),
- RTYPE_GENERIC = (9 << 6),
-*/
} flexcop_usb_request_type_t;
#endif
@@ -47,7 +44,6 @@ typedef enum {
B2C2_USB_READ_V8_MEM = 0x05,
B2C2_USB_READ_REG = 0x08,
B2C2_USB_WRITE_REG = 0x0A,
-/* B2C2_USB_WRITEREGLO = 0x0A, */
B2C2_USB_WRITEREGHI = 0x0B,
B2C2_USB_FLASH_BLOCK = 0x10,
B2C2_USB_I2C_REQUEST = 0x11,
@@ -62,15 +58,13 @@ typedef enum {
USB_FUNC_I2C_REPEATWRITE = 0x04,
USB_FUNC_GET_DESCRIPTOR = 0x05,
USB_FUNC_I2C_REPEATREAD = 0x06,
-/* DKT 020208 - add this to support special case of DiSEqC */
+ /* DKT 020208 - add this to support special case of DiSEqC */
USB_FUNC_I2C_CHECKWRITE = 0x07,
USB_FUNC_I2C_CHECKRESULT = 0x08,
} flexcop_usb_i2c_function_t;
-/*
- * function definition for UTILITY request 0x12
- * DKT 020304 - new utility function
- */
+/* function definition for UTILITY request 0x12
+ * DKT 020304 - new utility function */
typedef enum {
UTILITY_SET_FILTER = 0x01,
UTILITY_DATA_ENABLE = 0x02,
@@ -84,7 +78,7 @@ typedef enum {
UTILITY_DATA_RESET = 0x0A,
UTILITY_GET_DATA_STATUS = 0x10,
UTILITY_GET_V8_REG = 0x11,
-/* DKT 020326 - add function for v1.14 */
+ /* DKT 020326 - add function for v1.14 */
UTILITY_SRAM_WRITE = 0x12,
UTILITY_SRAM_READ = 0x13,
UTILITY_SRAM_TESTFILL = 0x14,
@@ -92,13 +86,13 @@ typedef enum {
UTILITY_SRAM_TESTVERIFY = 0x16,
} flexcop_usb_utility_function_t;
-#define B2C2_WAIT_FOR_OPERATION_RW 1*HZ /* 1 s */
-#define B2C2_WAIT_FOR_OPERATION_RDW 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_WDW 1*HZ /* 1 s */
+#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ)
+#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ)
-#define B2C2_WAIT_FOR_OPERATION_V8READ 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3*HZ /* 3 s */
-#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3*HZ /* 3 s */
+#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ)
+#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ)
typedef enum {
V8_MEMORY_PAGE_DVB_CI = 0x20,
@@ -107,13 +101,11 @@ typedef enum {
V8_MEMORY_PAGE_FLASH = 0x80
} flexcop_usb_mem_page_t;
-#define V8_MEMORY_EXTENDED (1 << 15)
-
-#define USB_MEM_READ_MAX 32
-#define USB_MEM_WRITE_MAX 1
-#define USB_FLASH_MAX 8
-
-#define V8_MEMORY_PAGE_SIZE 0x8000 // 32K
-#define V8_MEMORY_PAGE_MASK 0x7FFF
+#define V8_MEMORY_EXTENDED (1 << 15)
+#define USB_MEM_READ_MAX 32
+#define USB_MEM_WRITE_MAX 1
+#define USB_FLASH_MAX 8
+#define V8_MEMORY_PAGE_SIZE 0x8000 /* 32K */
+#define V8_MEMORY_PAGE_MASK 0x7FFF
#endif
diff --git a/linux/drivers/media/dvb/b2c2/flexcop.c b/linux/drivers/media/dvb/b2c2/flexcop.c
index 91068952b..2df1b0214 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop.c
+++ b/linux/drivers/media/dvb/b2c2/flexcop.c
@@ -1,22 +1,20 @@
/*
- * flexcop.c - driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * Copyright (C) 2004-5 Patrick Boettcher <patrick.boettcher@desy.de>
- *
- * based on the skystar2-driver
- * Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.c - main module part
+ * Copyright (C) 2004-9 Patrick Boettcher <patrick.boettcher@desy.de>
+ * based on skystar2-driver Copyright (C) 2003 Vadim Catana, skystar@moldova.cc
*
* Acknowledgements:
- * John Jurrius from BBTI, Inc. for extensive support with
- * code examples and data books
- *
- * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
+ * John Jurrius from BBTI, Inc. for extensive support
+ * with code examples and data books
+ * Bjarne Steinsbo, bjarne at steinsbo.com (some ideas for rewriting)
*
* Contributions to the skystar2-driver have been done by
- * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
- * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
- * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac filtering)
- *
+ * Vincenzo Di Massa, hawk.it at tiscalinet.it (several DiSEqC fixes)
+ * Roberto Ragusa, r.ragusa at libero.it (polishing, restyling the code)
+ * Uwe Bugla, uwe.bugla at gmx.de (doing tests, restyling code, writing docu)
+ * Niklas Peinecke, peinecke at gdv.uni-hannover.de (hardware pid/mac
+ * filtering)
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
@@ -46,7 +44,10 @@
int b2c2_flexcop_debug;
module_param_named(debug, b2c2_flexcop_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level (1=info,2=tuner,4=i2c,8=ts,16=sram,32=reg (|-able))." DEBSTATUS);
+MODULE_PARM_DESC(debug,
+ "set debug level (1=info,2=tuner,4=i2c,8=ts,"
+ "16=sram,32=reg (|-able))."
+ DEBSTATUS);
#undef DEBSTATUS
DVB_DEFINE_MOD_OPT_ADAPTER_NR(adapter_nr);
@@ -57,37 +58,36 @@ flexcop_ibi_value ibi_zero;
static int flexcop_dvb_start_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct flexcop_device *fc = dvbdmxfeed->demux->priv;
- return flexcop_pid_feed_control(fc,dvbdmxfeed,1);
+ return flexcop_pid_feed_control(fc, dvbdmxfeed, 1);
}
static int flexcop_dvb_stop_feed(struct dvb_demux_feed *dvbdmxfeed)
{
struct flexcop_device *fc = dvbdmxfeed->demux->priv;
- return flexcop_pid_feed_control(fc,dvbdmxfeed,0);
+ return flexcop_pid_feed_control(fc, dvbdmxfeed, 0);
}
static int flexcop_dvb_init(struct flexcop_device *fc)
{
int ret = dvb_register_adapter(&fc->dvb_adapter,
- "FlexCop Digital TV device", fc->owner,
- fc->dev, adapter_nr);
+ "FlexCop Digital TV device", fc->owner,
+ fc->dev, adapter_nr);
if (ret < 0) {
err("error registering DVB adapter");
return ret;
}
fc->dvb_adapter.priv = fc;
- fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING | DMX_MEMORY_BASED_FILTERING);
+ fc->demux.dmx.capabilities = (DMX_TS_FILTERING | DMX_SECTION_FILTERING
+ | DMX_MEMORY_BASED_FILTERING);
fc->demux.priv = fc;
-
fc->demux.filternum = fc->demux.feednum = FC_MAX_FEED;
-
fc->demux.start_feed = flexcop_dvb_start_feed;
fc->demux.stop_feed = flexcop_dvb_stop_feed;
fc->demux.write_to_decoder = NULL;
if ((ret = dvb_dmx_init(&fc->demux)) < 0) {
- err("dvb_dmx failed: error %d",ret);
+ err("dvb_dmx failed: error %d", ret);
goto err_dmx;
}
@@ -97,23 +97,23 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
fc->dmxdev.demux = &fc->demux.dmx;
fc->dmxdev.capabilities = 0;
if ((ret = dvb_dmxdev_init(&fc->dmxdev, &fc->dvb_adapter)) < 0) {
- err("dvb_dmxdev_init failed: error %d",ret);
+ err("dvb_dmxdev_init failed: error %d", ret);
goto err_dmx_dev;
}
if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
- err("adding hw_frontend to dmx failed: error %d",ret);
+ err("adding hw_frontend to dmx failed: error %d", ret);
goto err_dmx_add_hw_frontend;
}
fc->mem_frontend.source = DMX_MEMORY_FE;
if ((ret = fc->demux.dmx.add_frontend(&fc->demux.dmx, &fc->mem_frontend)) < 0) {
- err("adding mem_frontend to dmx failed: error %d",ret);
+ err("adding mem_frontend to dmx failed: error %d", ret);
goto err_dmx_add_mem_frontend;
}
if ((ret = fc->demux.dmx.connect_frontend(&fc->demux.dmx, &fc->hw_frontend)) < 0) {
- err("connect frontend failed: error %d",ret);
+ err("connect frontend failed: error %d", ret);
goto err_connect_frontend;
}
@@ -123,9 +123,9 @@ static int flexcop_dvb_init(struct flexcop_device *fc)
return 0;
err_connect_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->mem_frontend);
err_dmx_add_mem_frontend:
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx, &fc->hw_frontend);
err_dmx_add_hw_frontend:
dvb_dmxdev_release(&fc->dmxdev);
err_dmx_dev:
@@ -141,12 +141,13 @@ static void flexcop_dvb_exit(struct flexcop_device *fc)
dvb_net_release(&fc->dvbnet);
fc->demux.dmx.close(&fc->demux.dmx);
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->mem_frontend);
- fc->demux.dmx.remove_frontend(&fc->demux.dmx,&fc->hw_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+ &fc->mem_frontend);
+ fc->demux.dmx.remove_frontend(&fc->demux.dmx,
+ &fc->hw_frontend);
dvb_dmxdev_release(&fc->dmxdev);
dvb_dmx_release(&fc->demux);
dvb_unregister_adapter(&fc->dvb_adapter);
-
deb_info("deinitialized dvb stuff\n");
}
fc->init_state &= ~FC_STATE_DVB_INIT;
@@ -168,9 +169,9 @@ EXPORT_SYMBOL(flexcop_pass_dmx_packets);
static void flexcop_reset(struct flexcop_device *fc)
{
- flexcop_ibi_value v210,v204;
+ flexcop_ibi_value v210, v204;
-/* reset the flexcop itself */
+ /* reset the flexcop itself */
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.raw = 0;
@@ -183,13 +184,11 @@ static void flexcop_reset(struct flexcop_device *fc)
v210.sw_reset_210.reset_block_600 = 1;
v210.sw_reset_210.reset_block_700 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
-
v210.sw_reset_210.Special_controls = 0xc259;
-
fc->write_ibi_reg(fc,sw_reset_210,v210);
msleep(1);
-/* reset the periphical devices */
+ /* reset the periphical devices */
v204 = fc->read_ibi_reg(fc,misc_204);
v204.misc_204.Per_reset_sig = 0;
@@ -201,25 +200,24 @@ static void flexcop_reset(struct flexcop_device *fc)
void flexcop_reset_block_300(struct flexcop_device *fc)
{
- flexcop_ibi_value v208_save = fc->read_ibi_reg(fc,ctrl_208),
- v210 = fc->read_ibi_reg(fc,sw_reset_210);
-
- deb_rdump("208: %08x, 210: %08x\n",v208_save.raw,v210.raw);
+ flexcop_ibi_value v208_save = fc->read_ibi_reg(fc, ctrl_208),
+ v210 = fc->read_ibi_reg(fc, sw_reset_210);
+ deb_rdump("208: %08x, 210: %08x\n", v208_save.raw, v210.raw);
fc->write_ibi_reg(fc,ctrl_208,ibi_zero);
v210.sw_reset_210.reset_block_300 = 1;
v210.sw_reset_210.Block_reset_enable = 0xb2;
fc->write_ibi_reg(fc,sw_reset_210,v210);
- udelay(1000);
fc->write_ibi_reg(fc,ctrl_208,v208_save);
}
struct flexcop_device *flexcop_device_kmalloc(size_t bus_specific_len)
{
void *bus;
- struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device), GFP_KERNEL);
+ struct flexcop_device *fc = kzalloc(sizeof(struct flexcop_device),
+ GFP_KERNEL);
if (!fc) {
err("no memory");
return NULL;
@@ -254,7 +252,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
flexcop_determine_revision(fc);
flexcop_sram_init(fc);
flexcop_hw_filter_init(fc);
-
flexcop_smc_ctrl(fc, 0);
if ((ret = flexcop_dvb_init(fc)))
@@ -279,7 +276,6 @@ int flexcop_device_initialize(struct flexcop_device *fc)
goto error;
flexcop_device_name(fc,"initialization of","complete");
-
return 0;
error:
diff --git a/linux/drivers/media/dvb/b2c2/flexcop.h b/linux/drivers/media/dvb/b2c2/flexcop.h
index 0cebe1d92..897b10c85 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop.h
@@ -1,9 +1,7 @@
/*
- * This file is part of linux driver the digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
- * flexcop.h - private header file for all flexcop-chip-source files.
- *
- * see flexcop.c for copyright information.
+ * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
+ * flexcop.h - private header file for all flexcop-chip-source files
+ * see flexcop.c for copyright information
*/
#ifndef __FLEXCOP_H__
#define __FLEXCOP_H___
@@ -21,11 +19,11 @@ extern int b2c2_flexcop_debug;
#define dprintk(level,args...)
#endif
-#define deb_info(args...) dprintk(0x01,args)
-#define deb_tuner(args...) dprintk(0x02,args)
-#define deb_i2c(args...) dprintk(0x04,args)
-#define deb_ts(args...) dprintk(0x08,args)
-#define deb_sram(args...) dprintk(0x10,args)
-#define deb_rdump(args...) dprintk(0x20,args)
+#define deb_info(args...) dprintk(0x01, args)
+#define deb_tuner(args...) dprintk(0x02, args)
+#define deb_i2c(args...) dprintk(0x04, args)
+#define deb_ts(args...) dprintk(0x08, args)
+#define deb_sram(args...) dprintk(0x10, args)
+#define deb_rdump(args...) dprintk(0x20, args)
#endif
diff --git a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
index ed9a6756b..8f64bdbd7 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_be.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
-
/* This file is automatically generated, do not edit things here. */
#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
#define __FLEXCOP_IBI_VALUE_INCLUDED__
diff --git a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
index 49f2315b6..c75830d7d 100644
--- a/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
+++ b/linux/drivers/media/dvb/b2c2/flexcop_ibi_value_le.h
@@ -1,10 +1,7 @@
-/* This file is part of linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
- *
+/* Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
* register descriptions
- *
- * see flexcop.c for copyright information.
+ * see flexcop.c for copyright information
*/
-
/* This file is automatically generated, do not edit things here. */
#ifndef __FLEXCOP_IBI_VALUE_INCLUDED__
#define __FLEXCOP_IBI_VALUE_INCLUDED__
diff --git a/linux/drivers/media/dvb/bt8xx/dst_ca.c b/linux/drivers/media/dvb/bt8xx/dst_ca.c
index 68aef6786..bdc22a467 100644
--- a/linux/drivers/media/dvb/bt8xx/dst_ca.c
+++ b/linux/drivers/media/dvb/bt8xx/dst_ca.c
@@ -648,16 +648,19 @@ free_mem_and_exit:
return result;
}
-static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long ioctl_arg)
+static long dst_ca_ioctl(struct file *file, unsigned int cmd, unsigned long ioctl_arg)
{
- struct dvb_device* dvbdev = (struct dvb_device*) file->private_data;
- struct dst_state* state = (struct dst_state*) dvbdev->priv;
+ struct dvb_device *dvbdev;
+ struct dst_state *state;
struct ca_slot_info *p_ca_slot_info;
struct ca_caps *p_ca_caps;
struct ca_msg *p_ca_message;
void __user *arg = (void __user *)ioctl_arg;
int result = 0;
+ lock_kernel();
+ dvbdev = (struct dvb_device *)file->private_data;
+ state = (struct dst_state *)dvbdev->priv;
p_ca_message = kmalloc(sizeof (struct ca_msg), GFP_KERNEL);
p_ca_slot_info = kmalloc(sizeof (struct ca_slot_info), GFP_KERNEL);
p_ca_caps = kmalloc(sizeof (struct ca_caps), GFP_KERNEL);
@@ -743,6 +746,7 @@ static int dst_ca_ioctl(struct inode *inode, struct file *file, unsigned int cmd
kfree (p_ca_slot_info);
kfree (p_ca_caps);
+ unlock_kernel();
return result;
}
@@ -780,7 +784,7 @@ static ssize_t dst_ca_write(struct file *file, const char __user *buffer, size_t
static const struct file_operations dst_ca_fops = {
.owner = THIS_MODULE,
- .ioctl = dst_ca_ioctl,
+ .unlocked_ioctl = dst_ca_ioctl,
.open = dst_ca_open,
.release = dst_ca_release,
.read = dst_ca_read,
diff --git a/linux/drivers/media/dvb/dvb-usb/Kconfig b/linux/drivers/media/dvb/dvb-usb/Kconfig
index 53a4a4732..60955a70d 100644
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig
@@ -309,6 +309,6 @@ config DVB_USB_CE6230
tristate "Intel CE6230 DVB-T USB2.0 support"
depends on DVB_USB && EXPERIMENTAL
select DVB_ZL10353
- select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+ select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
help
Say Y here to support the Intel CE6230 DVB-T USB2.0 receiver
diff --git a/linux/drivers/media/dvb/dvb-usb/ce6230.c b/linux/drivers/media/dvb/dvb-usb/ce6230.c
index 2a959c4bd..3ae3bde45 100644
--- a/linux/drivers/media/dvb/dvb-usb/ce6230.c
+++ b/linux/drivers/media/dvb/dvb-usb/ce6230.c
@@ -104,7 +104,7 @@ static int ce6230_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[],
struct dvb_usb_device *d = i2c_get_adapdata(adap);
int i = 0;
struct req_t req;
- int ret;
+ int ret = 0;
memset(&req, 0, sizeof(&req));
if (num > 2)
@@ -253,6 +253,7 @@ static int ce6230_probe(struct usb_interface *intf,
static struct usb_device_id ce6230_table[] = {
{ USB_DEVICE(USB_VID_INTEL, USB_PID_INTEL_CE9500) },
+ { USB_DEVICE(USB_VID_AVERMEDIA, USB_PID_AVERMEDIA_A310) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, ce6230_table);
@@ -287,13 +288,18 @@ static struct dvb_usb_device_properties ce6230_properties = {
.i2c_algo = &ce6230_i2c_algo,
- .num_device_descs = 1,
+ .num_device_descs = 2,
.devices = {
{
.name = "Intel CE9500 reference design",
.cold_ids = {NULL},
.warm_ids = {&ce6230_table[0], NULL},
},
+ {
+ .name = "AVerMedia A310 USB 2.0 DVB-T tuner",
+ .cold_ids = {NULL},
+ .warm_ids = {&ce6230_table[1], NULL},
+ },
}
};
diff --git a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
index d8901f7a8..31fe6e10a 100644
--- a/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
+++ b/linux/drivers/media/dvb/dvb-usb/dib0700_devices.c
@@ -1495,6 +1495,8 @@ struct usb_device_id dib0700_usb_id_table[] = {
/* 45 */{ USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_PD378S) },
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC) },
{ USB_DEVICE(USB_VID_HAUPPAUGE, USB_PID_HAUPPAUGE_TIGER_ATSC_B210) },
+ { USB_DEVICE(USB_VID_YUAN, USB_PID_YUAN_MC770) },
+ { USB_DEVICE(USB_VID_ELGATO, USB_PID_ELGATO_EYETV_DTT) },
{ 0 } /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, dib0700_usb_id_table);
@@ -1694,7 +1696,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 10,
+ .num_device_descs = 11,
.devices = {
{ "DiBcom STK7070P reference design",
{ &dib0700_usb_id_table[15], NULL },
@@ -1732,6 +1734,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[33], NULL },
{ NULL },
},
+ { "Elgato EyeTV DTT",
+ { &dib0700_usb_id_table[49], NULL },
+ { NULL },
+ },
{ "Yuan PD378S",
{ &dib0700_usb_id_table[45], NULL },
{ NULL },
@@ -1810,7 +1816,7 @@ struct dvb_usb_device_properties dib0700_devices[] = {
},
},
- .num_device_descs = 5,
+ .num_device_descs = 7,
.devices = {
{ "Terratec Cinergy HT USB XE",
{ &dib0700_usb_id_table[27], NULL },
@@ -1836,6 +1842,10 @@ struct dvb_usb_device_properties dib0700_devices[] = {
{ &dib0700_usb_id_table[39], NULL },
{ NULL },
},
+ { "YUAN High-Tech MC770",
+ { &dib0700_usb_id_table[48], NULL },
+ { NULL },
+ },
},
.rc_interval = DEFAULT_RC_INTERVAL,
.rc_key_map = dib0700_rc_keys,
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index 7031bafe6..f506c7411 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -27,6 +27,7 @@
#define USB_VID_DIBCOM 0x10b8
#define USB_VID_DPOSH 0x1498
#define USB_VID_DVICO 0x0fe9
+#define USB_VID_ELGATO 0x0fd9
#define USB_VID_EMPIA 0xeb1a
#define USB_VID_GENPIX 0x09c0
#define USB_VID_GRANDTEC 0x5032
@@ -49,6 +50,7 @@
#define USB_VID_TERRATEC 0x0ccd
#define USB_VID_TELESTAR 0x10b9
#define USB_VID_VISIONPLUS 0x13d3
+#define USB_VID_SONY 0x1415
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_UNIWILL 0x1584
@@ -56,7 +58,6 @@
#define USB_VID_GIGABYTE 0x1044
#define USB_VID_YUAN 0x1164
#define USB_VID_XTENSIONS 0x1ae7
-#define USB_VID_SONY 0x1415
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -168,6 +169,7 @@
#define USB_PID_AVERMEDIA_VOLAR_X 0xa815
#define USB_PID_AVERMEDIA_VOLAR_X_2 0x8150
#define USB_PID_AVERMEDIA_A309 0xa309
+#define USB_PID_AVERMEDIA_A310 0xa310
#define USB_PID_AVERMEDIA_A850 0x850a
#define USB_PID_TECHNOTREND_CONNECT_S2400 0x3006
#define USB_PID_TERRATEC_CINERGY_DT_XS_DIVERSITY 0x005a
@@ -242,10 +244,12 @@
#define USB_PID_YUAN_EC372S 0x1edc
#define USB_PID_YUAN_STK7700PH 0x1f08
#define USB_PID_YUAN_PD378S 0x2edc
+#define USB_PID_YUAN_MC770 0x0871
#define USB_PID_DW2102 0x2102
#define USB_PID_XTENSIONS_XD_380 0x0381
#define USB_PID_TELESTAR_STARSTICK_2 0x8000
#define USB_PID_MSI_DIGI_VOX_MINI_III 0x8807
#define USB_PID_SONY_PLAYTV 0x0003
+#define USB_PID_ELGATO_EYETV_DTT 0x0021
#endif
diff --git a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
index 081550761..fd64daa06 100644
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -224,7 +224,7 @@ struct dvb_usb_device_properties {
int generic_bulk_ctrl_endpoint;
int num_device_descs;
- struct dvb_usb_device_description devices[10];
+ struct dvb_usb_device_description devices[11];
};
/**
diff --git a/linux/drivers/media/dvb/frontends/au8522_decoder.c b/linux/drivers/media/dvb/frontends/au8522_decoder.c
index 70af9cda7..326f94d1e 100644
--- a/linux/drivers/media/dvb/frontends/au8522_decoder.c
+++ b/linux/drivers/media/dvb/frontends/au8522_decoder.c
@@ -837,7 +837,6 @@ MODULE_DEVICE_TABLE(i2c, au8522_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "au8522",
- .driverid = I2C_DRIVERID_AU8522,
.probe = au8522_probe,
.remove = au8522_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/dvb/frontends/itd1000_priv.h b/linux/drivers/media/dvb/frontends/itd1000_priv.h
index 8cdc54e57..08ca85122 100644
--- a/linux/drivers/media/dvb/frontends/itd1000_priv.h
+++ b/linux/drivers/media/dvb/frontends/itd1000_priv.h
@@ -31,7 +31,7 @@ struct itd1000_state {
/* ugly workaround for flexcop's incapable i2c-controller
* FIXME, if possible
*/
- u8 shadow[255];
+ u8 shadow[256];
};
enum itd1000_register {
diff --git a/linux/drivers/media/dvb/frontends/stb6100_cfg.h b/linux/drivers/media/dvb/frontends/stb6100_cfg.h
index d3133405d..6314d18c7 100644
--- a/linux/drivers/media/dvb/frontends/stb6100_cfg.h
+++ b/linux/drivers/media/dvb/frontends/stb6100_cfg.h
@@ -36,7 +36,6 @@ static int stb6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
return err;
}
*frequency = t_state.frequency;
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
}
return 0;
}
@@ -59,7 +58,6 @@ static int stb6100_set_frequency(struct dvb_frontend *fe, u32 frequency)
return err;
}
}
- printk("%s: Frequency=%d\n", __func__, t_state.frequency);
return 0;
}
@@ -81,7 +79,6 @@ static int stb6100_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
}
*bandwidth = t_state.bandwidth;
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
@@ -103,6 +100,5 @@ static int stb6100_set_bandwidth(struct dvb_frontend *fe, u32 bandwidth)
return err;
}
}
- printk("%s: Bandwidth=%d\n", __func__, t_state.bandwidth);
return 0;
}
diff --git a/linux/drivers/media/dvb/pluto2/pluto2.c b/linux/drivers/media/dvb/pluto2/pluto2.c
index 8522757a5..b27073216 100644
--- a/linux/drivers/media/dvb/pluto2/pluto2.c
+++ b/linux/drivers/media/dvb/pluto2/pluto2.c
@@ -116,6 +116,7 @@ struct pluto {
/* irq */
unsigned int overflow;
+ unsigned int dead;
/* dma */
dma_addr_t dma_addr;
@@ -344,8 +345,10 @@ static irqreturn_t pluto_irq(int irq, void *dev_id)
return IRQ_NONE;
if (tscr == 0xffffffff) {
- // FIXME: maybe recover somehow
- dev_err(&pluto->pdev->dev, "card hung up :(\n");
+ if (pluto->dead == 0)
+ dev_err(&pluto->pdev->dev, "card has hung or been ejected.\n");
+ /* It's dead Jim */
+ pluto->dead = 1;
return IRQ_HANDLED;
}
diff --git a/linux/drivers/media/dvb/siano/smssdio.c b/linux/drivers/media/dvb/siano/smssdio.c
new file mode 100644
index 000000000..31ba8c5af
--- /dev/null
+++ b/linux/drivers/media/dvb/siano/smssdio.c
@@ -0,0 +1,356 @@
+/*
+ * smssdio.c - Siano 1xxx SDIO interface driver
+ *
+ * Copyright 2008 Pierre Ossman
+ *
+ * Based on code by Siano Mobile Silicon, Inc.,
+ * Copyright (C) 2006-2008, Uri Shkolnik
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or (at
+ * your option) any later version.
+ *
+ *
+ * This hardware is a bit odd in that all transfers should be done
+ * to/from the SMSSDIO_DATA register, yet the "increase address" bit
+ * always needs to be set.
+ *
+ * Also, buffers from the card are always aligned to 128 byte
+ * boundaries.
+ */
+
+/*
+ * General cleanup notes:
+ *
+ * - only typedefs should be name *_t
+ *
+ * - use ERR_PTR and friends for smscore_register_device()
+ *
+ * - smscore_getbuffer should zero fields
+ *
+ * Fix stop command
+ */
+
+#include <linux/moduleparam.h>
+#include <linux/firmware.h>
+#include <linux/delay.h>
+#include <linux/mmc/card.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+
+#include "smscoreapi.h"
+#include "sms-cards.h"
+
+/* Registers */
+
+#define SMSSDIO_DATA 0x00
+#define SMSSDIO_INT 0x04
+
+static const struct sdio_device_id smssdio_ids[] = {
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_STELLAR),
+ .driver_data = SMS1XXX_BOARD_SIANO_STELLAR},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_A0),
+ .driver_data = SMS1XXX_BOARD_SIANO_NOVA_A},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_NOVA_B0),
+ .driver_data = SMS1XXX_BOARD_SIANO_NOVA_B},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VEGA_A0),
+ .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+ {SDIO_DEVICE(SDIO_VENDOR_ID_SIANO, SDIO_DEVICE_ID_SIANO_VENICE),
+ .driver_data = SMS1XXX_BOARD_SIANO_VEGA},
+ { /* end: all zeroes */ },
+};
+
+MODULE_DEVICE_TABLE(sdio, smssdio_ids);
+
+struct smssdio_device {
+ struct sdio_func *func;
+
+ struct smscore_device_t *coredev;
+
+ struct smscore_buffer_t *split_cb;
+};
+
+/*******************************************************************/
+/* Siano core callbacks */
+/*******************************************************************/
+
+static int smssdio_sendrequest(void *context, void *buffer, size_t size)
+{
+ int ret;
+ struct smssdio_device *smsdev;
+
+ smsdev = context;
+
+ sdio_claim_host(smsdev->func);
+
+ while (size >= smsdev->func->cur_blksize) {
+ ret = sdio_write_blocks(smsdev->func, SMSSDIO_DATA, buffer, 1);
+ if (ret)
+ goto out;
+
+ buffer += smsdev->func->cur_blksize;
+ size -= smsdev->func->cur_blksize;
+ }
+
+ if (size) {
+ ret = sdio_write_bytes(smsdev->func, SMSSDIO_DATA,
+ buffer, size);
+ if (ret)
+ goto out;
+ }
+
+out:
+ sdio_release_host(smsdev->func);
+
+ return ret;
+}
+
+/*******************************************************************/
+/* SDIO callbacks */
+/*******************************************************************/
+
+static void smssdio_interrupt(struct sdio_func *func)
+{
+ int ret, isr;
+
+ struct smssdio_device *smsdev;
+ struct smscore_buffer_t *cb;
+ struct SmsMsgHdr_ST *hdr;
+ size_t size;
+
+ smsdev = sdio_get_drvdata(func);
+
+ /*
+ * The interrupt register has no defined meaning. It is just
+ * a way of turning of the level triggered interrupt.
+ */
+ isr = sdio_readb(func, SMSSDIO_INT, &ret);
+ if (ret) {
+ dev_err(&smsdev->func->dev,
+ "Unable to read interrupt register!\n");
+ return;
+ }
+
+ if (smsdev->split_cb == NULL) {
+ cb = smscore_getbuffer(smsdev->coredev);
+ if (!cb) {
+ dev_err(&smsdev->func->dev,
+ "Unable to allocate data buffer!\n");
+ return;
+ }
+
+ ret = sdio_read_blocks(smsdev->func, cb->p, SMSSDIO_DATA, 1);
+ if (ret) {
+ dev_err(&smsdev->func->dev,
+ "Error %d reading initial block!\n", ret);
+ return;
+ }
+
+ hdr = cb->p;
+
+ if (hdr->msgFlags & MSG_HDR_FLAG_SPLIT_MSG) {
+ smsdev->split_cb = cb;
+ return;
+ }
+
+ size = hdr->msgLength - smsdev->func->cur_blksize;
+ } else {
+ cb = smsdev->split_cb;
+ hdr = cb->p;
+
+ size = hdr->msgLength - sizeof(struct SmsMsgHdr_ST);
+
+ smsdev->split_cb = NULL;
+ }
+
+ if (hdr->msgLength > smsdev->func->cur_blksize) {
+ void *buffer;
+
+ size = ALIGN(size, 128);
+ buffer = cb->p + hdr->msgLength;
+
+ BUG_ON(smsdev->func->cur_blksize != 128);
+
+ /*
+ * First attempt to transfer all of it in one go...
+ */
+ ret = sdio_read_blocks(smsdev->func, buffer,
+ SMSSDIO_DATA, size / 128);
+ if (ret && ret != -EINVAL) {
+ smscore_putbuffer(smsdev->coredev, cb);
+ dev_err(&smsdev->func->dev,
+ "Error %d reading data from card!\n", ret);
+ return;
+ }
+
+ /*
+ * ..then fall back to one block at a time if that is
+ * not possible...
+ *
+ * (we have to do this manually because of the
+ * problem with the "increase address" bit)
+ */
+ if (ret == -EINVAL) {
+ while (size) {
+ ret = sdio_read_blocks(smsdev->func,
+ buffer, SMSSDIO_DATA, 1);
+ if (ret) {
+ smscore_putbuffer(smsdev->coredev, cb);
+ dev_err(&smsdev->func->dev,
+ "Error %d reading "
+ "data from card!\n", ret);
+ return;
+ }
+
+ buffer += smsdev->func->cur_blksize;
+ if (size > smsdev->func->cur_blksize)
+ size -= smsdev->func->cur_blksize;
+ else
+ size = 0;
+ }
+ }
+ }
+
+ cb->size = hdr->msgLength;
+ cb->offset = 0;
+
+ smscore_onresponse(smsdev->coredev, cb);
+}
+
+static int smssdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ int ret;
+
+ int board_id;
+ struct smssdio_device *smsdev;
+ struct smsdevice_params_t params;
+
+ board_id = id->driver_data;
+
+ smsdev = kzalloc(sizeof(struct smssdio_device), GFP_KERNEL);
+ if (!smsdev)
+ return -ENOMEM;
+
+ smsdev->func = func;
+
+ memset(&params, 0, sizeof(struct smsdevice_params_t));
+
+ params.device = &func->dev;
+ params.buffer_size = 0x5000; /* ?? */
+ params.num_buffers = 22; /* ?? */
+ params.context = smsdev;
+
+ snprintf(params.devpath, sizeof(params.devpath),
+ "sdio\\%s", sdio_func_id(func));
+
+ params.sendrequest_handler = smssdio_sendrequest;
+
+ params.device_type = sms_get_board(board_id)->type;
+
+ if (params.device_type != SMS_STELLAR)
+ params.flags |= SMS_DEVICE_FAMILY2;
+ else {
+ /*
+ * FIXME: Stellar needs special handling...
+ */
+ ret = -ENODEV;
+ goto free;
+ }
+
+ ret = smscore_register_device(&params, &smsdev->coredev);
+ if (ret < 0)
+ goto free;
+
+ smscore_set_board_id(smsdev->coredev, board_id);
+
+ sdio_claim_host(func);
+
+ ret = sdio_enable_func(func);
+ if (ret)
+ goto release;
+
+ ret = sdio_set_block_size(func, 128);
+ if (ret)
+ goto disable;
+
+ ret = sdio_claim_irq(func, smssdio_interrupt);
+ if (ret)
+ goto disable;
+
+ sdio_set_drvdata(func, smsdev);
+
+ sdio_release_host(func);
+
+ ret = smscore_start_device(smsdev->coredev);
+ if (ret < 0)
+ goto reclaim;
+
+ return 0;
+
+reclaim:
+ sdio_claim_host(func);
+ sdio_release_irq(func);
+disable:
+ sdio_disable_func(func);
+release:
+ sdio_release_host(func);
+ smscore_unregister_device(smsdev->coredev);
+free:
+ kfree(smsdev);
+
+ return ret;
+}
+
+static void smssdio_remove(struct sdio_func *func)
+{
+ struct smssdio_device *smsdev;
+
+ smsdev = sdio_get_drvdata(func);
+
+ /* FIXME: racy! */
+ if (smsdev->split_cb)
+ smscore_putbuffer(smsdev->coredev, smsdev->split_cb);
+
+ smscore_unregister_device(smsdev->coredev);
+
+ sdio_claim_host(func);
+ sdio_release_irq(func);
+ sdio_disable_func(func);
+ sdio_release_host(func);
+
+ kfree(smsdev);
+}
+
+static struct sdio_driver smssdio_driver = {
+ .name = "smssdio",
+ .id_table = smssdio_ids,
+ .probe = smssdio_probe,
+ .remove = smssdio_remove,
+};
+
+/*******************************************************************/
+/* Module functions */
+/*******************************************************************/
+
+int smssdio_register(void)
+{
+ int ret = 0;
+
+ printk(KERN_INFO "smssdio: Siano SMS1xxx SDIO driver\n");
+ printk(KERN_INFO "smssdio: Copyright Pierre Ossman\n");
+
+ ret = sdio_register_driver(&smssdio_driver);
+
+ return ret;
+}
+
+void smssdio_unregister(void)
+{
+ sdio_unregister_driver(&smssdio_driver);
+}
+
+MODULE_DESCRIPTION("Siano SMS1xxx SDIO driver");
+MODULE_AUTHOR("Pierre Ossman");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/ttpci/budget-ci.c b/linux/drivers/media/dvb/ttpci/budget-ci.c
index 99fcb55d5..1b564eb79 100644
--- a/linux/drivers/media/dvb/ttpci/budget-ci.c
+++ b/linux/drivers/media/dvb/ttpci/budget-ci.c
@@ -1084,6 +1084,10 @@ static struct tda10023_config tda10023_config = {
.deltaf = 0xa511,
};
+static struct tda827x_config tda827x_config = {
+ .config = 0,
+};
+
/* TT S2-3200 DVB-S (STB0899) Inittab */
static const struct stb0899_s1_reg tt3200_stb0899_s1_init_1[] = {
@@ -1422,7 +1426,7 @@ static void frontend_init(struct budget_ci *budget_ci)
case 0x101a: /* TT Budget-C-1501 (philips tda10023/philips tda8274A) */
budget_ci->budget.dvb_frontend = dvb_attach(tda10023_attach, &tda10023_config, &budget_ci->budget.i2c_adap, 0x48);
if (budget_ci->budget.dvb_frontend) {
- if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, NULL) == NULL) {
+ if (dvb_attach(tda827x_attach, budget_ci->budget.dvb_frontend, 0x61, &budget_ci->budget.i2c_adap, &tda827x_config) == NULL) {
printk(KERN_ERR "%s: No tda827x found!\n", __func__);
dvb_frontend_detach(budget_ci->budget.dvb_frontend);
budget_ci->budget.dvb_frontend = NULL;
diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 114bf04a6..58abbe374 100644
--- a/linux/drivers/media/video/Kconfig
+++ b/linux/drivers/media/video/Kconfig
@@ -249,6 +249,20 @@ config VIDEO_VP27SMPX
To compile this driver as a module, choose M here: the
module will be called vp27smpx.
+comment "RDS decoders"
+
+config VIDEO_SAA6588
+ tristate "SAA6588 Radio Chip RDS decoder support"
+ depends on VIDEO_V4L2 && I2C
+
+ help
+ Support for this Radio Data System (RDS) decoder. This allows
+ seeing radio station identification transmitted using this
+ standard.
+
+ To compile this driver as a module, choose M here: the
+ module will be called saa6588.
+
comment "Video decoders"
config VIDEO_BT819
@@ -467,18 +481,6 @@ config VIDEO_VIVI
source "drivers/media/video/bt8xx/Kconfig"
-config VIDEO_SAA6588
- tristate "SAA6588 Radio Chip RDS decoder support on BT848 cards"
- depends on I2C && VIDEO_BT848
-
- help
- Support for Radio Data System (RDS) decoder. This allows seeing
- radio station identification transmitted using this standard.
- Currently, it works only with bt8x8 chips.
-
- To compile this driver as a module, choose M here: the
- module will be called saa6588.
-
config VIDEO_PMS
tristate "Mediavision Pro Movie Studio Video For Linux"
depends on ISA && VIDEO_V4L1
diff --git a/linux/drivers/media/video/bt8xx/Kconfig b/linux/drivers/media/video/bt8xx/Kconfig
index ce71e8e7b..3077c4501 100644
--- a/linux/drivers/media/video/bt8xx/Kconfig
+++ b/linux/drivers/media/video/bt8xx/Kconfig
@@ -10,7 +10,7 @@ config VIDEO_BT848
select VIDEO_MSP3400 if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TVAUDIO if VIDEO_HELPER_CHIPS_AUTO
select VIDEO_TDA7432 if VIDEO_HELPER_CHIPS_AUTO
- select VIDEO_TDA9875 if VIDEO_HELPER_CHIPS_AUTO
+ select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
---help---
Support for BT848 based frame grabber/overlay boards. This includes
the Miro, Hauppauge and STB boards. Please read the material in
diff --git a/linux/drivers/media/video/bt8xx/bttv-cards.c b/linux/drivers/media/video/bt8xx/bttv-cards.c
index d2136141e..1c13dbfec 100644
--- a/linux/drivers/media/video/bt8xx/bttv-cards.c
+++ b/linux/drivers/media/video/bt8xx/bttv-cards.c
@@ -97,12 +97,10 @@ static unsigned int pll[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int svhs[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
static unsigned int remote[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET };
+static unsigned int audiodev[BTTV_MAX];
+static unsigned int saa6588[BTTV_MAX];
static struct bttv *master[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = NULL };
-#ifdef MODULE
-static unsigned int autoload = 1;
-#else
-static unsigned int autoload;
-#endif
+static unsigned int autoload = UNSET;
static unsigned int gpiomask = UNSET;
static unsigned int audioall = UNSET;
static unsigned int audiomux[5] = { [ 0 ... 4 ] = UNSET };
@@ -121,6 +119,7 @@ module_param_array(pll, int, NULL, 0444);
module_param_array(tuner, int, NULL, 0444);
module_param_array(svhs, int, NULL, 0444);
module_param_array(remote, int, NULL, 0444);
+module_param_array(audiodev, int, NULL, 0444);
module_param_array(audiomux, int, NULL, 0444);
MODULE_PARM_DESC(triton1,"set ETBF pci config bit "
@@ -131,7 +130,14 @@ MODULE_PARM_DESC(latency,"pci latency timer");
MODULE_PARM_DESC(card,"specify TV/grabber card model, see CARDLIST file for a list");
MODULE_PARM_DESC(pll,"specify installed crystal (0=none, 28=28 MHz, 35=35 MHz)");
MODULE_PARM_DESC(tuner,"specify installed tuner type");
-MODULE_PARM_DESC(autoload,"automatically load i2c modules like tuner.o, default is 1 (yes)");
+MODULE_PARM_DESC(autoload, "obsolete option, please do not use anymore");
+MODULE_PARM_DESC(audiodev, "specify audio device:\n"
+ "\t\t-1 = no audio\n"
+ "\t\t 0 = autodetect (default)\n"
+ "\t\t 1 = msp3400\n"
+ "\t\t 2 = tda7432\n"
+ "\t\t 3 = tvaudio");
+MODULE_PARM_DESC(saa6588, "if 1, then load the saa6588 RDS module, default (0) is to use the card definition.");
MODULE_PARM_DESC(no_overlay,"allow override overlay default (0 disables, 1 enables)"
" [some VIA/SIS chipsets are known to have problem with overlay]");
@@ -3356,6 +3362,17 @@ void __devinit bttv_init_card1(struct bttv *btv)
/* initialization part two -- after registering i2c bus */
void __devinit bttv_init_card2(struct bttv *btv)
{
+ static const unsigned short tvaudio_addrs[] = {
+ I2C_ADDR_TDA8425 >> 1,
+ I2C_ADDR_TEA6300 >> 1,
+ I2C_ADDR_TEA6420 >> 1,
+ I2C_ADDR_TDA9840 >> 1,
+ I2C_ADDR_TDA985x_L >> 1,
+ I2C_ADDR_TDA985x_H >> 1,
+ I2C_ADDR_TDA9874 >> 1,
+ I2C_ADDR_PIC16C54 >> 1,
+ I2C_CLIENT_END
+ };
int addr=ADDR_UNSET;
btv->tuner_type = UNSET;
@@ -3519,6 +3536,12 @@ void __devinit bttv_init_card2(struct bttv *btv)
printk(KERN_INFO "bttv%d: tuner type=%d\n", btv->c.nr,
btv->tuner_type);
+ if (autoload != UNSET) {
+ printk(KERN_WARNING "bttv%d: the autoload option is obsolete.\n", btv->c.nr);
+ printk(KERN_WARNING "bttv%d: use option msp3400, tda7432 or tvaudio to\n", btv->c.nr);
+ printk(KERN_WARNING "bttv%d: override which audio module should be used.\n", btv->c.nr);
+ }
+
if (UNSET == btv->tuner_type)
btv->tuner_type = TUNER_ABSENT;
@@ -3526,8 +3549,13 @@ void __devinit bttv_init_card2(struct bttv *btv)
struct tuner_setup tun_setup;
/* Load tuner module before issuing tuner config call! */
- if (autoload)
- request_module("tuner");
+ if (bttv_tvcards[btv->c.type].has_radio)
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV_WITH_DEMOD));
tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV;
tun_setup.type = btv->tuner_type;
@@ -3536,7 +3564,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (bttv_tvcards[btv->c.type].has_radio)
tun_setup.mode_mask |= T_RADIO;
- bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
+ bttv_call_all(btv, tuner, s_type_addr, &tun_setup);
}
if (btv->tda9887_conf) {
@@ -3545,7 +3573,7 @@ void __devinit bttv_init_card2(struct bttv *btv)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &btv->tda9887_conf;
- bttv_call_i2c_clients(btv, TUNER_SET_CONFIG, &tda9887_cfg);
+ bttv_call_all(btv, tuner, s_config, &tda9887_cfg);
}
btv->dig = bttv_tvcards[btv->c.type].has_dig_in ?
@@ -3568,31 +3596,127 @@ void __devinit bttv_init_card2(struct bttv *btv)
if (bttv_tvcards[btv->c.type].audio_mode_gpio)
btv->audio_mode_gpio=bttv_tvcards[btv->c.type].audio_mode_gpio;
- if (!autoload)
- return;
-
if (btv->tuner_type == TUNER_ABSENT)
return; /* no tuner or related drivers to load */
+ if (btv->has_saa6588 || saa6588[btv->c.nr]) {
+ /* Probe for RDS receiver chip */
+ static const unsigned short addrs[] = {
+ 0x20 >> 1,
+ 0x22 >> 1,
+ I2C_CLIENT_END
+ };
+ struct v4l2_subdev *sd;
+
+ sd = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "saa6588", "saa6588", addrs);
+ btv->has_saa6588 = (sd != NULL);
+ }
+
/* try to detect audio/fader chips */
- if (!bttv_tvcards[btv->c.type].no_msp34xx &&
- bttv_I2CRead(btv, I2C_ADDR_MSP3400, "MSP34xx") >=0)
- request_module("msp3400");
- if (bttv_tvcards[btv->c.type].msp34xx_alt &&
- bttv_I2CRead(btv, I2C_ADDR_MSP3400_ALT, "MSP34xx (alternate address)") >=0)
- request_module("msp3400");
+ /* First check if the user specified the audio chip via a module
+ option. */
+
+ switch (audiodev[btv->c.nr]) {
+ case -1:
+ return; /* do not load any audio module */
- if (!bttv_tvcards[btv->c.type].no_tda9875 &&
- bttv_I2CRead(btv, I2C_ADDR_TDA9875, "TDA9875") >=0)
- request_module("tda9875");
+ case 0: /* autodetect */
+ break;
- if (!bttv_tvcards[btv->c.type].no_tda7432 &&
- bttv_I2CRead(btv, I2C_ADDR_TDA7432, "TDA7432") >=0)
- request_module("tda7432");
+ case 1: {
+ /* The user specified that we should probe for msp3400 */
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400 >> 1,
+ I2C_ADDR_MSP3400_ALT >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ if (btv->sd_msp34xx)
+ return;
+ goto no_audio;
+ }
+
+ case 2: {
+ /* The user specified that we should probe for tda7432 */
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA7432 >> 1,
+ I2C_CLIENT_END
+ };
+
+ if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tda7432", "tda7432", addrs))
+ return;
+ goto no_audio;
+ }
+
+ case 3: {
+ /* The user specified that we should probe for tvaudio */
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tvaudio", "tvaudio", tvaudio_addrs);
+ if (btv->sd_tvaudio)
+ return;
+ goto no_audio;
+ }
+
+ default:
+ printk(KERN_WARNING "bttv%d: unknown audiodev value!\n",
+ btv->c.nr);
+ return;
+ }
+
+ /* There were no overrides, so now we try to discover this through the
+ card definition */
+
+ /* probe for msp3400 first: this driver can detect whether or not
+ it really is a msp3400, so it will return NULL when the device
+ found is really something else (e.g. a tea6300). */
+ if (!bttv_tvcards[btv->c.type].no_msp34xx) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400 >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ } else if (bttv_tvcards[btv->c.type].msp34xx_alt) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_MSP3400_ALT >> 1,
+ I2C_CLIENT_END
+ };
+
+ btv->sd_msp34xx = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "msp3400", "msp3400", addrs);
+ }
+
+ /* If we found a msp34xx, then we're done. */
+ if (btv->sd_msp34xx)
+ return;
+
+ /* it might also be a tda7432. */
+ if (!bttv_tvcards[btv->c.type].no_tda7432) {
+ static const unsigned short addrs[] = {
+ I2C_ADDR_TDA7432 >> 1,
+ I2C_CLIENT_END
+ };
+
+ if (v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tda7432", "tda7432", addrs))
+ return;
+ }
+
+ /* Now see if we can find one of the tvaudio devices. */
+ btv->sd_tvaudio = v4l2_i2c_new_probed_subdev(&btv->c.i2c_adap,
+ "tvaudio", "tvaudio", tvaudio_addrs);
+ if (btv->sd_tvaudio)
+ return;
- if (bttv_tvcards[btv->c.type].needs_tvaudio)
- request_module("tvaudio");
+no_audio:
+ printk(KERN_WARNING "bttv%d: audio absent, no audio device found!\n",
+ btv->c.nr);
}
@@ -3664,6 +3788,7 @@ static int terratec_active_radio_upgrade(struct bttv *btv)
printk("bttv%d: Terratec Active Radio Upgrade found.\n",
btv->c.nr);
btv->has_radio = 1;
+ btv->has_saa6588 = 1;
btv->has_matchbox = 1;
} else {
btv->has_radio = 0;
diff --git a/linux/drivers/media/video/bt8xx/bttv-driver.c b/linux/drivers/media/video/bt8xx/bttv-driver.c
index acb7b5e3d..f40eb10fd 100644
--- a/linux/drivers/media/video/bt8xx/bttv-driver.c
+++ b/linux/drivers/media/video/bt8xx/bttv-driver.c
@@ -1181,7 +1181,6 @@ audio_mux(struct bttv *btv, int input, int mute)
{
int gpio_val, signal;
struct v4l2_control ctrl;
- struct i2c_client *c;
gpio_inout(bttv_tvcards[btv->c.type].gpiomask,
bttv_tvcards[btv->c.type].gpiomask);
@@ -1220,9 +1219,8 @@ audio_mux(struct bttv *btv, int input, int mute)
ctrl.id = V4L2_CID_AUDIO_MUTE;
ctrl.value = btv->mute;
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, &ctrl);
- c = btv->i2c_msp34xx_client;
- if (c) {
+ bttv_call_all(btv, core, s_ctrl, &ctrl);
+ if (btv->sd_msp34xx) {
struct v4l2_routing route;
/* Note: the inputs tuner/radio/extern/intern are translated
@@ -1261,15 +1259,14 @@ audio_mux(struct bttv *btv, int input, int mute)
break;
}
route.output = MSP_OUTPUT_DEFAULT;
- c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(btv->sd_msp34xx, audio, s_routing, &route);
}
- c = btv->i2c_tvaudio_client;
- if (c) {
+ if (btv->sd_tvaudio) {
struct v4l2_routing route;
route.input = input;
route.output = 0;
- c->driver->command(c, VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(btv->sd_tvaudio, audio, s_routing, &route);
}
return 0;
}
@@ -1360,7 +1357,7 @@ set_tvnorm(struct bttv *btv, unsigned int norm)
#endif
}
id = tvnorm->v4l2_id;
- bttv_call_i2c_clients(btv, VIDIOC_S_STD, &id);
+ bttv_call_all(btv, tuner, s_std, id);
return 0;
}
@@ -1504,7 +1501,7 @@ static int bttv_g_ctrl(struct file *file, void *priv,
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- bttv_call_i2c_clients(btv, VIDIOC_G_CTRL, c);
+ bttv_call_all(btv, core, g_ctrl, c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -1578,12 +1575,12 @@ static int bttv_s_ctrl(struct file *file, void *f,
if (btv->volume_gpio)
btv->volume_gpio(btv, c->value);
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+ bttv_call_all(btv, core, s_ctrl, c);
break;
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_BASS:
case V4L2_CID_AUDIO_TREBLE:
- bttv_call_i2c_clients(btv, VIDIOC_S_CTRL, c);
+ bttv_call_all(btv, core, s_ctrl, c);
break;
case V4L2_CID_PRIVATE_CHROMA_AGC:
@@ -2001,7 +1998,7 @@ static int bttv_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&btv->lock);
- bttv_call_i2c_clients(btv, VIDIOC_S_TUNER, t);
+ bttv_call_all(btv, tuner, s_tuner, t);
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 1);
@@ -2046,7 +2043,7 @@ static int bttv_s_frequency(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&btv->lock);
btv->freq = f->frequency;
- bttv_call_i2c_clients(btv, VIDIOC_S_FREQUENCY, f);
+ bttv_call_all(btv, tuner, s_frequency, f);
if (btv->has_matchbox && btv->radio_user)
tea5757_set_freq(btv, btv->freq);
mutex_unlock(&btv->lock);
@@ -2060,7 +2057,7 @@ static int bttv_log_status(struct file *file, void *f)
printk(KERN_INFO "bttv%d: ======== START STATUS CARD #%d ========\n",
btv->c.nr, btv->c.nr);
- bttv_call_i2c_clients(btv, VIDIOC_LOG_STATUS, NULL);
+ bttv_call_all(btv, core, log_status);
printk(KERN_INFO "bttv%d: ======== END STATUS CARD #%d ========\n",
btv->c.nr, btv->c.nr);
return 0;
@@ -2956,8 +2953,6 @@ static int bttv_g_parm(struct file *file, void *f,
struct bttv_fh *fh = f;
struct bttv *btv = fh->btv;
- if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
v4l2_video_std_frame_period(bttv_tvnorms[btv->tvnorm].v4l2_id,
&parm->parm.capture.timeperframe);
return 0;
@@ -2976,7 +2971,7 @@ static int bttv_g_tuner(struct file *file, void *priv,
mutex_lock(&btv->lock);
t->rxsubchans = V4L2_TUNER_SUB_MONO;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
strcpy(t->name, "Television");
t->capability = V4L2_TUNER_CAP_NORM;
t->type = V4L2_TUNER_ANALOG_TV;
@@ -3467,7 +3462,7 @@ static int radio_open(struct file *file)
btv->radio_user++;
- bttv_call_i2c_clients(btv,AUDC_SET_RADIO,NULL);
+ bttv_call_all(btv, tuner, s_radio);
audio_input(btv,TVAUDIO_INPUT_RADIO);
mutex_unlock(&btv->lock);
@@ -3487,7 +3482,7 @@ static int radio_release(struct file *file)
btv->radio_user--;
- bttv_call_i2c_clients(btv, RDS_CMD_CLOSE, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_CLOSE, &cmd);
return 0;
}
@@ -3520,7 +3515,7 @@ static int radio_g_tuner(struct file *file, void *priv, struct v4l2_tuner *t)
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
if (btv->audio_mode_gpio)
btv->audio_mode_gpio(btv, t, 0);
@@ -3562,7 +3557,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- bttv_call_i2c_clients(btv, VIDIOC_G_TUNER, t);
+ bttv_call_all(btv, tuner, g_tuner, t);
return 0;
}
@@ -3623,7 +3618,7 @@ static ssize_t radio_read(struct file *file, char __user *data,
cmd.instance = file;
cmd.result = -ENODEV;
- bttv_call_i2c_clients(btv, RDS_CMD_READ, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_READ, &cmd);
return cmd.result;
}
@@ -3636,7 +3631,7 @@ static unsigned int radio_poll(struct file *file, poll_table *wait)
cmd.instance = file;
cmd.event_list = wait;
cmd.result = -ENODEV;
- bttv_call_i2c_clients(btv, RDS_CMD_POLL, &cmd);
+ bttv_call_all(btv, core, ioctl, RDS_CMD_POLL, &cmd);
return cmd.result;
}
diff --git a/linux/drivers/media/video/bt8xx/bttv-i2c.c b/linux/drivers/media/video/bt8xx/bttv-i2c.c
index c35f09cf4..dbb21f77b 100644
--- a/linux/drivers/media/video/bt8xx/bttv-i2c.c
+++ b/linux/drivers/media/video/bt8xx/bttv-i2c.c
@@ -36,8 +36,6 @@
#include <linux/jiffies.h>
#include <asm/io.h>
-static int attach_inform(struct i2c_client *client);
-
static int i2c_debug;
static int i2c_hw;
static int i2c_scan;
@@ -269,51 +267,6 @@ static const struct i2c_algorithm bttv_algo = {
/* ----------------------------------------------------------------------- */
/* I2C functions - common stuff */
-static int attach_inform(struct i2c_client *client)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
- struct bttv *btv = to_bttv(v4l2_dev);
- int addr=ADDR_UNSET;
-
-
- if (ADDR_UNSET != bttv_tvcards[btv->c.type].tuner_addr)
- addr = bttv_tvcards[btv->c.type].tuner_addr;
-
-
- if (bttv_debug)
- printk(KERN_DEBUG "bttv%d: %s i2c attach [addr=0x%x,client=%s]\n",
- btv->c.nr, client->driver->driver.name, client->addr,
- client->name);
- if (!client->driver->command)
- return 0;
-
- if (client->driver->id == I2C_DRIVERID_MSP3400)
- btv->i2c_msp34xx_client = client;
- if (client->driver->id == I2C_DRIVERID_TVAUDIO)
- btv->i2c_tvaudio_client = client;
- if (btv->tuner_type != TUNER_ABSENT) {
- struct tuner_setup tun_setup;
-
- if (addr == ADDR_UNSET || addr == client->addr) {
- tun_setup.mode_mask = T_ANALOG_TV | T_DIGITAL_TV | T_RADIO;
- tun_setup.type = btv->tuner_type;
- tun_setup.addr = addr;
- bttv_call_i2c_clients(btv, TUNER_SET_TYPE_ADDR, &tun_setup);
- }
-
- }
-
- return 0;
-}
-
-void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg)
-{
- if (0 != btv->i2c_rc)
- return;
- i2c_clients_command(&btv->c.i2c_adap, cmd, arg);
-}
-
-
/* read I2C */
int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for)
{
@@ -424,8 +377,9 @@ int __devinit init_bttv_i2c(struct bttv *btv)
btv->c.i2c_adap.algo_data = &btv->i2c_algo;
}
btv->c.i2c_adap.owner = THIS_MODULE;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
btv->c.i2c_adap.class = I2C_CLASS_TV_ANALOG;
- btv->c.i2c_adap.client_register = attach_inform;
+#endif
btv->c.i2c_adap.dev.parent = &btv->c.pci->dev;
snprintf(btv->c.i2c_adap.name, sizeof(btv->c.i2c_adap.name),
@@ -435,10 +389,12 @@ int __devinit init_bttv_i2c(struct bttv *btv)
i2c_set_adapdata(&btv->c.i2c_adap, &btv->c.v4l2_dev);
btv->i2c_client.adapter = &btv->c.i2c_adap;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
if (bttv_tvcards[btv->c.type].no_video)
btv->c.i2c_adap.class &= ~I2C_CLASS_TV_ANALOG;
if (bttv_tvcards[btv->c.type].has_dvb)
btv->c.i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
+#endif
if (btv->use_i2c_hw) {
btv->i2c_rc = i2c_add_adapter(&btv->c.i2c_adap);
diff --git a/linux/drivers/media/video/bt8xx/bttv.h b/linux/drivers/media/video/bt8xx/bttv.h
index 947f6e51a..6b7b62bd4 100644
--- a/linux/drivers/media/video/bt8xx/bttv.h
+++ b/linux/drivers/media/video/bt8xx/bttv.h
@@ -241,6 +241,9 @@ struct tvcard {
unsigned int no_tda7432:1;
unsigned int needs_tvaudio:1;
unsigned int msp34xx_alt:1;
+ /* Note: currently no card definition needs to mark the presence
+ of a RDS saa6588 chip. If this is ever needed, then add a new
+ 'has_saa6588' bit here. */
unsigned int no_video:1; /* video pci function is unused */
unsigned int has_dvb:1;
@@ -358,7 +361,9 @@ void bttv_gpio_bits(struct bttv_core *core, u32 mask, u32 bits);
/* ---------------------------------------------------------- */
/* i2c */
-extern void bttv_call_i2c_clients(struct bttv *btv, unsigned int cmd, void *arg);
+#define bttv_call_all(btv, o, f, args...) \
+ v4l2_device_call_all(&btv->c.v4l2_dev, 0, o, f, ##args)
+
extern int bttv_I2CRead(struct bttv *btv, unsigned char addr, char *probe_for);
extern int bttv_I2CWrite(struct bttv *btv, unsigned char addr, unsigned char b1,
unsigned char b2, int both);
diff --git a/linux/drivers/media/video/bt8xx/bttvp.h b/linux/drivers/media/video/bt8xx/bttvp.h
index 5915c261e..65a8c1df1 100644
--- a/linux/drivers/media/video/bt8xx/bttvp.h
+++ b/linux/drivers/media/video/bt8xx/bttvp.h
@@ -331,6 +331,7 @@ struct bttv {
unsigned int tuner_type; /* tuner chip type */
unsigned int tda9887_conf;
unsigned int svhs, dig;
+ unsigned int has_saa6588:1;
struct bttv_pll_info pll;
int triton1;
int gpioirq;
@@ -354,8 +355,8 @@ struct bttv {
int i2c_state, i2c_rc;
int i2c_done;
wait_queue_head_t i2c_queue;
- struct i2c_client *i2c_msp34xx_client;
- struct i2c_client *i2c_tvaudio_client;
+ struct v4l2_subdev *sd_msp34xx;
+ struct v4l2_subdev *sd_tvaudio;
/* video4linux (1) */
struct video_device *video_dev;
diff --git a/linux/drivers/media/video/cafe_ccic.c b/linux/drivers/media/video/cafe_ccic.c
index 2619d77ef..2516e80ed 100644
--- a/linux/drivers/media/video/cafe_ccic.c
+++ b/linux/drivers/media/video/cafe_ccic.c
@@ -1152,8 +1152,6 @@ static int cafe_vidioc_reqbufs(struct file *filp, void *priv,
* Make sure it's something we can do. User pointers could be
* implemented without great pain, but that's not been done yet.
*/
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
/*
@@ -1217,9 +1215,7 @@ static int cafe_vidioc_querybuf(struct file *filp, void *priv,
int ret = -EINVAL;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out;
- if (buf->index < 0 || buf->index >= cam->n_sbufs)
+ if (buf->index >= cam->n_sbufs)
goto out;
*buf = cam->sb_bufs[buf->index].v4lbuf;
ret = 0;
@@ -1237,9 +1233,7 @@ static int cafe_vidioc_qbuf(struct file *filp, void *priv,
unsigned long flags;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out;
- if (buf->index < 0 || buf->index >= cam->n_sbufs)
+ if (buf->index >= cam->n_sbufs)
goto out;
sbuf = cam->sb_bufs + buf->index;
if (sbuf->v4lbuf.flags & V4L2_BUF_FLAG_QUEUED) {
@@ -1270,8 +1264,6 @@ static int cafe_vidioc_dqbuf(struct file *filp, void *priv,
unsigned long flags;
mutex_lock(&cam->s_mutex);
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- goto out_unlock;
if (cam->state != S_STREAMING)
goto out_unlock;
if (list_empty(&cam->sb_full) && filp->f_flags & O_NONBLOCK) {
@@ -1504,8 +1496,6 @@ static int cafe_vidioc_enum_fmt_vid_cap(struct file *filp,
struct cafe_camera *cam = priv;
int ret;
- if (fmt->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
mutex_lock(&cam->s_mutex);
ret = sensor_call(cam, video, enum_fmt, fmt);
mutex_unlock(&cam->s_mutex);
diff --git a/linux/drivers/media/video/cs5345.c b/linux/drivers/media/video/cs5345.c
index 31d6c4aa4..3e018b558 100644
--- a/linux/drivers/media/video/cs5345.c
+++ b/linux/drivers/media/video/cs5345.c
@@ -147,11 +147,6 @@ static int cs5345_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cs5345_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs5345_core_ops = {
@@ -222,8 +217,6 @@ MODULE_DEVICE_TABLE(i2c, cs5345_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs5345",
- .driverid = I2C_DRIVERID_CS5345,
- .command = cs5345_command,
.probe = cs5345_probe,
.remove = cs5345_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/cs53l32a.c b/linux/drivers/media/video/cs53l32a.c
index c8b5fa157..4745fd21c 100644
--- a/linux/drivers/media/video/cs53l32a.c
+++ b/linux/drivers/media/video/cs53l32a.c
@@ -29,7 +29,7 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include "compat.h"
MODULE_DESCRIPTION("i2c device driver for cs53l32a Audio ADC");
@@ -42,9 +42,11 @@ module_param(debug, bool, 0644);
MODULE_PARM_DESC(debug, "Debugging messages, 0=Off (default), 1=On");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
static unsigned short normal_i2c[] = { 0x22 >> 1, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
+#endif
/* ----------------------------------------------------------------------- */
@@ -123,11 +125,6 @@ static int cs53l32a_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cs53l32a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cs53l32a_core_ops = {
@@ -225,7 +222,6 @@ MODULE_DEVICE_TABLE(i2c, cs53l32a_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cs53l32a",
- .command = cs53l32a_command,
.remove = cs53l32a_remove,
.probe = cs53l32a_probe,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/cx18/cx18-av-audio.c b/linux/drivers/media/video/cx18/cx18-av-audio.c
index a2f0ad570..9e30983f2 100644
--- a/linux/drivers/media/video/cx18/cx18-av-audio.c
+++ b/linux/drivers/media/video/cx18/cx18-av-audio.c
@@ -464,82 +464,76 @@ static void set_mute(struct cx18 *cx, int mute)
}
}
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
struct cx18_av_state *state = &cx->av_state;
- struct v4l2_control *ctrl = arg;
int retval;
+ u8 v;
- switch (cmd) {
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- {
- u8 v;
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) & ~0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- cx18_av_write(cx, 0x8d3, 0x1f);
- }
- v = cx18_av_read(cx, 0x810) | 0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) & ~0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
+ cx18_av_write(cx, 0x8d3, 0x1f);
+ }
+ v = cx18_av_read(cx, 0x810) | 0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- retval = set_audclk_freq(cx, *(u32 *)arg);
+ retval = set_audclk_freq(cx, freq);
- v = cx18_av_read(cx, 0x810) & ~0x1;
- cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
- if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
- v = cx18_av_read(cx, 0x803) | 0x10;
- cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
- }
- return retval;
+ v = cx18_av_read(cx, 0x810) & ~0x1;
+ cx18_av_write_expect(cx, 0x810, v, v, 0x0f);
+ if (state->aud_input > CX18_AV_AUDIO_SERIAL2) {
+ v = cx18_av_read(cx, 0x803) | 0x10;
+ cx18_av_write_expect(cx, 0x803, v, v, 0x1f);
}
+ return retval;
+}
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(cx);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(cx);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(cx);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(cx);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(cx);
- break;
- default:
- return -EINVAL;
- }
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(cx);
break;
-
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(cx, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(cx, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(cx);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(cx);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(cx);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(cx);
break;
-
default:
return -EINVAL;
}
+ return 0;
+}
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl)
+{
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(cx, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(cx, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/linux/drivers/media/video/cx18/cx18-av-core.c b/linux/drivers/media/video/cx18/cx18-av-core.c
index 21f4be839..f4dd9d78e 100644
--- a/linux/drivers/media/video/cx18/cx18-av-core.c
+++ b/linux/drivers/media/video/cx18/cx18-av-core.c
@@ -413,19 +413,6 @@ void cx18_av_std_setup(struct cx18 *cx)
cx18_av_write(cx, 0x47f, state->slicer_line_delay);
}
-static int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
- struct v4l2_decode_vbi_line *vbi_line)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- return cx18_av_vbi(cx, VIDIOC_INT_DECODE_VBI_LINE, vbi_line);
-}
-
-static int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct cx18 *cx = v4l2_get_subdevdata(sd);
- return cx18_av_audio(cx, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq);
-}
-
static void input_change(struct cx18 *cx)
{
struct cx18_av_state *state = &cx->av_state;
@@ -772,7 +759,7 @@ static int cx18_av_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
- return cx18_av_audio(cx, VIDIOC_S_CTRL, ctrl);
+ return cx18_av_audio_s_ctrl(cx, ctrl);
default:
return -EINVAL;
@@ -802,7 +789,7 @@ static int cx18_av_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_TREBLE:
case V4L2_CID_AUDIO_BALANCE:
case V4L2_CID_AUDIO_MUTE:
- return cx18_av_audio(cx, VIDIOC_G_CTRL, ctrl);
+ return cx18_av_audio_g_ctrl(cx, ctrl);
default:
return -EINVAL;
}
@@ -845,13 +832,7 @@ static int cx18_av_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
struct cx18 *cx = v4l2_get_subdevdata(sd);
- switch (fmt->type) {
- case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_G_FMT, fmt);
- default:
- return -EINVAL;
- }
- return 0;
+ return cx18_av_vbi_g_fmt(cx, fmt);
}
static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
@@ -925,10 +906,10 @@ static int cx18_av_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+ return cx18_av_vbi_s_fmt(cx, fmt);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx18_av_vbi(cx, VIDIOC_S_FMT, fmt);
+ return cx18_av_vbi_s_fmt(cx, fmt);
default:
return -EINVAL;
diff --git a/linux/drivers/media/video/cx18/cx18-av-core.h b/linux/drivers/media/video/cx18/cx18-av-core.h
index 2687a2c91..c458120e8 100644
--- a/linux/drivers/media/video/cx18/cx18-av-core.h
+++ b/linux/drivers/media/video/cx18/cx18-av-core.h
@@ -355,11 +355,16 @@ int cx18_av_loadfw(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-audio.c */
-int cx18_av_audio(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_audio_g_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_audio_s_ctrl(struct cx18 *cx, struct v4l2_control *ctrl);
+int cx18_av_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
void cx18_av_audio_set_path(struct cx18 *cx);
/* ----------------------------------------------------------------------- */
/* cx18_av-vbi.c */
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg);
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+ struct v4l2_decode_vbi_line *vbi);
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt);
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt);
#endif
diff --git a/linux/drivers/media/video/cx18/cx18-av-vbi.c b/linux/drivers/media/video/cx18/cx18-av-vbi.c
index 27699839b..23b31670b 100644
--- a/linux/drivers/media/video/cx18/cx18-av-vbi.c
+++ b/linux/drivers/media/video/cx18/cx18-av-vbi.c
@@ -129,196 +129,189 @@ static int decode_vps(u8 *dst, u8 *p)
return err & 0xf0;
}
-int cx18_av_vbi(struct cx18 *cx, unsigned int cmd, void *arg)
+int cx18_av_vbi_g_fmt(struct cx18 *cx, struct v4l2_format *fmt)
{
struct cx18_av_state *state = &cx->av_state;
- struct v4l2_format *fmt;
struct v4l2_sliced_vbi_format *svbi;
+ static const u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i;
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
- break;
-
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 7);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- } else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx18_av_read(cx, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |= svbi->service_lines[0][i] |
- svbi->service_lines[1][i];
- }
- }
- break;
- }
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx18_av_read(cx, 0x404) & 0x10) == 0)
+ return 0;
+
+ if (is_pal) {
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx18_av_read(cx, 0x424 + i - 7);
- case VIDIOC_S_FMT:
- {
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
- fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup standard */
- cx18_av_std_setup(cx);
-
- /* VBI Offset */
- cx18_av_write(cx, 0x47f, state->slicer_line_delay);
- cx18_av_write(cx, 0x404, 0x2e);
- break;
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
+ } else {
+ for (i = 10; i <= 21; i++) {
+ u8 v = cx18_av_read(cx, 0x424 + i - 10);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
+ }
+ }
+ return 0;
+}
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
+int cx18_av_vbi_s_fmt(struct cx18 *cx, struct v4l2_format *fmt)
+{
+ struct cx18_av_state *state = &cx->av_state;
+ struct v4l2_sliced_vbi_format *svbi;
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i, x;
+ u8 lcr[24];
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
/* Setup standard */
cx18_av_std_setup(cx);
- /* Sliced VBI */
- cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
- cx18_av_write(cx, 0x406, 0x13);
+ /* VBI Offset */
cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+ cx18_av_write(cx, 0x404, 0x2e);
+ return 0;
+ }
- /* Force impossible lines to 0 */
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup standard */
+ cx18_av_std_setup(cx);
+
+ /* Sliced VBI */
+ cx18_av_write(cx, 0x404, 0x32); /* Ancillary data */
+ cx18_av_write(cx, 0x406, 0x13);
+ cx18_av_write(cx, 0x47f, state->slicer_line_delay);
+
+ /* Force impossible lines to 0 */
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
- /* Build register values for requested service lines */
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
+ /* Build register values for requested service lines */
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
}
}
+ }
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++)
- cx18_av_write(cx, i, lcr[6 + x]);
- } else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++)
- cx18_av_write(cx, i, lcr[9 + x]);
- for (i = 0x431; i <= 0x434; i++)
- cx18_av_write(cx, i, 0);
- }
+ if (is_pal) {
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+ cx18_av_write(cx, i, lcr[6 + x]);
+ } else {
+ for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+ cx18_av_write(cx, i, lcr[9 + x]);
+ for (i = 0x431; i <= 0x434; i++)
+ cx18_av_write(cx, i, 0);
+ }
- cx18_av_write(cx, 0x43c, 0x16);
- /* FIXME - should match vblank set in cx18_av_std_setup() */
- cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
- break;
+ cx18_av_write(cx, 0x43c, 0x16);
+ /* FIXME - should match vblank set in cx18_av_std_setup() */
+ cx18_av_write(cx, 0x474, is_pal ? 0x2a : 26);
+ return 0;
+}
+
+int cx18_av_decode_vbi_line(struct v4l2_subdev *sd,
+ struct v4l2_decode_vbi_line *vbi)
+{
+ struct cx18 *cx = v4l2_get_subdevdata(sd);
+ struct cx18_av_state *state = &cx->av_state;
+ struct vbi_anc_data *anc = (struct vbi_anc_data *)vbi->p;
+ u8 *p;
+ int did, sdid, l, err = 0;
+
+ /*
+ * Check for the ancillary data header for sliced VBI
+ */
+ if (anc->preamble[0] ||
+ anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
+ (anc->did != sliced_vbi_did[0] &&
+ anc->did != sliced_vbi_did[1])) {
+ vbi->line = vbi->type = 0;
+ return 0;
}
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p;
- struct vbi_anc_data *anc = (struct vbi_anc_data *) vbi->p;
- int did, sdid, l, err = 0;
-
- /*
- * Check for the ancillary data header for sliced VBI
- */
- if (anc->preamble[0] ||
- anc->preamble[1] != 0xff || anc->preamble[2] != 0xff ||
- (anc->did != sliced_vbi_did[0] &&
- anc->did != sliced_vbi_did[1])) {
- vbi->line = vbi->type = 0;
- break;
- }
+ did = anc->did;
+ sdid = anc->sdid & 0xf;
+ l = anc->idid[0] & 0x3f;
+ l += state->slicer_line_offset;
+ p = anc->payload;
- did = anc->did;
- sdid = anc->sdid & 0xf;
- l = anc->idid[0] & 0x3f;
- l += state->slicer_line_offset;
- p = anc->payload;
-
- /* Decode the SDID set by the slicer */
- switch (sdid) {
- case 1:
- sdid = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- sdid = V4L2_SLICED_WSS_625;
- break;
- case 6:
- sdid = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- sdid = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0)
- err = 1;
- break;
- default:
- sdid = 0;
+ /* Decode the SDID set by the slicer */
+ switch (sdid) {
+ case 1:
+ sdid = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ sdid = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ sdid = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ sdid = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0)
err = 1;
- break;
- }
-
- vbi->type = err ? 0 : sdid;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
- vbi->p = p;
break;
- }
+ default:
+ sdid = 0;
+ err = 1;
+ break;
}
+ vbi->type = err ? 0 : sdid;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (did == sliced_vbi_did[1]);
+ vbi->p = p;
return 0;
}
diff --git a/linux/drivers/media/video/cx231xx/Kconfig b/linux/drivers/media/video/cx231xx/Kconfig
index aba05d3bd..477d4ab5e 100644
--- a/linux/drivers/media/video/cx231xx/Kconfig
+++ b/linux/drivers/media/video/cx231xx/Kconfig
@@ -7,11 +7,11 @@ config VIDEO_CX231XX
select VIDEOBUF_VMALLOC
select VIDEO_CX25840
- ---help---
- This is a video4linux driver for Conexant 231xx USB based TV cards.
+ ---help---
+ This is a video4linux driver for Conexant 231xx USB based TV cards.
- To compile this driver as a module, choose M here: the
- module will be called cx231xx
+ To compile this driver as a module, choose M here: the
+ module will be called cx231xx
config VIDEO_CX231XX_ALSA
tristate "Conexant Cx231xx ALSA audio module"
diff --git a/linux/drivers/media/video/cx23885/cx23885-417.c b/linux/drivers/media/video/cx23885/cx23885-417.c
index 0766a97a0..aeef889fd 100644
--- a/linux/drivers/media/video/cx23885/cx23885-417.c
+++ b/linux/drivers/media/video/cx23885/cx23885-417.c
@@ -896,7 +896,7 @@ static int cx23885_load_firmware(struct cx23885_dev *dev)
if (retval != 0) {
printk(KERN_ERR
"ERROR: Hotplug firmware request failed (%s).\n",
- CX2341X_FIRM_ENC_FILENAME);
+ CX23885_FIRM_IMAGE_NAME);
printk(KERN_ERR "Please fix your hotplug setup, the board will "
"not work without firmware loaded!\n");
return -1;
@@ -1194,8 +1194,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *id)
* This will likely need to be enabled for non NTSC
* formats.
*/
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_S_STD, id);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, id);
+ call_all(dev, tuner, s_std, id);
#endif
return 0;
}
@@ -1206,21 +1205,16 @@ static int vidioc_enum_input(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
struct cx23885_input *input;
- unsigned int n;
+ int n;
- n = i->index;
-
- if (n >= 4)
+ if (i->index >= 4)
return -EINVAL;
- input = &cx23885_boards[dev->board].input[n];
+ input = &cx23885_boards[dev->board].input[i->index];
if (input->type == 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = n;
-
/* FIXME
* strcpy(i->name, input->name); */
strcpy(i->name, "unset");
@@ -1263,10 +1257,8 @@ static int vidioc_g_tuner(struct file *file, void *priv,
return -EINVAL;
if (0 != t->index)
return -EINVAL;
- memset(t, 0, sizeof(*t));
strcpy(t->name, "Television");
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_TUNER, t);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+ call_all(dev, tuner, g_tuner, t);
dprintk(1, "VIDIOC_G_TUNER: tuner type %d\n", t->type);
@@ -1283,7 +1275,7 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_TUNER, t);
+ call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -1294,14 +1286,12 @@ static int vidioc_g_frequency(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- memset(f, 0, sizeof(*f));
if (UNSET == dev->tuner_type)
return -EINVAL;
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1328,8 +1318,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
return -EINVAL;
dev->freq = f->frequency;
- /* Assumption that tuner is always on bus 1 */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
cx23885_initialize_codec(dev);
@@ -1343,7 +1332,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
/* Update the A/V core */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ call_all(dev, core, s_ctrl, ctl);
return 0;
}
@@ -1354,7 +1343,6 @@ static int vidioc_querycap(struct file *file, void *priv,
struct cx23885_dev *dev = fh->dev;
struct cx23885_tsport *tsport = &dev->ts1;
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, dev->name);
strlcpy(cap->card, cx23885_boards[tsport->dev->board].name,
sizeof(cap->card));
@@ -1374,16 +1362,10 @@ static int vidioc_querycap(struct file *file, void *priv,
static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
struct v4l2_fmtdesc *f)
{
- int index;
-
- index = f->index;
- if (index != 0)
+ if (f->index != 0)
return -EINVAL;
- memset(f, 0, sizeof(*f));
- f->index = index;
strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
@@ -1395,8 +1377,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- memset(f, 0, sizeof(*f));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
@@ -1416,12 +1396,10 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
dev->ts1.ts_packet_size * dev->ts1.ts_packet_count;
- f->fmt.pix.sizeimage =
f->fmt.pix.colorspace = 0;
dprintk(1, "VIDIOC_TRY_FMT: w: %d, h: %d, f: %d\n",
dev->ts1.width, dev->ts1.height, fh->mpegq.field);
@@ -1434,7 +1412,6 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
struct cx23885_fh *fh = file->private_data;
struct cx23885_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage =
@@ -1551,12 +1528,7 @@ static int vidioc_log_status(struct file *file, void *priv)
printk(KERN_INFO
"%s/2: ============ START LOG STATUS ============\n",
dev->name);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_LOG_STATUS,
- NULL);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_LOG_STATUS,
- NULL);
+ call_all(dev, core, log_status);
cx2341x_log_status(&dev->mpeg_params, name);
printk(KERN_INFO
"%s/2: ============= END LOG STATUS =============\n",
diff --git a/linux/drivers/media/video/cx23885/cx23885-cards.c b/linux/drivers/media/video/cx23885/cx23885-cards.c
index e6db78f8b..493551ec0 100644
--- a/linux/drivers/media/video/cx23885/cx23885-cards.c
+++ b/linux/drivers/media/video/cx23885/cx23885-cards.c
@@ -740,7 +740,9 @@ void cx23885_card_setup(struct cx23885_dev *dev)
case CX23885_BOARD_LEADTEK_WINFAST_PXDVR3200_H:
case CX23885_BOARD_COMPRO_VIDEOMATE_E650F:
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
- request_module("cx25840");
+ dev->sd_cx25840 = v4l2_i2c_new_subdev(&dev->i2c_bus[2].i2c_adap,
+ "cx25840", "cx25840", 0x88 >> 1);
+ v4l2_subdev_call(dev->sd_cx25840, core, init, 0);
break;
}
diff --git a/linux/drivers/media/video/cx23885/cx23885-core.c b/linux/drivers/media/video/cx23885/cx23885-core.c
index d894d4900..2bffcbc48 100644
--- a/linux/drivers/media/video/cx23885/cx23885-core.c
+++ b/linux/drivers/media/video/cx23885/cx23885-core.c
@@ -876,7 +876,7 @@ static int cx23885_dev_setup(struct cx23885_dev *dev)
cx23885_i2c_register(&dev->i2c_bus[1]);
cx23885_i2c_register(&dev->i2c_bus[2]);
cx23885_card_setup(dev);
- cx23885_call_i2c_clients(&dev->i2c_bus[0], TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
cx23885_ir_init(dev);
if (cx23885_boards[dev->board].porta == CX23885_ANALOG_VIDEO) {
@@ -1750,16 +1750,20 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
if (NULL == dev)
return -ENOMEM;
+ err = v4l2_device_register(&pci_dev->dev, &dev->v4l2_dev);
+ if (err < 0)
+ goto fail_free;
+
/* pci init */
dev->pci = pci_dev;
if (pci_enable_device(pci_dev)) {
err = -EIO;
- goto fail_free;
+ goto fail_unreg;
}
if (cx23885_dev_setup(dev) < 0) {
err = -EINVAL;
- goto fail_free;
+ goto fail_unreg;
}
/* print pci info */
@@ -1786,8 +1790,6 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
goto fail_irq;
}
- pci_set_drvdata(pci_dev, dev);
-
switch (dev->board) {
case CX23885_BOARD_NETUP_DUAL_DVBS2_CI:
cx_set(PCI_INT_MSK, 0x01800000); /* for NetUP */
@@ -1798,6 +1800,8 @@ static int __devinit cx23885_initdev(struct pci_dev *pci_dev,
fail_irq:
cx23885_dev_unregister(dev);
+fail_unreg:
+ v4l2_device_unregister(&dev->v4l2_dev);
fail_free:
kfree(dev);
return err;
@@ -1805,7 +1809,8 @@ fail_free:
static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
{
- struct cx23885_dev *dev = pci_get_drvdata(pci_dev);
+ struct v4l2_device *v4l2_dev = pci_get_drvdata(pci_dev);
+ struct cx23885_dev *dev = to_cx23885(v4l2_dev);
cx23885_shutdown(dev);
@@ -1813,13 +1818,13 @@ static void __devexit cx23885_finidev(struct pci_dev *pci_dev)
/* unregister stuff */
free_irq(pci_dev->irq, dev);
- pci_set_drvdata(pci_dev, NULL);
mutex_lock(&devlist);
list_del(&dev->devlist);
mutex_unlock(&devlist);
cx23885_dev_unregister(dev);
+ v4l2_device_unregister(v4l2_dev);
kfree(dev);
}
diff --git a/linux/drivers/media/video/cx23885/cx23885-dvb.c b/linux/drivers/media/video/cx23885/cx23885-dvb.c
index 364543987..dfb16b91e 100644
--- a/linux/drivers/media/video/cx23885/cx23885-dvb.c
+++ b/linux/drivers/media/video/cx23885/cx23885-dvb.c
@@ -674,7 +674,7 @@ static int dvb_register(struct cx23885_tsport *port)
fe0->dvb.frontend->callback = cx23885_tuner_callback;
/* Put the analog decoder in standby to keep it quiet */
- cx23885_call_i2c_clients(i2c_bus, TUNER_SET_STANDBY, NULL);
+ call_all(dev, core, s_standby, 0);
if (fe0->dvb.frontend->ops.analog_ops.standby)
fe0->dvb.frontend->ops.analog_ops.standby(fe0->dvb.frontend);
diff --git a/linux/drivers/media/video/cx23885/cx23885-i2c.c b/linux/drivers/media/video/cx23885/cx23885-i2c.c
index 2210b47d2..3b0b9d3e3 100644
--- a/linux/drivers/media/video/cx23885/cx23885-i2c.c
+++ b/linux/drivers/media/video/cx23885/cx23885-i2c.c
@@ -269,82 +269,6 @@ static int i2c_xfer(struct i2c_adapter *i2c_adap,
return retval;
}
-static int attach_inform(struct i2c_client *client)
-{
- struct cx23885_i2c *bus = i2c_get_adapdata(client->adapter);
- struct cx23885_dev *dev = bus->dev;
- struct tuner_setup tun_setup;
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
-
- if (!client->driver->command)
- return 0;
-#if 0
- if (dev->radio_type != UNSET) {
-
- dprintk(1, "%s (radio) i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr,
- client->name);
-
- if ((dev->radio_addr == ADDR_UNSET) ||
- (dev->radio_addr == client->addr)) {
- tun_setup.mode_mask = T_RADIO;
- tun_setup.type = dev->radio_type;
- tun_setup.addr = dev->radio_addr;
-
- client->driver->command(client, TUNER_SET_TYPE_ADDR,
- &tun_setup);
- }
- }
-#endif
-
- if (dev->tuner_type != UNSET) {
-
- dprintk(1, "%s (tuner) i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr,
- client->name);
-
- if ((dev->tuner_addr == ADDR_UNSET) ||
- (dev->tuner_addr == client->addr)) {
-
- dprintk(1, "%s (tuner || addr UNSET)\n",
- client->driver->driver.name);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name,
- client->addr, client->name);
-
- tun_setup.mode_mask = T_ANALOG_TV;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
-
- client->driver->command(client, TUNER_SET_TYPE_ADDR,
- &tun_setup);
- }
- }
-
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct cx23885_dev *dev = i2c_get_adapdata(client->adapter);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
-
- return 0;
-}
-
-void cx23885_call_i2c_clients(struct cx23885_i2c *bus,
- unsigned int cmd, void *arg)
-{
- if (bus->i2c_rc != 0)
- return;
-
- i2c_clients_command(&bus->i2c_adap, cmd, arg);
-}
-
static u32 cx23885_functionality(struct i2c_adapter *adap)
{
return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_I2C;
@@ -365,9 +289,9 @@ static struct i2c_adapter cx23885_i2c_adap_template = {
.owner = THIS_MODULE,
.id = I2C_HW_B_CX23885,
.algo = &cx23885_i2c_algo_template,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
.class = I2C_CLASS_TV_ANALOG,
- .client_register = attach_inform,
- .client_unregister = detach_inform,
+#endif
};
static struct i2c_client cx23885_i2c_client_template = {
@@ -424,15 +348,18 @@ int cx23885_i2c_register(struct cx23885_i2c *bus)
bus->i2c_algo.data = bus;
bus->i2c_adap.algo_data = bus;
- i2c_set_adapdata(&bus->i2c_adap, bus);
+ i2c_set_adapdata(&bus->i2c_adap, &dev->v4l2_dev);
i2c_add_adapter(&bus->i2c_adap);
bus->i2c_client.adapter = &bus->i2c_adap;
if (0 == bus->i2c_rc) {
dprintk(1, "%s: i2c bus %d registered\n", dev->name, bus->nr);
- if (i2c_scan)
+ if (i2c_scan) {
+ printk(KERN_INFO "%s: scan bus %d:\n",
+ dev->name, bus->nr);
do_i2c_scan(dev->name, &bus->i2c_client);
+ }
} else
printk(KERN_WARNING "%s: i2c bus %d register FAILED\n",
dev->name, bus->nr);
diff --git a/linux/drivers/media/video/cx23885/cx23885-video.c b/linux/drivers/media/video/cx23885/cx23885-video.c
index ba22520a2..a45bd3b77 100644
--- a/linux/drivers/media/video/cx23885/cx23885-video.c
+++ b/linux/drivers/media/video/cx23885/cx23885-video.c
@@ -334,11 +334,7 @@ static int cx23885_set_tvnorm(struct cx23885_dev *dev, v4l2_std_id norm)
dev->tvnorm = norm;
- /* Tell the analog tuner/demods */
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_STD, &norm);
-
- /* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_STD, &norm);
+ call_all(dev, tuner, s_std, norm);
return 0;
}
@@ -355,8 +351,8 @@ static struct video_device *cx23885_vdev_init(struct cx23885_dev *dev,
if (NULL == vfd)
return NULL;
*vfd = *template;
- vfd->minor = -1;
- vfd->parent = &pci->dev;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
vfd->release = video_device_release;
snprintf(vfd->name, sizeof(vfd->name), "%s %s (%s)",
dev->name, type, cx23885_boards[dev->board].name);
@@ -445,12 +441,10 @@ static int cx23885_video_mux(struct cx23885_dev *dev, unsigned int input)
route.input = INPUT(input)->vmux;
/* Tell the internal A/V decoder */
- cx23885_call_i2c_clients(&dev->i2c_bus[2],
- VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_subdev_call(dev->sd_cx25840, video, s_routing, &route);
#if 0
route.input = 0; /* Let the AVCore default */
- cx23885_call_i2c_clients(&dev->i2c_bus[2],
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ v4l2_subdev_call(dev->sd_cx25840, audio, s_routing, &route);
#endif
return 0;
@@ -840,8 +834,7 @@ static int video_open(struct file *file)
dev->tvaudio = WW_FM;
cx23885_set_tvaudio(dev);
cx23885_set_stereo(dev, V4L2_TUNER_MODE_STEREO, 1);
- cx23885_call_i2c_clients(&dev->i2c_bus[1],
- AUDC_SET_RADIO, NULL);
+ call_all(dev, tuner, s_radio);
}
#endif
unlock_kernel();
@@ -944,7 +937,7 @@ static int video_release(struct file *file)
* tuner video. Closing this will result in no video to the encoder.
*/
#if 0
- cx23885_call_i2c_clients(&dev->i2c_bus[1], TUNER_SET_STANDBY, NULL);
+ call_all(dev, tuner, s_standby);
#endif
return 0;
@@ -964,7 +957,7 @@ static int cx23885_get_control(struct cx23885_dev *dev,
struct v4l2_control *ctl)
{
dprintk(1, "%s() calling cx25840(VIDIOC_G_CTRL)\n", __func__);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_G_CTRL, ctl);
+ call_all(dev, core, g_ctrl, ctl);
return 0;
}
@@ -974,7 +967,7 @@ static int cx23885_set_control(struct cx23885_dev *dev,
dprintk(1, "%s() calling cx25840(VIDIOC_S_CTRL)"
" (disabled - no action)\n", __func__);
#if 0
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_CTRL, ctl);
+ call_all(dev, core, s_ctrl, ctl);
#endif
return 0;
}
@@ -1081,7 +1074,7 @@ static int vidioc_s_fmt_vid_cap(struct file *file, void *priv,
fh->vidq.field = f->fmt.pix.field;
dprintk(2, "%s() width=%d height=%d field=%d\n", __func__,
fh->width, fh->height, fh->vidq.field);
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_S_FMT, f);
+ call_all(dev, video, s_fmt, f);
return 0;
}
@@ -1370,7 +1363,7 @@ static int vidioc_g_frequency(struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = dev->freq;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_FREQUENCY, f);
+ call_all(dev, tuner, g_frequency, f);
return 0;
}
@@ -1385,7 +1378,7 @@ static int cx23885_set_freq(struct cx23885_dev *dev, struct v4l2_frequency *f)
mutex_lock(&dev->lock);
dev->freq = f->frequency;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_FREQUENCY, f);
+ call_all(dev, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep(10);
@@ -1419,7 +1412,7 @@ static int vidioc_g_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_G_REGISTER, reg);
+ call_all(dev, core, g_register, reg);
return 0;
}
@@ -1432,7 +1425,7 @@ static int vidioc_s_register(struct file *file, void *fh,
if (!v4l2_chip_match_host(&reg->match))
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[2], VIDIOC_DBG_S_REGISTER, reg);
+ call_all(dev, core, s_register, reg);
return 0;
}
@@ -1468,7 +1461,7 @@ static int radio_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_G_TUNER, t);
+ call_all(dev, tuner, g_tuner, t);
return 0;
}
@@ -1503,7 +1496,7 @@ static int radio_s_tuner(struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- cx23885_call_i2c_clients(&dev->i2c_bus[1], VIDIOC_S_TUNER, t);
+ call_all(dev, tuner, s_tuner, t);
return 0;
}
@@ -1782,13 +1775,30 @@ int cx23885_video_register(struct cx23885_dev *dev)
#endif
cx_set(PCI_INT_MSK, 1);
-#if 0
- /* FIXME: These should be correctly defined */
- /* load and configure helper modules */
- if (TUNER_ABSENT != core->tuner_type)
- request_module("tuner");
+ if (TUNER_ABSENT != dev->tuner_type) {
+ struct v4l2_subdev *sd = NULL;
+
+ if (dev->tuner_addr)
+ sd = v4l2_i2c_new_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", dev->tuner_addr);
+ else
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_bus[1].i2c_adap,
+ "tuner", "tuner", v4l2_i2c_tuner_addrs(ADDRS_TV));
+ if (sd) {
+ struct tuner_setup tun_setup;
+ tun_setup.mode_mask = T_ANALOG_TV;
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = v4l2_i2c_subdev_addr(sd);
+
+ v4l2_subdev_call(sd, tuner, s_type_addr, &tun_setup);
+ }
+ }
+
+#if 0
if (cx23885_boards[dev->board].audio_chip == V4L2_IDENT_WM8775)
+ /* Must use v4l2_i2c_new_subdev instead of request_module
+ once this is implemented for real. */
request_module("wm8775");
#endif
diff --git a/linux/drivers/media/video/cx23885/cx23885.h b/linux/drivers/media/video/cx23885/cx23885.h
index e8118c6bd..c090a7df9 100644
--- a/linux/drivers/media/video/cx23885/cx23885.h
+++ b/linux/drivers/media/video/cx23885/cx23885.h
@@ -24,7 +24,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/kdev_t.h>
-#include <media/v4l2-common.h>
+#include <media/v4l2-device.h>
#include <media/tuner.h>
#include <media/tveeprom.h>
#include <media/videobuf-dma-sg.h>
@@ -278,6 +278,7 @@ struct cx23885_tsport {
struct cx23885_dev {
struct list_head devlist;
atomic_t refcount;
+ struct v4l2_device v4l2_dev;
/* pci stuff */
struct pci_dev *pci;
@@ -323,6 +324,7 @@ struct cx23885_dev {
unsigned int radio_type;
unsigned char radio_addr;
unsigned int has_radio;
+ struct v4l2_subdev *sd_cx25840;
/* V4l */
u32 freq;
@@ -343,6 +345,14 @@ struct cx23885_dev {
};
+static inline struct cx23885_dev *to_cx23885(struct v4l2_device *v4l2_dev)
+{
+ return container_of(v4l2_dev, struct cx23885_dev, v4l2_dev);
+}
+
+#define call_all(dev, o, f, args...) \
+ v4l2_device_call_all(&dev->v4l2_dev, 0, o, f, ##args)
+
extern struct list_head cx23885_devlist;
#define SRAM_CH01 0 /* Video A */
@@ -459,8 +469,6 @@ extern struct videobuf_queue_ops cx23885_vbi_qops;
/* cx23885-i2c.c */
extern int cx23885_i2c_register(struct cx23885_i2c *bus);
extern int cx23885_i2c_unregister(struct cx23885_i2c *bus);
-extern void cx23885_call_i2c_clients(struct cx23885_i2c *bus, unsigned int cmd,
- void *arg);
extern void cx23885_av_clk(struct cx23885_dev *dev, int enable);
/* ----------------------------------------------------------- */
diff --git a/linux/drivers/media/video/cx25840/cx25840-audio.c b/linux/drivers/media/video/cx25840/cx25840-audio.c
index 9dcdef03e..f0a91f981 100644
--- a/linux/drivers/media/video/cx25840/cx25840-audio.c
+++ b/linux/drivers/media/video/cx25840/cx25840-audio.c
@@ -378,75 +378,74 @@ static void set_mute(struct i2c_client *client, int mute)
}
}
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct v4l2_control *ctrl = arg;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
int retval;
- switch (cmd) {
- case VIDIOC_INT_AUDIO_CLOCK_FREQ:
- if (!state->is_cx25836)
- cx25840_and_or(client, 0x810, ~0x1, 1);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0);
- cx25840_write(client, 0x8d3, 0x1f);
- }
- retval = set_audclk_freq(client, *(u32 *)arg);
- if (state->aud_input != CX25840_AUDIO_SERIAL) {
- cx25840_and_or(client, 0x803, ~0x10, 0x10);
- }
- if (!state->is_cx25836)
- cx25840_and_or(client, 0x810, ~0x1, 0);
- return retval;
-
- case VIDIOC_G_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- ctrl->value = get_volume(client);
- break;
- case V4L2_CID_AUDIO_BASS:
- ctrl->value = get_bass(client);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- ctrl->value = get_treble(client);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- ctrl->value = get_balance(client);
- break;
- case V4L2_CID_AUDIO_MUTE:
- ctrl->value = get_mute(client);
- break;
- default:
- return -EINVAL;
- }
- break;
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 1);
+ if (state->aud_input != CX25840_AUDIO_SERIAL) {
+ cx25840_and_or(client, 0x803, ~0x10, 0);
+ cx25840_write(client, 0x8d3, 0x1f);
+ }
+ retval = set_audclk_freq(client, freq);
+ if (state->aud_input != CX25840_AUDIO_SERIAL)
+ cx25840_and_or(client, 0x803, ~0x10, 0x10);
+ if (!state->is_cx25836)
+ cx25840_and_or(client, 0x810, ~0x1, 0);
+ return retval;
+}
- case VIDIOC_S_CTRL:
- switch (ctrl->id) {
- case V4L2_CID_AUDIO_VOLUME:
- set_volume(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BASS:
- set_bass(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_TREBLE:
- set_treble(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_BALANCE:
- set_balance(client, ctrl->value);
- break;
- case V4L2_CID_AUDIO_MUTE:
- set_mute(client, ctrl->value);
- break;
- default:
- return -EINVAL;
- }
- break;
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ ctrl->value = get_volume(client);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ ctrl->value = get_bass(client);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ ctrl->value = get_treble(client);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ ctrl->value = get_balance(client);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ ctrl->value = get_mute(client);
+ break;
default:
return -EINVAL;
}
+ return 0;
+}
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+
+ switch (ctrl->id) {
+ case V4L2_CID_AUDIO_VOLUME:
+ set_volume(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BASS:
+ set_bass(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_TREBLE:
+ set_treble(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_BALANCE:
+ set_balance(client, ctrl->value);
+ break;
+ case V4L2_CID_AUDIO_MUTE:
+ set_mute(client, ctrl->value);
+ break;
+ default:
+ return -EINVAL;
+ }
return 0;
}
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.c b/linux/drivers/media/video/cx25840/cx25840-core.c
index 5387a846f..67971cc3c 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.c
+++ b/linux/drivers/media/video/cx25840/cx25840-core.c
@@ -39,7 +39,7 @@
#include <linux/delay.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/cx25840.h>
#include "compat.h"
@@ -49,15 +49,17 @@ MODULE_DESCRIPTION("Conexant CX25840 audio/video decoder driver");
MODULE_AUTHOR("Ulf Eklund, Chris Kennedy, Hans Verkuil, Tyler Trafford");
MODULE_LICENSE("GPL");
-static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
-
static int cx25840_debug;
module_param_named(debug,cx25840_debug, int, 0644);
MODULE_PARM_DESC(debug, "Debugging messages [0=Off (default) 1=On]");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
+static unsigned short normal_i2c[] = { 0x88 >> 1, I2C_CLIENT_END };
+
I2C_CLIENT_INSMOD;
+#endif
/* ----------------------------------------------------------------------- */
@@ -891,7 +893,7 @@ static int cx25840_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_MUTE:
if (state->is_cx25836)
return -EINVAL;
- return cx25840_audio(client, VIDIOC_S_CTRL, ctrl);
+ return cx25840_audio_s_ctrl(sd, ctrl);
default:
return -EINVAL;
@@ -928,7 +930,7 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
case V4L2_CID_AUDIO_MUTE:
if (state->is_cx25836)
return -EINVAL;
- return cx25840_audio(client, VIDIOC_G_CTRL, ctrl);
+ return cx25840_audio_g_ctrl(sd, ctrl);
default:
return -EINVAL;
}
@@ -940,11 +942,9 @@ static int cx25840_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
static int cx25840_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
switch (fmt->type) {
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_G_FMT, fmt);
+ return cx25840_vbi_g_fmt(sd, fmt);
default:
return -EINVAL;
}
@@ -1006,10 +1006,10 @@ static int cx25840_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
break;
case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+ return cx25840_vbi_s_fmt(sd, fmt);
case V4L2_BUF_TYPE_VBI_CAPTURE:
- return cx25840_vbi(client, VIDIOC_S_FMT, fmt);
+ return cx25840_vbi_s_fmt(sd, fmt);
default:
return -EINVAL;
@@ -1271,20 +1271,6 @@ static int cx25840_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register *
}
#endif
-static int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return cx25840_vbi(client, VIDIOC_INT_DECODE_VBI_LINE, vbi);
-}
-
-static int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq)
-{
- struct i2c_client *client = v4l2_get_subdevdata(sd);
-
- return cx25840_audio(client, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freq);
-}
-
static int cx25840_s_stream(struct v4l2_subdev *sd, int enable)
{
struct cx25840_state *state = to_state(sd);
@@ -1510,19 +1496,6 @@ static int cx25840_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int cx25840_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- /* ignore this command */
- if (cmd == TUNER_SET_TYPE_ADDR || cmd == TUNER_SET_CONFIG)
- return 0;
-
- /* Old-style drivers rely on initialization on first use, so
- call the init whenever a command is issued to this driver.
- New-style drivers using v4l2_subdev should call init explicitly. */
- cx25840_init(i2c_get_clientdata(client), 0);
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops cx25840_core_ops = {
@@ -1663,8 +1636,6 @@ MODULE_DEVICE_TABLE(i2c, cx25840_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "cx25840",
- .driverid = I2C_DRIVERID_CX25840,
- .command = cx25840_command,
.probe = cx25840_probe,
.remove = cx25840_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/cx25840/cx25840-core.h b/linux/drivers/media/video/cx25840/cx25840-core.h
index 422c63752..580c320da 100644
--- a/linux/drivers/media/video/cx25840/cx25840-core.h
+++ b/linux/drivers/media/video/cx25840/cx25840-core.h
@@ -77,11 +77,15 @@ int cx25840_loadfw(struct i2c_client *client);
/* ----------------------------------------------------------------------- */
/* cx25850-audio.c */
-int cx25840_audio(struct i2c_client *client, unsigned int cmd, void *arg);
void cx25840_audio_set_path(struct i2c_client *client);
+int cx25840_s_clock_freq(struct v4l2_subdev *sd, u32 freq);
+int cx25840_audio_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
+int cx25840_audio_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl);
/* ----------------------------------------------------------------------- */
/* cx25850-vbi.c */
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg);
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt);
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi);
#endif
diff --git a/linux/drivers/media/video/cx25840/cx25840-vbi.c b/linux/drivers/media/video/cx25840/cx25840-vbi.c
index 7790afd5b..011987326 100644
--- a/linux/drivers/media/video/cx25840/cx25840-vbi.c
+++ b/linux/drivers/media/video/cx25840/cx25840-vbi.c
@@ -83,199 +83,181 @@ static int decode_vps(u8 * dst, u8 * p)
return err & 0xf0;
}
-int cx25840_vbi(struct i2c_client *client, unsigned int cmd, void *arg)
+int cx25840_vbi_g_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
{
- struct cx25840_state *state = to_state(i2c_get_clientdata(client));
- struct v4l2_format *fmt;
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
struct v4l2_sliced_vbi_format *svbi;
+ static const u16 lcr2vbi[] = {
+ 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
+ 0, V4L2_SLICED_WSS_625, 0, /* 4 */
+ V4L2_SLICED_CAPTION_525, /* 6 */
+ 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
+ 0, 0, 0, 0
+ };
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int i;
- switch (cmd) {
- case VIDIOC_G_FMT:
- {
- static u16 lcr2vbi[] = {
- 0, V4L2_SLICED_TELETEXT_B, 0, /* 1 */
- 0, V4L2_SLICED_WSS_625, 0, /* 4 */
- V4L2_SLICED_CAPTION_525, /* 6 */
- 0, 0, V4L2_SLICED_VPS, 0, 0, /* 9 */
- 0, 0, 0, 0
- };
- int is_pal = !(state->std & V4L2_STD_525_60);
- int i;
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- memset(svbi, 0, sizeof(*svbi));
- /* we're done if raw VBI is active */
- if ((cx25840_read(client, 0x404) & 0x10) == 0)
- break;
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ memset(svbi, 0, sizeof(*svbi));
+ /* we're done if raw VBI is active */
+ if ((cx25840_read(client, 0x404) & 0x10) == 0)
+ return 0;
- if (is_pal) {
- for (i = 7; i <= 23; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 7);
+ if (is_pal) {
+ for (i = 7; i <= 23; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 7);
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
- else {
- for (i = 10; i <= 21; i++) {
- u8 v = cx25840_read(client, 0x424 + i - 10);
-
- svbi->service_lines[0][i] = lcr2vbi[v >> 4];
- svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
- svbi->service_set |=
- svbi->service_lines[0][i] | svbi->service_lines[1][i];
- }
+ } else {
+ for (i = 10; i <= 21; i++) {
+ u8 v = cx25840_read(client, 0x424 + i - 10);
+
+ svbi->service_lines[0][i] = lcr2vbi[v >> 4];
+ svbi->service_lines[1][i] = lcr2vbi[v & 0xf];
+ svbi->service_set |= svbi->service_lines[0][i] |
+ svbi->service_lines[1][i];
}
- break;
}
+ return 0;
+}
- case VIDIOC_S_FMT:
- {
- int is_pal = !(state->std & V4L2_STD_525_60);
- int vbi_offset = is_pal ? 1 : 0;
- int i, x;
- u8 lcr[24];
-
- fmt = arg;
- if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
- fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
- return -EINVAL;
- svbi = &fmt->fmt.sliced;
- if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
- /* raw VBI */
- memset(svbi, 0, sizeof(*svbi));
-
- /* Setup standard */
- cx25840_std_setup(client);
-
- /* VBI Offset */
- cx25840_write(client, 0x47f, vbi_offset);
- cx25840_write(client, 0x404, 0x2e);
- break;
- }
-
- for (x = 0; x <= 23; x++)
- lcr[x] = 0x00;
+int cx25840_vbi_s_fmt(struct v4l2_subdev *sd, struct v4l2_format *fmt)
+{
+ struct i2c_client *client = v4l2_get_subdevdata(sd);
+ struct cx25840_state *state = to_state(sd);
+ struct v4l2_sliced_vbi_format *svbi;
+ int is_pal = !(state->std & V4L2_STD_525_60);
+ int vbi_offset = is_pal ? 1 : 0;
+ int i, x;
+ u8 lcr[24];
+
+ if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE &&
+ fmt->type != V4L2_BUF_TYPE_VBI_CAPTURE)
+ return -EINVAL;
+ svbi = &fmt->fmt.sliced;
+ if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
+ /* raw VBI */
+ memset(svbi, 0, sizeof(*svbi));
/* Setup standard */
cx25840_std_setup(client);
- /* Sliced VBI */
- cx25840_write(client, 0x404, 0x32); /* Ancillary data */
- cx25840_write(client, 0x406, 0x13);
+ /* VBI Offset */
cx25840_write(client, 0x47f, vbi_offset);
+ cx25840_write(client, 0x404, 0x2e);
+ return 0;
+ }
- if (is_pal) {
- for (i = 0; i <= 6; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- } else {
- for (i = 0; i <= 9; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
-
- for (i = 22; i <= 23; i++)
- svbi->service_lines[0][i] =
- svbi->service_lines[1][i] = 0;
- }
-
- for (i = 7; i <= 23; i++) {
- for (x = 0; x <= 1; x++) {
- switch (svbi->service_lines[1-x][i]) {
- case V4L2_SLICED_TELETEXT_B:
- lcr[i] |= 1 << (4 * x);
- break;
- case V4L2_SLICED_WSS_625:
- lcr[i] |= 4 << (4 * x);
- break;
- case V4L2_SLICED_CAPTION_525:
- lcr[i] |= 6 << (4 * x);
- break;
- case V4L2_SLICED_VPS:
- lcr[i] |= 9 << (4 * x);
- break;
- }
- }
- }
+ for (x = 0; x <= 23; x++)
+ lcr[x] = 0x00;
+
+ /* Setup standard */
+ cx25840_std_setup(client);
+
+ /* Sliced VBI */
+ cx25840_write(client, 0x404, 0x32); /* Ancillary data */
+ cx25840_write(client, 0x406, 0x13);
+ cx25840_write(client, 0x47f, vbi_offset);
+
+ if (is_pal) {
+ for (i = 0; i <= 6; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ } else {
+ for (i = 0; i <= 9; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+
+ for (i = 22; i <= 23; i++)
+ svbi->service_lines[0][i] =
+ svbi->service_lines[1][i] = 0;
+ }
- if (is_pal) {
- for (x = 1, i = 0x424; i <= 0x434; i++, x++) {
- cx25840_write(client, i, lcr[6 + x]);
- }
- }
- else {
- for (x = 1, i = 0x424; i <= 0x430; i++, x++) {
- cx25840_write(client, i, lcr[9 + x]);
- }
- for (i = 0x431; i <= 0x434; i++) {
- cx25840_write(client, i, 0);
+ for (i = 7; i <= 23; i++) {
+ for (x = 0; x <= 1; x++) {
+ switch (svbi->service_lines[1-x][i]) {
+ case V4L2_SLICED_TELETEXT_B:
+ lcr[i] |= 1 << (4 * x);
+ break;
+ case V4L2_SLICED_WSS_625:
+ lcr[i] |= 4 << (4 * x);
+ break;
+ case V4L2_SLICED_CAPTION_525:
+ lcr[i] |= 6 << (4 * x);
+ break;
+ case V4L2_SLICED_VPS:
+ lcr[i] |= 9 << (4 * x);
+ break;
}
}
+ }
- cx25840_write(client, 0x43c, 0x16);
-
- if (is_pal) {
- cx25840_write(client, 0x474, 0x2a);
- } else {
- cx25840_write(client, 0x474, 0x22);
- }
- break;
+ if (is_pal) {
+ for (x = 1, i = 0x424; i <= 0x434; i++, x++)
+ cx25840_write(client, i, lcr[6 + x]);
+ } else {
+ for (x = 1, i = 0x424; i <= 0x430; i++, x++)
+ cx25840_write(client, i, lcr[9 + x]);
+ for (i = 0x431; i <= 0x434; i++)
+ cx25840_write(client, i, 0);
}
- case VIDIOC_INT_DECODE_VBI_LINE:
- {
- struct v4l2_decode_vbi_line *vbi = arg;
- u8 *p = vbi->p;
- int id1, id2, l, err = 0;
+ cx25840_write(client, 0x43c, 0x16);
+ cx25840_write(client, 0x474, is_pal ? 0x2a : 0x22);
+ return 0;
+}
- if (p[0] || p[1] != 0xff || p[2] != 0xff ||
- (p[3] != 0x55 && p[3] != 0x91)) {
- vbi->line = vbi->type = 0;
- break;
- }
+int cx25840_decode_vbi_line(struct v4l2_subdev *sd, struct v4l2_decode_vbi_line *vbi)
+{
+ struct cx25840_state *state = to_state(sd);
+ u8 *p = vbi->p;
+ int id1, id2, l, err = 0;
+
+ if (p[0] || p[1] != 0xff || p[2] != 0xff ||
+ (p[3] != 0x55 && p[3] != 0x91)) {
+ vbi->line = vbi->type = 0;
+ return 0;
+ }
- p += 4;
- id1 = p[-1];
- id2 = p[0] & 0xf;
- l = p[2] & 0x3f;
- l += state->vbi_line_offset;
- p += 4;
+ p += 4;
+ id1 = p[-1];
+ id2 = p[0] & 0xf;
+ l = p[2] & 0x3f;
+ l += state->vbi_line_offset;
+ p += 4;
- switch (id2) {
- case 1:
- id2 = V4L2_SLICED_TELETEXT_B;
- break;
- case 4:
- id2 = V4L2_SLICED_WSS_625;
- break;
- case 6:
- id2 = V4L2_SLICED_CAPTION_525;
- err = !odd_parity(p[0]) || !odd_parity(p[1]);
- break;
- case 9:
- id2 = V4L2_SLICED_VPS;
- if (decode_vps(p, p) != 0) {
- err = 1;
- }
- break;
- default:
- id2 = 0;
+ switch (id2) {
+ case 1:
+ id2 = V4L2_SLICED_TELETEXT_B;
+ break;
+ case 4:
+ id2 = V4L2_SLICED_WSS_625;
+ break;
+ case 6:
+ id2 = V4L2_SLICED_CAPTION_525;
+ err = !odd_parity(p[0]) || !odd_parity(p[1]);
+ break;
+ case 9:
+ id2 = V4L2_SLICED_VPS;
+ if (decode_vps(p, p) != 0)
err = 1;
- break;
- }
-
- vbi->type = err ? 0 : id2;
- vbi->line = err ? 0 : l;
- vbi->is_second_field = err ? 0 : (id1 == 0x55);
- vbi->p = p;
break;
- }
+ default:
+ id2 = 0;
+ err = 1;
+ break;
}
+ vbi->type = err ? 0 : id2;
+ vbi->line = err ? 0 : l;
+ vbi->is_second_field = err ? 0 : (id1 == 0x55);
+ vbi->p = p;
return 0;
}
diff --git a/linux/drivers/media/video/cx88/cx88-blackbird.c b/linux/drivers/media/video/cx88/cx88-blackbird.c
index 46e009403..b62eadc71 100644
--- a/linux/drivers/media/video/cx88/cx88-blackbird.c
+++ b/linux/drivers/media/video/cx88/cx88-blackbird.c
@@ -761,7 +761,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
return -EINVAL;
strlcpy(f->description, "MPEG", sizeof(f->description));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->pixelformat = V4L2_PIX_FMT_MPEG;
return 0;
}
@@ -772,7 +771,6 @@ static int vidioc_g_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_fh *fh = priv;
struct cx8802_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */
@@ -791,7 +789,6 @@ static int vidioc_try_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_fh *fh = priv;
struct cx8802_dev *dev = fh->dev;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -808,7 +805,6 @@ static int vidioc_s_fmt_vid_cap (struct file *file, void *priv,
struct cx8802_dev *dev = fh->dev;
struct cx88_core *core = dev->core;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
f->fmt.pix.bytesperline = 0;
f->fmt.pix.sizeimage = dev->ts_packet_size * dev->ts_packet_count; /* 188 * 4 * 1024; */;
@@ -938,7 +934,7 @@ static int vidioc_log_status (struct file *file, void *priv)
snprintf(name, sizeof(name), "%s/2", core->name);
printk("%s/2: ============ START LOG STATUS ============\n",
core->name);
- cx88_call_i2c_clients(core, VIDIOC_LOG_STATUS, NULL);
+ call_all(core, core, log_status);
cx2341x_log_status(&dev->params, name);
printk("%s/2: ============= END LOG STATUS =============\n",
core->name);
@@ -993,7 +989,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
f->type = V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq;
- cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+ call_all(core, tuner, g_frequency, f);
return 0;
}
diff --git a/linux/drivers/media/video/cx88/cx88-cards.c b/linux/drivers/media/video/cx88/cx88-cards.c
index 719315d02..a170dedbf 100644
--- a/linux/drivers/media/video/cx88/cx88-cards.c
+++ b/linux/drivers/media/video/cx88/cx88-cards.c
@@ -733,6 +733,8 @@ static const struct cx88_board cx88_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ /* Some variants use a tda9874 and so need the tvaudio module. */
+ .audio_chip = V4L2_IDENT_TVAUDIO,
.input = {{
.type = CX88_VMUX_TELEVISION,
.vmux = 0,
@@ -3018,7 +3020,7 @@ static void cx88_card_setup(struct cx88_core *core)
tea5767_cfg.tuner = TUNER_TEA5767;
tea5767_cfg.priv = &ctl;
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tea5767_cfg);
+ call_all(core, tuner, s_config, &tea5767_cfg);
break;
}
case CX88_BOARD_TEVII_S420:
@@ -3043,7 +3045,7 @@ static void cx88_card_setup(struct cx88_core *core)
tun_setup.type = core->board.radio_type;
tun_setup.addr = core->board.radio_addr;
tun_setup.tuner_callback = cx88_tuner_callback;
- cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+ call_all(core, tuner, s_type_addr, &tun_setup);
mode_mask &= ~T_RADIO;
}
@@ -3053,7 +3055,7 @@ static void cx88_card_setup(struct cx88_core *core)
tun_setup.addr = core->board.tuner_addr;
tun_setup.tuner_callback = cx88_tuner_callback;
- cx88_call_i2c_clients(core, TUNER_SET_TYPE_ADDR, &tun_setup);
+ call_all(core, tuner, s_type_addr, &tun_setup);
}
if (core->board.tda9887_conf) {
@@ -3062,7 +3064,7 @@ static void cx88_card_setup(struct cx88_core *core)
tda9887_cfg.tuner = TUNER_TDA9887;
tda9887_cfg.priv = &core->board.tda9887_conf;
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &tda9887_cfg);
+ call_all(core, tuner, s_config, &tda9887_cfg);
}
if (core->board.tuner_type == TUNER_XC2028) {
@@ -3078,9 +3080,9 @@ static void cx88_card_setup(struct cx88_core *core)
xc2028_cfg.priv = &ctl;
info_printk(core, "Asking xc2028/3028 to load firmware %s\n",
ctl.fname);
- cx88_call_i2c_clients(core, TUNER_SET_CONFIG, &xc2028_cfg);
+ call_all(core, tuner, s_config, &xc2028_cfg);
}
- cx88_call_i2c_clients (core, TUNER_SET_STANDBY, NULL);
+ call_all(core, core, s_standby, 0);
}
/* ------------------------------------------------------------------ */
@@ -3160,6 +3162,8 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
int i;
core = kzalloc(sizeof(*core), GFP_KERNEL);
+ if (core == NULL)
+ return NULL;
atomic_inc(&core->refcount);
core->pci_bus = pci->bus->number;
@@ -3190,6 +3194,11 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
pci_resource_len(pci, 0));
core->bmmio = (u8 __iomem *)core->lmmio;
+ if (core->lmmio == NULL) {
+ kfree(core);
+ return NULL;
+ }
+
/* board config */
core->boardnr = UNSET;
if (card[core->nr] < ARRAY_SIZE(cx88_boards))
@@ -3228,8 +3237,36 @@ struct cx88_core *cx88_core_create(struct pci_dev *pci, int nr)
cx88_i2c_init(core, pci);
/* load tuner module, if needed */
- if (TUNER_ABSENT != core->board.tuner_type)
- request_module("tuner");
+ if (TUNER_ABSENT != core->board.tuner_type) {
+ /* Ignore 0x6b and 0x6f on cx88 boards.
+ * FusionHDTV5 RT Gold has an ir receiver at 0x6b
+ * and an RTC at 0x6f which can get corrupted if probed. */
+ static const unsigned short tv_addrs[] = {
+ 0x42, 0x43, 0x4a, 0x4b, /* tda8290 */
+ 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+ 0x68, 0x69, 0x6a, 0x6c, 0x6d, 0x6e,
+ I2C_CLIENT_END
+ };
+ int has_demod = (core->board.tda9887_conf & TDA9887_PRESENT);
+
+ /* I don't trust the radio_type as is stored in the card
+ definitions, so we just probe for it.
+ The radio_type is sometimes missing, or set to UNSET but
+ later code configures a tea5767.
+ */
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner", "tuner",
+ v4l2_i2c_tuner_addrs(ADDRS_RADIO));
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (core->board.tuner_addr == ADDR_UNSET) {
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap, "tuner",
+ "tuner", has_demod ? tv_addrs + 4 : tv_addrs);
+ } else {
+ v4l2_i2c_new_subdev(&core->i2c_adap,
+ "tuner", "tuner", core->board.tuner_addr);
+ }
+ }
cx88_card_setup(core);
cx88_ir_init(core, pci);
diff --git a/linux/drivers/media/video/cx88/cx88-core.c b/linux/drivers/media/video/cx88/cx88-core.c
index ca36a48fa..faee9d885 100644
--- a/linux/drivers/media/video/cx88/cx88-core.c
+++ b/linux/drivers/media/video/cx88/cx88-core.c
@@ -1020,7 +1020,7 @@ int cx88_set_tvnorm(struct cx88_core *core, v4l2_std_id norm)
set_tvaudio(core);
// tell i2c chips
- cx88_call_i2c_clients(core,VIDIOC_S_STD,&norm);
+ call_all(core, tuner, s_std, norm);
// done
return 0;
@@ -1088,8 +1088,13 @@ void cx88_core_put(struct cx88_core *core, struct pci_dev *pci)
mutex_lock(&devlist);
cx88_ir_fini(core);
- if (0 == core->i2c_rc)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+ if (0 == core->i2c_rc) {
+ if (core->i2c_rtc)
+ i2c_unregister_device(core->i2c_rtc);
i2c_del_adapter(&core->i2c_adap);
+ }
+#endif
list_del(&core->devlist);
iounmap(core->lmmio);
cx88_devcount--;
diff --git a/linux/drivers/media/video/cx88/cx88-dvb.c b/linux/drivers/media/video/cx88/cx88-dvb.c
index 10cf470ce..3de497312 100644
--- a/linux/drivers/media/video/cx88/cx88-dvb.c
+++ b/linux/drivers/media/video/cx88/cx88-dvb.c
@@ -1175,7 +1175,7 @@ static int dvb_register(struct cx8802_dev *dev)
fe1->dvb.frontend->ops.ts_bus_ctrl = cx88_dvb_bus_ctrl;
/* Put the analog decoder in standby to keep it quiet */
- cx88_call_i2c_clients(core, TUNER_SET_STANDBY, NULL);
+ call_all(core, core, s_standby, 0);
/* register everything */
return videobuf_dvb_register_bus(&dev->frontends, THIS_MODULE, dev,
diff --git a/linux/drivers/media/video/cx88/cx88-i2c.c b/linux/drivers/media/video/cx88/cx88-i2c.c
index 4a17a7579..718f1ce69 100644
--- a/linux/drivers/media/video/cx88/cx88-i2c.c
+++ b/linux/drivers/media/video/cx88/cx88-i2c.c
@@ -97,39 +97,6 @@ static int cx8800_bit_getsda(void *data)
/* ----------------------------------------------------------------------- */
-static int attach_inform(struct i2c_client *client)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
- struct cx88_core *core = to_core(v4l2_dev);
-
- dprintk(1, "%s i2c attach [addr=0x%x,client=%s]\n",
- client->driver->driver.name, client->addr, client->name);
- return 0;
-}
-
-static int detach_inform(struct i2c_client *client)
-{
- struct v4l2_device *v4l2_dev = i2c_get_adapdata(client->adapter);
- struct cx88_core *core = to_core(v4l2_dev);
-
- dprintk(1, "i2c detach [client=%s]\n", client->name);
- return 0;
-}
-
-void cx88_call_i2c_clients(struct cx88_core *core, unsigned int cmd, void *arg)
-{
- if (0 != core->i2c_rc)
- return;
-
- if (core->gate_ctrl)
- core->gate_ctrl(core, 1);
-
- i2c_clients_command(&core->i2c_adap, cmd, arg);
-
- if (core->gate_ctrl)
- core->gate_ctrl(core, 0);
-}
-
static const struct i2c_algo_bit_data cx8800_i2c_algo_template = {
.setsda = cx8800_bit_setsda,
.setscl = cx8800_bit_setscl,
@@ -175,17 +142,17 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
memcpy(&core->i2c_algo, &cx8800_i2c_algo_template,
sizeof(core->i2c_algo));
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
if (core->board.tuner_type != TUNER_ABSENT)
core->i2c_adap.class |= I2C_CLASS_TV_ANALOG;
if (core->board.mpeg & CX88_MPEG_DVB)
core->i2c_adap.class |= I2C_CLASS_TV_DIGITAL;
+#endif
core->i2c_adap.dev.parent = &pci->dev;
strlcpy(core->i2c_adap.name,core->name,sizeof(core->i2c_adap.name));
core->i2c_adap.owner = THIS_MODULE;
core->i2c_adap.id = I2C_HW_B_CX2388x;
- core->i2c_adap.client_register = attach_inform;
- core->i2c_adap.client_unregister = detach_inform;
core->i2c_algo.udelay = i2c_udelay;
core->i2c_algo.data = core;
i2c_set_adapdata(&core->i2c_adap, &core->v4l2_dev);
@@ -224,8 +191,6 @@ int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci)
/* ----------------------------------------------------------------------- */
-EXPORT_SYMBOL(cx88_call_i2c_clients);
-
/*
* Local variables:
* c-basic-offset: 8
diff --git a/linux/drivers/media/video/cx88/cx88-video.c b/linux/drivers/media/video/cx88/cx88-video.c
index 827168d67..ea3920c8a 100644
--- a/linux/drivers/media/video/cx88/cx88-video.c
+++ b/linux/drivers/media/video/cx88/cx88-video.c
@@ -432,8 +432,7 @@ int cx88_video_mux(struct cx88_core *core, unsigned int input)
struct v4l2_routing route;
route.input = INPUT(input).audioroute;
- cx88_call_i2c_clients(core,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ call_all(core, audio, s_routing, &route);
}
/* cx2388's C-ADC is connected to the tuner only.
When used with S-Video, that ADC is busy dealing with
@@ -1053,8 +1052,7 @@ static int video_open(struct file *file)
struct v4l2_routing route;
route.input = core->board.radio.audioroute;
- cx88_call_i2c_clients(core,
- VIDIOC_INT_S_AUDIO_ROUTING, &route);
+ call_all(core, audio, s_routing, &route);
}
/* "I2S ADC mode" */
core->tvaudio = WW_I2SADC;
@@ -1065,7 +1063,7 @@ static int video_open(struct file *file)
cx88_set_tvaudio(core);
cx88_set_stereo(core,V4L2_TUNER_MODE_STEREO,1);
}
- cx88_call_i2c_clients(core,AUDC_SET_RADIO,NULL);
+ call_all(core, tuner, s_radio);
}
unlock_kernel();
@@ -1159,7 +1157,7 @@ static int video_release(struct file *file)
kfree(fh);
if(atomic_dec_and_test(&dev->core->users))
- cx88_call_i2c_clients (dev->core, TUNER_SET_STANDBY, NULL);
+ call_all(dev->core, core, s_standby, 0);
return 0;
}
@@ -1661,7 +1659,7 @@ static int vidioc_g_frequency (struct file *file, void *priv,
f->type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
f->frequency = core->freq;
- cx88_call_i2c_clients(core,VIDIOC_G_FREQUENCY,f);
+ call_all(core, tuner, g_frequency, f);
return 0;
}
@@ -1677,7 +1675,7 @@ int cx88_set_freq (struct cx88_core *core,
mutex_lock(&core->lock);
core->freq = f->frequency;
cx88_newstation(core);
- cx88_call_i2c_clients(core,VIDIOC_S_FREQUENCY,f);
+ call_all(core, tuner, s_frequency, f);
/* When changing channels it is required to reset TVAUDIO */
msleep (10);
@@ -1759,7 +1757,7 @@ static int radio_g_tuner (struct file *file, void *priv,
strcpy(t->name, "Radio");
t->type = V4L2_TUNER_RADIO;
- cx88_call_i2c_clients(core,VIDIOC_G_TUNER,t);
+ call_all(core, tuner, g_tuner, t);
return 0;
}
@@ -1793,7 +1791,7 @@ static int radio_s_tuner (struct file *file, void *priv,
if (0 != t->index)
return -EINVAL;
- cx88_call_i2c_clients(core,VIDIOC_S_TUNER,t);
+ call_all(core, tuner, s_tuner, t);
return 0;
}
@@ -2158,12 +2156,34 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev,
/* load and configure helper modules */
if (core->board.audio_chip == V4L2_IDENT_WM8775)
- request_module("wm8775");
+ v4l2_i2c_new_subdev(&core->i2c_adap,
+ "wm8775", "wm8775", 0x36 >> 1);
+
+ if (core->board.audio_chip == V4L2_IDENT_TVAUDIO) {
+ /* This probes for a tda9874 as is used on some
+ Pixelview Ultra boards. */
+ static const unsigned short i2c_addr[] = {
+ 0xb0 >> 1, I2C_CLIENT_END
+ };
+
+ v4l2_i2c_new_probed_subdev(&core->i2c_adap,
+ "tvaudio", "tvaudio", i2c_addr);
+ }
switch (core->boardnr) {
case CX88_BOARD_DVICO_FUSIONHDTV_5_GOLD:
- case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD:
+ case CX88_BOARD_DVICO_FUSIONHDTV_7_GOLD: {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 22)
+ static struct i2c_board_info rtc_info = {
+ I2C_BOARD_INFO("isl1208", 0x6f)
+ };
+
request_module("rtc-isl1208");
+ core->i2c_rtc = i2c_new_device(&core->i2c_adap, &rtc_info);
+#else
+ request_module("rtc-isl1208");
+#endif
+ }
/* break intentionally omitted */
case CX88_BOARD_DVICO_FUSIONHDTV_5_PCI_NANO:
request_module("ir-kbd-i2c");
diff --git a/linux/drivers/media/video/cx88/cx88.h b/linux/drivers/media/video/cx88/cx88.h
index d70e26000..e7fbe8aea 100644
--- a/linux/drivers/media/video/cx88/cx88.h
+++ b/linux/drivers/media/video/cx88/cx88.h
@@ -332,6 +332,7 @@ struct cx88_core {
/* config info -- analog */
struct v4l2_device v4l2_dev;
+ struct i2c_client *i2c_rtc;
unsigned int boardnr;
struct cx88_board board;
@@ -375,6 +376,17 @@ static inline struct cx88_core *to_core(struct v4l2_device *v4l2_dev)
return container_of(v4l2_dev, struct cx88_core, v4l2_dev);
}
+#define call_all(core, o, f, args...) \
+ do { \
+ if (!core->i2c_rc) { \
+ if (core->gate_ctrl) \
+ core->gate_ctrl(core, 1); \
+ v4l2_device_call_all(&core->v4l2_dev, 0, o, f, ##args); \
+ if (core->gate_ctrl) \
+ core->gate_ctrl(core, 0); \
+ } \
+ } while (0)
+
struct cx8800_dev;
struct cx8802_dev;
@@ -637,8 +649,6 @@ extern struct videobuf_queue_ops cx8800_vbi_qops;
/* cx88-i2c.c */
extern int cx88_i2c_init(struct cx88_core *core, struct pci_dev *pci);
-extern void cx88_call_i2c_clients(struct cx88_core *core,
- unsigned int cmd, void *arg);
/* ----------------------------------------------------------- */
diff --git a/linux/drivers/media/video/dabusb.c b/linux/drivers/media/video/dabusb.c
index b399f18c1..9e9cba431 100644
--- a/linux/drivers/media/video/dabusb.c
+++ b/linux/drivers/media/video/dabusb.c
@@ -351,7 +351,7 @@ static int dabusb_loadmem (pdabusb_t s, const char *fname)
PINTEL_HEX_RECORD ptr = firmware;
#else
const struct ihex_binrec *rec;
- const struct firmware *fw;
+ const struct firmware *uninitialized_var(fw);
#endif
dbg("Enter dabusb_loadmem (internal)");
@@ -734,7 +734,7 @@ static int dabusb_release (struct inode *inode, struct file *file)
return 0;
}
-static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+static long dabusb_ioctl (struct file *file, unsigned int cmd, unsigned long arg)
{
pdabusb_t s = (pdabusb_t) file->private_data;
pbulk_transfer_t pbulk;
@@ -743,13 +743,17 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
dbg("dabusb_ioctl");
- if (s->remove_pending)
+ lock_kernel();
+ if (s->remove_pending) {
+ unlock_kernel();
return -EIO;
+ }
mutex_lock(&s->mutex);
if (!s->usbdev) {
mutex_unlock(&s->mutex);
+ unlock_kernel();
return -EIO;
}
@@ -790,6 +794,7 @@ static int dabusb_ioctl (struct inode *inode, struct file *file, unsigned int cm
break;
}
mutex_unlock(&s->mutex);
+ unlock_kernel();
return ret;
}
@@ -802,7 +807,7 @@ static struct file_operations dabusb_fops =
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = dabusb_read,
- .ioctl = dabusb_ioctl,
+ .unlocked_ioctl = dabusb_ioctl,
.open = dabusb_open,
.release = dabusb_release,
};
diff --git a/linux/drivers/media/video/em28xx/em28xx-cards.c b/linux/drivers/media/video/em28xx/em28xx-cards.c
index 6b4a204a9..56c27b745 100644
--- a/linux/drivers/media/video/em28xx/em28xx-cards.c
+++ b/linux/drivers/media/video/em28xx/em28xx-cards.c
@@ -32,6 +32,8 @@
#include <media/msp3400.h>
#include <media/saa7115.h>
#include <media/tvp5150.h>
+#include <media/tvaudio.h>
+#include <media/i2c-addr.h>
#include <media/tveeprom.h>
#include <media/v4l2-common.h>
#include <media/v4l2-chip-ident.h>
@@ -1305,6 +1307,7 @@ struct em28xx_board em28xx_boards[] = {
[EM2820_BOARD_COMPRO_VIDEOMATE_FORYOU] = {
.name = "Compro VideoMate ForYou/Stereo",
.tuner_type = TUNER_LG_PAL_NEW_TAPC,
+ .tvaudio_addr = 0xb0,
.tda9887_conf = TDA9887_PRESENT,
.decoder = EM28XX_TVP5150,
.adecoder = EM28XX_TVAUDIO,
@@ -1513,6 +1516,24 @@ static struct em28xx_hash_table em28xx_i2c_hash[] = {
{0xc51200e3, EM2820_BOARD_GADMEI_TVR200, TUNER_LG_PAL_NEW_TAPC},
};
+/* I2C possible address to saa7115, tvp5150, msp3400, tvaudio */
+static unsigned short saa711x_addrs[] = {
+ 0x4a >> 1, 0x48 >> 1, /* SAA7111, SAA7111A and SAA7113 */
+ 0x42 >> 1, 0x40 >> 1, /* SAA7114, SAA7115 and SAA7118 */
+ I2C_CLIENT_END };
+
+static unsigned short tvp5150_addrs[] = {
+ 0xb8 >> 1,
+ 0xba >> 1,
+ I2C_CLIENT_END
+};
+
+static unsigned short msp3400_addrs[] = {
+ 0x80 >> 1,
+ 0x88 >> 1,
+ I2C_CLIENT_END
+};
+
int em28xx_tuner_callback(void *ptr, int component, int command, int arg)
{
int rc = 0;
@@ -1741,31 +1762,55 @@ static void em28xx_setup_xc3028(struct em28xx *dev, struct xc2028_ctrl *ctl)
}
}
-static void em28xx_config_tuner(struct em28xx *dev)
+static void em28xx_tuner_setup(struct em28xx *dev)
{
- struct v4l2_priv_tun_config xc2028_cfg;
struct tuner_setup tun_setup;
struct v4l2_frequency f;
if (dev->tuner_type == TUNER_ABSENT)
return;
+ memset(&tun_setup, 0, sizeof(tun_setup));
+
tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = dev->tuner_type;
- tun_setup.addr = dev->tuner_addr;
tun_setup.tuner_callback = em28xx_tuner_callback;
- em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR, &tun_setup);
+ if (dev->board.radio.type) {
+ tun_setup.type = dev->board.radio.type;
+ tun_setup.addr = dev->board.radio_addr;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+ }
+
+ if ((dev->tuner_type != TUNER_ABSENT) && (dev->tuner_type)) {
+ tun_setup.type = dev->tuner_type;
+ tun_setup.addr = dev->tuner_addr;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_type_addr, &tun_setup);
+ }
+
+ if (dev->tda9887_conf) {
+ struct v4l2_priv_tun_config tda9887_cfg;
+
+ tda9887_cfg.tuner = TUNER_TDA9887;
+ tda9887_cfg.priv = &dev->tda9887_conf;
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &tda9887_cfg);
+ }
if (dev->tuner_type == TUNER_XC2028) {
+ struct v4l2_priv_tun_config xc2028_cfg;
struct xc2028_ctrl ctl;
+ memset(&xc2028_cfg, 0, sizeof(xc2028_cfg));
+ memset(&ctl, 0, sizeof(ctl));
+
em28xx_setup_xc3028(dev, &ctl);
xc2028_cfg.tuner = TUNER_XC2028;
xc2028_cfg.priv = &ctl;
- em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG, &xc2028_cfg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_config, &xc2028_cfg);
}
/* configure tuner */
@@ -1773,7 +1818,7 @@ static void em28xx_config_tuner(struct em28xx *dev)
f.type = V4L2_TUNER_ANALOG_TV;
f.frequency = 9076; /* just a magic number */
dev->ctl_freq = f.frequency;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
}
static int em28xx_hint_board(struct em28xx *dev)
@@ -1980,22 +2025,50 @@ void em28xx_card_setup(struct em28xx *dev)
if (tuner >= 0)
dev->tuner_type = tuner;
-#ifdef CONFIG_MODULES
/* request some modules */
if (dev->board.has_msp34xx)
- request_module("msp3400");
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "msp3400",
+ "msp3400", msp3400_addrs);
+
if (dev->board.decoder == EM28XX_SAA711X)
- request_module("saa7115");
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "saa7115",
+ "saa7115_auto", saa711x_addrs);
+
if (dev->board.decoder == EM28XX_TVP5150)
- request_module("tvp5150");
- if (dev->board.tuner_type != TUNER_ABSENT)
- request_module("tuner");
- if (dev->board.adecoder == EM28XX_TVAUDIO)
- request_module("tvaudio");
-#endif
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tvp5150",
+ "tvp5150", tvp5150_addrs);
- em28xx_config_tuner(dev);
+ if (dev->board.adecoder == EM28XX_TVAUDIO)
+ v4l2_i2c_new_subdev(&dev->i2c_adap, "tvaudio",
+ "tvaudio", dev->board.tvaudio_addr);
+
+ if (dev->board.tuner_type != TUNER_ABSENT) {
+ int has_demod = (dev->tda9887_conf & TDA9887_PRESENT);
+
+ if (dev->board.radio.type)
+ v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner", "tuner",
+ dev->board.radio_addr);
+
+ if (has_demod)
+ v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(ADDRS_DEMOD));
+ if (dev->tuner_addr == 0) {
+ enum v4l2_i2c_tuner_type type =
+ has_demod ? ADDRS_TV_WITH_DEMOD : ADDRS_TV;
+ struct v4l2_subdev *sd;
+
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "tuner",
+ "tuner", v4l2_i2c_tuner_addrs(type));
+
+ if (sd)
+ dev->tuner_addr = v4l2_i2c_subdev_addr(sd);
+ } else {
+ v4l2_i2c_new_subdev(&dev->i2c_adap, "tuner",
+ "tuner", dev->tuner_addr);
+ }
+ }
+ em28xx_tuner_setup(dev);
em28xx_ir_init(dev);
}
@@ -2055,6 +2128,9 @@ void em28xx_release_resources(struct em28xx *dev)
em28xx_remove_from_devlist(dev);
em28xx_i2c_unregister(dev);
+
+ v4l2_device_unregister(&dev->v4l2_dev);
+
usb_put_dev(dev->udev);
/* Mark device as unused */
@@ -2099,9 +2175,16 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
}
}
+ retval = v4l2_device_register(&dev->udev->dev, &dev->v4l2_dev);
+ if (retval < 0) {
+ em28xx_errdev("Call to v4l2_device_register() failed!\n");
+ return retval;
+ }
+
/* register i2c bus */
errCode = em28xx_i2c_register(dev);
if (errCode < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: em28xx_i2c_register - errCode [%d]!\n",
__func__, errCode);
return errCode;
@@ -2113,6 +2196,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
/* Configure audio */
errCode = em28xx_audio_setup(dev);
if (errCode < 0) {
+ v4l2_device_unregister(&dev->v4l2_dev);
em28xx_errdev("%s: Error while setting audio - errCode [%d]!\n",
__func__, errCode);
}
@@ -2160,7 +2244,7 @@ static int em28xx_init_dev(struct em28xx **devhandle, struct usb_device *udev,
em28xx_init_extension(dev);
/* Save some power by putting tuner to sleep */
- em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_standby, 0);
return 0;
@@ -2179,7 +2263,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
struct usb_device *udev;
struct usb_interface *uif;
struct em28xx *dev = NULL;
- int retval = -ENODEV;
+ int retval;
int i, nr, ifnum, isoc_pipe;
char *speed;
char descr[255] = "";
@@ -2201,7 +2285,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
interface->altsetting[0].desc.bInterfaceClass);
em28xx_devused &= ~(1<<nr);
- return -ENODEV;
+ retval = -ENODEV;
+ goto err;
}
endpoint = &interface->cur_altsetting->endpoint[0].desc;
@@ -2234,7 +2319,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
"interface not used by the driver\n");
em28xx_devused &= ~(1<<nr);
- return -ENODEV;
+ retval = -ENODEV;
+ goto err;
}
}
@@ -2277,7 +2363,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
printk(DRIVER_NAME ": Supports only %i em28xx boards.\n",
EM28XX_MAXBOARDS);
em28xx_devused &= ~(1<<nr);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
/* allocate memory for our device state and initialize it */
@@ -2285,7 +2372,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
if (dev == NULL) {
em28xx_err(DRIVER_NAME ": out of memory!\n");
em28xx_devused &= ~(1<<nr);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
snprintf(dev->name, 29, "em28xx #%d", nr);
@@ -2312,7 +2400,8 @@ static int em28xx_usb_probe(struct usb_interface *interface,
em28xx_errdev("out of memory!\n");
em28xx_devused &= ~(1<<nr);
kfree(dev);
- return -ENOMEM;
+ retval = -ENOMEM;
+ goto err;
}
for (i = 0; i < dev->num_alt ; i++) {
@@ -2331,8 +2420,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
if (retval) {
em28xx_devused &= ~(1<<dev->devno);
kfree(dev);
-
- return retval;
+ goto err;
}
/* save our data pointer in this interface device */
@@ -2346,6 +2434,9 @@ static int em28xx_usb_probe(struct usb_interface *interface,
mutex_unlock(&dev->lock);
return 0;
+
+err:
+ return retval;
}
/*
@@ -2371,6 +2462,8 @@ static void em28xx_usb_disconnect(struct usb_interface *interface)
wake_up_interruptible_all(&dev->open);
+ v4l2_device_disconnect(&dev->v4l2_dev);
+
if (dev->users) {
em28xx_warn
("device /dev/video%d is open! Deregistration and memory "
diff --git a/linux/drivers/media/video/em28xx/em28xx-core.c b/linux/drivers/media/video/em28xx/em28xx-core.c
index 4edd3870e..08eb11e72 100644
--- a/linux/drivers/media/video/em28xx/em28xx-core.c
+++ b/linux/drivers/media/video/em28xx/em28xx-core.c
@@ -1030,11 +1030,12 @@ void em28xx_wake_i2c(struct em28xx *dev)
struct v4l2_routing route;
int zero = 0;
- route.input = INPUT(dev->ctl_input)->vmux;
+ route.input = INPUT(dev->ctl_input)->vmux;
route.output = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_RESET, &zero);
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
- em28xx_i2c_call_clients(dev, VIDIOC_STREAMON, NULL);
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, reset, zero);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_stream, 0);
}
/*
diff --git a/linux/drivers/media/video/em28xx/em28xx-i2c.c b/linux/drivers/media/video/em28xx/em28xx-i2c.c
index e9abb2769..24456cebd 100644
--- a/linux/drivers/media/video/em28xx/em28xx-i2c.c
+++ b/linux/drivers/media/video/em28xx/em28xx-i2c.c
@@ -459,70 +459,15 @@ static u32 functionality(struct i2c_adapter *adap)
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 0x86:
- case 0x84:
- case 0x96:
- case 0x94:
- {
- struct v4l2_priv_tun_config tda9887_cfg;
-
- struct tuner_setup tun_setup;
-
- tun_setup.mode_mask = T_ANALOG_TV | T_RADIO;
- tun_setup.type = TUNER_TDA9887;
- tun_setup.addr = client->addr;
-
- em28xx_i2c_call_clients(dev, TUNER_SET_TYPE_ADDR,
- &tun_setup);
-
- tda9887_cfg.tuner = TUNER_TDA9887;
- tda9887_cfg.priv = &dev->tda9887_conf;
- em28xx_i2c_call_clients(dev, TUNER_SET_CONFIG,
- &tda9887_cfg);
- break;
- }
- case 0x42:
- dprintk1(1, "attach_inform: saa7114 detected.\n");
- break;
- case 0x4a:
- dprintk1(1, "attach_inform: saa7113 detected.\n");
- break;
- case 0xa0:
- dprintk1(1, "attach_inform: eeprom detected.\n");
- break;
case 0x60:
case 0x8e:
- {
- struct IR_i2c *ir = i2c_get_clientdata(client);
- dprintk1(1, "attach_inform: IR detected (%s).\n",
- ir->phys);
+ dprintk1(1, "attach_inform: IR detected (%s).\n", ir->phys);
em28xx_set_ir(dev, ir);
break;
}
- case 0x80:
- case 0x88:
- dprintk1(1, "attach_inform: msp34xx detected.\n");
- break;
- case 0xb8:
- case 0xba:
- dprintk1(1, "attach_inform: tvp5150 detected.\n");
- break;
-
- case 0xb0:
- dprintk1(1, "attach_inform: tda9874 detected\n");
- break;
-
- default:
- if (!dev->tuner_addr)
- dev->tuner_addr = client->addr;
-
- dprintk1(1, "attach inform: detected I2C address %x\n",
- client->addr << 1);
- dprintk1(1, "driver id %d\n", client->driver->id);
-
- }
return 0;
}
@@ -537,7 +482,9 @@ static struct i2c_algorithm em28xx_algo = {
static struct i2c_adapter em28xx_adap_template = {
.owner = THIS_MODULE,
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
.class = I2C_CLASS_TV_ANALOG,
+#endif
.name = "em28xx",
.id = I2C_HW_B_EM28XX,
.algo = &em28xx_algo,
@@ -598,16 +545,6 @@ void em28xx_do_i2c_scan(struct em28xx *dev)
}
/*
- * em28xx_i2c_call_clients()
- * send commands to all attached i2c devices
- */
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg)
-{
- BUG_ON(NULL == dev->i2c_adap.algo_data);
- i2c_clients_command(&dev->i2c_adap, cmd, arg);
-}
-
-/*
* em28xx_i2c_register()
* register i2c bus
*/
@@ -621,6 +558,7 @@ int em28xx_i2c_register(struct em28xx *dev)
dev->i2c_adap.dev.parent = &dev->udev->dev;
strcpy(dev->i2c_adap.name, dev->name);
dev->i2c_adap.algo_data = dev;
+ i2c_set_adapdata(&dev->i2c_adap, &dev->v4l2_dev);
retval = i2c_add_adapter(&dev->i2c_adap);
if (retval < 0) {
diff --git a/linux/drivers/media/video/em28xx/em28xx-video.c b/linux/drivers/media/video/em28xx/em28xx-video.c
index ef02999ec..f5ca05aab 100644
--- a/linux/drivers/media/video/em28xx/em28xx-video.c
+++ b/linux/drivers/media/video/em28xx/em28xx-video.c
@@ -49,7 +49,7 @@
"Sascha Sommer <saschasommer@freenet.de>"
#define DRIVER_DESC "Empia em28xx based USB video device driver"
-#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 1)
+#define EM28XX_VERSION_CODE KERNEL_VERSION(0, 1, 2)
#define em28xx_videodbg(fmt, arg...) do {\
if (video_debug) \
@@ -404,7 +404,7 @@ buffer_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size)
f.frequency = dev->ctl_freq;
f.type = fh->radio ? V4L2_TUNER_RADIO : V4L2_TUNER_ANALOG_TV;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, &f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, &f);
return 0;
}
@@ -530,25 +530,25 @@ static void video_mux(struct em28xx *dev, int index)
if (!dev->ctl_aoutput)
dev->ctl_aoutput = EM28XX_AOUT_MASTER;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_VIDEO_ROUTING, &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, s_routing, &route);
if (dev->board.has_msp34xx) {
if (dev->i2s_speed) {
- em28xx_i2c_call_clients(dev, VIDIOC_INT_I2S_CLOCK_FREQ,
- &dev->i2s_speed);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio,
+ s_i2s_clock_freq, dev->i2s_speed);
}
- route.input = dev->ctl_ainput;
+ route.input = dev->ctl_ainput;
route.output = MSP_OUTPUT(MSP_SC_IN_DSP_SCART1);
+
/* Note: this is msp3400 specific */
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
- &route);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
}
if (dev->board.adecoder != EM28XX_NOADECODER) {
- route.input = dev->ctl_ainput;
+ route.input = dev->ctl_ainput;
route.output = dev->ctl_aoutput;
- em28xx_i2c_call_clients(dev, VIDIOC_INT_S_AUDIO_ROUTING,
- &route);
+
+ v4l2_device_call_all(&dev->v4l2_dev, 0, audio, s_routing, &route);
}
em28xx_audio_analog_set(dev);
@@ -833,7 +833,7 @@ static int vidioc_s_std(struct file *file, void *priv, v4l2_std_id *norm)
get_scale(dev, dev->width, dev->height, &dev->hscale, &dev->vscale);
em28xx_resolution_set(dev);
- em28xx_i2c_call_clients(dev, VIDIOC_S_STD, &dev->norm);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_std, dev->norm);
mutex_unlock(&dev->lock);
return 0;
@@ -1005,8 +1005,9 @@ static int vidioc_queryctrl(struct file *file, void *priv,
}
}
}
+
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_QUERYCTRL, qc);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, queryctrl, qc);
mutex_unlock(&dev->lock);
if (qc->type)
@@ -1030,11 +1031,11 @@ static int vidioc_g_ctrl(struct file *file, void *priv,
mutex_lock(&dev->lock);
if (dev->board.has_msp34xx)
- em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
else {
rc = em28xx_get_ctrl(dev, ctrl);
if (rc < 0) {
- em28xx_i2c_call_clients(dev, VIDIOC_G_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_ctrl, ctrl);
rc = 0;
}
}
@@ -1058,7 +1059,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
mutex_lock(&dev->lock);
if (dev->board.has_msp34xx)
- em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
else {
rc = 1;
for (i = 0; i < ARRAY_SIZE(em28xx_qctrl); i++) {
@@ -1077,7 +1078,7 @@ static int vidioc_s_ctrl(struct file *file, void *priv,
/* Control not found - try to send it to the attached devices */
if (rc == 1) {
- em28xx_i2c_call_clients(dev, VIDIOC_S_CTRL, ctrl);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_ctrl, ctrl);
rc = 0;
}
@@ -1102,10 +1103,9 @@ static int vidioc_g_tuner(struct file *file, void *priv,
strcpy(t->name, "Tuner");
mutex_lock(&dev->lock);
-
- em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
-
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
mutex_unlock(&dev->lock);
+
return 0;
}
@@ -1124,10 +1124,9 @@ static int vidioc_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&dev->lock);
-
- em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
-
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
mutex_unlock(&dev->lock);
+
return 0;
}
@@ -1167,7 +1166,7 @@ static int vidioc_s_frequency(struct file *file, void *priv,
mutex_lock(&dev->lock);
dev->ctl_freq = f->frequency;
- em28xx_i2c_call_clients(dev, VIDIOC_S_FREQUENCY, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_frequency, f);
mutex_unlock(&dev->lock);
@@ -1196,7 +1195,7 @@ static int vidioc_g_chip_ident(struct file *file, void *priv,
chip->ident = V4L2_IDENT_NONE;
chip->revision = 0;
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_CHIP_IDENT, chip);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_chip_ident, chip);
return 0;
}
@@ -1221,7 +1220,7 @@ static int vidioc_g_register(struct file *file, void *priv,
reg->size = 1;
return 0;
case V4L2_CHIP_MATCH_I2C_DRIVER:
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_G_REGISTER, reg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, g_register, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
@@ -1273,7 +1272,7 @@ static int vidioc_s_register(struct file *file, void *priv,
return rc;
case V4L2_CHIP_MATCH_I2C_DRIVER:
- em28xx_i2c_call_clients(dev, VIDIOC_DBG_S_REGISTER, reg);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_register, reg);
return 0;
case V4L2_CHIP_MATCH_I2C_ADDR:
/* Not supported yet */
@@ -1419,13 +1418,13 @@ static int vidioc_g_fmt_sliced_vbi_cap(struct file *file, void *priv,
mutex_lock(&dev->lock);
f->fmt.sliced.service_set = 0;
-
- em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
if (f->fmt.sliced.service_set == 0)
rc = -EINVAL;
mutex_unlock(&dev->lock);
+
return rc;
}
@@ -1441,7 +1440,7 @@ static int vidioc_try_set_sliced_vbi_cap(struct file *file, void *priv,
return rc;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_G_FMT, f);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, video, g_fmt, f);
mutex_unlock(&dev->lock);
if (f->fmt.sliced.service_set == 0)
@@ -1579,7 +1578,7 @@ static int radio_g_tuner(struct file *file, void *priv,
t->type = V4L2_TUNER_RADIO;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_G_TUNER, t);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, g_tuner, t);
mutex_unlock(&dev->lock);
return 0;
@@ -1614,7 +1613,7 @@ static int radio_s_tuner(struct file *file, void *priv,
return -EINVAL;
mutex_lock(&dev->lock);
- em28xx_i2c_call_clients(dev, VIDIOC_S_TUNER, t);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_tuner, t);
mutex_unlock(&dev->lock);
return 0;
@@ -1717,7 +1716,7 @@ static int em28xx_v4l2_open(struct file *filp)
#if 0
em28xx_start_radio(dev);
#endif
- em28xx_i2c_call_clients(dev, AUDC_SET_RADIO, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, tuner, s_radio);
}
dev->users++;
@@ -1800,7 +1799,7 @@ static int em28xx_v4l2_close(struct file *filp)
}
/* Save some power by putting tuner to sleep */
- em28xx_i2c_call_clients(dev, TUNER_SET_STANDBY, NULL);
+ v4l2_device_call_all(&dev->v4l2_dev, 0, core, s_standby, 0);
/* do this before setting alternate! */
em28xx_uninit_isoc(dev);
@@ -2026,11 +2025,12 @@ static struct video_device *em28xx_vdev_init(struct em28xx *dev,
vfd = video_device_alloc();
if (NULL == vfd)
return NULL;
- *vfd = *template;
- vfd->minor = -1;
- vfd->parent = &dev->udev->dev;
- vfd->release = video_device_release;
- vfd->debug = video_debug;
+
+ *vfd = *template;
+ vfd->minor = -1;
+ vfd->v4l2_dev = &dev->v4l2_dev;
+ vfd->release = video_device_release;
+ vfd->debug = video_debug;
snprintf(vfd->name, sizeof(vfd->name), "%s %s",
dev->name, type_name);
diff --git a/linux/drivers/media/video/em28xx/em28xx.h b/linux/drivers/media/video/em28xx/em28xx.h
index c9be33aba..a9d0a865f 100644
--- a/linux/drivers/media/video/em28xx/em28xx.h
+++ b/linux/drivers/media/video/em28xx/em28xx.h
@@ -28,6 +28,7 @@
#include "compat.h"
#include <linux/videodev2.h>
#include <media/videobuf-vmalloc.h>
+#include <media/v4l2-device.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
@@ -386,6 +387,8 @@ struct em28xx_board {
unsigned int valid:1;
unsigned char xclk, i2c_speed;
+ unsigned char radio_addr;
+ unsigned short tvaudio_addr;
enum em28xx_decoder decoder;
enum em28xx_adecoder adecoder;
@@ -469,6 +472,7 @@ struct em28xx {
int devno; /* marks the number of this device */
enum em28xx_chip_id chip_id;
+ struct v4l2_device v4l2_dev;
struct em28xx_board board;
unsigned int stream_on:1; /* Locks streams */
@@ -586,11 +590,9 @@ struct em28xx_ops {
};
/* Provided by em28xx-i2c.c */
-
-void em28xx_i2c_call_clients(struct em28xx *dev, unsigned int cmd, void *arg);
void em28xx_do_i2c_scan(struct em28xx *dev);
-int em28xx_i2c_register(struct em28xx *dev);
-int em28xx_i2c_unregister(struct em28xx *dev);
+int em28xx_i2c_register(struct em28xx *dev);
+int em28xx_i2c_unregister(struct em28xx *dev);
/* Provided by em28xx-core.c */
diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c
index 88de8b865..93c35d083 100644
--- a/linux/drivers/media/video/gspca/gspca.c
+++ b/linux/drivers/media/video/gspca/gspca.c
@@ -777,7 +777,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *priv,
fmtdesc->pixelformat = fmt_tb[index];
if (gspca_is_compressed(fmt_tb[index]))
fmtdesc->flags = V4L2_FMT_FLAG_COMPRESSED;
- fmtdesc->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
fmtdesc->description[0] = fmtdesc->pixelformat & 0xff;
fmtdesc->description[1] = (fmtdesc->pixelformat >> 8) & 0xff;
fmtdesc->description[2] = (fmtdesc->pixelformat >> 16) & 0xff;
@@ -974,8 +973,6 @@ static int vidioc_querycap(struct file *file, void *priv,
struct gspca_dev *gspca_dev = priv;
int ret;
- memset(cap, 0, sizeof *cap);
-
/* protect the access to the usb device */
if (mutex_lock_interruptible(&gspca_dev->usb_lock))
return -ERESTARTSYS;
@@ -1353,7 +1350,6 @@ static int vidioc_g_parm(struct file *filp, void *priv,
{
struct gspca_dev *gspca_dev = priv;
- parm->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
parm->parm.capture.readbuffers = gspca_dev->nbufread;
if (gspca_dev->sd_desc->get_streamparm) {
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-control.c b/linux/drivers/media/video/hdpvr/hdpvr-control.c
index 51de74aeb..06791749d 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr-control.c
+++ b/linux/drivers/media/video/hdpvr/hdpvr-control.c
@@ -40,9 +40,9 @@ int hdpvr_config_call(struct hdpvr_device *dev, uint value, u8 valbuf)
dev->usbc_buf, 1, 10000);
mutex_unlock(&dev->usbc_mutex);
- dev_dbg(&dev->udev->dev,
- "config call request for value 0x%x returned %d\n", value,
- ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "config call request for value 0x%x returned %d\n", value,
+ ret);
return ret < 0 ? ret : 0;
}
@@ -57,7 +57,7 @@ struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
vidinf = kzalloc(sizeof(struct hdpvr_video_info), GFP_KERNEL);
if (!vidinf) {
- dev_err(&dev->udev->dev, "out of memory");
+ v4l2_err(&dev->v4l2_dev, "out of memory\n");
goto err;
}
@@ -78,8 +78,8 @@ struct hdpvr_video_info *get_video_info(struct hdpvr_device *dev)
if (hdpvr_debug & MSG_INFO) {
hex_dump_to_buffer(dev->usbc_buf, 5, 16, 1, print_buf,
sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev, "get video info returned: %d, %s\n",
- ret, print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get video info returned: %d, %s\n", ret, print_buf);
}
#endif
mutex_unlock(&dev->usbc_mutex);
@@ -111,9 +111,9 @@ int get_input_lines_info(struct hdpvr_device *dev)
if (hdpvr_debug & MSG_INFO) {
hex_dump_to_buffer(dev->usbc_buf, 3, 16, 1, print_buf,
sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev,
- "get input lines info returned: %d, %s\n", ret,
- print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "get input lines info returned: %d, %s\n", ret,
+ print_buf);
}
#endif
lines = dev->usbc_buf[1] << 8 | dev->usbc_buf[0];
@@ -155,8 +155,8 @@ int hdpvr_set_audio(struct hdpvr_device *dev, u8 input,
dev->usbc_buf[1] = 1;
else {
mutex_unlock(&dev->usbc_mutex);
- dev_err(&dev->udev->dev, "invalid audio codec %d\n",
- codec);
+ v4l2_err(&dev->v4l2_dev, "invalid audio codec %d\n",
+ codec);
ret = -EINVAL;
goto error;
}
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-core.c b/linux/drivers/media/video/hdpvr/hdpvr-core.c
index e96aed42d..188bd5aea 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr-core.c
+++ b/linux/drivers/media/video/hdpvr/hdpvr-core.c
@@ -125,7 +125,7 @@ static int device_authorization(struct hdpvr_device *dev)
size_t buf_size = 46;
char *print_buf = kzalloc(5*buf_size+1, GFP_KERNEL);
if (!print_buf) {
- dev_err(&dev->udev->dev, "Out of memory");
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto error;
}
#endif
@@ -138,17 +138,17 @@ static int device_authorization(struct hdpvr_device *dev)
dev->usbc_buf, 46,
10000);
if (ret != 46) {
- dev_err(&dev->udev->dev,
- "unexpected answer of status request, len %d", ret);
+ v4l2_err(&dev->v4l2_dev,
+ "unexpected answer of status request, len %d\n", ret);
goto error;
}
#ifdef HDPVR_DEBUG
else {
hex_dump_to_buffer(dev->usbc_buf, 46, 16, 1, print_buf,
sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev,
- "Status request returned, len %d: %s\n",
- ret, print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "Status request returned, len %d: %s\n",
+ ret, print_buf);
}
#endif
if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION) {
@@ -156,11 +156,11 @@ static int device_authorization(struct hdpvr_device *dev)
} else if (dev->usbc_buf[1] == HDPVR_FIRMWARE_VERSION_AC3) {
dev->flags |= HDPVR_FLAG_AC3_CAP;
} else if (dev->usbc_buf[1] > HDPVR_FIRMWARE_VERSION_AC3) {
- dev_notice(&dev->udev->dev, "untested firmware version 0x%x, "
- "the driver might not work\n", dev->usbc_buf[1]);
+ v4l2_info(&dev->v4l2_dev, "untested firmware version 0x%x, "
+ "the driver might not work\n", dev->usbc_buf[1]);
dev->flags |= HDPVR_FLAG_AC3_CAP;
} else {
- dev_err(&dev->udev->dev, "unknown firmware version 0x%x\n",
+ v4l2_err(&dev->v4l2_dev, "unknown firmware version 0x%x\n",
dev->usbc_buf[1]);
ret = -EINVAL;
goto error;
@@ -169,12 +169,14 @@ static int device_authorization(struct hdpvr_device *dev)
response = dev->usbc_buf+38;
#ifdef HDPVR_DEBUG
hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev, "challenge: %s\n", print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, "challenge: %s\n",
+ print_buf);
#endif
challenge(response);
#ifdef HDPVR_DEBUG
hex_dump_to_buffer(response, 8, 16, 1, print_buf, sizeof(print_buf), 0);
- dev_dbg(&dev->udev->dev, " response: %s\n", print_buf);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev, " response: %s\n",
+ print_buf);
#endif
msleep(100);
@@ -184,7 +186,8 @@ static int device_authorization(struct hdpvr_device *dev)
0x0000, 0x0000,
response, 8,
10000);
- dev_dbg(&dev->udev->dev, "magic request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "magic request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
retval = ret != 8;
@@ -214,12 +217,13 @@ static int hdpvr_device_init(struct hdpvr_device *dev)
CTRL_LOW_PASS_FILTER_VALUE, CTRL_DEFAULT_INDEX,
buf, 4,
1000);
- dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
vidinf = get_video_info(dev);
if (!vidinf)
- dev_dbg(&dev->udev->dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"no valid video signal or device init failed\n");
else
kfree(vidinf);
@@ -231,7 +235,8 @@ static int hdpvr_device_init(struct hdpvr_device *dev)
usb_sndctrlpipe(dev->udev, 0),
0xd4, 0x38, 0, 0, buf, 1,
1000);
- dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
/* boost analog audio */
buf[0] = boost_audio;
@@ -239,7 +244,8 @@ static int hdpvr_device_init(struct hdpvr_device *dev)
usb_sndctrlpipe(dev->udev, 0),
0xd5, 0x38, 0, 0, buf, 1,
1000);
- dev_dbg(&dev->udev->dev, "control request returned %d\n", ret);
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "control request returned %d\n", ret);
mutex_unlock(&dev->usbc_mutex);
dev->status = STATUS_IDLE;
@@ -278,12 +284,19 @@ static int hdpvr_probe(struct usb_interface *interface,
err("Out of memory");
goto error;
}
+
+ /* register v4l2_device early so it can be used for printks */
+ if (v4l2_device_register(&interface->dev, &dev->v4l2_dev)) {
+ err("v4l2_device_register failed");
+ goto error;
+ }
+
mutex_init(&dev->io_mutex);
mutex_init(&dev->i2c_mutex);
mutex_init(&dev->usbc_mutex);
dev->usbc_buf = kmalloc(64, GFP_KERNEL);
if (!dev->usbc_buf) {
- dev_err(&dev->udev->dev, "Out of memory");
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto error;
}
@@ -325,26 +338,27 @@ static int hdpvr_probe(struct usb_interface *interface,
}
if (!dev->bulk_in_endpointAddr) {
- err("Could not find bulk-in endpoint");
+ v4l2_err(&dev->v4l2_dev, "Could not find bulk-in endpoint\n");
goto error;
}
/* init the device */
if (hdpvr_device_init(dev)) {
- err("device init failed");
+ v4l2_err(&dev->v4l2_dev, "device init failed\n");
goto error;
}
mutex_lock(&dev->io_mutex);
if (hdpvr_alloc_buffers(dev, NUM_BUFFERS)) {
- err("allocating transfer buffers failed");
+ v4l2_err(&dev->v4l2_dev,
+ "allocating transfer buffers failed\n");
goto error;
}
mutex_unlock(&dev->io_mutex);
- if (hdpvr_register_videodev(dev,
+ if (hdpvr_register_videodev(dev, &interface->dev,
video_nr[atomic_inc_return(&dev_nr)])) {
- err("registering videodev failed");
+ v4l2_err(&dev->v4l2_dev, "registering videodev failed\n");
goto error;
}
@@ -352,7 +366,7 @@ static int hdpvr_probe(struct usb_interface *interface,
/* until i2c is working properly */
retval = 0; /* hdpvr_register_i2c_adapter(dev); */
if (retval < 0) {
- err("registering i2c adapter failed");
+ v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n");
goto error;
}
#endif /* CONFIG_I2C */
@@ -361,7 +375,7 @@ static int hdpvr_probe(struct usb_interface *interface,
usb_set_intfdata(interface, dev);
/* let the user know what node this device is now attached to */
- v4l2_info(dev->video_dev, "device now attached to /dev/video%d\n",
+ v4l2_info(&dev->v4l2_dev, "device now attached to /dev/video%d\n",
dev->video_dev->minor);
return 0;
@@ -387,11 +401,14 @@ static void hdpvr_disconnect(struct usb_interface *interface)
/* prevent more I/O from starting and stop any ongoing */
mutex_lock(&dev->io_mutex);
dev->status = STATUS_DISCONNECTED;
+ v4l2_device_disconnect(&dev->v4l2_dev);
video_unregister_device(dev->video_dev);
wake_up_interruptible(&dev->wait_data);
wake_up_interruptible(&dev->wait_buffer);
+ mutex_unlock(&dev->io_mutex);
msleep(100);
flush_workqueue(dev->workqueue);
+ mutex_lock(&dev->io_mutex);
hdpvr_cancel_queue(dev);
destroy_workqueue(dev->workqueue);
mutex_unlock(&dev->io_mutex);
@@ -408,9 +425,9 @@ static void hdpvr_disconnect(struct usb_interface *interface)
atomic_dec(&dev_nr);
- printk(KERN_INFO "Hauppauge HD PVR: device /dev/video%d disconnected\n",
- minor);
+ v4l2_info(&dev->v4l2_dev, "device /dev/video%d disconnected\n", minor);
+ v4l2_device_unregister(&dev->v4l2_dev);
kfree(dev->usbc_buf);
kfree(dev);
}
diff --git a/linux/drivers/media/video/hdpvr/hdpvr-video.c b/linux/drivers/media/video/hdpvr/hdpvr-video.c
index 235978003..3e6ffee8d 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr-video.c
+++ b/linux/drivers/media/video/hdpvr/hdpvr-video.c
@@ -28,6 +28,13 @@
#define BULK_URB_TIMEOUT 1250 /* 1.25 seconds */
+#define print_buffer_status() { \
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev, \
+ "%s:%d buffer stat: %d free, %d proc\n", \
+ __func__, __LINE__, \
+ list_size(&dev->free_buff_list), \
+ list_size(&dev->rec_buff_list)); }
+
struct hdpvr_fh {
struct hdpvr_device *dev;
};
@@ -117,21 +124,21 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
struct hdpvr_buffer *buf;
struct urb *urb;
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"allocating %u buffers\n", count);
for (i = 0; i < count; i++) {
buf = kzalloc(sizeof(struct hdpvr_buffer), GFP_KERNEL);
if (!buf) {
- err("cannot allocate buffer");
+ v4l2_err(&dev->v4l2_dev, "cannot allocate buffer\n");
goto exit;
}
buf->dev = dev;
urb = usb_alloc_urb(0, GFP_KERNEL);
if (!urb) {
- err("cannot allocate urb");
+ v4l2_err(&dev->v4l2_dev, "cannot allocate urb\n");
goto exit;
}
buf->urb = urb;
@@ -139,7 +146,8 @@ int hdpvr_alloc_buffers(struct hdpvr_device *dev, uint count)
mem = usb_buffer_alloc(dev->udev, dev->bulk_in_size, GFP_KERNEL,
&urb->transfer_dma);
if (!mem) {
- err("cannot allocate usb transfer buffer");
+ v4l2_err(&dev->v4l2_dev,
+ "cannot allocate usb transfer buffer\n");
goto exit;
}
@@ -172,7 +180,8 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev)
buf = list_entry(dev->free_buff_list.next, struct hdpvr_buffer,
buff_list);
if (buf->status != BUFSTAT_AVAILABLE) {
- err("buffer not marked as availbale");
+ v4l2_err(&dev->v4l2_dev,
+ "buffer not marked as availbale\n");
ret = -EFAULT;
goto err;
}
@@ -182,7 +191,9 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev)
urb->actual_length = 0;
ret = usb_submit_urb(urb, GFP_KERNEL);
if (ret) {
- err("usb_submit_urb in %s returned %d", __func__, ret);
+ v4l2_err(&dev->v4l2_dev,
+ "usb_submit_urb in %s returned %d\n",
+ __func__, ret);
if (++err_count > 2)
break;
continue;
@@ -191,10 +202,7 @@ static int hdpvr_submit_buffers(struct hdpvr_device *dev)
list_move_tail(&buf->buff_list, &dev->rec_buff_list);
}
err:
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
- "buffer queue stat: %d free, %d proc\n",
- list_size(&dev->free_buff_list),
- list_size(&dev->rec_buff_list));
+ print_buffer_status();
mutex_unlock(&dev->io_mutex);
return ret;
}
@@ -225,7 +233,7 @@ static void hdpvr_transmit_buffers(struct work_struct *work)
while (dev->status == STATUS_STREAMING) {
if (hdpvr_submit_buffers(dev)) {
- v4l2_err(dev->video_dev, "couldn't submit buffers\n");
+ v4l2_err(&dev->v4l2_dev, "couldn't submit buffers\n");
goto error;
}
if (wait_event_interruptible(dev->wait_buffer,
@@ -234,11 +242,11 @@ static void hdpvr_transmit_buffers(struct work_struct *work)
goto error;
}
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"transmit worker exited\n");
return;
error:
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"transmit buffers errored\n");
dev->status = STATUS_ERROR;
}
@@ -257,7 +265,7 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
vidinf = get_video_info(dev);
if (vidinf) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"video signal: %dx%d@%dhz\n", vidinf->width,
vidinf->height, vidinf->fps);
kfree(vidinf);
@@ -266,7 +274,7 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
ret = usb_control_msg(dev->udev,
usb_sndctrlpipe(dev->udev, 0),
0xb8, 0x38, 0x1, 0, NULL, 0, 8000);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"encoder start control request returned %d\n", ret);
hdpvr_config_call(dev, CTRL_START_STREAMING_VALUE, 0x00);
@@ -274,14 +282,14 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
INIT_WORK(&dev->worker, hdpvr_transmit_buffers);
queue_work(dev->workqueue, &dev->worker);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
"streaming started\n");
dev->status = STATUS_STREAMING;
return 0;
}
msleep(250);
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"no video signal at input %d\n", dev->options.video_input);
return -EAGAIN;
}
@@ -290,22 +298,50 @@ static int hdpvr_start_streaming(struct hdpvr_device *dev)
/* function expects dev->io_mutex to be hold by caller */
static int hdpvr_stop_streaming(struct hdpvr_device *dev)
{
+ uint actual_length, c = 0;
+ u8 *buf;
+
if (dev->status == STATUS_IDLE)
return 0;
else if (dev->status != STATUS_STREAMING)
return -EAGAIN;
+ buf = kmalloc(dev->bulk_in_size, GFP_KERNEL);
+ if (!buf)
+ v4l2_err(&dev->v4l2_dev, "failed to allocate temporary buffer "
+ "for emptying the internal device buffer. "
+ "Next capture start will be slow\n");
+
dev->status = STATUS_SHUTTING_DOWN;
hdpvr_config_call(dev, CTRL_STOP_STREAMING_VALUE, 0x00);
+ mutex_unlock(&dev->io_mutex);
wake_up_interruptible(&dev->wait_buffer);
msleep(50);
flush_workqueue(dev->workqueue);
+ mutex_lock(&dev->io_mutex);
/* kill the still outstanding urbs */
hdpvr_cancel_queue(dev);
+ /* emptying the device buffer beforeshutting it down */
+ while (buf && ++c < 500 &&
+ !usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in_endpointAddr),
+ buf, dev->bulk_in_size, &actual_length,
+ BULK_URB_TIMEOUT)) {
+ /* wait */
+ msleep(5);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "%2d: got %d bytes\n", c, actual_length);
+ }
+ kfree(buf);
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "used %d urbs to empty device buffers\n", c-1);
+ msleep(10);
+
dev->status = STATUS_IDLE;
return 0;
@@ -325,14 +361,14 @@ static int hdpvr_open(struct file *file)
dev = (struct hdpvr_device *)video_get_drvdata(video_devdata(file));
if (!dev) {
- err("open failing with with ENODEV");
+ v4l2_err(&dev->v4l2_dev, "open failing with with ENODEV\n");
retval = -ENODEV;
goto err;
}
fh = kzalloc(sizeof(struct hdpvr_fh), GFP_KERNEL);
if (!fh) {
- err("Out of memory?");
+ v4l2_err(&dev->v4l2_dev, "Out of memory\n");
goto err;
}
/* lock the device to allow correctly handling errors
@@ -391,19 +427,15 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
mutex_lock(&dev->io_mutex);
if (dev->status == STATUS_IDLE) {
if (hdpvr_start_streaming(dev)) {
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
- "start_streaming failed");
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
ret = -EIO;
msleep(200);
dev->status = STATUS_IDLE;
mutex_unlock(&dev->io_mutex);
goto err;
}
-
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
- "buffer queue stat: %d free, %d proc\n",
- list_size(&dev->free_buff_list),
- list_size(&dev->rec_buff_list));
+ print_buffer_status();
}
mutex_unlock(&dev->io_mutex);
@@ -444,7 +476,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
if (copy_to_user(buffer, urb->transfer_buffer + buf->pos,
cnt)) {
- err("read: copy_to_user failed");
+ v4l2_err(&dev->v4l2_dev, "read: copy_to_user failed\n");
if (!ret)
ret = -EFAULT;
goto err;
@@ -463,10 +495,7 @@ static ssize_t hdpvr_read(struct file *file, char __user *buffer, size_t count,
list_move_tail(&buf->buff_list, &dev->free_buff_list);
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
- "buffer queue stat: %d free, %d proc\n",
- list_size(&dev->free_buff_list),
- list_size(&dev->rec_buff_list));
+ print_buffer_status();
mutex_unlock(&dev->io_mutex);
@@ -483,6 +512,7 @@ err:
static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
{
+ struct hdpvr_buffer *buf = NULL;
struct hdpvr_fh *fh = (struct hdpvr_fh *)filp->private_data;
struct hdpvr_device *dev = fh->dev;
unsigned int mask = 0;
@@ -494,31 +524,23 @@ static unsigned int hdpvr_poll(struct file *filp, poll_table *wait)
if (dev->status == STATUS_IDLE) {
if (hdpvr_start_streaming(dev)) {
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
- "start_streaming failed");
+ v4l2_dbg(MSG_BUFFER, hdpvr_debug, &dev->v4l2_dev,
+ "start_streaming failed\n");
dev->status = STATUS_IDLE;
}
- v4l2_dbg(MSG_BUFFER, hdpvr_debug, dev->video_dev,
- "buffer queue stat: %d free, %d proc\n",
- list_size(&dev->free_buff_list),
- list_size(&dev->rec_buff_list));
+ print_buffer_status();
}
mutex_unlock(&dev->io_mutex);
- poll_wait(filp, &dev->wait_data, wait);
-
- mutex_lock(&dev->io_mutex);
- if (!list_empty(&dev->rec_buff_list)) {
-
- struct hdpvr_buffer *buf = list_entry(dev->rec_buff_list.next,
- struct hdpvr_buffer,
- buff_list);
-
- if (buf->status == BUFSTAT_READY)
- mask |= POLLIN | POLLRDNORM;
+ buf = hdpvr_get_next_buffer(dev);
+ /* only wait if no data is available */
+ if (!buf || buf->status != BUFSTAT_READY) {
+ poll_wait(filp, &dev->wait_data, wait);
+ buf = hdpvr_get_next_buffer(dev);
}
- mutex_unlock(&dev->io_mutex);
+ if (buf && buf->status == BUFSTAT_READY)
+ mask |= POLLIN | POLLRDNORM;
return mask;
}
@@ -1139,9 +1161,9 @@ static int vidioc_encoder_cmd(struct file *filp, void *priv,
res = hdpvr_stop_streaming(dev);
break;
default:
- v4l2_dbg(MSG_INFO, hdpvr_debug, dev->video_dev,
+ v4l2_dbg(MSG_INFO, hdpvr_debug, &dev->v4l2_dev,
"Unsupported encoder cmd %d\n", a->cmd);
- return -EINVAL;
+ res = -EINVAL;
}
mutex_unlock(&dev->io_mutex);
return res;
@@ -1200,22 +1222,23 @@ static const struct video_device hdpvr_video_template = {
V4L2_STD_PAL_60,
};
-int hdpvr_register_videodev(struct hdpvr_device *dev, int devnum)
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+ int devnum)
{
/* setup and register video device */
dev->video_dev = video_device_alloc();
if (!dev->video_dev) {
- err("video_device_alloc() failed");
+ v4l2_err(&dev->v4l2_dev, "video_device_alloc() failed\n");
goto error;
}
*(dev->video_dev) = hdpvr_video_template;
strcpy(dev->video_dev->name, "Hauppauge HD PVR");
- dev->video_dev->parent = &dev->udev->dev;
+ dev->video_dev->parent = parent;
video_set_drvdata(dev->video_dev, dev);
if (video_register_device(dev->video_dev, VFL_TYPE_GRABBER, devnum)) {
- err("V4L2 device registration failed");
+ v4l2_err(&dev->v4l2_dev, "video_device registration failed\n");
goto error;
}
diff --git a/linux/drivers/media/video/hdpvr/hdpvr.h b/linux/drivers/media/video/hdpvr/hdpvr.h
index 9bc8051b5..1edd87591 100644
--- a/linux/drivers/media/video/hdpvr/hdpvr.h
+++ b/linux/drivers/media/video/hdpvr/hdpvr.h
@@ -15,6 +15,8 @@
#include <linux/workqueue.h>
#include <linux/videodev2.h>
+#include <media/v4l2-device.h>
+
#define HDPVR_MAJOR_VERSION 0
#define HDPVR_MINOR_VERSION 2
#define HDPVR_RELEASE 0
@@ -65,6 +67,8 @@ struct hdpvr_device {
struct video_device *video_dev;
/* the usb device for this device */
struct usb_device *udev;
+ /* v4l2-device unused */
+ struct v4l2_device v4l2_dev;
/* the max packet size of the bulk endpoint */
size_t bulk_in_size;
@@ -284,7 +288,8 @@ int get_input_lines_info(struct hdpvr_device *dev);
/*========================================================================*/
/* v4l2 registration */
-int hdpvr_register_videodev(struct hdpvr_device *dev, int devnumber);
+int hdpvr_register_videodev(struct hdpvr_device *dev, struct device *parent,
+ int devnumber);
int hdpvr_cancel_queue(struct hdpvr_device *dev);
diff --git a/linux/drivers/media/video/ks0127.c b/linux/drivers/media/video/ks0127.c
index 3dbda6e92..a1b12557a 100644
--- a/linux/drivers/media/video/ks0127.c
+++ b/linux/drivers/media/video/ks0127.c
@@ -431,7 +431,7 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
case KS_INPUT_COMPOSITE_5:
case KS_INPUT_COMPOSITE_6:
v4l2_dbg(1, debug, sd,
- "VIDIOC_S_INPUT %d: Composite\n", route->input);
+ "s_routing %d: Composite\n", route->input);
/* autodetect 50/60 Hz */
ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
@@ -465,7 +465,7 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
case KS_INPUT_SVIDEO_2:
case KS_INPUT_SVIDEO_3:
v4l2_dbg(1, debug, sd,
- "VIDIOC_S_INPUT %d: S-Video\n", route->input);
+ "s_routing %d: S-Video\n", route->input);
/* autodetect 50/60 Hz */
ks0127_and_or(sd, KS_CMDA, 0xfc, 0x00);
/* VSE=0 */
@@ -496,7 +496,7 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
break;
case KS_INPUT_YUV656:
- v4l2_dbg(1, debug, sd, "VIDIOC_S_INPUT 15: YUV656\n");
+ v4l2_dbg(1, debug, sd, "s_routing 15: YUV656\n");
if (ks->norm & V4L2_STD_525_60)
/* force 60 Hz */
ks0127_and_or(sd, KS_CMDA, 0xfc, 0x03);
@@ -541,7 +541,7 @@ static int ks0127_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *r
default:
v4l2_dbg(1, debug, sd,
- "VIDIOC_INT_S_VIDEO_ROUTING: Unknown input %d\n", route->input);
+ "s_routing: Unknown input %d\n", route->input);
break;
}
@@ -561,23 +561,23 @@ static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
ks->norm = std;
if (std & V4L2_STD_NTSC) {
v4l2_dbg(1, debug, sd,
- "VIDIOC_S_STD: NTSC_M\n");
+ "s_std: NTSC_M\n");
ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
} else if (std & V4L2_STD_PAL_N) {
v4l2_dbg(1, debug, sd,
- "KS0127_SET_NORM: NTSC_N (fixme)\n");
+ "s_std: NTSC_N (fixme)\n");
ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
} else if (std & V4L2_STD_PAL) {
v4l2_dbg(1, debug, sd,
- "VIDIOC_S_STD: PAL_N\n");
+ "s_std: PAL_N\n");
ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x20);
} else if (std & V4L2_STD_PAL_M) {
v4l2_dbg(1, debug, sd,
- "KS0127_SET_NORM: PAL_M (fixme)\n");
+ "s_std: PAL_M (fixme)\n");
ks0127_and_or(sd, KS_CHROMA, 0x9f, 0x40);
} else if (std & V4L2_STD_SECAM) {
v4l2_dbg(1, debug, sd,
- "KS0127_SET_NORM: SECAM\n");
+ "s_std: SECAM\n");
/* set to secam autodetection */
ks0127_and_or(sd, KS_CHROMA, 0xdf, 0x20);
@@ -589,7 +589,7 @@ static int ks0127_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
/* force to secam mode */
ks0127_and_or(sd, KS_DEMOD, 0xf0, 0x0f);
} else {
- v4l2_dbg(1, debug, sd, "VIDIOC_S_STD: Unknown norm %llx\n",
+ v4l2_dbg(1, debug, sd, "s_std: Unknown norm %llx\n",
(unsigned long long)std);
}
return 0;
@@ -618,7 +618,6 @@ static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd
u8 status;
v4l2_std_id std = V4L2_STD_ALL;
- v4l2_dbg(1, debug, sd, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n");
status = ks0127_read(sd, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
stat = 0;
@@ -637,11 +636,13 @@ static int ks0127_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pstd
static int ks0127_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
+ v4l2_dbg(1, debug, sd, "querystd\n");
return ks0127_status(sd, NULL, std);
}
static int ks0127_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
+ v4l2_dbg(1, debug, sd, "g_input_status\n");
return ks0127_status(sd, status, NULL);
}
diff --git a/linux/drivers/media/video/m52790.c b/linux/drivers/media/video/m52790.c
index 982ab4268..203a60348 100644
--- a/linux/drivers/media/video/m52790.c
+++ b/linux/drivers/media/video/m52790.c
@@ -138,11 +138,6 @@ static int m52790_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int m52790_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops m52790_core_ops = {
@@ -222,7 +217,6 @@ MODULE_DEVICE_TABLE(i2c, m52790_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "m52790",
- .command = m52790_command,
.probe = m52790_probe,
.remove = m52790_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/meye.c b/linux/drivers/media/video/meye.c
index 85b2cff1a..11f0b5e0d 100644
--- a/linux/drivers/media/video/meye.c
+++ b/linux/drivers/media/video/meye.c
@@ -1261,18 +1261,13 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
if (f->index > 1)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->index == 0) {
/* standard YUV 422 capture */
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = 0;
strcpy(f->description, "YUV422");
f->pixelformat = V4L2_PIX_FMT_YUYV;
} else {
/* compressed MJPEG capture */
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strcpy(f->description, "MJPEG");
f->pixelformat = V4L2_PIX_FMT_MJPEG;
@@ -1284,9 +1279,6 @@ static int vidioc_enum_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
return -EINVAL;
@@ -1317,9 +1309,6 @@ static int vidioc_try_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
switch (meye.mchip_mode) {
case MCHIP_HIC_MODE_CONT_OUT:
default:
@@ -1343,9 +1332,6 @@ static int vidioc_g_fmt_vid_cap(struct file *file, void *fh,
static int vidioc_s_fmt_vid_cap(struct file *file, void *fh,
struct v4l2_format *f)
{
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_YUYV &&
f->fmt.pix.pixelformat != V4L2_PIX_FMT_MJPEG)
return -EINVAL;
@@ -1391,9 +1377,6 @@ static int vidioc_reqbufs(struct file *file, void *fh,
{
int i;
- if (req->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (req->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
@@ -1434,9 +1417,9 @@ static int vidioc_reqbufs(struct file *file, void *fh,
static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
- int index = buf->index;
+ unsigned int index = buf->index;
- if (index < 0 || index >= gbuffers)
+ if (index >= gbuffers)
return -EINVAL;
buf->bytesused = meye.grab_buffer[index].size;
@@ -1460,13 +1443,10 @@ static int vidioc_querybuf(struct file *file, void *fh, struct v4l2_buffer *buf)
static int vidioc_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
- if (buf->index < 0 || buf->index >= gbuffers)
+ if (buf->index >= gbuffers)
return -EINVAL;
if (meye.grab_buffer[buf->index].state != MEYE_BUF_UNUSED)
@@ -1486,9 +1466,6 @@ static int vidioc_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf)
{
int reqnr;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
diff --git a/linux/drivers/media/video/msp3400-driver.c b/linux/drivers/media/video/msp3400-driver.c
index fdcc1c1c5..fbe69a62d 100644
--- a/linux/drivers/media/video/msp3400-driver.c
+++ b/linux/drivers/media/video/msp3400-driver.c
@@ -57,7 +57,7 @@
#else
#include <linux/freezer.h>
#endif
-#include <linux/videodev.h>
+#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/v4l2-i2c-drv-legacy.h>
diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c
index e3dab2119..83f3cae47 100644
--- a/linux/drivers/media/video/mt9m001.c
+++ b/linux/drivers/media/video/mt9m001.c
@@ -207,7 +207,7 @@ static unsigned long mt9m001_query_bus_param(struct soc_camera_device *icd)
struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd);
struct soc_camera_link *icl = mt9m001->client->dev.platform_data;
/* MT9M001 has all capture_format parameters fixed */
- unsigned long flags = SOCAM_PCLK_SAMPLE_RISING |
+ unsigned long flags = SOCAM_PCLK_SAMPLE_FALLING |
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH |
SOCAM_DATA_ACTIVE_HIGH | SOCAM_MASTER;
diff --git a/linux/drivers/media/video/omap24xxcam.c b/linux/drivers/media/video/omap24xxcam.c
index 61f3c83db..d828597ba 100644
--- a/linux/drivers/media/video/omap24xxcam.c
+++ b/linux/drivers/media/video/omap24xxcam.c
@@ -1285,9 +1285,6 @@ static int vidioc_g_parm(struct file *file, void *fh,
struct omap24xxcam_device *cam = ofh->cam;
int rval;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
mutex_lock(&cam->mutex);
rval = vidioc_int_g_parm(cam->sdev, a);
mutex_unlock(&cam->mutex);
@@ -1303,9 +1300,6 @@ static int vidioc_s_parm(struct file *file, void *fh,
struct v4l2_streamparm old_streamparm;
int rval;
- if (a->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
mutex_lock(&cam->mutex);
if (cam->streaming) {
rval = -EBUSY;
diff --git a/linux/drivers/media/video/ov772x.c b/linux/drivers/media/video/ov772x.c
index cde3a1019..b17a7400d 100644
--- a/linux/drivers/media/video/ov772x.c
+++ b/linux/drivers/media/video/ov772x.c
@@ -169,11 +169,11 @@
#define GAM15 0x8C /* Gamma Curve 15th segment input end point */
#define SLOP 0x8D /* Gamma curve highest segment slope */
#define DNSTH 0x8E /* De-noise threshold */
-#define EDGE0 0x8F /* Edge enhancement control 0 */
-#define EDGE1 0x90 /* Edge enhancement control 1 */
+#define EDGE_STRNGT 0x8F /* Edge strength control when manual mode */
+#define EDGE_TRSHLD 0x90 /* Edge threshold control when manual mode */
#define DNSOFF 0x91 /* Auto De-noise threshold control */
-#define EDGE2 0x92 /* Edge enhancement strength low point control */
-#define EDGE3 0x93 /* Edge enhancement strength high point control */
+#define EDGE_UPPER 0x92 /* Edge strength upper limit when Auto mode */
+#define EDGE_LOWER 0x93 /* Edge strength lower limit when Auto mode */
#define MTX1 0x94 /* Matrix coefficient 1 */
#define MTX2 0x95 /* Matrix coefficient 2 */
#define MTX3 0x96 /* Matrix coefficient 3 */
@@ -358,6 +358,14 @@
#define VOSZ_VGA 0xF0
#define VOSZ_QVGA 0x78
+/* DSPAUTO (DSP Auto Function ON/OFF Control) */
+#define AWB_ACTRL 0x80 /* AWB auto threshold control */
+#define DENOISE_ACTRL 0x40 /* De-noise auto threshold control */
+#define EDGE_ACTRL 0x20 /* Edge enhancement auto strength control */
+#define UV_ACTRL 0x10 /* UV adjust auto slope control */
+#define SCAL0_ACTRL 0x08 /* Auto scaling factor control */
+#define SCAL1_2_ACTRL 0x04 /* Auto scaling factor control */
+
/*
* ID
*/
@@ -670,7 +678,7 @@ static int ov772x_set_bus_param(struct soc_camera_device *icd,
static unsigned long ov772x_query_bus_param(struct soc_camera_device *icd)
{
struct ov772x_priv *priv = container_of(icd, struct ov772x_priv, icd);
- struct soc_camera_link *icl = priv->client->dev.platform_data;
+ struct soc_camera_link *icl = &priv->info->link;
unsigned long flags = SOCAM_PCLK_SAMPLE_RISING | SOCAM_MASTER |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_DATA_ACTIVE_HIGH | priv->info->buswidth;
@@ -816,6 +824,53 @@ static int ov772x_set_params(struct ov772x_priv *priv, u32 width, u32 height,
ov772x_reset(priv->client);
/*
+ * Edge Ctrl
+ */
+ if (priv->info->edgectrl.strength & OV772X_MANUAL_EDGE_CTRL) {
+
+ /*
+ * Manual Edge Control Mode
+ *
+ * Edge auto strength bit is set by default.
+ * Remove it when manual mode.
+ */
+
+ ret = ov772x_mask_set(priv->client, DSPAUTO, EDGE_ACTRL, 0x00);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ ret = ov772x_mask_set(priv->client,
+ EDGE_TRSHLD, EDGE_THRESHOLD_MASK,
+ priv->info->edgectrl.threshold);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ ret = ov772x_mask_set(priv->client,
+ EDGE_STRNGT, EDGE_STRENGTH_MASK,
+ priv->info->edgectrl.strength);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ } else if (priv->info->edgectrl.upper > priv->info->edgectrl.lower) {
+ /*
+ * Auto Edge Control Mode
+ *
+ * set upper and lower limit
+ */
+ ret = ov772x_mask_set(priv->client,
+ EDGE_UPPER, EDGE_UPPER_MASK,
+ priv->info->edgectrl.upper);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+
+ ret = ov772x_mask_set(priv->client,
+ EDGE_LOWER, EDGE_LOWER_MASK,
+ priv->info->edgectrl.lower);
+ if (ret < 0)
+ goto ov772x_set_fmt_error;
+ }
+
+ /*
* set size format
*/
ret = ov772x_write_array(priv->client, priv->win->regs);
diff --git a/linux/drivers/media/video/ovcamchip/ovcamchip_core.c b/linux/drivers/media/video/ovcamchip/ovcamchip_core.c
index 63303b70f..8de129b41 100644
--- a/linux/drivers/media/video/ovcamchip/ovcamchip_core.c
+++ b/linux/drivers/media/video/ovcamchip/ovcamchip_core.c
@@ -335,11 +335,6 @@ static long ovcamchip_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
}
}
-static int ovcamchip_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops ovcamchip_core_ops = {
@@ -409,7 +404,6 @@ MODULE_DEVICE_TABLE(i2c, ovcamchip_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "ovcamchip",
- .command = ovcamchip_command,
.probe = ovcamchip_probe,
.remove = ovcamchip_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/pvrusb2/Makefile b/linux/drivers/media/video/pvrusb2/Makefile
index a4478618a..de2fc14f0 100644
--- a/linux/drivers/media/video/pvrusb2/Makefile
+++ b/linux/drivers/media/video/pvrusb2/Makefile
@@ -10,6 +10,7 @@ pvrusb2-objs := pvrusb2-i2c-core.o \
pvrusb2-ctrl.o pvrusb2-std.o pvrusb2-devattr.o \
pvrusb2-context.o pvrusb2-io.o pvrusb2-ioread.o \
pvrusb2-cx2584x-v4l.o pvrusb2-wm8775.o \
+ pvrusb2-cs53l32a.o \
$(obj-pvrusb2-dvb-y) \
$(obj-pvrusb2-sysfs-y) $(obj-pvrusb2-debugifc-y)
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 5fa8af50b..77360a385 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -138,14 +138,12 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *cptr)
int pvr2_ctrl_get_def(struct pvr2_ctrl *cptr, int *valptr)
{
int ret = 0;
- if (!cptr) return 0;
+ if (!cptr) return -EINVAL;
LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
- if (cptr->info->get_def_value) {
- ret = cptr->info->get_def_value(cptr, valptr);
- } else {
- *valptr = cptr->info->default_value;
- }
+ if (cptr->info->get_def_value) {
+ ret = cptr->info->get_def_value(cptr, valptr);
+ } else {
+ *valptr = cptr->info->default_value;
}
} while(0); LOCK_GIVE(cptr->hdw->big_lock);
return ret;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index bea17cd64..def29ddb3 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -2948,6 +2948,7 @@ static void pvr2_subdev_update(struct pvr2_hdw *hdw)
pvr2_trace(PVR2_TRACE_CHIPS, "subdev tuner set_type(%d)",
hdw->tuner_type);
if (((int)(hdw->tuner_type)) >= 0) {
+ memset(&setup, 0, sizeof(setup));
setup.addr = ADDR_UNSET;
setup.type = hdw->tuner_type;
setup.mode_mask = T_RADIO | T_ANALOG_TV;
diff --git a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
index 84379d6e0..7ed3b8453 100644
--- a/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
+++ b/linux/drivers/media/video/pvrusb2/pvrusb2-sysfs.c
@@ -154,14 +154,16 @@ static ssize_t show_def(struct device *class_dev,
struct pvr2_sysfs_ctl_item *cip;
int val;
int ret;
+ unsigned int cnt = 0;
cip = container_of(attr, struct pvr2_sysfs_ctl_item, attr_def);
ret = pvr2_ctrl_get_def(cip->cptr, &val);
- pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %d, stat=%d",
- cip->chptr, cip->ctl_id, val, ret);
- if (ret < 0) {
- return ret;
- }
- return scnprintf(buf, PAGE_SIZE, "%d\n", val);
+ if (ret < 0) return ret;
+ ret = pvr2_ctrl_value_to_sym(cip->cptr, ~0, val,
+ buf, PAGE_SIZE - 1, &cnt);
+ pvr2_sysfs_trace("pvr2_sysfs(%p) show_def(cid=%d) is %.*s (%d)",
+ cip->chptr, cip->ctl_id, cnt, buf, val);
+ buf[cnt] = '\n';
+ return cnt + 1;
}
static ssize_t show_val_norm(struct device *class_dev,
diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c
index d1aa540ba..98825d631 100644
--- a/linux/drivers/media/video/pxa_camera.c
+++ b/linux/drivers/media/video/pxa_camera.c
@@ -173,6 +173,13 @@
CICR0_EOFM | CICR0_FOM)
/*
+ * YUV422P picture size should be a multiple of 16, so the heuristic aligns
+ * height, width on 4 byte boundaries to reach the 16 multiple for the size.
+ */
+#define YUV422P_X_Y_ALIGN 4
+#define YUV422P_SIZE_ALIGN YUV422P_X_Y_ALIGN * YUV422P_X_Y_ALIGN
+
+/*
* Structures
*/
enum pxa_camera_active_dma {
@@ -246,20 +253,11 @@ static int pxa_videobuf_setup(struct videobuf_queue *vq, unsigned int *count,
unsigned int *size)
{
struct soc_camera_device *icd = vq->priv_data;
- struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
- struct pxa_camera_dev *pcdev = ici->priv;
dev_dbg(&icd->dev, "count=%d, size=%d\n", *count, *size);
- /* planar capture requires Y, U and V buffers to be page aligned */
- if (pcdev->channels == 3) {
- *size = PAGE_ALIGN(icd->width * icd->height); /* Y pages */
- *size += PAGE_ALIGN(icd->width * icd->height / 2); /* U pages */
- *size += PAGE_ALIGN(icd->width * icd->height / 2); /* V pages */
- } else {
- *size = icd->width * icd->height *
- ((icd->current_fmt->depth + 7) >> 3);
- }
+ *size = roundup(icd->width * icd->height *
+ ((icd->current_fmt->depth + 7) >> 3), 8);
if (0 == *count)
*count = 32;
@@ -299,19 +297,63 @@ static void free_buffer(struct videobuf_queue *vq, struct pxa_buffer *buf)
buf->vb.state = VIDEOBUF_NEEDS_INIT;
}
+static int calculate_dma_sglen(struct scatterlist *sglist, int sglen,
+ int sg_first_ofs, int size)
+{
+ int i, offset, dma_len, xfer_len;
+ struct scatterlist *sg;
+
+ offset = sg_first_ofs;
+ for_each_sg(sglist, sg, sglen, i) {
+ dma_len = sg_dma_len(sg);
+
+ /* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
+ xfer_len = roundup(min(dma_len - offset, size), 8);
+
+ size = max(0, size - xfer_len);
+ offset = 0;
+ if (size == 0)
+ break;
+ }
+
+ BUG_ON(size != 0);
+ return i + 1;
+}
+
+/**
+ * pxa_init_dma_channel - init dma descriptors
+ * @pcdev: pxa camera device
+ * @buf: pxa buffer to find pxa dma channel
+ * @dma: dma video buffer
+ * @channel: dma channel (0 => 'Y', 1 => 'U', 2 => 'V')
+ * @cibr: camera Receive Buffer Register
+ * @size: bytes to transfer
+ * @sg_first: first element of sg_list
+ * @sg_first_ofs: offset in first element of sg_list
+ *
+ * Prepares the pxa dma descriptors to transfer one camera channel.
+ * Beware sg_first and sg_first_ofs are both input and output parameters.
+ *
+ * Returns 0 or -ENOMEM if no coherent memory is available
+ */
static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
struct pxa_buffer *buf,
struct videobuf_dmabuf *dma, int channel,
- int sglen, int sg_start, int cibr,
- unsigned int size)
+ int cibr, int size,
+ struct scatterlist **sg_first, int *sg_first_ofs)
{
struct pxa_cam_dma *pxa_dma = &buf->dmas[channel];
- int i;
+ struct scatterlist *sg;
+ int i, offset, sglen;
+ int dma_len = 0, xfer_len = 0;
if (pxa_dma->sg_cpu)
dma_free_coherent(pcdev->dev, pxa_dma->sg_size,
pxa_dma->sg_cpu, pxa_dma->sg_dma);
+ sglen = calculate_dma_sglen(*sg_first, dma->sglen,
+ *sg_first_ofs, size);
+
pxa_dma->sg_size = (sglen + 1) * sizeof(struct pxa_dma_desc);
pxa_dma->sg_cpu = dma_alloc_coherent(pcdev->dev, pxa_dma->sg_size,
&pxa_dma->sg_dma, GFP_KERNEL);
@@ -319,31 +361,75 @@ static int pxa_init_dma_channel(struct pxa_camera_dev *pcdev,
return -ENOMEM;
pxa_dma->sglen = sglen;
+ offset = *sg_first_ofs;
- for (i = 0; i < sglen; i++) {
- int sg_i = sg_start + i;
- struct scatterlist *sg = dma->sglist;
- unsigned int dma_len = sg_dma_len(&sg[sg_i]), xfer_len;
+ dev_dbg(pcdev->dev, "DMA: sg_first=%p, sglen=%d, ofs=%d, dma.desc=%x\n",
+ *sg_first, sglen, *sg_first_ofs, pxa_dma->sg_dma);
- pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
- pxa_dma->sg_cpu[i].dtadr = sg_dma_address(&sg[sg_i]);
+
+ for_each_sg(*sg_first, sg, sglen, i) {
+ dma_len = sg_dma_len(sg);
/* PXA27x Developer's Manual 27.4.4.1: round up to 8 bytes */
- xfer_len = (min(dma_len, size) + 7) & ~7;
+ xfer_len = roundup(min(dma_len - offset, size), 8);
+ size = max(0, size - xfer_len);
+
+ pxa_dma->sg_cpu[i].dsadr = pcdev->res->start + cibr;
+ pxa_dma->sg_cpu[i].dtadr = sg_dma_address(sg) + offset;
pxa_dma->sg_cpu[i].dcmd =
DCMD_FLOWSRC | DCMD_BURST8 | DCMD_INCTRGADDR | xfer_len;
- size -= dma_len;
+#ifdef DEBUG
+ if (!i)
+ pxa_dma->sg_cpu[i].dcmd |= DCMD_STARTIRQEN;
+#endif
pxa_dma->sg_cpu[i].ddadr =
pxa_dma->sg_dma + (i + 1) * sizeof(struct pxa_dma_desc);
+
+ dev_vdbg(pcdev->dev, "DMA: desc.%08x->@phys=0x%08x, len=%d\n",
+ pxa_dma->sg_dma + i * sizeof(struct pxa_dma_desc),
+ sg_dma_address(sg) + offset, xfer_len);
+ offset = 0;
+
+ if (size == 0)
+ break;
}
- pxa_dma->sg_cpu[sglen - 1].ddadr = DDADR_STOP;
- pxa_dma->sg_cpu[sglen - 1].dcmd |= DCMD_ENDIRQEN;
+ pxa_dma->sg_cpu[sglen].ddadr = DDADR_STOP;
+ pxa_dma->sg_cpu[sglen].dcmd = DCMD_FLOWSRC | DCMD_BURST8 | DCMD_ENDIRQEN;
+
+ /*
+ * Handle 1 special case :
+ * - in 3 planes (YUV422P format), we might finish with xfer_len equal
+ * to dma_len (end on PAGE boundary). In this case, the sg element
+ * for next plane should be the next after the last used to store the
+ * last scatter gather RAM page
+ */
+ if (xfer_len >= dma_len) {
+ *sg_first_ofs = xfer_len - dma_len;
+ *sg_first = sg_next(sg);
+ } else {
+ *sg_first_ofs = xfer_len;
+ *sg_first = sg;
+ }
return 0;
}
+static void pxa_videobuf_set_actdma(struct pxa_camera_dev *pcdev,
+ struct pxa_buffer *buf)
+{
+ buf->active_dma = DMA_Y;
+ if (pcdev->channels == 3)
+ buf->active_dma |= DMA_U | DMA_V;
+}
+
+/*
+ * Please check the DMA prepared buffer structure in :
+ * Documentation/video4linux/pxa_camera.txt
+ * Please check also in pxa_camera_check_link_miss() to understand why DMA chain
+ * modification while DMA chain is running will work anyway.
+ */
static int pxa_videobuf_prepare(struct videobuf_queue *vq,
struct videobuf_buffer *vb, enum v4l2_field field)
{
@@ -352,7 +438,6 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
struct pxa_camera_dev *pcdev = ici->priv;
struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
int ret;
- int sglen_y, sglen_yu = 0, sglen_u = 0, sglen_v = 0;
int size_y, size_u = 0, size_v = 0;
dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
@@ -391,62 +476,58 @@ static int pxa_videobuf_prepare(struct videobuf_queue *vq,
}
if (vb->state == VIDEOBUF_NEEDS_INIT) {
- unsigned int size = vb->size;
+ int size = vb->size;
+ int next_ofs = 0;
struct videobuf_dmabuf *dma = videobuf_to_dma(vb);
+ struct scatterlist *sg;
ret = videobuf_iolock(vq, vb, NULL);
if (ret)
goto fail;
if (pcdev->channels == 3) {
- /* FIXME the calculations should be more precise */
- sglen_y = dma->sglen / 2;
- sglen_u = sglen_v = dma->sglen / 4 + 1;
- sglen_yu = sglen_y + sglen_u;
size_y = size / 2;
size_u = size_v = size / 4;
} else {
- sglen_y = dma->sglen;
size_y = size;
}
- /* init DMA for Y channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 0, sglen_y,
- 0, 0x28, size_y);
+ sg = dma->sglist;
+ /* init DMA for Y channel */
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 0, CIBR0, size_y,
+ &sg, &next_ofs);
if (ret) {
dev_err(pcdev->dev,
"DMA initialization for Y/RGB failed\n");
goto fail;
}
- if (pcdev->channels == 3) {
- /* init DMA for U channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 1, sglen_u,
- sglen_y, 0x30, size_u);
- if (ret) {
- dev_err(pcdev->dev,
- "DMA initialization for U failed\n");
- goto fail_u;
- }
-
- /* init DMA for V channel */
- ret = pxa_init_dma_channel(pcdev, buf, dma, 2, sglen_v,
- sglen_yu, 0x38, size_v);
- if (ret) {
- dev_err(pcdev->dev,
- "DMA initialization for V failed\n");
- goto fail_v;
- }
+ /* init DMA for U channel */
+ if (size_u)
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 1, CIBR1,
+ size_u, &sg, &next_ofs);
+ if (ret) {
+ dev_err(pcdev->dev,
+ "DMA initialization for U failed\n");
+ goto fail_u;
+ }
+
+ /* init DMA for V channel */
+ if (size_v)
+ ret = pxa_init_dma_channel(pcdev, buf, dma, 2, CIBR2,
+ size_v, &sg, &next_ofs);
+ if (ret) {
+ dev_err(pcdev->dev,
+ "DMA initialization for V failed\n");
+ goto fail_v;
}
vb->state = VIDEOBUF_PREPARED;
}
buf->inwork = 0;
- buf->active_dma = DMA_Y;
- if (pcdev->channels == 3)
- buf->active_dma |= DMA_U | DMA_V;
+ pxa_videobuf_set_actdma(pcdev, buf);
return 0;
@@ -463,6 +544,92 @@ out:
return ret;
}
+/**
+ * pxa_dma_start_channels - start DMA channel for active buffer
+ * @pcdev: pxa camera device
+ *
+ * Initialize DMA channels to the beginning of the active video buffer, and
+ * start these channels.
+ */
+static void pxa_dma_start_channels(struct pxa_camera_dev *pcdev)
+{
+ int i;
+ struct pxa_buffer *active;
+
+ active = pcdev->active;
+
+ for (i = 0; i < pcdev->channels; i++) {
+ dev_dbg(pcdev->dev, "%s (channel=%d) ddadr=%08x\n", __func__,
+ i, active->dmas[i].sg_dma);
+ DDADR(pcdev->dma_chans[i]) = active->dmas[i].sg_dma;
+ DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
+ }
+}
+
+static void pxa_dma_stop_channels(struct pxa_camera_dev *pcdev)
+{
+ int i;
+
+ for (i = 0; i < pcdev->channels; i++) {
+ dev_dbg(pcdev->dev, "%s (channel=%d)\n", __func__, i);
+ DCSR(pcdev->dma_chans[i]) = 0;
+ }
+}
+
+static void pxa_dma_add_tail_buf(struct pxa_camera_dev *pcdev,
+ struct pxa_buffer *buf)
+{
+ int i;
+ struct pxa_dma_desc *buf_last_desc;
+
+ for (i = 0; i < pcdev->channels; i++) {
+ buf_last_desc = buf->dmas[i].sg_cpu + buf->dmas[i].sglen;
+ buf_last_desc->ddadr = DDADR_STOP;
+
+ if (pcdev->sg_tail[i])
+ /* Link the new buffer to the old tail */
+ pcdev->sg_tail[i]->ddadr = buf->dmas[i].sg_dma;
+
+ /* Update the channel tail */
+ pcdev->sg_tail[i] = buf_last_desc;
+ }
+}
+
+/**
+ * pxa_camera_start_capture - start video capturing
+ * @pcdev: camera device
+ *
+ * Launch capturing. DMA channels should not be active yet. They should get
+ * activated at the end of frame interrupt, to capture only whole frames, and
+ * never begin the capture of a partial frame.
+ */
+static void pxa_camera_start_capture(struct pxa_camera_dev *pcdev)
+{
+ unsigned long cicr0, cifr;
+
+ dev_dbg(pcdev->dev, "%s\n", __func__);
+ /* Reset the FIFOs */
+ cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
+ __raw_writel(cifr, pcdev->base + CIFR);
+ /* Enable End-Of-Frame Interrupt */
+ cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
+ cicr0 &= ~CICR0_EOFM;
+ __raw_writel(cicr0, pcdev->base + CICR0);
+}
+
+static void pxa_camera_stop_capture(struct pxa_camera_dev *pcdev)
+{
+ unsigned long cicr0;
+
+ pxa_dma_stop_channels(pcdev);
+
+ cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
+ __raw_writel(cicr0, pcdev->base + CICR0);
+
+ pcdev->active = NULL;
+ dev_dbg(pcdev->dev, "%s\n", __func__);
+}
+
static void pxa_videobuf_queue(struct videobuf_queue *vq,
struct videobuf_buffer *vb)
{
@@ -470,81 +637,20 @@ static void pxa_videobuf_queue(struct videobuf_queue *vq,
struct soc_camera_host *ici = to_soc_camera_host(icd->dev.parent);
struct pxa_camera_dev *pcdev = ici->priv;
struct pxa_buffer *buf = container_of(vb, struct pxa_buffer, vb);
- struct pxa_buffer *active;
unsigned long flags;
- int i;
- dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
+ dev_dbg(&icd->dev, "%s (vb=0x%p) 0x%08lx %d active=%p\n", __func__,
+ vb, vb->baddr, vb->bsize, pcdev->active);
+
spin_lock_irqsave(&pcdev->lock, flags);
list_add_tail(&vb->queue, &pcdev->capture);
vb->state = VIDEOBUF_ACTIVE;
- active = pcdev->active;
+ pxa_dma_add_tail_buf(pcdev, buf);
- if (!active) {
- unsigned long cifr, cicr0;
-
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
-
- for (i = 0; i < pcdev->channels; i++) {
- DDADR(pcdev->dma_chans[i]) = buf->dmas[i].sg_dma;
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- pcdev->sg_tail[i] = buf->dmas[i].sg_cpu + buf->dmas[i].sglen - 1;
- }
-
- pcdev->active = buf;
-
- cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
- } else {
- struct pxa_cam_dma *buf_dma;
- struct pxa_cam_dma *act_dma;
- int nents;
-
- for (i = 0; i < pcdev->channels; i++) {
- buf_dma = &buf->dmas[i];
- act_dma = &active->dmas[i];
- nents = buf_dma->sglen;
-
- /* Stop DMA engine */
- DCSR(pcdev->dma_chans[i]) = 0;
-
- /* Add the descriptors we just initialized to
- the currently running chain */
- pcdev->sg_tail[i]->ddadr = buf_dma->sg_dma;
- pcdev->sg_tail[i] = buf_dma->sg_cpu + buf_dma->sglen - 1;
-
- /* Setup a dummy descriptor with the DMA engines current
- * state
- */
- buf_dma->sg_cpu[nents].dsadr =
- pcdev->res->start + 0x28 + i*8; /* CIBRx */
- buf_dma->sg_cpu[nents].dtadr =
- DTADR(pcdev->dma_chans[i]);
- buf_dma->sg_cpu[nents].dcmd =
- DCMD(pcdev->dma_chans[i]);
-
- if (DDADR(pcdev->dma_chans[i]) == DDADR_STOP) {
- /* The DMA engine is on the last
- descriptor, set the next descriptors
- address to the descriptors we just
- initialized */
- buf_dma->sg_cpu[nents].ddadr = buf_dma->sg_dma;
- } else {
- buf_dma->sg_cpu[nents].ddadr =
- DDADR(pcdev->dma_chans[i]);
- }
-
- /* The next descriptor is the dummy descriptor */
- DDADR(pcdev->dma_chans[i]) = buf_dma->sg_dma + nents *
- sizeof(struct pxa_dma_desc);
-
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- }
- }
+ if (!pcdev->active)
+ pxa_camera_start_capture(pcdev);
spin_unlock_irqrestore(&pcdev->lock, flags);
}
@@ -582,7 +688,7 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
struct videobuf_buffer *vb,
struct pxa_buffer *buf)
{
- unsigned long cicr0;
+ int i;
/* _init is used to debug races, see comment in pxa_camera_reqbufs() */
list_del_init(&vb->queue);
@@ -590,15 +696,12 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
do_gettimeofday(&vb->ts);
vb->field_count++;
wake_up(&vb->done);
+ dev_dbg(pcdev->dev, "%s dequeud buffer (vb=0x%p)\n", __func__, vb);
if (list_empty(&pcdev->capture)) {
- pcdev->active = NULL;
- DCSR(pcdev->dma_chans[0]) = 0;
- DCSR(pcdev->dma_chans[1]) = 0;
- DCSR(pcdev->dma_chans[2]) = 0;
-
- cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
+ pxa_camera_stop_capture(pcdev);
+ for (i = 0; i < pcdev->channels; i++)
+ pcdev->sg_tail[i] = NULL;
return;
}
@@ -606,6 +709,35 @@ static void pxa_camera_wakeup(struct pxa_camera_dev *pcdev,
struct pxa_buffer, vb.queue);
}
+/**
+ * pxa_camera_check_link_miss - check missed DMA linking
+ * @pcdev: camera device
+ *
+ * The DMA chaining is done with DMA running. This means a tiny temporal window
+ * remains, where a buffer is queued on the chain, while the chain is already
+ * stopped. This means the tailed buffer would never be transfered by DMA.
+ * This function restarts the capture for this corner case, where :
+ * - DADR() == DADDR_STOP
+ * - a videobuffer is queued on the pcdev->capture list
+ *
+ * Please check the "DMA hot chaining timeslice issue" in
+ * Documentation/video4linux/pxa_camera.txt
+ *
+ * Context: should only be called within the dma irq handler
+ */
+static void pxa_camera_check_link_miss(struct pxa_camera_dev *pcdev)
+{
+ int i, is_dma_stopped = 1;
+
+ for (i = 0; i < pcdev->channels; i++)
+ if (DDADR(pcdev->dma_chans[i]) != DDADR_STOP)
+ is_dma_stopped = 0;
+ dev_dbg(pcdev->dev, "%s : top queued buffer=%p, dma_stopped=%d\n",
+ __func__, pcdev->active, is_dma_stopped);
+ if (pcdev->active && is_dma_stopped)
+ pxa_camera_start_capture(pcdev);
+}
+
static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
enum pxa_camera_active_dma act_dma)
{
@@ -613,61 +745,70 @@ static void pxa_camera_dma_irq(int channel, struct pxa_camera_dev *pcdev,
unsigned long flags;
u32 status, camera_status, overrun;
struct videobuf_buffer *vb;
- unsigned long cifr, cicr0;
spin_lock_irqsave(&pcdev->lock, flags);
status = DCSR(channel);
- DCSR(channel) = status | DCSR_ENDINTR;
+ DCSR(channel) = status;
+
+ camera_status = __raw_readl(pcdev->base + CISR);
+ overrun = CISR_IFO_0;
+ if (pcdev->channels == 3)
+ overrun |= CISR_IFO_1 | CISR_IFO_2;
if (status & DCSR_BUSERR) {
dev_err(pcdev->dev, "DMA Bus Error IRQ!\n");
goto out;
}
- if (!(status & DCSR_ENDINTR)) {
+ if (!(status & (DCSR_ENDINTR | DCSR_STARTINTR))) {
dev_err(pcdev->dev, "Unknown DMA IRQ source, "
"status: 0x%08x\n", status);
goto out;
}
- if (!pcdev->active) {
- dev_err(pcdev->dev, "DMA End IRQ with no active buffer!\n");
- goto out;
- }
-
- camera_status = __raw_readl(pcdev->base + CISR);
- overrun = CISR_IFO_0;
- if (pcdev->channels == 3)
- overrun |= CISR_IFO_1 | CISR_IFO_2;
- if (camera_status & overrun) {
- dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n", camera_status);
- /* Stop the Capture Interface */
- cicr0 = __raw_readl(pcdev->base + CICR0) & ~CICR0_ENB;
- __raw_writel(cicr0, pcdev->base + CICR0);
-
- /* Stop DMA */
- DCSR(channel) = 0;
- /* Reset the FIFOs */
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
- /* Enable End-Of-Frame Interrupt */
- cicr0 &= ~CICR0_EOFM;
- __raw_writel(cicr0, pcdev->base + CICR0);
- /* Restart the Capture Interface */
- __raw_writel(cicr0 | CICR0_ENB, pcdev->base + CICR0);
+ /*
+ * pcdev->active should not be NULL in DMA irq handler.
+ *
+ * But there is one corner case : if capture was stopped due to an
+ * overrun of channel 1, and at that same channel 2 was completed.
+ *
+ * When handling the overrun in DMA irq for channel 1, we'll stop the
+ * capture and restart it (and thus set pcdev->active to NULL). But the
+ * DMA irq handler will already be pending for channel 2. So on entering
+ * the DMA irq handler for channel 2 there will be no active buffer, yet
+ * that is normal.
+ */
+ if (!pcdev->active)
goto out;
- }
vb = &pcdev->active->vb;
buf = container_of(vb, struct pxa_buffer, vb);
WARN_ON(buf->inwork || list_empty(&vb->queue));
- dev_dbg(pcdev->dev, "%s (vb=0x%p) 0x%08lx %d\n", __func__,
- vb, vb->baddr, vb->bsize);
- buf->active_dma &= ~act_dma;
- if (!buf->active_dma)
- pxa_camera_wakeup(pcdev, vb, buf);
+ dev_dbg(pcdev->dev, "%s channel=%d %s%s(vb=0x%p) dma.desc=%x\n",
+ __func__, channel, status & DCSR_STARTINTR ? "SOF " : "",
+ status & DCSR_ENDINTR ? "EOF " : "", vb, DDADR(channel));
+
+ if (status & DCSR_ENDINTR) {
+ /*
+ * It's normal if the last frame creates an overrun, as there
+ * are no more DMA descriptors to fetch from QCI fifos
+ */
+ if (camera_status & overrun &&
+ !list_is_last(pcdev->capture.next, &pcdev->capture)) {
+ dev_dbg(pcdev->dev, "FIFO overrun! CISR: %x\n",
+ camera_status);
+ pxa_camera_stop_capture(pcdev);
+ pxa_camera_start_capture(pcdev);
+ goto out;
+ }
+ buf->active_dma &= ~act_dma;
+ if (!buf->active_dma) {
+ pxa_camera_wakeup(pcdev, vb, buf);
+ pxa_camera_check_link_miss(pcdev);
+ }
+ }
out:
spin_unlock_irqrestore(&pcdev->lock, flags);
@@ -796,6 +937,8 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
{
struct pxa_camera_dev *pcdev = data;
unsigned long status, cicr0;
+ struct pxa_buffer *buf;
+ struct videobuf_buffer *vb;
status = __raw_readl(pcdev->base + CISR);
dev_dbg(pcdev->dev, "Camera interrupt status 0x%lx\n", status);
@@ -806,12 +949,14 @@ static irqreturn_t pxa_camera_irq(int irq, void *data)
__raw_writel(status, pcdev->base + CISR);
if (status & CISR_EOF) {
- int i;
- for (i = 0; i < pcdev->channels; i++) {
- DDADR(pcdev->dma_chans[i]) =
- pcdev->active->dmas[i].sg_dma;
- DCSR(pcdev->dma_chans[i]) = DCSR_RUN;
- }
+ pcdev->active = list_first_entry(&pcdev->capture,
+ struct pxa_buffer, vb.queue);
+ vb = &pcdev->active->vb;
+ buf = container_of(vb, struct pxa_buffer, vb);
+ pxa_videobuf_set_actdma(pcdev, buf);
+
+ pxa_dma_start_channels(pcdev);
+
cicr0 = __raw_readl(pcdev->base + CICR0) | CICR0_EOFM;
__raw_writel(cicr0, pcdev->base + CICR0);
}
@@ -1275,6 +1420,18 @@ static int pxa_camera_try_fmt(struct soc_camera_device *icd,
pix->width = 2048;
pix->width &= ~0x01;
+ /*
+ * YUV422P planar format requires images size to be a 16 bytes
+ * multiple. If not, zeros will be inserted between Y and U planes, and
+ * U and V planes, and YUV422P standard would be violated.
+ */
+ if (xlate->host_fmt->fourcc == V4L2_PIX_FMT_YUV422P) {
+ if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
+ pix->height = ALIGN(pix->height, YUV422P_X_Y_ALIGN);
+ if (!IS_ALIGNED(pix->width * pix->height, YUV422P_SIZE_ALIGN))
+ pix->width = ALIGN(pix->width, YUV422P_X_Y_ALIGN);
+ }
+
pix->bytesperline = pix->width *
DIV_ROUND_UP(xlate->host_fmt->depth, 8);
pix->sizeimage = pix->height * pix->bytesperline;
@@ -1382,18 +1539,8 @@ static int pxa_camera_resume(struct soc_camera_device *icd)
ret = pcdev->icd->ops->resume(pcdev->icd);
/* Restart frame capture if active buffer exists */
- if (!ret && pcdev->active) {
- unsigned long cifr, cicr0;
-
- /* Reset the FIFOs */
- cifr = __raw_readl(pcdev->base + CIFR) | CIFR_RESET_F;
- __raw_writel(cifr, pcdev->base + CIFR);
-
- cicr0 = __raw_readl(pcdev->base + CICR0);
- cicr0 &= ~CICR0_EOFM; /* Enable End-Of-Frame Interrupt */
- cicr0 |= CICR0_ENB; /* Restart the Capture Interface */
- __raw_writel(cicr0, pcdev->base + CICR0);
- }
+ if (!ret && pcdev->active)
+ pxa_camera_start_capture(pcdev);
return ret;
}
diff --git a/linux/drivers/media/video/saa6588.c b/linux/drivers/media/video/saa6588.c
index d89d70892..60934e0a9 100644
--- a/linux/drivers/media/video/saa6588.c
+++ b/linux/drivers/media/video/saa6588.c
@@ -34,9 +34,10 @@
#include <media/rds.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include "compat.h"
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
/* Addresses to scan */
static unsigned short normal_i2c[] = {
0x20 >> 1,
@@ -45,6 +46,7 @@ static unsigned short normal_i2c[] = {
};
I2C_CLIENT_INSMOD;
+#endif
/* insmod options */
static unsigned int debug;
@@ -440,11 +442,6 @@ static int saa6588_g_chip_ident(struct v4l2_subdev *sd, struct v4l2_dbg_chip_ide
return v4l2_chip_ident_i2c_client(client, chip, V4L2_IDENT_SAA6588, 0);
}
-static int saa6588_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa6588_core_ops = {
@@ -526,7 +523,6 @@ MODULE_DEVICE_TABLE(i2c, saa6588_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa6588",
- .command = saa6588_command,
.probe = saa6588_probe,
.remove = saa6588_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/saa7115.c b/linux/drivers/media/video/saa7115.c
index 2570ebf89..0719b5f13 100644
--- a/linux/drivers/media/video/saa7115.c
+++ b/linux/drivers/media/video/saa7115.c
@@ -932,8 +932,8 @@ static void saa711x_set_v4lstd(struct v4l2_subdev *sd, v4l2_std_id std)
/* Prevent unnecessary standard changes. During a standard
change the I-Port is temporarily disabled. Any devices
reading from that port can get confused.
- Note that VIDIOC_S_STD is also used to switch from
- radio to TV mode, so if a VIDIOC_S_STD is broadcast to
+ Note that s_std is also used to switch from
+ radio to TV mode, so if a s_std is broadcast to
all I2C devices then you do not want to have an unwanted
side-effect here. */
if (std == state->std)
diff --git a/linux/drivers/media/video/saa7134/Kconfig b/linux/drivers/media/video/saa7134/Kconfig
index a2089acb0..0ba68987b 100644
--- a/linux/drivers/media/video/saa7134/Kconfig
+++ b/linux/drivers/media/video/saa7134/Kconfig
@@ -6,6 +6,7 @@ config VIDEO_SAA7134
select VIDEO_TUNER
select VIDEO_TVEEPROM
select CRC32
+ select VIDEO_SAA6588 if VIDEO_HELPER_CHIPS_AUTO
---help---
This is a video4linux driver for Philips SAA713x based
TV cards.
diff --git a/linux/drivers/media/video/saa7134/saa6752hs.c b/linux/drivers/media/video/saa7134/saa6752hs.c
index 3af36d929..2b82466d4 100644
--- a/linux/drivers/media/video/saa7134/saa6752hs.c
+++ b/linux/drivers/media/video/saa7134/saa6752hs.c
@@ -48,7 +48,7 @@
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
/* Addresses to scan */
-static unsigned short normal_i2c[] = {0x20, I2C_CLIENT_END};
+static unsigned short normal_i2c[] = {0x20, 0x21, I2C_CLIENT_END};
I2C_CLIENT_INSMOD;
#endif
diff --git a/linux/drivers/media/video/saa7134/saa7134-cards.c b/linux/drivers/media/video/saa7134/saa7134-cards.c
index e8efc883c..cb94daeda 100644
--- a/linux/drivers/media/video/saa7134/saa7134-cards.c
+++ b/linux/drivers/media/video/saa7134/saa7134-cards.c
@@ -273,6 +273,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
@@ -409,6 +410,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.gpiomask = 0x820000,
.inputs = {{
@@ -819,6 +821,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
.vmux = 4,
@@ -978,6 +981,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.inputs = {{
.name = name_comp1,
.vmux = 1,
@@ -1700,6 +1704,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .rds_addr = 0x10,
.tda9887_conf = TDA9887_PRESENT,
.inputs = {{
.name = name_tv,
@@ -2365,6 +2370,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x21,
.inputs = {{
.name = "Composite 0",
.vmux = 0,
@@ -4172,6 +4178,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4208,6 +4215,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
@@ -4245,6 +4253,7 @@ struct saa7134_board saa7134_boards[] = {
.radio_type = UNSET,
.tuner_addr = ADDR_UNSET,
.radio_addr = ADDR_UNSET,
+ .empress_addr = 0x20,
.tda9887_conf = TDA9887_PRESENT,
.inputs = { {
.name = name_tv,
diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c
index b99b1ed1c..1bf7c3a1b 100644
--- a/linux/drivers/media/video/saa7134/saa7134-core.c
+++ b/linux/drivers/media/video/saa7134/saa7134-core.c
@@ -1043,13 +1043,25 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev,
/* load i2c helpers */
if (card_is_empress(dev)) {
struct v4l2_subdev *sd =
- v4l2_i2c_new_subdev(&dev->i2c_adap, "saa6752hs",
- "saa6752hs", 0x20);
+ v4l2_i2c_new_subdev(&dev->i2c_adap,
+ "saa6752hs", "saa6752hs",
+ saa7134_boards[dev->board].empress_addr);
if (sd)
sd->grp_id = GRP_EMPRESS;
}
+ if (saa7134_boards[dev->board].rds_addr) {
+ unsigned short addrs[2] = { 0, I2C_CLIENT_END };
+ struct v4l2_subdev *sd;
+
+ addrs[0] = saa7134_boards[dev->board].rds_addr;
+ sd = v4l2_i2c_new_probed_subdev(&dev->i2c_adap, "saa6588",
+ "saa6588", addrs);
+ if (sd)
+ printk(KERN_INFO "%s: found RDS decoder\n", dev->name);
+ }
+
request_submodules(dev);
v4l2_prio_init(&dev->prio);
diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c
index 609342128..bab6b56c8 100644
--- a/linux/drivers/media/video/saa7134/saa7134-empress.c
+++ b/linux/drivers/media/video/saa7134/saa7134-empress.c
@@ -416,8 +416,7 @@ static int empress_g_chip_ident(struct file *file, void *fh,
if (chip->match.type == V4L2_CHIP_MATCH_I2C_DRIVER &&
!strcmp(chip->match.name, "saa6752hs"))
return saa_call_empress(dev, core, g_chip_ident, chip);
- if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR &&
- chip->match.addr == 0x20)
+ if (chip->match.type == V4L2_CHIP_MATCH_I2C_ADDR)
return saa_call_empress(dev, core, g_chip_ident, chip);
return -EINVAL;
}
diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c
index d188aae14..8ad0c72d0 100644
--- a/linux/drivers/media/video/saa7134/saa7134-video.c
+++ b/linux/drivers/media/video/saa7134/saa7134-video.c
@@ -30,6 +30,7 @@
#include "saa7134-reg.h"
#include "saa7134.h"
#include <media/v4l2-common.h>
+#include <media/rds.h>
/* ------------------------------------------------------------------ */
@@ -1462,6 +1463,7 @@ static int video_release(struct file *file)
{
struct saa7134_fh *fh = file->private_data;
struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
unsigned long flags;
/* turn off overlay */
@@ -1495,6 +1497,8 @@ static int video_release(struct file *file)
saa_andorb(SAA7134_OFMT_DATA_B, 0x1f, 0);
saa_call_all(dev, core, s_standby, 0);
+ if (fh->radio)
+ saa_call_all(dev, core, ioctl, RDS_CMD_CLOSE, &cmd);
/* free stuff */
videobuf_mmap_free(&fh->cap);
@@ -1515,6 +1519,37 @@ static int video_mmap(struct file *file, struct vm_area_struct * vma)
return videobuf_mmap_mapper(saa7134_queue(fh), vma);
}
+static ssize_t radio_read(struct file *file, char __user *data,
+ size_t count, loff_t *ppos)
+{
+ struct saa7134_fh *fh = file->private_data;
+ struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
+
+ cmd.block_count = count/3;
+ cmd.buffer = data;
+ cmd.instance = file;
+ cmd.result = -ENODEV;
+
+ saa_call_all(dev, core, ioctl, RDS_CMD_READ, &cmd);
+
+ return cmd.result;
+}
+
+static unsigned int radio_poll(struct file *file, poll_table *wait)
+{
+ struct saa7134_fh *fh = file->private_data;
+ struct saa7134_dev *dev = fh->dev;
+ struct rds_command cmd;
+
+ cmd.instance = file;
+ cmd.event_list = wait;
+ cmd.result = -ENODEV;
+ saa_call_all(dev, core, ioctl, RDS_CMD_POLL, &cmd);
+
+ return cmd.result;
+}
+
/* ------------------------------------------------------------------ */
static int saa7134_try_get_set_fmt_vbi_cap(struct file *file, void *priv,
@@ -2446,8 +2481,10 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = {
static const struct v4l2_file_operations radio_fops = {
.owner = THIS_MODULE,
.open = video_open,
+ .read = radio_read,
.release = video_release,
.ioctl = video_ioctl2,
+ .poll = radio_poll,
};
static const struct v4l2_ioctl_ops radio_ioctl_ops = {
diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h
index d2b29ed9e..85a1dfd19 100644
--- a/linux/drivers/media/video/saa7134/saa7134.h
+++ b/linux/drivers/media/video/saa7134/saa7134.h
@@ -333,6 +333,8 @@ struct saa7134_board {
unsigned int radio_type;
unsigned char tuner_addr;
unsigned char radio_addr;
+ unsigned char empress_addr;
+ unsigned char rds_addr;
unsigned int tda9887_conf;
unsigned int tuner_config;
diff --git a/linux/drivers/media/video/saa717x.c b/linux/drivers/media/video/saa717x.c
index 3ad43f6b3..ae8fcde9d 100644
--- a/linux/drivers/media/video/saa717x.c
+++ b/linux/drivers/media/video/saa717x.c
@@ -1386,11 +1386,6 @@ static int saa717x_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
return 0;
}
-static int saa717x_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops saa717x_core_ops = {
@@ -1539,10 +1534,8 @@ MODULE_DEVICE_TABLE(i2c, saa717x_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "saa717x",
- .command = saa717x_command,
.probe = saa717x_probe,
.remove = saa717x_remove,
- .legacy_class = I2C_CLASS_TV_ANALOG | I2C_CLASS_TV_DIGITAL,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
.id_table = saa717x_id,
#endif
diff --git a/linux/drivers/media/video/saa7191.c b/linux/drivers/media/video/saa7191.c
index 9df505e0f..0a14ab6db 100644
--- a/linux/drivers/media/video/saa7191.c
+++ b/linux/drivers/media/video/saa7191.c
@@ -603,6 +603,7 @@ static const struct v4l2_subdev_video_ops saa7191_video_ops = {
static const struct v4l2_subdev_ops saa7191_ops = {
.core = &saa7191_core_ops,
.video = &saa7191_video_ops,
+ .tuner = &saa7191_tuner_ops,
};
static int saa7191_probe(struct i2c_client *client,
diff --git a/linux/drivers/media/video/soc_camera.c b/linux/drivers/media/video/soc_camera.c
index da6d224eb..9e432d390 100644
--- a/linux/drivers/media/video/soc_camera.c
+++ b/linux/drivers/media/video/soc_camera.c
@@ -765,7 +765,10 @@ static int soc_camera_s_register(struct file *file, void *fh,
static int device_register_link(struct soc_camera_device *icd)
{
- int ret = device_register(&icd->dev);
+ int ret = dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
+
+ if (!ret)
+ ret = device_register(&icd->dev);
if (ret < 0) {
/* Prevent calling device_unregister() */
@@ -1061,7 +1064,6 @@ int soc_camera_device_register(struct soc_camera_device *icd)
icd->devnum = num;
icd->dev.bus = &soc_camera_bus_type;
- dev_set_name(&icd->dev, "%u-%u", icd->iface, icd->devnum);
icd->dev.release = dummy_release;
icd->use_count = 0;
diff --git a/linux/drivers/media/video/stk-webcam.c b/linux/drivers/media/video/stk-webcam.c
index 54efa2cc0..7cbc4f736 100644
--- a/linux/drivers/media/video/stk-webcam.c
+++ b/linux/drivers/media/video/stk-webcam.c
@@ -1113,8 +1113,6 @@ static int stk_vidioc_reqbufs(struct file *filp,
if (dev == NULL)
return -ENODEV;
- if (rb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (rb->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if (is_streaming(dev)
@@ -1153,8 +1151,6 @@ static int stk_vidioc_qbuf(struct file *filp,
struct stk_camera *dev = priv;
struct stk_sio_buffer *sbuf;
unsigned long flags;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (buf->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
@@ -1181,8 +1177,7 @@ static int stk_vidioc_dqbuf(struct file *filp,
unsigned long flags;
int ret;
- if (buf->type != V4L2_BUF_TYPE_VIDEO_CAPTURE
- || !is_streaming(dev))
+ if (!is_streaming(dev))
return -EINVAL;
if (filp->f_flags & O_NONBLOCK && list_empty(&dev->sio_full))
@@ -1241,9 +1236,6 @@ static int stk_vidioc_streamoff(struct file *filp,
static int stk_vidioc_g_parm(struct file *filp,
void *priv, struct v4l2_streamparm *sp)
{
- if (sp->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
/*FIXME This is not correct */
sp->parm.capture.timeperframe.numerator = 1;
sp->parm.capture.timeperframe.denominator = 30;
diff --git a/linux/drivers/media/video/tda7432.c b/linux/drivers/media/video/tda7432.c
index 104fc4246..07c21a6d7 100644
--- a/linux/drivers/media/video/tda7432.c
+++ b/linux/drivers/media/video/tda7432.c
@@ -50,7 +50,7 @@
#include <media/v4l2-device.h>
#include <media/v4l2-ioctl.h>
#include <media/i2c-addr.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include "compat.h"
#ifndef VIDEO_AUDIO_BALANCE
@@ -70,6 +70,7 @@ MODULE_PARM_DESC(maxvol,"Set maximium volume to +20db (0), default is 0db(1)");
module_param(maxvol, int, S_IRUGO | S_IWUSR);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
/* Address to scan (I2C address of this chip) */
static unsigned short normal_i2c[] = {
I2C_ADDR_TDA7432 >> 1,
@@ -77,6 +78,7 @@ static unsigned short normal_i2c[] = {
};
I2C_CLIENT_INSMOD;
+#endif
/* Structure of address and subaddresses for the tda7432 */
@@ -434,11 +436,6 @@ static int tda7432_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return -EINVAL;
}
-static int tda7432_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda7432_core_ops = {
@@ -503,7 +500,6 @@ MODULE_DEVICE_TABLE(i2c, tda7432_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda7432",
- .command = tda7432_command,
.probe = tda7432_probe,
.remove = tda7432_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/tda9875.c b/linux/drivers/media/video/tda9875.c
index 938bafbbd..0351b13db 100644
--- a/linux/drivers/media/video/tda9875.c
+++ b/linux/drivers/media/video/tda9875.c
@@ -28,7 +28,7 @@
#include <linux/i2c.h>
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include <media/i2c-addr.h>
#include "compat.h"
@@ -36,6 +36,7 @@ static int debug; /* insmod parameter */
module_param(debug, int, S_IRUGO | S_IWUSR);
MODULE_LICENSE("GPL");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
/* Addresses to scan */
static unsigned short normal_i2c[] = {
I2C_ADDR_TDA9875 >> 1,
@@ -43,6 +44,7 @@ static unsigned short normal_i2c[] = {
};
I2C_CLIENT_INSMOD;
+#endif
/* This is a superset of the TDA9875 */
struct tda9875 {
@@ -335,11 +337,6 @@ static int tda9875_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
return -EINVAL;
}
-static int tda9875_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tda9875_core_ops = {
@@ -418,7 +415,6 @@ MODULE_DEVICE_TABLE(i2c, tda9875_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tda9875",
- .command = tda9875_command,
.probe = tda9875_probe,
.remove = tda9875_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/tlv320aic23b.c b/linux/drivers/media/video/tlv320aic23b.c
index 1eac4f7e7..bfba9ac0d 100644
--- a/linux/drivers/media/video/tlv320aic23b.c
+++ b/linux/drivers/media/video/tlv320aic23b.c
@@ -124,11 +124,6 @@ static int tlv320aic23b_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int tlv320aic23b_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops tlv320aic23b_core_ops = {
@@ -213,7 +208,6 @@ MODULE_DEVICE_TABLE(i2c, tlv320aic23b_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "tlv320aic23b",
- .command = tlv320aic23b_command,
.probe = tlv320aic23b_probe,
.remove = tlv320aic23b_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c
index 9a0ddd57c..0ac702201 100644
--- a/linux/drivers/media/video/tuner-core.c
+++ b/linux/drivers/media/video/tuner-core.c
@@ -365,7 +365,8 @@ static void set_type(struct i2c_client *c, unsigned int type,
}
t->type = type;
- t->config = new_config;
+ /* prevent invalid config values */
+ t->config = ((new_config >= 0) && (new_config < 256)) ? new_config : 0;
if (tuner_callback != NULL) {
tuner_dbg("defining GPIO callback\n");
t->fe.callback = tuner_callback;
@@ -787,8 +788,7 @@ static int tuner_s_radio(struct v4l2_subdev *sd)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, V4L2_TUNER_RADIO, "AUDC_SET_RADIO")
- == -EINVAL)
+ if (set_mode(client, t, V4L2_TUNER_RADIO, "s_radio") == -EINVAL)
return 0;
if (t->radio_freq)
set_freq(client, t->radio_freq);
@@ -802,7 +802,7 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
tuner_dbg("Putting tuner to sleep\n");
- if (check_mode(t, "TUNER_SET_STANDBY") == -EINVAL)
+ if (check_mode(t, "s_standby") == -EINVAL)
return 0;
t->mode = T_STANDBY;
if (analog_ops->standby)
@@ -810,132 +810,6 @@ static int tuner_s_standby(struct v4l2_subdev *sd, u32 standby)
return 0;
}
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
-static long tuner_ioctl(struct v4l2_subdev *sd, unsigned int cmd, void *arg)
-{
- struct tuner *t = to_tuner(sd);
- struct i2c_client *client = v4l2_get_subdevdata(sd);
- struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
- struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
-
- switch (cmd) {
- case VIDIOCSAUDIO:
- if (check_mode(t, "VIDIOCSAUDIO") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- /* Should be implemented, since bttv calls it */
- tuner_dbg("VIDIOCSAUDIO not implemented.\n");
- break;
- case VIDIOCSCHAN:
- {
- static const v4l2_std_id map[] = {
- [VIDEO_MODE_PAL] = V4L2_STD_PAL,
- [VIDEO_MODE_NTSC] = V4L2_STD_NTSC_M,
- [VIDEO_MODE_SECAM] = V4L2_STD_SECAM,
- [4 /* bttv */ ] = V4L2_STD_PAL_M,
- [5 /* bttv */ ] = V4L2_STD_PAL_N,
- [6 /* bttv */ ] = V4L2_STD_NTSC_M_JP,
- };
- struct video_channel *vc = arg;
-
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (set_mode(client,t,V4L2_TUNER_ANALOG_TV, "VIDIOCSCHAN")==-EINVAL)
- return 0;
-
- if (vc->norm < ARRAY_SIZE(map))
- t->std = map[vc->norm];
- tuner_fixup_std(t);
- if (t->tv_freq)
- set_tv_freq(client, t->tv_freq);
- return 0;
- }
- case VIDIOCSFREQ:
- {
- unsigned long *v = arg;
-
- if (check_mode(t, "VIDIOCSFREQ") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- set_freq(client, *v);
- return 0;
- }
- case VIDIOCGTUNER:
- {
- struct video_tuner *vt = arg;
-
- if (check_mode(t, "VIDIOCGTUNER") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (V4L2_TUNER_RADIO == t->mode) {
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- if (tuner_status & TUNER_STATUS_STEREO)
- vt->flags |= VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &= ~VIDEO_TUNER_STEREO_ON;
- } else {
- if (analog_ops->is_stereo) {
- if (analog_ops->is_stereo(&t->fe))
- vt->flags |=
- VIDEO_TUNER_STEREO_ON;
- else
- vt->flags &=
- ~VIDEO_TUNER_STEREO_ON;
- }
- }
- if (analog_ops->has_signal)
- vt->signal =
- analog_ops->has_signal(&t->fe);
-
- vt->flags |= VIDEO_TUNER_LOW; /* Allow freqs at 62.5 Hz */
-
- vt->rangelow = radio_range[0] * 16000;
- vt->rangehigh = radio_range[1] * 16000;
-
- } else {
- vt->rangelow = tv_range[0] * 16;
- vt->rangehigh = tv_range[1] * 16;
- }
-
- return 0;
- }
- case VIDIOCGAUDIO:
- {
- struct video_audio *va = arg;
-
- if (check_mode(t, "VIDIOCGAUDIO") == -EINVAL)
- return 0;
- if (check_v4l2(t) == -EINVAL)
- return 0;
-
- if (V4L2_TUNER_RADIO == t->mode) {
- if (fe_tuner_ops->get_status) {
- u32 tuner_status;
-
- fe_tuner_ops->get_status(&t->fe, &tuner_status);
- va->mode = (tuner_status & TUNER_STATUS_STEREO)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- } else if (analog_ops->is_stereo)
- va->mode = analog_ops->is_stereo(&t->fe)
- ? VIDEO_SOUND_STEREO : VIDEO_SOUND_MONO;
- }
- return 0;
- }
- }
- return -ENOIOCTLCMD;
-}
-#endif
-
static int tuner_s_config(struct v4l2_subdev *sd, const struct v4l2_priv_tun_config *cfg)
{
struct tuner *t = to_tuner(sd);
@@ -961,8 +835,7 @@ static int tuner_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "VIDIOC_S_STD")
- == -EINVAL)
+ if (set_mode(client, t, V4L2_TUNER_ANALOG_TV, "s_std") == -EINVAL)
return 0;
switch_v4l2();
@@ -979,8 +852,7 @@ static int tuner_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (set_mode(client, t, f->type, "VIDIOC_S_FREQUENCY")
- == -EINVAL)
+ if (set_mode(client, t, f->type, "s_frequency") == -EINVAL)
return 0;
switch_v4l2();
set_freq(client, f->frequency);
@@ -993,7 +865,7 @@ static int tuner_g_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *f)
struct tuner *t = to_tuner(sd);
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- if (check_mode(t, "VIDIOC_G_FREQUENCY") == -EINVAL)
+ if (check_mode(t, "g_frequency") == -EINVAL)
return 0;
switch_v4l2();
f->type = t->mode;
@@ -1017,7 +889,7 @@ static int tuner_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct analog_demod_ops *analog_ops = &t->fe.ops.analog_ops;
struct dvb_tuner_ops *fe_tuner_ops = &t->fe.ops.tuner_ops;
- if (check_mode(t, "VIDIOC_G_TUNER") == -EINVAL)
+ if (check_mode(t, "g_tuner") == -EINVAL)
return 0;
switch_v4l2();
@@ -1066,7 +938,7 @@ static int tuner_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct tuner *t = to_tuner(sd);
struct i2c_client *client = v4l2_get_subdevdata(sd);
- if (check_mode(t, "VIDIOC_S_TUNER") == -EINVAL)
+ if (check_mode(t, "s_tuner") == -EINVAL)
return 0;
switch_v4l2();
@@ -1123,9 +995,6 @@ static int tuner_resume(struct i2c_client *c)
static const struct v4l2_subdev_core_ops tuner_core_ops = {
.log_status = tuner_log_status,
.s_standby = tuner_s_standby,
-#ifdef CONFIG_VIDEO_ALLOW_V4L1
- .ioctl = tuner_ioctl,
-#endif
};
static const struct v4l2_subdev_tuner_ops tuner_tuner_ops = {
diff --git a/linux/drivers/media/video/tvaudio.c b/linux/drivers/media/video/tvaudio.c
index d630dca83..39d796908 100644
--- a/linux/drivers/media/video/tvaudio.c
+++ b/linux/drivers/media/video/tvaudio.c
@@ -1055,6 +1055,116 @@ static int tda9874a_initialize(struct CHIPSTATE *chip)
return 0;
}
+/* ---------------------------------------------------------------------- */
+/* audio chip description - defines+functions for tda9875 */
+/* The TDA9875 is made by Philips Semiconductor
+ * http://www.semiconductors.philips.com
+ * TDA9875: I2C-bus controlled DSP audio processor, FM demodulator
+ *
+ */
+
+/* subaddresses for TDA9875 */
+#define TDA9875_MUT 0x12 /*General mute (value --> 0b11001100*/
+#define TDA9875_CFG 0x01 /* Config register (value --> 0b00000000 */
+#define TDA9875_DACOS 0x13 /*DAC i/o select (ADC) 0b0000100*/
+#define TDA9875_LOSR 0x16 /*Line output select regirter 0b0100 0001*/
+
+#define TDA9875_CH1V 0x0c /*Channel 1 volume (mute)*/
+#define TDA9875_CH2V 0x0d /*Channel 2 volume (mute)*/
+#define TDA9875_SC1 0x14 /*SCART 1 in (mono)*/
+#define TDA9875_SC2 0x15 /*SCART 2 in (mono)*/
+
+#define TDA9875_ADCIS 0x17 /*ADC input select (mono) 0b0110 000*/
+#define TDA9875_AER 0x19 /*Audio effect (AVL+Pseudo) 0b0000 0110*/
+#define TDA9875_MCS 0x18 /*Main channel select (DAC) 0b0000100*/
+#define TDA9875_MVL 0x1a /* Main volume gauche */
+#define TDA9875_MVR 0x1b /* Main volume droite */
+#define TDA9875_MBA 0x1d /* Main Basse */
+#define TDA9875_MTR 0x1e /* Main treble */
+#define TDA9875_ACS 0x1f /* Auxilary channel select (FM) 0b0000000*/
+#define TDA9875_AVL 0x20 /* Auxilary volume gauche */
+#define TDA9875_AVR 0x21 /* Auxilary volume droite */
+#define TDA9875_ABA 0x22 /* Auxilary Basse */
+#define TDA9875_ATR 0x23 /* Auxilary treble */
+
+#define TDA9875_MSR 0x02 /* Monitor select register */
+#define TDA9875_C1MSB 0x03 /* Carrier 1 (FM) frequency register MSB */
+#define TDA9875_C1MIB 0x04 /* Carrier 1 (FM) frequency register (16-8]b */
+#define TDA9875_C1LSB 0x05 /* Carrier 1 (FM) frequency register LSB */
+#define TDA9875_C2MSB 0x06 /* Carrier 2 (nicam) frequency register MSB */
+#define TDA9875_C2MIB 0x07 /* Carrier 2 (nicam) frequency register (16-8]b */
+#define TDA9875_C2LSB 0x08 /* Carrier 2 (nicam) frequency register LSB */
+#define TDA9875_DCR 0x09 /* Demodulateur configuration regirter*/
+#define TDA9875_DEEM 0x0a /* FM de-emphasis regirter*/
+#define TDA9875_FMAT 0x0b /* FM Matrix regirter*/
+
+/* values */
+#define TDA9875_MUTE_ON 0xff /* general mute */
+#define TDA9875_MUTE_OFF 0xcc /* general no mute */
+
+static int tda9875_initialize(struct CHIPSTATE *chip)
+{
+ chip_write(chip, TDA9875_CFG, 0xd0); /*reg de config 0 (reset)*/
+ chip_write(chip, TDA9875_MSR, 0x03); /* Monitor 0b00000XXX*/
+ chip_write(chip, TDA9875_C1MSB, 0x00); /*Car1(FM) MSB XMHz*/
+ chip_write(chip, TDA9875_C1MIB, 0x00); /*Car1(FM) MIB XMHz*/
+ chip_write(chip, TDA9875_C1LSB, 0x00); /*Car1(FM) LSB XMHz*/
+ chip_write(chip, TDA9875_C2MSB, 0x00); /*Car2(NICAM) MSB XMHz*/
+ chip_write(chip, TDA9875_C2MIB, 0x00); /*Car2(NICAM) MIB XMHz*/
+ chip_write(chip, TDA9875_C2LSB, 0x00); /*Car2(NICAM) LSB XMHz*/
+ chip_write(chip, TDA9875_DCR, 0x00); /*Demod config 0x00*/
+ chip_write(chip, TDA9875_DEEM, 0x44); /*DE-Emph 0b0100 0100*/
+ chip_write(chip, TDA9875_FMAT, 0x00); /*FM Matrix reg 0x00*/
+ chip_write(chip, TDA9875_SC1, 0x00); /* SCART 1 (SC1)*/
+ chip_write(chip, TDA9875_SC2, 0x01); /* SCART 2 (sc2)*/
+
+ chip_write(chip, TDA9875_CH1V, 0x10); /* Channel volume 1 mute*/
+ chip_write(chip, TDA9875_CH2V, 0x10); /* Channel volume 2 mute */
+ chip_write(chip, TDA9875_DACOS, 0x02); /* sig DAC i/o(in:nicam)*/
+ chip_write(chip, TDA9875_ADCIS, 0x6f); /* sig ADC input(in:mono)*/
+ chip_write(chip, TDA9875_LOSR, 0x00); /* line out (in:mono)*/
+ chip_write(chip, TDA9875_AER, 0x00); /*06 Effect (AVL+PSEUDO) */
+ chip_write(chip, TDA9875_MCS, 0x44); /* Main ch select (DAC) */
+ chip_write(chip, TDA9875_MVL, 0x03); /* Vol Main left 10dB */
+ chip_write(chip, TDA9875_MVR, 0x03); /* Vol Main right 10dB*/
+ chip_write(chip, TDA9875_MBA, 0x00); /* Main Bass Main 0dB*/
+ chip_write(chip, TDA9875_MTR, 0x00); /* Main Treble Main 0dB*/
+ chip_write(chip, TDA9875_ACS, 0x44); /* Aux chan select (dac)*/
+ chip_write(chip, TDA9875_AVL, 0x00); /* Vol Aux left 0dB*/
+ chip_write(chip, TDA9875_AVR, 0x00); /* Vol Aux right 0dB*/
+ chip_write(chip, TDA9875_ABA, 0x00); /* Aux Bass Main 0dB*/
+ chip_write(chip, TDA9875_ATR, 0x00); /* Aux Aigus Main 0dB*/
+
+ chip_write(chip, TDA9875_MUT, 0xcc); /* General mute */
+ return 0;
+}
+
+static int tda9875_volume(int val) { return (unsigned char)(val / 602 - 84); }
+static int tda9875_bass(int val) { return (unsigned char)(max(-12, val / 2115 - 15)); }
+static int tda9875_treble(int val) { return (unsigned char)(val / 2622 - 12); }
+
+/* ----------------------------------------------------------------------- */
+
+
+/* *********************** *
+ * i2c interface functions *
+ * *********************** */
+
+static int tda9875_checkit(struct CHIPSTATE *chip)
+{
+ struct v4l2_subdev *sd = &chip->sd;
+ int dic, rev;
+
+ dic = chip_read2(chip, 254);
+ rev = chip_read2(chip, 255);
+
+ if (dic == 0 || dic == 2) { /* tda9875 and tda9875A */
+ v4l2_info(sd, "found tda9875%s rev. %d.\n",
+ dic == 0 ? "" : "A", rev);
+ return 1;
+ }
+ return 0;
+}
/* ---------------------------------------------------------------------- */
/* audio chip descriptions - defines+functions for tea6420 */
@@ -1288,6 +1398,7 @@ static int tda9850 = 1;
static int tda9855 = 1;
static int tda9873 = 1;
static int tda9874a = 1;
+static int tda9875 = 1;
static int tea6300; /* default 0 - address clash with msp34xx */
static int tea6320; /* default 0 - address clash with msp34xx */
static int tea6420 = 1;
@@ -1300,6 +1411,7 @@ module_param(tda9850, int, 0444);
module_param(tda9855, int, 0444);
module_param(tda9873, int, 0444);
module_param(tda9874a, int, 0444);
+module_param(tda9875, int, 0444);
module_param(tea6300, int, 0444);
module_param(tea6320, int, 0444);
module_param(tea6420, int, 0444);
@@ -1357,6 +1469,26 @@ static struct CHIPDESC chiplist[] = {
.setmode = tda9874a_setmode,
},
{
+ .name = "tda9875",
+ .insmodopt = &tda9875,
+ .addr_lo = I2C_ADDR_TDA9875 >> 1,
+ .addr_hi = I2C_ADDR_TDA9875 >> 1,
+ .flags = CHIP_HAS_VOLUME | CHIP_HAS_BASSTREBLE,
+
+ /* callbacks */
+ .initialize = tda9875_initialize,
+ .checkit = tda9875_checkit,
+ .volfunc = tda9875_volume,
+ .bassfunc = tda9875_bass,
+ .treblefunc = tda9875_treble,
+ .leftreg = TDA9875_MVL,
+ .rightreg = TDA9875_MVR,
+ .bassreg = TDA9875_MBA,
+ .treblereg = TDA9875_MTR,
+ .leftinit = 58880,
+ .rightinit = 58880,
+ },
+ {
.name = "tda9850",
.insmodopt = &tda9850,
.addr_lo = I2C_ADDR_TDA985x_L >> 1,
@@ -1519,6 +1651,8 @@ static int tvaudio_g_ctrl(struct v4l2_subdev *sd,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ break;
ctrl->value=chip->muted;
return 0;
case V4L2_CID_AUDIO_VOLUME:
@@ -1560,6 +1694,9 @@ static int tvaudio_s_ctrl(struct v4l2_subdev *sd,
switch (ctrl->id) {
case V4L2_CID_AUDIO_MUTE:
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ break;
+
if (ctrl->value < 0 || ctrl->value >= 2)
return -ERANGE;
chip->muted = ctrl->value;
@@ -1644,7 +1781,9 @@ static int tvaudio_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
switch (qc->id) {
case V4L2_CID_AUDIO_MUTE:
- return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ if (desc->flags & CHIP_HAS_INPUTSEL)
+ return v4l2_ctrl_query_fill(qc, 0, 1, 1, 0);
+ break;
case V4L2_CID_AUDIO_VOLUME:
if (desc->flags & CHIP_HAS_VOLUME)
return v4l2_ctrl_query_fill(qc, 0, 65535, 65535 / 100, 58880);
@@ -1669,7 +1808,9 @@ static int tvaudio_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
struct CHIPSTATE *chip = to_state(sd);
struct CHIPDESC *desc = chip->desc;
- if (!(desc->flags & CHIP_HAS_INPUTSEL) || rt->input >= 4)
+ if (!(desc->flags & CHIP_HAS_INPUTSEL))
+ return 0;
+ if (rt->input >= 4)
return -EINVAL;
/* There are four inputs: tuner, radio, extern and intern. */
chip->input = rt->input;
@@ -1686,8 +1827,11 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct CHIPDESC *desc = chip->desc;
int mode = 0;
+ if (!desc->setmode)
+ return 0;
if (chip->radio)
return 0;
+
switch (vt->audmode) {
case V4L2_TUNER_MODE_MONO:
case V4L2_TUNER_MODE_STEREO:
@@ -1703,7 +1847,7 @@ static int tvaudio_s_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
}
chip->audmode = vt->audmode;
- if (desc->setmode && mode) {
+ if (mode) {
chip->watch_stereo = 0;
/* del_timer(&chip->wt); */
chip->mode = mode;
@@ -1718,15 +1862,17 @@ static int tvaudio_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
struct CHIPDESC *desc = chip->desc;
int mode = V4L2_TUNER_MODE_MONO;
+ if (!desc->getmode)
+ return 0;
if (chip->radio)
return 0;
+
vt->audmode = chip->audmode;
vt->rxsubchans = 0;
vt->capability = V4L2_TUNER_CAP_STEREO |
V4L2_TUNER_CAP_LANG1 | V4L2_TUNER_CAP_LANG2;
- if (desc->getmode)
- mode = desc->getmode(chip);
+ mode = desc->getmode(chip);
if (mode & V4L2_TUNER_MODE_MONO)
vt->rxsubchans |= V4L2_TUNER_SUB_MONO;
@@ -1916,6 +2062,7 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
}
chip->thread = NULL;
+ init_timer(&chip->wt);
if (desc->flags & CHIP_NEED_CHECKMODE) {
if (!desc->getmode || !desc->setmode) {
/* This shouldn't be happen. Warn user, but keep working
@@ -1925,7 +2072,6 @@ static int tvaudio_probe(struct i2c_client *client, const struct i2c_device_id *
return 0;
}
/* start async thread */
- init_timer(&chip->wt);
chip->wt.function = chip_thread_wake;
chip->wt.data = (unsigned long)chip;
chip->thread = kthread_run(chip_thread, chip, client->name);
diff --git a/linux/drivers/media/video/tvp5150.c b/linux/drivers/media/video/tvp5150.c
index 9ae372246..67c18f280 100644
--- a/linux/drivers/media/video/tvp5150.c
+++ b/linux/drivers/media/video/tvp5150.c
@@ -643,7 +643,7 @@ static int tvp5150_g_sliced_vbi_cap(struct v4l2_subdev *sd,
const struct i2c_vbi_ram_value *regs = vbi_ram_default;
int line;
- v4l2_dbg(1, debug, sd, "VIDIOC_G_SLICED_VBI_CAP\n");
+ v4l2_dbg(1, debug, sd, "g_sliced_vbi_cap\n");
memset(cap, 0, sizeof *cap);
while (regs->reg != (u16)-1 ) {
@@ -842,7 +842,7 @@ static int tvp5150_reset(struct v4l2_subdev *sd, u32 val)
static int tvp5150_g_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
{
- v4l2_dbg(1, debug, sd, "VIDIOC_G_CTRL called\n");
+ v4l2_dbg(1, debug, sd, "g_ctrl called\n");
switch (ctrl->id) {
case V4L2_CID_BRIGHTNESS:
@@ -872,7 +872,7 @@ static int tvp5150_s_ctrl(struct v4l2_subdev *sd, struct v4l2_control *ctrl)
if (ctrl->value < tvp5150_qctrl[i].minimum ||
ctrl->value > tvp5150_qctrl[i].maximum)
return -ERANGE;
- v4l2_dbg(1, debug, sd, "VIDIOC_S_CTRL: id=%d, value=%d\n",
+ v4l2_dbg(1, debug, sd, "s_ctrl: id=%d, value=%d\n",
ctrl->id, ctrl->value);
break;
}
@@ -1081,7 +1081,7 @@ static int tvp5150_queryctrl(struct v4l2_subdev *sd, struct v4l2_queryctrl *qc)
{
int i;
- v4l2_dbg(1, debug, sd, "VIDIOC_QUERYCTRL called\n");
+ v4l2_dbg(1, debug, sd, "queryctrl called\n");
for (i = 0; i < ARRAY_SIZE(tvp5150_qctrl); i++)
if (qc->id && qc->id == tvp5150_qctrl[i].id) {
diff --git a/linux/drivers/media/video/upd64031a.c b/linux/drivers/media/video/upd64031a.c
index 0fd1c9312..0d7f37a9e 100644
--- a/linux/drivers/media/video/upd64031a.c
+++ b/linux/drivers/media/video/upd64031a.c
@@ -193,11 +193,6 @@ static int upd64031a_s_register(struct v4l2_subdev *sd, struct v4l2_dbg_register
}
#endif
-static int upd64031a_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops upd64031a_core_ops = {
@@ -275,7 +270,6 @@ MODULE_DEVICE_TABLE(i2c, upd64031a_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64031a",
- .command = upd64031a_command,
.probe = upd64031a_probe,
.remove = upd64031a_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/upd64083.c b/linux/drivers/media/video/upd64083.c
index aed167493..fdedc41ef 100644
--- a/linux/drivers/media/video/upd64083.c
+++ b/linux/drivers/media/video/upd64083.c
@@ -170,11 +170,6 @@ static int upd64083_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int upd64083_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops upd64083_core_ops = {
@@ -247,7 +242,6 @@ MODULE_DEVICE_TABLE(i2c, upd64083_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "upd64083",
- .command = upd64083_command,
.probe = upd64083_probe,
.remove = upd64083_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/usbvideo/vicam.c b/linux/drivers/media/video/usbvideo/vicam.c
index 5a039b5d6..3b332ef52 100644
--- a/linux/drivers/media/video/usbvideo/vicam.c
+++ b/linux/drivers/media/video/usbvideo/vicam.c
@@ -489,7 +489,7 @@ initialize_camera(struct vicam_camera *cam)
#else
int err;
const struct ihex_binrec *rec;
- const struct firmware *fw;
+ const struct firmware *uninitialized_var(fw);
err = request_ihex_firmware(&fw, "vicam/firmware.fw", &cam->udev->dev);
if (err) {
diff --git a/linux/drivers/media/video/usbvision/usbvision-video.c b/linux/drivers/media/video/usbvision/usbvision-video.c
index 74a7652de..fa62a2fd7 100644
--- a/linux/drivers/media/video/usbvision/usbvision-video.c
+++ b/linux/drivers/media/video/usbvision/usbvision-video.c
@@ -757,8 +757,7 @@ static int vidioc_reqbufs (struct file *file,
/* Check input validity:
the user must do a VIDEO CAPTURE and MMAP method. */
- if((vr->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) ||
- (vr->memory != V4L2_MEMORY_MMAP))
+ if (vr->memory != V4L2_MEMORY_MMAP)
return -EINVAL;
if(usbvision->streaming == Stream_On) {
@@ -816,9 +815,6 @@ static int vidioc_qbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
unsigned long lock_flags;
/* FIXME : works only on VIDEO_CAPTURE MODE, MMAP. */
- if(vb->type != V4L2_CAP_VIDEO_CAPTURE) {
- return -EINVAL;
- }
if(vb->index>=usbvision->num_frames) {
return -EINVAL;
}
@@ -853,9 +849,6 @@ static int vidioc_dqbuf (struct file *file, void *priv, struct v4l2_buffer *vb)
struct usbvision_frame *f;
unsigned long lock_flags;
- if (vb->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
-
if (list_empty(&(usbvision->outqueue))) {
if (usbvision->streaming == Stream_Idle)
return -EINVAL;
@@ -921,7 +914,6 @@ static int vidioc_enum_fmt_vid_cap (struct file *file, void *priv,
if(vfd->index>=USBVISION_SUPPORTED_PALETTES-1) {
return -EINVAL;
}
- vfd->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
strcpy(vfd->description,usbvision_v4l2_format[vfd->index].desc);
vfd->pixelformat = usbvision_v4l2_format[vfd->index].format;
return 0;
diff --git a/linux/drivers/media/video/uvc/uvc_driver.c b/linux/drivers/media/video/uvc/uvc_driver.c
index 0d2d87198..31d60647d 100644
--- a/linux/drivers/media/video/uvc/uvc_driver.c
+++ b/linux/drivers/media/video/uvc/uvc_driver.c
@@ -1917,6 +1917,15 @@ static struct usb_device_id uvc_ids[] = {
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 0,
.driver_info = UVC_QUIRK_STREAM_NO_FID },
+ /* Syntek (JAOtech Smart Terminal) */
+ { .match_flags = USB_DEVICE_ID_MATCH_DEVICE
+ | USB_DEVICE_ID_MATCH_INT_INFO,
+ .idVendor = 0x174f,
+ .idProduct = 0x8a34,
+ .bInterfaceClass = USB_CLASS_VIDEO,
+ .bInterfaceSubClass = 1,
+ .bInterfaceProtocol = 0,
+ .driver_info = UVC_QUIRK_STREAM_NO_FID },
/* Lenovo Thinkpad SL500 */
{ .match_flags = USB_DEVICE_ID_MATCH_DEVICE
| USB_DEVICE_ID_MATCH_INT_INFO,
diff --git a/linux/drivers/media/video/uvc/uvc_v4l2.c b/linux/drivers/media/video/uvc/uvc_v4l2.c
index 0baa59f61..aa7949d95 100644
--- a/linux/drivers/media/video/uvc/uvc_v4l2.c
+++ b/linux/drivers/media/video/uvc/uvc_v4l2.c
@@ -679,11 +679,17 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
{
struct v4l2_fmtdesc *fmt = arg;
struct uvc_format *format;
+ enum v4l2_buf_type type = fmt->type;
+ __u32 index = fmt->index;
if (fmt->type != video->streaming->type ||
fmt->index >= video->streaming->nformats)
return -EINVAL;
+ memset(fmt, 0, sizeof(*fmt));
+ fmt->index = index;
+ fmt->type = type;
+
format = &video->streaming->format[fmt->index];
fmt->flags = 0;
if (format->flags & UVC_FMT_FLAG_COMPRESSED)
diff --git a/linux/drivers/media/video/v4l1-compat.c b/linux/drivers/media/video/v4l1-compat.c
index 4a4cb4c57..ee3991f2f 100644
--- a/linux/drivers/media/video/v4l1-compat.c
+++ b/linux/drivers/media/video/v4l1-compat.c
@@ -576,6 +576,8 @@ static noinline long v4l1_compat_get_input_info(
chan->norm = VIDEO_MODE_NTSC;
if (sid & V4L2_STD_SECAM)
chan->norm = VIDEO_MODE_SECAM;
+ if (sid == V4L2_STD_ALL)
+ chan->norm = VIDEO_MODE_AUTO;
}
done:
return err;
@@ -602,6 +604,9 @@ static noinline long v4l1_compat_set_input(
case VIDEO_MODE_SECAM:
sid = V4L2_STD_SECAM;
break;
+ case VIDEO_MODE_AUTO:
+ sid = V4L2_STD_ALL;
+ break;
}
if (0 != sid) {
err = drv(file, VIDIOC_S_STD, &sid);
@@ -805,9 +810,9 @@ static noinline long v4l1_compat_select_tuner(
t.index = tun->tuner;
- err = drv(file, VIDIOC_S_INPUT, &t);
+ err = drv(file, VIDIOC_S_TUNER, &t);
if (err < 0)
- dprintk("VIDIOCSTUNER / VIDIOC_S_INPUT: %ld\n", err);
+ dprintk("VIDIOCSTUNER / VIDIOC_S_TUNER: %ld\n", err);
return err;
}
diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c
index 5e9b46c21..2c4d38979 100644
--- a/linux/drivers/media/video/v4l2-dev.c
+++ b/linux/drivers/media/video/v4l2-dev.c
@@ -236,6 +236,23 @@ static long v4l2_unlocked_ioctl(struct file *filp,
return vdev->fops->unlocked_ioctl(filp, cmd, arg);
}
+#ifdef CONFIG_MMU
+#define v4l2_get_unmapped_area NULL
+#else
+static unsigned long v4l2_get_unmapped_area(struct file *filp,
+ unsigned long addr, unsigned long len, unsigned long pgoff,
+ unsigned long flags)
+{
+ struct video_device *vdev = video_devdata(filp);
+
+ if (!vdev->fops->get_unmapped_area)
+ return -ENOSYS;
+ if (video_is_unregistered(vdev))
+ return -ENODEV;
+ return vdev->fops->get_unmapped_area(filp, addr, len, pgoff, flags);
+}
+#endif
+
static int v4l2_mmap(struct file *filp, struct vm_area_struct *vm)
{
struct video_device *vdev = video_devdata(filp);
@@ -288,6 +305,7 @@ static const struct file_operations v4l2_unlocked_fops = {
.read = v4l2_read,
.write = v4l2_write,
.open = v4l2_open,
+ .get_unmapped_area = v4l2_get_unmapped_area,
.mmap = v4l2_mmap,
.unlocked_ioctl = v4l2_unlocked_ioctl,
#ifdef CONFIG_COMPAT
@@ -303,6 +321,7 @@ static const struct file_operations v4l2_fops = {
.read = v4l2_read,
.write = v4l2_write,
.open = v4l2_open,
+ .get_unmapped_area = v4l2_get_unmapped_area,
.mmap = v4l2_mmap,
.ioctl = v4l2_ioctl,
#ifdef CONFIG_COMPAT
diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c
index 5cf729c9d..c16ef96ee 100644
--- a/linux/drivers/media/video/v4l2-ioctl.c
+++ b/linux/drivers/media/video/v4l2-ioctl.c
@@ -1552,6 +1552,9 @@ static long __video_do_ioctl(struct file *file,
struct v4l2_streamparm *p = arg;
if (ops->vidioc_g_parm) {
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
ret = ops->vidioc_g_parm(file, fh, p);
} else {
if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
@@ -1571,6 +1574,10 @@ static long __video_do_ioctl(struct file *file,
if (!ops->vidioc_s_parm)
break;
+ ret = check_fmt(ops, p->type);
+ if (ret)
+ break;
+
dbgarg(cmd, "type=%d\n", p->type);
ret = ops->vidioc_s_parm(file, fh, p);
break;
diff --git a/linux/drivers/media/video/vino.c b/linux/drivers/media/video/vino.c
index ba4e8b97d..274b99b56 100644
--- a/linux/drivers/media/video/vino.c
+++ b/linux/drivers/media/video/vino.c
@@ -3106,22 +3106,14 @@ out:
static int vino_enum_fmt_vid_cap(struct file *file, void *__fh,
struct v4l2_fmtdesc *fd)
{
- enum v4l2_buf_type type = fd->type;
- int index = fd->index;
+ dprintk("format index = %d\n", fd->index);
- dprintk("format index = %d\n", index);
-
- if ((fd->index < 0) ||
- (fd->index >= VINO_DATA_FMT_COUNT))
+ if (fd->index >= VINO_DATA_FMT_COUNT)
return -EINVAL;
- dprintk("format name = %s\n",
- vino_data_formats[index].description);
-
- memset(fd, 0, sizeof(struct v4l2_fmtdesc));
- fd->index = index;
- fd->type = type;
- fd->pixelformat = vino_data_formats[index].pixelformat;
- strcpy(fd->description, vino_data_formats[index].description);
+ dprintk("format name = %s\n", vino_data_formats[fd->index].description);
+
+ fd->pixelformat = vino_data_formats[fd->index].pixelformat;
+ strcpy(fd->description, vino_data_formats[fd->index].description);
return 0;
}
@@ -3331,28 +3323,18 @@ static int vino_g_parm(struct file *file, void *__fh,
{
struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
- switch (sp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_captureparm *cp = &sp->parm.capture;
- memset(cp, 0, sizeof(struct v4l2_captureparm));
+ cp->capability = V4L2_CAP_TIMEPERFRAME;
+ cp->timeperframe.numerator = 1;
- cp->capability = V4L2_CAP_TIMEPERFRAME;
- cp->timeperframe.numerator = 1;
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
+ cp->timeperframe.denominator = vcs->fps;
- cp->timeperframe.denominator = vcs->fps;
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
-
- // TODO: cp->readbuffers = xxx;
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ /* TODO: cp->readbuffers = xxx; */
return 0;
}
@@ -3362,32 +3344,21 @@ static int vino_s_parm(struct file *file, void *__fh,
{
struct vino_channel_settings *vcs = video_drvdata(file);
unsigned long flags;
+ struct v4l2_captureparm *cp = &sp->parm.capture;
- switch (sp->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct v4l2_captureparm *cp = &sp->parm.capture;
-
- spin_lock_irqsave(&vino_drvdata->input_lock, flags);
-
- if ((cp->timeperframe.numerator == 0) ||
- (cp->timeperframe.denominator == 0)) {
- /* reset framerate */
- vino_set_default_framerate(vcs);
- } else {
- vino_set_framerate(vcs, cp->timeperframe.denominator /
- cp->timeperframe.numerator);
- }
-
- spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+ spin_lock_irqsave(&vino_drvdata->input_lock, flags);
- // TODO: set buffers according to cp->readbuffers
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ if ((cp->timeperframe.numerator == 0) ||
+ (cp->timeperframe.denominator == 0)) {
+ /* reset framerate */
+ vino_set_default_framerate(vcs);
+ } else {
+ vino_set_framerate(vcs, cp->timeperframe.denominator /
+ cp->timeperframe.numerator);
}
+ spin_unlock_irqrestore(&vino_drvdata->input_lock, flags);
+
return 0;
}
@@ -3395,42 +3366,35 @@ static int vino_reqbufs(struct file *file, void *__fh,
struct v4l2_requestbuffers *rb)
{
struct vino_channel_settings *vcs = video_drvdata(file);
+
if (vcs->reading)
return -EBUSY;
- switch (rb->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- // TODO: check queue type
- if (rb->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
+ /* TODO: check queue type */
+ if (rb->memory != V4L2_MEMORY_MMAP) {
+ dprintk("type not mmap\n");
+ return -EINVAL;
+ }
- dprintk("count = %d\n", rb->count);
- if (rb->count > 0) {
- if (vino_is_capturing(vcs)) {
- dprintk("busy, capturing\n");
- return -EBUSY;
- }
+ dprintk("count = %d\n", rb->count);
+ if (rb->count > 0) {
+ if (vino_is_capturing(vcs)) {
+ dprintk("busy, capturing\n");
+ return -EBUSY;
+ }
- if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
- dprintk("busy, buffers still mapped\n");
- return -EBUSY;
- } else {
- vcs->streaming = 0;
- vino_queue_free(&vcs->fb_queue);
- vino_queue_init(&vcs->fb_queue, &rb->count);
- }
+ if (vino_queue_has_mapped_buffers(&vcs->fb_queue)) {
+ dprintk("busy, buffers still mapped\n");
+ return -EBUSY;
} else {
vcs->streaming = 0;
- vino_capture_stop(vcs);
vino_queue_free(&vcs->fb_queue);
+ vino_queue_init(&vcs->fb_queue, &rb->count);
}
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ } else {
+ vcs->streaming = 0;
+ vino_capture_stop(vcs);
+ vino_queue_free(&vcs->fb_queue);
}
return 0;
@@ -3478,35 +3442,27 @@ static int vino_querybuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
struct vino_channel_settings *vcs = video_drvdata(file);
+ struct vino_framebuffer *fb;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
-
- // TODO: check queue type
- if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
- dprintk("invalid index = %d\n",
- b->index);
- return -EINVAL;
- }
-
- fb = vino_queue_get_buffer(&vcs->fb_queue,
- b->index);
- if (fb == NULL) {
- dprintk("vino_queue_get_buffer() failed");
- return -EINVAL;
- }
-
- vino_v4l2_get_buffer_status(vcs, fb, b);
- break;
+ /* TODO: check queue type */
+ if (b->index >= vino_queue_get_length(&vcs->fb_queue)) {
+ dprintk("invalid index = %d\n",
+ b->index);
+ return -EINVAL;
}
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
+
+ fb = vino_queue_get_buffer(&vcs->fb_queue,
+ b->index);
+ if (fb == NULL) {
+ dprintk("vino_queue_get_buffer() failed");
return -EINVAL;
}
+ vino_v4l2_get_buffer_status(vcs, fb, b);
+
return 0;
}
@@ -3514,36 +3470,28 @@ static int vino_qbuf(struct file *file, void *__fh,
struct v4l2_buffer *b)
{
struct vino_channel_settings *vcs = video_drvdata(file);
+ struct vino_framebuffer *fb;
+ int ret;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
- int ret;
-
- // TODO: check queue type
- if (b->memory != V4L2_MEMORY_MMAP) {
- dprintk("type not mmap\n");
- return -EINVAL;
- }
+ /* TODO: check queue type */
+ if (b->memory != V4L2_MEMORY_MMAP) {
+ dprintk("type not mmap\n");
+ return -EINVAL;
+ }
- fb = vino_capture_enqueue(vcs, b->index);
- if (fb == NULL)
- return -EINVAL;
+ fb = vino_capture_enqueue(vcs, b->index);
+ if (fb == NULL)
+ return -EINVAL;
- vino_v4l2_get_buffer_status(vcs, fb, b);
+ vino_v4l2_get_buffer_status(vcs, fb, b);
- if (vcs->streaming) {
- ret = vino_capture_next(vcs, 1);
- if (ret)
- return ret;
- }
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
+ if (vcs->streaming) {
+ ret = vino_capture_next(vcs, 1);
+ if (ret)
+ return ret;
}
return 0;
@@ -3554,73 +3502,63 @@ static int vino_dqbuf(struct file *file, void *__fh,
{
struct vino_channel_settings *vcs = video_drvdata(file);
unsigned int nonblocking = file->f_flags & O_NONBLOCK;
+ struct vino_framebuffer *fb;
+ unsigned int incoming, outgoing;
+ int err;
+
if (vcs->reading)
return -EBUSY;
- switch (b->type) {
- case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
- struct vino_framebuffer *fb;
- unsigned int incoming, outgoing;
- int err;
+ /* TODO: check queue type */
+
+ err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
+ if (err) {
+ dprintk("vino_queue_get_incoming() failed\n");
+ return -EINVAL;
+ }
+ err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
+ if (err) {
+ dprintk("vino_queue_get_outgoing() failed\n");
+ return -EINVAL;
+ }
- // TODO: check queue type
+ dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
- err = vino_queue_get_incoming(&vcs->fb_queue, &incoming);
- if (err) {
- dprintk("vino_queue_get_incoming() failed\n");
+ if (outgoing == 0) {
+ if (incoming == 0) {
+ dprintk("no incoming or outgoing buffers\n");
return -EINVAL;
}
- err = vino_queue_get_outgoing(&vcs->fb_queue, &outgoing);
- if (err) {
- dprintk("vino_queue_get_outgoing() failed\n");
- return -EINVAL;
+ if (nonblocking) {
+ dprintk("non-blocking I/O was selected and "
+ "there are no buffers to dequeue\n");
+ return -EAGAIN;
}
- dprintk("incoming = %d, outgoing = %d\n", incoming, outgoing);
-
- if (outgoing == 0) {
- if (incoming == 0) {
- dprintk("no incoming or outgoing buffers\n");
- return -EINVAL;
- }
- if (nonblocking) {
- dprintk("non-blocking I/O was selected and "
- "there are no buffers to dequeue\n");
- return -EAGAIN;
- }
-
+ err = vino_wait_for_frame(vcs);
+ if (err) {
err = vino_wait_for_frame(vcs);
if (err) {
- err = vino_wait_for_frame(vcs);
- if (err) {
- /* interrupted or
- * no frames captured because
- * of frame skipping */
- // vino_capture_failed(vcs);
- return -EIO;
- }
+ /* interrupted or no frames captured because of
+ * frame skipping */
+ /* vino_capture_failed(vcs); */
+ return -EIO;
}
}
+ }
- fb = vino_queue_remove(&vcs->fb_queue, &b->index);
- if (fb == NULL) {
- dprintk("vino_queue_remove() failed\n");
- return -EINVAL;
- }
-
- err = vino_check_buffer(vcs, fb);
+ fb = vino_queue_remove(&vcs->fb_queue, &b->index);
+ if (fb == NULL) {
+ dprintk("vino_queue_remove() failed\n");
+ return -EINVAL;
+ }
- vino_v4l2_get_buffer_status(vcs, fb, b);
+ err = vino_check_buffer(vcs, fb);
- if (err)
- return -EIO;
+ vino_v4l2_get_buffer_status(vcs, fb, b);
- break;
- }
- case V4L2_BUF_TYPE_VIDEO_OVERLAY:
- default:
- return -EINVAL;
- }
+ if (err)
+ return -EIO;
return 0;
}
diff --git a/linux/drivers/media/video/vp27smpx.c b/linux/drivers/media/video/vp27smpx.c
index 3104d0e1f..be046e961 100644
--- a/linux/drivers/media/video/vp27smpx.c
+++ b/linux/drivers/media/video/vp27smpx.c
@@ -135,11 +135,6 @@ static int vp27smpx_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int vp27smpx_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops vp27smpx_core_ops = {
@@ -217,7 +212,6 @@ MODULE_DEVICE_TABLE(i2c, vp27smpx_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "vp27smpx",
- .command = vp27smpx_command,
.probe = vp27smpx_probe,
.remove = vp27smpx_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/vpx3220.c b/linux/drivers/media/video/vpx3220.c
index ee6c74176..224c899d1 100644
--- a/linux/drivers/media/video/vpx3220.c
+++ b/linux/drivers/media/video/vpx3220.c
@@ -316,8 +316,6 @@ static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pst
int res = V4L2_IN_ST_NO_SIGNAL, status;
v4l2_std_id std = 0;
- v4l2_dbg(1, debug, sd, "VIDIOC_QUERYSTD/VIDIOC_INT_G_INPUT_STATUS\n");
-
status = vpx3220_fp_read(sd, 0x0f3);
v4l2_dbg(1, debug, sd, "status: 0x%04x\n", status);
@@ -356,11 +354,13 @@ static int vpx3220_status(struct v4l2_subdev *sd, u32 *pstatus, v4l2_std_id *pst
static int vpx3220_querystd(struct v4l2_subdev *sd, v4l2_std_id *std)
{
+ v4l2_dbg(1, debug, sd, "querystd\n");
return vpx3220_status(sd, NULL, std);
}
static int vpx3220_g_input_status(struct v4l2_subdev *sd, u32 *status)
{
+ v4l2_dbg(1, debug, sd, "g_input_status\n");
return vpx3220_status(sd, status, NULL);
}
@@ -374,7 +374,7 @@ static int vpx3220_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
choosen video norm */
temp_input = vpx3220_fp_read(sd, 0xf2);
- v4l2_dbg(1, debug, sd, "VIDIOC_S_STD %llx\n", (unsigned long long)std);
+ v4l2_dbg(1, debug, sd, "s_std %llx\n", (unsigned long long)std);
if (std & V4L2_STD_NTSC) {
vpx3220_write_fp_block(sd, init_ntsc, sizeof(init_ntsc) >> 1);
v4l2_dbg(1, debug, sd, "norm switched to NTSC\n");
@@ -430,7 +430,7 @@ static int vpx3220_s_routing(struct v4l2_subdev *sd, const struct v4l2_routing *
static int vpx3220_s_stream(struct v4l2_subdev *sd, int enable)
{
- v4l2_dbg(1, debug, sd, "VIDIOC_STREAM%s\n", enable ? "ON" : "OFF");
+ v4l2_dbg(1, debug, sd, "s_stream %s\n", enable ? "on" : "off");
vpx3220_write(sd, 0xf2, (enable ? 0x1b : 0x00));
return 0;
diff --git a/linux/drivers/media/video/wm8739.c b/linux/drivers/media/video/wm8739.c
index df7d6a094..619782737 100644
--- a/linux/drivers/media/video/wm8739.c
+++ b/linux/drivers/media/video/wm8739.c
@@ -258,11 +258,6 @@ static int wm8739_log_status(struct v4l2_subdev *sd)
return 0;
}
-static int wm8739_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops wm8739_core_ops = {
@@ -351,7 +346,6 @@ MODULE_DEVICE_TABLE(i2c, wm8739_id);
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8739",
- .command = wm8739_command,
.probe = wm8739_probe,
.remove = wm8739_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/wm8775.c b/linux/drivers/media/video/wm8775.c
index 3140c1313..bd4729d13 100644
--- a/linux/drivers/media/video/wm8775.c
+++ b/linux/drivers/media/video/wm8775.c
@@ -34,16 +34,18 @@
#include <linux/videodev2.h>
#include <media/v4l2-device.h>
#include <media/v4l2-chip-ident.h>
-#include <media/v4l2-i2c-drv-legacy.h>
+#include <media/v4l2-i2c-drv.h>
#include "compat.h"
MODULE_DESCRIPTION("wm8775 driver");
MODULE_AUTHOR("Ulf Eklund, Hans Verkuil");
MODULE_LICENSE("GPL");
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 22)
static unsigned short normal_i2c[] = { 0x36 >> 1, I2C_CLIENT_END };
I2C_CLIENT_INSMOD;
+#endif
/* ----------------------------------------------------------------------- */
@@ -162,11 +164,6 @@ static int wm8775_s_frequency(struct v4l2_subdev *sd, struct v4l2_frequency *fre
return 0;
}
-static int wm8775_command(struct i2c_client *client, unsigned cmd, void *arg)
-{
- return v4l2_subdev_command(i2c_get_clientdata(client), cmd, arg);
-}
-
/* ----------------------------------------------------------------------- */
static const struct v4l2_subdev_core_ops wm8775_core_ops = {
@@ -271,8 +268,6 @@ MODULE_DEVICE_TABLE(i2c, wm8775_id);
#endif
static struct v4l2_i2c_driver_data v4l2_i2c_data = {
.name = "wm8775",
- .driverid = I2C_DRIVERID_WM8775,
- .command = wm8775_command,
.probe = wm8775_probe,
.remove = wm8775_remove,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
diff --git a/linux/drivers/media/video/zoran/zoran_driver.c b/linux/drivers/media/video/zoran/zoran_driver.c
index 7ef3c015d..c702ea0fe 100644
--- a/linux/drivers/media/video/zoran/zoran_driver.c
+++ b/linux/drivers/media/video/zoran/zoran_driver.c
@@ -246,9 +246,9 @@ static int v4l_fbuffer_alloc(struct zoran_fh *fh)
SetPageReserved(virt_to_page(mem + off));
dprintk(4,
KERN_INFO
- "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%lx)\n",
+ "%s: %s - V4L frame %d mem 0x%lx (bus: 0x%llx)\n",
ZR_DEVNAME(zr), __func__, i, (unsigned long) mem,
- virt_to_bus(mem));
+ (unsigned long long)virt_to_bus(mem));
}
fh->buffers.allocated = 1;
diff --git a/linux/drivers/media/video/zr364xx.c b/linux/drivers/media/video/zr364xx.c
index 698b7b9ba..2e4d8147b 100644
--- a/linux/drivers/media/video/zr364xx.c
+++ b/linux/drivers/media/video/zr364xx.c
@@ -427,7 +427,6 @@ static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
static int zr364xx_vidioc_querycap(struct file *file, void *priv,
struct v4l2_capability *cap)
{
- memset(cap, 0, sizeof(*cap));
strcpy(cap->driver, DRIVER_DESC);
cap->capabilities = V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_READWRITE;
return 0;
@@ -438,8 +437,6 @@ static int zr364xx_vidioc_enum_input(struct file *file, void *priv,
{
if (i->index != 0)
return -EINVAL;
- memset(i, 0, sizeof(*i));
- i->index = 0;
strcpy(i->name, DRIVER_DESC " Camera");
i->type = V4L2_INPUT_TYPE_CAMERA;
return 0;
@@ -531,11 +528,6 @@ static int zr364xx_vidioc_enum_fmt_vid_cap(struct file *file,
{
if (f->index > 0)
return -EINVAL;
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(f, 0, sizeof(*f));
- f->index = 0;
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->flags = V4L2_FMT_FLAG_COMPRESSED;
strcpy(f->description, "JPEG");
f->pixelformat = V4L2_PIX_FMT_JPEG;
@@ -552,8 +544,6 @@ static int zr364xx_vidioc_try_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
return -EINVAL;
if (f->fmt.pix.field != V4L2_FIELD_ANY &&
@@ -579,10 +569,6 @@ static int zr364xx_vidioc_g_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
- memset(&f->fmt.pix, 0, sizeof(struct v4l2_pix_format));
- f->type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
f->fmt.pix.pixelformat = V4L2_PIX_FMT_JPEG;
f->fmt.pix.field = V4L2_FIELD_NONE;
f->fmt.pix.width = cam->width;
@@ -604,8 +590,6 @@ static int zr364xx_vidioc_s_fmt_vid_cap(struct file *file, void *priv,
return -ENODEV;
cam = video_get_drvdata(vdev);
- if (f->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
- return -EINVAL;
if (f->fmt.pix.pixelformat != V4L2_PIX_FMT_JPEG)
return -EINVAL;
if (f->fmt.pix.field != V4L2_FIELD_ANY &&