diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/Documentation/video4linux/gspca.txt | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-cards.c | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-driver.h | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/cx18/cx18-ioctl.c | 6 | ||||
-rw-r--r-- | linux/drivers/media/video/gspca/gspca.c | 21 | ||||
-rw-r--r-- | linux/drivers/media/video/gspca/pac207.c | 1 | ||||
-rw-r--r-- | linux/drivers/media/video/gspca/sonixj.c | 51 | ||||
-rw-r--r-- | linux/drivers/media/video/gspca/zc3xx.c | 4 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-cards.h | 2 | ||||
-rw-r--r-- | linux/drivers/media/video/ivtv/ivtv-ioctl.c | 41 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa6752hs.c | 127 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-empress.c | 25 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-i2c.c | 10 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134-video.c | 42 | ||||
-rw-r--r-- | linux/drivers/media/video/saa7134/saa7134.h | 3 |
15 files changed, 200 insertions, 141 deletions
diff --git a/linux/Documentation/video4linux/gspca.txt b/linux/Documentation/video4linux/gspca.txt index 9a3e4d797..308ce4ee2 100644 --- a/linux/Documentation/video4linux/gspca.txt +++ b/linux/Documentation/video4linux/gspca.txt @@ -42,6 +42,7 @@ zc3xx 0458:7007 Genius VideoCam V2 zc3xx 0458:700c Genius VideoCam V3 zc3xx 0458:700f Genius VideoCam Web V2 sonixj 0458:7025 Genius Eye 311Q +sonixj 0458:702e Genius Slim 310 NB sonixj 045e:00f5 MicroSoft VX3000 sonixj 045e:00f7 MicroSoft VX1000 ov519 045e:028c Micro$oft xbox cam @@ -181,6 +182,7 @@ pac207 093a:2468 PAC207 pac207 093a:2470 Genius GF112 pac207 093a:2471 Genius VideoCam ge111 pac207 093a:2472 Genius VideoCam ge110 +pac207 093a:2476 Genius e-Messenger 112 pac7311 093a:2600 PAC7311 Typhoon pac7311 093a:2601 Philips SPC 610 NC pac7311 093a:2603 PAC7312 diff --git a/linux/drivers/media/video/cx18/cx18-cards.c b/linux/drivers/media/video/cx18/cx18-cards.c index 8fe5f38c4..3cb9734ec 100644 --- a/linux/drivers/media/video/cx18/cx18-cards.c +++ b/linux/drivers/media/video/cx18/cx18-cards.c @@ -163,7 +163,7 @@ static const struct cx18_card cx18_card_h900 = { }, .audio_inputs = { { CX18_CARD_INPUT_AUD_TUNER, - CX18_AV_AUDIO8, 0 }, + CX18_AV_AUDIO5, 0 }, { CX18_CARD_INPUT_LINE_IN1, CX18_AV_AUDIO_SERIAL1, 0 }, }, diff --git a/linux/drivers/media/video/cx18/cx18-driver.h b/linux/drivers/media/video/cx18/cx18-driver.h index cc6f288a6..66cb74887 100644 --- a/linux/drivers/media/video/cx18/cx18-driver.h +++ b/linux/drivers/media/video/cx18/cx18-driver.h @@ -63,8 +63,8 @@ # error "This driver requires kernel PCI support." #endif -/* Default delay to throttle mmio access to the CX23418 so it doesn't choke */ -#define CX18_DEFAULT_MMIO_NDELAY 31 /* 30.3 ns = 1 PCI clock(s) / 33 MHz */ +/* Default delay to throttle mmio access to the CX23418 */ +#define CX18_DEFAULT_MMIO_NDELAY 0 /* 0 ns = 0 PCI clock(s) / 33 MHz */ #define CX18_MEM_OFFSET 0x00000000 #define CX18_MEM_SIZE 0x04000000 diff --git a/linux/drivers/media/video/cx18/cx18-ioctl.c b/linux/drivers/media/video/cx18/cx18-ioctl.c index 1ef2690d4..b909c78d3 100644 --- a/linux/drivers/media/video/cx18/cx18-ioctl.c +++ b/linux/drivers/media/video/cx18/cx18-ioctl.c @@ -201,7 +201,6 @@ static int cx18_try_fmt_vid_cap(struct file *file, void *fh, { struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; - int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; @@ -249,8 +248,7 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, struct cx18_open_id *id = fh; struct cx18 *cx = id->cx; int ret; - int w = fmt->fmt.pix.width; - int h = fmt->fmt.pix.height; + int w, h; ret = v4l2_prio_check(&cx->prio, &id->prio); if (ret) @@ -259,6 +257,8 @@ static int cx18_s_fmt_vid_cap(struct file *file, void *fh, ret = cx18_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; + w = fmt->fmt.pix.width; + h = fmt->fmt.pix.height; if (cx->params.width == w && cx->params.height == h) return 0; diff --git a/linux/drivers/media/video/gspca/gspca.c b/linux/drivers/media/video/gspca/gspca.c index 122644224..8c98c7a05 100644 --- a/linux/drivers/media/video/gspca/gspca.c +++ b/linux/drivers/media/video/gspca/gspca.c @@ -47,7 +47,7 @@ MODULE_AUTHOR("Jean-Francois Moine <http://moinejf.free.fr>"); MODULE_DESCRIPTION("GSPCA USB Camera Driver"); MODULE_LICENSE("GPL"); -#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 2, 0) +#define DRIVER_VERSION_NUMBER KERNEL_VERSION(2, 3, 0) static int video_nr = -1; @@ -195,7 +195,7 @@ static void bulk_irq(struct urb *urb { struct gspca_dev *gspca_dev = (struct gspca_dev *) urb->context; struct gspca_frame *frame; - int j, ret; + int j; PDEBUG(D_PACK, "bulk irq"); if (!gspca_dev->streaming) @@ -222,11 +222,6 @@ static void bulk_irq(struct urb *urb urb->transfer_buffer, urb->actual_length); } - /* resubmit the URB */ - urb->status = 0; - ret = usb_submit_urb(urb, GFP_ATOMIC); - if (ret < 0) - PDEBUG(D_ERR|D_PACK, "usb_submit_urb() ret %d", ret); } /* @@ -512,20 +507,20 @@ static int create_urbs(struct gspca_dev *gspca_dev, PDEBUG(D_STREAM, "isoc %d pkts size %d = bsize:%d", npkt, psize, bsize); + nurbs = DEF_NURBS; } else { npkt = 0; bsize = psize; PDEBUG(D_STREAM, "bulk bsize:%d", bsize); + nurbs = 1; } - nurbs = DEF_NURBS; gspca_dev->nurbs = nurbs; for (n = 0; n < nurbs; n++) { urb = usb_alloc_urb(npkt, GFP_KERNEL); if (!urb) { err("usb_alloc_urb failed"); - for (i = 0; i < n; i++) - usb_free_urb(gspca_dev->urb[i]); + destroy_urbs(gspca_dev); return -ENOMEM; } urb->transfer_buffer = usb_buffer_alloc(gspca_dev->dev, @@ -535,8 +530,8 @@ static int create_urbs(struct gspca_dev *gspca_dev, if (urb->transfer_buffer == NULL) { usb_free_urb(urb); - destroy_urbs(gspca_dev); err("usb_buffer_urb failed"); + destroy_urbs(gspca_dev); return -ENOMEM; } gspca_dev->urb[n] = urb; @@ -594,6 +589,10 @@ static int gspca_init_transfer(struct gspca_dev *gspca_dev) gspca_dev->streaming = 1; atomic_set(&gspca_dev->nevent, 0); + /* start the bulk transfer is done by the subdriver */ + if (gspca_dev->bulk) + break; + /* submit the URBs */ for (n = 0; n < gspca_dev->nurbs; n++) { ret = usb_submit_urb(gspca_dev->urb[n], GFP_KERNEL); diff --git a/linux/drivers/media/video/gspca/pac207.c b/linux/drivers/media/video/gspca/pac207.c index 83b5f740c..34e923d00 100644 --- a/linux/drivers/media/video/gspca/pac207.c +++ b/linux/drivers/media/video/gspca/pac207.c @@ -534,6 +534,7 @@ static const __devinitdata struct usb_device_id device_table[] = { {USB_DEVICE(0x093a, 0x2470)}, {USB_DEVICE(0x093a, 0x2471)}, {USB_DEVICE(0x093a, 0x2472)}, + {USB_DEVICE(0x093a, 0x2476)}, {USB_DEVICE(0x2001, 0xf115)}, {} }; diff --git a/linux/drivers/media/video/gspca/sonixj.c b/linux/drivers/media/video/gspca/sonixj.c index e95613b12..a77164581 100644 --- a/linux/drivers/media/video/gspca/sonixj.c +++ b/linux/drivers/media/video/gspca/sonixj.c @@ -39,6 +39,7 @@ struct sd { unsigned char contrast; unsigned char colors; unsigned char autogain; + __u8 vflip; /* ov7630 only */ signed char ag_cnt; #define AG_CNT_START 13 @@ -70,6 +71,8 @@ static int sd_setcolors(struct gspca_dev *gspca_dev, __s32 val); static int sd_getcolors(struct gspca_dev *gspca_dev, __s32 *val); static int sd_setautogain(struct gspca_dev *gspca_dev, __s32 val); static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val); +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val); +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val); static struct ctrl sd_ctrls[] = { { @@ -131,6 +134,22 @@ static struct ctrl sd_ctrls[] = { .set = sd_setautogain, .get = sd_getautogain, }, +/* ov7630 only */ +#define VFLIP_IDX 4 + { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Vflip", + .minimum = 0, + .maximum = 1, + .step = 1, +#define VFLIP_DEF 0 + .default_value = VFLIP_DEF, + }, + .set = sd_setvflip, + .get = sd_getvflip, + }, }; static struct v4l2_pix_format vga_mode[] = { @@ -450,7 +469,8 @@ static const __u8 ov7630_sensor_init[][8] = { {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x12, 0x48, 0x00, 0x00, 0x00, 0x10}, /*fixme: + 0x12, 0x04*/ - {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, +/* {0xa1, 0x21, 0x75, 0x82, 0x00, 0x00, 0x00, 0x10}, * COMN + * set by setvflip */ {0xa1, 0x21, 0x10, 0x32, 0x00, 0x00, 0x00, 0x10}, {0xa1, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}, {0xb1, 0x21, 0x01, 0x80, 0x80, 0x00, 0x00, 0x10}, @@ -972,6 +992,8 @@ static int sd_config(struct gspca_dev *gspca_dev, gspca_dev->ctrl_dis = (1 << AUTOGAIN_IDX); break; } + if (sd->sensor != SENSOR_OV7630) + gspca_dev->ctrl_dis |= (1 << VFLIP_IDX); return 0; } @@ -1200,6 +1222,14 @@ static void setautogain(struct gspca_dev *gspca_dev) sd->ag_cnt = -1; } +static void setvflip(struct sd *sd) +{ + if (sd->sensor != SENSOR_OV7630) + return; + i2c_w1(&sd->gspca_dev, 0x75, /* COMN */ + sd->vflip ? 0x82 : 0x02); +} + /* -- start the camera -- */ static void sd_start(struct gspca_dev *gspca_dev) { @@ -1298,6 +1328,7 @@ static void sd_start(struct gspca_dev *gspca_dev) break; case SENSOR_OV7630: ov7630_InitSensor(gspca_dev); + setvflip(sd); reg17 = 0xe2; reg1 = 0x44; break; @@ -1586,6 +1617,23 @@ static int sd_getautogain(struct gspca_dev *gspca_dev, __s32 *val) return 0; } +static int sd_setvflip(struct gspca_dev *gspca_dev, __s32 val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + sd->vflip = val; + setvflip(sd); + return 0; +} + +static int sd_getvflip(struct gspca_dev *gspca_dev, __s32 *val) +{ + struct sd *sd = (struct sd *) gspca_dev; + + *val = sd->vflip; + return 0; +} + /* sub-driver description */ static const struct sd_desc sd_desc = { .name = MODULE_NAME, @@ -1607,6 +1655,7 @@ static const struct sd_desc sd_desc = { static const __devinitdata struct usb_device_id device_table[] = { #if !defined CONFIG_USB_SN9C102 && !defined CONFIG_USB_SN9C102_MODULE {USB_DEVICE(0x0458, 0x7025), BSI(SN9C120, MI0360, 0x5d)}, + {USB_DEVICE(0x0458, 0x702e), BSI(SN9C120, OV7660, 0x21)}, {USB_DEVICE(0x045e, 0x00f5), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x045e, 0x00f7), BSI(SN9C105, OV7660, 0x21)}, {USB_DEVICE(0x0471, 0x0327), BSI(SN9C105, MI0360, 0x5d)}, diff --git a/linux/drivers/media/video/gspca/zc3xx.c b/linux/drivers/media/video/gspca/zc3xx.c index 782952b7a..3153bd4cd 100644 --- a/linux/drivers/media/video/gspca/zc3xx.c +++ b/linux/drivers/media/video/gspca/zc3xx.c @@ -6581,8 +6581,8 @@ static int setlightfreq(struct gspca_dev *gspca_dev) cs2102_60HZ, cs2102_60HZScale}, /* SENSOR_CS2102K 1 */ {cs2102_NoFliker, cs2102_NoFlikerScale, - cs2102_50HZ, cs2102_50HZScale, - cs2102_60HZ, cs2102_60HZScale}, + NULL, NULL, /* currently disabled */ + NULL, NULL}, /* SENSOR_GC0305 2 */ {gc0305_NoFliker, gc0305_NoFliker, gc0305_50HZ, gc0305_50HZ, diff --git a/linux/drivers/media/video/ivtv/ivtv-cards.h b/linux/drivers/media/video/ivtv/ivtv-cards.h index 381af1bce..0b8fe85fb 100644 --- a/linux/drivers/media/video/ivtv/ivtv-cards.h +++ b/linux/drivers/media/video/ivtv/ivtv-cards.h @@ -154,7 +154,7 @@ #define IVTV_CAP_ENCODER (V4L2_CAP_VIDEO_CAPTURE | V4L2_CAP_TUNER | \ V4L2_CAP_AUDIO | V4L2_CAP_READWRITE | V4L2_CAP_VBI_CAPTURE | \ V4L2_CAP_SLICED_VBI_CAPTURE) -#define IVTV_CAP_DECODER (V4L2_CAP_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT | \ +#define IVTV_CAP_DECODER (V4L2_CAP_VIDEO_OUTPUT | \ V4L2_CAP_SLICED_VBI_OUTPUT | V4L2_CAP_VIDEO_OUTPUT_OVERLAY) struct ivtv_card_video_input { diff --git a/linux/drivers/media/video/ivtv/ivtv-ioctl.c b/linux/drivers/media/video/ivtv/ivtv-ioctl.c index 61030309d..f00854ad6 100644 --- a/linux/drivers/media/video/ivtv/ivtv-ioctl.c +++ b/linux/drivers/media/video/ivtv/ivtv-ioctl.c @@ -101,18 +101,15 @@ void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) } } -static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) +static void check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal) { int f, l; - u16 set = 0; for (f = 0; f < 2; f++) { for (l = 0; l < 24; l++) { fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal); - set |= fmt->service_lines[f][l]; } } - return set != 0; } u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt) @@ -474,7 +471,7 @@ static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format int h = fmt->fmt.pix.height; w = min(w, 720); - w = max(w, 1); + w = max(w, 2); h = min(h, itv->is_50hz ? 576 : 480); h = max(h, 2); ivtv_g_fmt_vid_cap(file, fh, fmt); @@ -512,27 +509,20 @@ static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_ static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt) { struct ivtv_open_id *id = fh; - s32 w, h; - int field; - int ret; + struct ivtv *itv = id->itv; + s32 w = fmt->fmt.pix.width; + s32 h = fmt->fmt.pix.height; + int field = fmt->fmt.pix.field; + int ret = ivtv_g_fmt_vid_out(file, fh, fmt); - w = fmt->fmt.pix.width; - h = fmt->fmt.pix.height; - field = fmt->fmt.pix.field; - ret = ivtv_g_fmt_vid_out(file, fh, fmt); + w = min(w, 720); + w = max(w, 2); + h = min(h, itv->is_out_50hz ? 576 : 480); + h = max(h, 2); + if (id->type == IVTV_DEC_STREAM_TYPE_YUV) + fmt->fmt.pix.field = field; fmt->fmt.pix.width = w; fmt->fmt.pix.height = h; - if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) { - fmt->fmt.pix.field = field; - if (fmt->fmt.pix.width < 2) - fmt->fmt.pix.width = 2; - if (fmt->fmt.pix.width > 720) - fmt->fmt.pix.width = 720; - if (fmt->fmt.pix.height < 2) - fmt->fmt.pix.height = 2; - if (fmt->fmt.pix.height > 576) - fmt->fmt.pix.height = 576; - } return ret; } @@ -560,9 +550,9 @@ static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *f struct ivtv_open_id *id = fh; struct ivtv *itv = id->itv; struct cx2341x_mpeg_params *p = &itv->params; + int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); int w = fmt->fmt.pix.width; int h = fmt->fmt.pix.height; - int ret = ivtv_try_fmt_vid_cap(file, fh, fmt); if (ret) return ret; @@ -600,8 +590,7 @@ static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_fo if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI) return ret; - if (check_service_set(vbifmt, itv->is_50hz) == 0) - return -EINVAL; + check_service_set(vbifmt, itv->is_50hz); if (atomic_read(&itv->capturing) > 0) return -EBUSY; itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); diff --git a/linux/drivers/media/video/saa7134/saa6752hs.c b/linux/drivers/media/video/saa7134/saa6752hs.c index 6c97d4ab4..8ccca4d56 100644 --- a/linux/drivers/media/video/saa7134/saa6752hs.c +++ b/linux/drivers/media/video/saa7134/saa6752hs.c @@ -225,7 +225,7 @@ static struct saa6752hs_mpeg_params param_defaults = /* ---------------------------------------------------------------------- */ -static int saa6752hs_chip_command(struct i2c_client* client, +static int saa6752hs_chip_command(struct i2c_client *client, enum saa6752hs_command command) { unsigned char buf[3]; @@ -292,54 +292,61 @@ static int saa6752hs_chip_command(struct i2c_client* client, } -static int saa6752hs_set_bitrate(struct i2c_client* client, +static inline void set_reg8(struct i2c_client *client, uint8_t reg, uint8_t val) +{ + u8 buf[2]; + + buf[0] = reg; + buf[1] = val; + i2c_master_send(client, buf, 2); +} + +static inline void set_reg16(struct i2c_client *client, uint8_t reg, uint16_t val) +{ + u8 buf[3]; + + buf[0] = reg; + buf[1] = val >> 8; + buf[2] = val & 0xff; + i2c_master_send(client, buf, 3); +} + +static int saa6752hs_set_bitrate(struct i2c_client *client, struct saa6752hs_state *h) { struct saa6752hs_mpeg_params *params = &h->params; - u8 buf[3]; int tot_bitrate; + int is_384k; /* set the bitrate mode */ - buf[0] = 0x71; - buf[1] = (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) ? 0 : 1; - i2c_master_send(client, buf, 2); + set_reg8(client, 0x71, + params->vi_bitrate_mode != V4L2_MPEG_VIDEO_BITRATE_MODE_VBR); /* set the video bitrate */ if (params->vi_bitrate_mode == V4L2_MPEG_VIDEO_BITRATE_MODE_VBR) { /* set the target bitrate */ - buf[0] = 0x80; - buf[1] = params->vi_bitrate >> 8; - buf[2] = params->vi_bitrate & 0xff; - i2c_master_send(client, buf, 3); + set_reg16(client, 0x80, params->vi_bitrate); /* set the max bitrate */ - buf[0] = 0x81; - buf[1] = params->vi_bitrate_peak >> 8; - buf[2] = params->vi_bitrate_peak & 0xff; - i2c_master_send(client, buf, 3); + set_reg16(client, 0x81, params->vi_bitrate_peak); tot_bitrate = params->vi_bitrate_peak; } else { /* set the target bitrate (no max bitrate for CBR) */ - buf[0] = 0x81; - buf[1] = params->vi_bitrate >> 8; - buf[2] = params->vi_bitrate & 0xff; - i2c_master_send(client, buf, 3); + set_reg16(client, 0x81, params->vi_bitrate); tot_bitrate = params->vi_bitrate; } /* set the audio encoding */ - buf[0] = 0x93; - buf[1] = (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); - i2c_master_send(client, buf, 2); + set_reg8(client, 0x93, + params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3); /* set the audio bitrate */ - buf[0] = 0x94; if (params->au_encoding == V4L2_MPEG_AUDIO_ENCODING_AC3) - buf[1] = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; + is_384k = V4L2_MPEG_AUDIO_AC3_BITRATE_384K == params->au_ac3_bitrate; else - buf[1] = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; - tot_bitrate += buf[1] ? 384 : 256; - i2c_master_send(client, buf, 2); + is_384k = V4L2_MPEG_AUDIO_L2_BITRATE_384K == params->au_l2_bitrate; + set_reg8(client, 0x94, is_384k); + tot_bitrate += is_384k ? 384 : 256; /* Note: the total max bitrate is determined by adding the video and audio bitrates together and also adding an extra 768kbit/s to stay on the @@ -350,16 +357,12 @@ static int saa6752hs_set_bitrate(struct i2c_client* client, tot_bitrate = MPEG_TOTAL_TARGET_BITRATE_MAX; /* set the total bitrate */ - buf[0] = 0xb1; - buf[1] = tot_bitrate >> 8; - buf[2] = tot_bitrate & 0xff; - i2c_master_send(client, buf, 3); - + set_reg16(client, 0xb1, tot_bitrate); return 0; } -static void saa6752hs_set_subsampling(struct i2c_client* client, - struct v4l2_format* f) +static void saa6752hs_set_subsampling(struct i2c_client *client, + struct v4l2_format *f) { struct saa6752hs_state *h = i2c_get_clientdata(client); int dist_352, dist_480, dist_720; @@ -666,51 +669,31 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) h = i2c_get_clientdata(client); /* Set video format - must be done first as it resets other settings */ - buf[0] = 0x41; - buf[1] = h->video_format; - i2c_master_send(client, buf, 2); + set_reg8(client, 0x41, h->video_format); /* Set number of lines in input signal */ - buf[0] = 0x40; - buf[1] = 0x00; - if (h->standard & V4L2_STD_525_60) - buf[1] = 0x01; - i2c_master_send(client, buf, 2); + set_reg8(client, 0x40, (h->standard & V4L2_STD_525_60) ? 1 : 0); /* set bitrate */ saa6752hs_set_bitrate(client, h); /* Set GOP structure {3, 13} */ - buf[0] = 0x72; - buf[1] = 0x03; - buf[2] = 0x0D; - i2c_master_send(client,buf,3); + set_reg16(client, 0x72, 0x030d); /* Set minimum Q-scale {4} */ - buf[0] = 0x82; - buf[1] = 0x04; - i2c_master_send(client,buf,2); + set_reg8(client, 0x82, 0x04); /* Set maximum Q-scale {12} */ - buf[0] = 0x83; - buf[1] = 0x0C; - i2c_master_send(client,buf,2); + set_reg8(client, 0x83, 0x0c); /* Set Output Protocol */ - buf[0] = 0xD0; - buf[1] = 0x81; - i2c_master_send(client,buf,2); + set_reg8(client, 0xd0, 0x81); /* Set video output stream format {TS} */ - buf[0] = 0xB0; - buf[1] = 0x05; - i2c_master_send(client,buf,2); + set_reg8(client, 0xb0, 0x05); /* Set leading null byte for TS */ - buf[0] = 0xF6; - buf[1] = (leading_null_bytes >> 8) & 0xff; - buf[2] = leading_null_bytes & 0xff; - i2c_master_send(client, buf, 3); + set_reg16(client, 0xf6, leading_null_bytes); /* compute PAT */ memcpy(localPAT, PAT, sizeof(PAT)); @@ -745,33 +728,21 @@ static int saa6752hs_init(struct i2c_client *client, u32 leading_null_bytes) localPMT[size - 1] = crc & 0xFF; /* Set Audio PID */ - buf[0] = 0xC1; - buf[1] = (h->params.ts_pid_audio >> 8) & 0xFF; - buf[2] = h->params.ts_pid_audio & 0xFF; - i2c_master_send(client,buf,3); + set_reg16(client, 0xc1, h->params.ts_pid_audio); /* Set Video PID */ - buf[0] = 0xC0; - buf[1] = (h->params.ts_pid_video >> 8) & 0xFF; - buf[2] = h->params.ts_pid_video & 0xFF; - i2c_master_send(client,buf,3); + set_reg16(client, 0xc0, h->params.ts_pid_video); /* Set PCR PID */ - buf[0] = 0xC4; - buf[1] = (h->params.ts_pid_pcr >> 8) & 0xFF; - buf[2] = h->params.ts_pid_pcr & 0xFF; - i2c_master_send(client,buf,3); + set_reg16(client, 0xc4, h->params.ts_pid_pcr); /* Send SI tables */ i2c_master_send(client, localPAT, sizeof(PAT)); i2c_master_send(client, localPMT, size); /* mute then unmute audio. This removes buzzing artefacts */ - buf[0] = 0xa4; - buf[1] = 1; - i2c_master_send(client, buf, 2); - buf[1] = 0; - i2c_master_send(client, buf, 2); + set_reg8(client, 0xa4, 1); + set_reg8(client, 0xa4, 0); /* start it going */ saa6752hs_chip_command(client, SAA6752HS_COMMAND_START); diff --git a/linux/drivers/media/video/saa7134/saa7134-empress.c b/linux/drivers/media/video/saa7134/saa7134-empress.c index 1451fdf99..9ebe166cc 100644 --- a/linux/drivers/media/video/saa7134/saa7134-empress.c +++ b/linux/drivers/media/video/saa7134/saa7134-empress.c @@ -303,15 +303,6 @@ static int empress_streamoff(struct file *file, void *priv, return videobuf_streamoff(&dev->empress_tsq); } -static int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, - unsigned int cmd, void *arg) -{ - if (dev->mpeg_i2c_client == NULL) - return -EINVAL; - return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, - cmd, arg); -} - static int empress_s_ext_ctrls(struct file *file, void *priv, struct v4l2_ext_controls *ctrls) { @@ -431,6 +422,20 @@ static int empress_g_chip_ident(struct file *file, void *fh, return -EINVAL; } +static int empress_s_std(struct file *file, void *priv, v4l2_std_id *id) +{ + struct saa7134_dev *dev = file->private_data; + + return saa7134_s_std_internal(dev, NULL, id); +} + +static int empress_g_std(struct file *file, void *priv, v4l2_std_id *id) +{ + struct saa7134_dev *dev = file->private_data; + + *id = dev->tvnorm->id; + return 0; +} static const struct file_operations ts_fops = { @@ -465,6 +470,8 @@ static const struct v4l2_ioctl_ops ts_ioctl_ops = { .vidioc_g_ctrl = empress_g_ctrl, .vidioc_s_ctrl = empress_s_ctrl, .vidioc_g_chip_ident = empress_g_chip_ident, + .vidioc_s_std = empress_s_std, + .vidioc_g_std = empress_g_std, }; /* ----------------------------------------------------------- */ diff --git a/linux/drivers/media/video/saa7134/saa7134-i2c.c b/linux/drivers/media/video/saa7134/saa7134-i2c.c index bdec276e0..2ca03df8c 100644 --- a/linux/drivers/media/video/saa7134/saa7134-i2c.c +++ b/linux/drivers/media/video/saa7134/saa7134-i2c.c @@ -432,6 +432,16 @@ void saa7134_i2c_call_clients(struct saa7134_dev *dev, i2c_clients_command(&dev->i2c_adap, cmd, arg); } +int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg) +{ + if (dev->mpeg_i2c_client == NULL) + return -EINVAL; + return dev->mpeg_i2c_client->driver->command(dev->mpeg_i2c_client, + cmd, arg); +} +EXPORT_SYMBOL_GPL(saa7134_i2c_call_saa6752); + int saa7134_i2c_register(struct saa7134_dev *dev) { dev->i2c_adap = saa7134_adap_template; diff --git a/linux/drivers/media/video/saa7134/saa7134-video.c b/linux/drivers/media/video/saa7134/saa7134-video.c index 547c0401a..241b60e3f 100644 --- a/linux/drivers/media/video/saa7134/saa7134-video.c +++ b/linux/drivers/media/video/saa7134/saa7134-video.c @@ -628,6 +628,9 @@ void saa7134_set_tvnorm_hw(struct saa7134_dev *dev) if (card_in(dev, dev->ctl_input).tv) saa7134_i2c_call_clients(dev, VIDIOC_S_STD, &dev->tvnorm->id); + /* Set the correct norm for the saa6752hs. This function + does nothing if there is no saa6752hs. */ + saa7134_i2c_call_saa6752(dev, VIDIOC_S_STD, &dev->tvnorm->id); } static void set_h_prescale(struct saa7134_dev *dev, int task, int prescale) @@ -1803,18 +1806,25 @@ static int saa7134_querycap(struct file *file, void *priv, return 0; } -static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) +int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id) { - struct saa7134_fh *fh = priv; - struct saa7134_dev *dev = fh->dev; unsigned long flags; unsigned int i; v4l2_std_id fixup; int err; - err = v4l2_prio_check(&dev->prio, &fh->prio); - if (0 != err) - return err; + /* When called from the empress code fh == NULL. + That needs to be fixed somehow, but for now this is + good enough. */ + if (fh) { + err = v4l2_prio_check(&dev->prio, &fh->prio); + if (0 != err) + return err; + } else if (res_locked(dev, RESOURCE_OVERLAY)) { + /* Don't change the std from the mpeg device + if overlay is active. */ + return -EBUSY; + } for (i = 0; i < TVNORMS; i++) if (*id == tvnorms[i].id) @@ -1847,7 +1857,7 @@ static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) *id = tvnorms[i].id; mutex_lock(&dev->lock); - if (res_check(fh, RESOURCE_OVERLAY)) { + if (fh && res_check(fh, RESOURCE_OVERLAY)) { spin_lock_irqsave(&dev->slock, flags); stop_preview(dev, fh); spin_unlock_irqrestore(&dev->slock, flags); @@ -1864,6 +1874,23 @@ static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) mutex_unlock(&dev->lock); return 0; } +EXPORT_SYMBOL_GPL(saa7134_s_std_internal); + +static int saa7134_s_std(struct file *file, void *priv, v4l2_std_id *id) +{ + struct saa7134_fh *fh = priv; + + return saa7134_s_std_internal(fh->dev, fh, id); +} + +static int saa7134_g_std(struct file *file, void *priv, v4l2_std_id *id) +{ + struct saa7134_fh *fh = priv; + struct saa7134_dev *dev = fh->dev; + + *id = dev->tvnorm->id; + return 0; +} static int saa7134_cropcap(struct file *file, void *priv, struct v4l2_cropcap *cap) @@ -2404,6 +2431,7 @@ static const struct v4l2_ioctl_ops video_ioctl_ops = { .vidioc_qbuf = saa7134_qbuf, .vidioc_dqbuf = saa7134_dqbuf, .vidioc_s_std = saa7134_s_std, + .vidioc_g_std = saa7134_g_std, .vidioc_enum_input = saa7134_enum_input, .vidioc_g_input = saa7134_g_input, .vidioc_s_input = saa7134_s_input, diff --git a/linux/drivers/media/video/saa7134/saa7134.h b/linux/drivers/media/video/saa7134/saa7134.h index 55aa60f52..50319493d 100644 --- a/linux/drivers/media/video/saa7134/saa7134.h +++ b/linux/drivers/media/video/saa7134/saa7134.h @@ -667,6 +667,8 @@ int saa7134_i2c_register(struct saa7134_dev *dev); int saa7134_i2c_unregister(struct saa7134_dev *dev); void saa7134_i2c_call_clients(struct saa7134_dev *dev, unsigned int cmd, void *arg); +int saa7134_i2c_call_saa6752(struct saa7134_dev *dev, + unsigned int cmd, void *arg); /* ----------------------------------------------------------- */ @@ -679,6 +681,7 @@ extern struct video_device saa7134_radio_template; int saa7134_s_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); int saa7134_g_ctrl_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, struct v4l2_control *c); int saa7134_queryctrl(struct file *file, void *priv, struct v4l2_queryctrl *c); +int saa7134_s_std_internal(struct saa7134_dev *dev, struct saa7134_fh *fh, v4l2_std_id *id); int saa7134_videoport_init(struct saa7134_dev *dev); void saa7134_set_tvnorm_hw(struct saa7134_dev *dev); |