From d0fbca290058bee7a54aefcc462e9ef33929d948 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 16 Aug 2008 11:55:04 +0100 Subject: Fix header export of videodev2.h, ivtv.h, ivtvfb.h From: David Woodhouse The exported copy of videodev2.h contains this line: #define #include This is because for some reason it defines __user for itself -- despite the fact that we remove all instances of __user when exporting headers. _All_ pointers in userspace are user pointers. Fix it by removing the unnecessary '#define __user' from the file. The new headers ivtv.h and ivtvfb.h would have the same problem... if whoever put them there had actually remembered to add them to the Kbuild file while he was at it. Fix those too, and export them as was presumably intended. Note that includes of are also stripped by the header export process, so those don't need to be conditional. kernel-sync: [mchehab.infradead.org: This is the backported version without the changes at include/linux/Kbuild, to be applied only at -hg] Signed-off-by: David Woodhouse Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- linux/include/linux/ivtv.h | 6 +----- linux/include/linux/ivtvfb.h | 6 +----- linux/include/linux/videodev2.h | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/linux/include/linux/ivtv.h b/linux/include/linux/ivtv.h index 794b8daa9..17ca64b5a 100644 --- a/linux/include/linux/ivtv.h +++ b/linux/include/linux/ivtv.h @@ -21,11 +21,7 @@ #ifndef __LINUX_IVTV_H__ #define __LINUX_IVTV_H__ -#ifdef __KERNEL__ -#include /* need __user */ -#else -#define __user -#endif +#include #include /* ivtv knows several distinct output modes: MPEG streaming, diff --git a/linux/include/linux/ivtvfb.h b/linux/include/linux/ivtvfb.h index e980ba62d..e20af47b5 100644 --- a/linux/include/linux/ivtvfb.h +++ b/linux/include/linux/ivtvfb.h @@ -21,11 +21,7 @@ #ifndef __LINUX_IVTVFB_H__ #define __LINUX_IVTVFB_H__ -#ifdef __KERNEL__ -#include /* need __user */ -#else -#define __user -#endif +#include #include /* Framebuffer external API */ diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h index f3ae9c88e..a79fc1584 100644 --- a/linux/include/linux/videodev2.h +++ b/linux/include/linux/videodev2.h @@ -55,13 +55,13 @@ */ #ifndef __LINUX_VIDEODEV2_H #define __LINUX_VIDEODEV2_H + #ifdef __KERNEL__ #include /* need struct timeval */ -#include /* need __user */ #else -#define __user #include #endif +#include #include #include -- cgit v1.2.3 From 8896d4269aa500bfa93d4a088bf12c470cfa5a2e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 20 Aug 2008 16:44:54 -0700 Subject: saa7134-core.c: fix warning From: Alexander Beregalov drivers/media/video/saa7134/saa7134-core.c:366: warning: 'saa7134_buffer_requeue' defined but not used Signed-off-by: Alexander Beregalov Signed-off-by: Andrew Morton Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/saa7134/saa7134-core.c | 52 ++++++++++++------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/linux/drivers/media/video/saa7134/saa7134-core.c b/linux/drivers/media/video/saa7134/saa7134-core.c index e02c3c1b1..62c9322aa 100644 --- a/linux/drivers/media/video/saa7134/saa7134-core.c +++ b/linux/drivers/media/video/saa7134/saa7134-core.c @@ -408,32 +408,6 @@ void saa7134_buffer_timeout(unsigned long data) spin_unlock_irqrestore(&dev->slock,flags); } -/* resends a current buffer in queue after resume */ - -static int saa7134_buffer_requeue(struct saa7134_dev *dev, - struct saa7134_dmaqueue *q) -{ - struct saa7134_buf *buf, *next; - - assert_spin_locked(&dev->slock); - - buf = q->curr; - next = buf; - dprintk("buffer_requeue\n"); - - if (!buf) - return 0; - - dprintk("buffer_requeue : resending active buffers \n"); - - if (!list_empty(&q->queue)) - next = list_entry(q->queue.next, struct saa7134_buf, - vb.queue); - buf->activate(dev, buf, next); - - return 0; -} - /* ------------------------------------------------------------------ */ int saa7134_set_dmabits(struct saa7134_dev *dev) @@ -1203,6 +1177,32 @@ static void __devexit saa7134_finidev(struct pci_dev *pci_dev) } #ifdef CONFIG_PM + +/* resends a current buffer in queue after resume */ +static int saa7134_buffer_requeue(struct saa7134_dev *dev, + struct saa7134_dmaqueue *q) +{ + struct saa7134_buf *buf, *next; + + assert_spin_locked(&dev->slock); + + buf = q->curr; + next = buf; + dprintk("buffer_requeue\n"); + + if (!buf) + return 0; + + dprintk("buffer_requeue : resending active buffers \n"); + + if (!list_empty(&q->queue)) + next = list_entry(q->queue.next, struct saa7134_buf, + vb.queue); + buf->activate(dev, buf, next); + + return 0; +} + static int saa7134_suspend(struct pci_dev *pci_dev , pm_message_t state) { -- cgit v1.2.3 From ea03de48c87e9209713cf3fb48848ab9cf138c0e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Thu, 21 Aug 2008 19:09:42 -0300 Subject: v4l2-ioctl.c: fix warning From: Alexander Beregalov drivers/media/video/v4l2-ioctl.c:496: warning: format '%08ld' expects type 'long int', but argument 5 has type 'suseconds_t' Signed-off-by: Alexander Beregalov Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-ioctl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/v4l2-ioctl.c b/linux/drivers/media/video/v4l2-ioctl.c index 1c8fa257d..51569f888 100644 --- a/linux/drivers/media/video/v4l2-ioctl.c +++ b/linux/drivers/media/video/v4l2-ioctl.c @@ -500,7 +500,7 @@ static void dbgbuf(unsigned int cmd, struct video_device *vfd, p->timestamp.tv_sec / 3600, (int)(p->timestamp.tv_sec / 60) % 60, (int)(p->timestamp.tv_sec % 60), - p->timestamp.tv_usec, + (long)p->timestamp.tv_usec, p->index, prt_names(p->type, v4l2_type_names), p->bytesused, p->flags, -- cgit v1.2.3 From 189a39592e02ff2f9a387eff92dfc3a3a2e4ddfb Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Sat, 9 Aug 2008 08:54:24 +0200 Subject: V4L: fix return value of register video func From: Henrik Kretzschmar If a wrong device type is used with video_register_device_index() it should better return an error number, instead of a constant. Signed-off-by: Henrik Kretzschmar Signed-off-by: Mauro Carvalho Chehab --- linux/drivers/media/video/v4l2-dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux/drivers/media/video/v4l2-dev.c b/linux/drivers/media/video/v4l2-dev.c index d97320091..594f2477f 100644 --- a/linux/drivers/media/video/v4l2-dev.c +++ b/linux/drivers/media/video/v4l2-dev.c @@ -316,7 +316,7 @@ int video_register_device_index(struct video_device *vfd, int type, int nr, default: printk(KERN_ERR "%s called with unknown type: %d\n", __func__, type); - return -1; + return -EINVAL; } /* pick a minor number */ -- cgit v1.2.3 From ad4e9eb607f09f8918f58c2d974e51a19db1b1d0 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 14 Aug 2008 16:36:37 +0200 Subject: Add Micron mt9m111 chip ID in V4L2 identifiers Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- include/media/v4l2-chip-ident.h | 1 + 1 files changed, 1 insertions(+), 0 deletions(-) --- linux/include/media/v4l2-chip-ident.h | 1 + 1 file changed, 1 insertion(+) diff --git a/linux/include/media/v4l2-chip-ident.h b/linux/include/media/v4l2-chip-ident.h index be782d5fc..d73a8e902 100644 --- a/linux/include/media/v4l2-chip-ident.h +++ b/linux/include/media/v4l2-chip-ident.h @@ -165,6 +165,7 @@ enum { /* Micron CMOS sensor chips: 45000-45099 */ V4L2_IDENT_MT9M001C12ST = 45000, V4L2_IDENT_MT9M001C12STM = 45005, + V4L2_IDENT_MT9M111 = 45007, V4L2_IDENT_MT9V022IX7ATC = 45010, /* No way to detect "normal" I77ATx */ V4L2_IDENT_MT9V022IX7ATM = 45015, /* and "lead free" IA7ATx chips */ }; -- cgit v1.2.3 From abbb53148b769e275aba74bdf00b7dc50b937628 Mon Sep 17 00:00:00 2001 From: Robert Jarzmik Date: Thu, 14 Aug 2008 17:02:51 +0200 Subject: Add support for Micron MT9M111 camera. Adds support for Micron MT9M111 camera chip, with basic features : - view rectangle configurable - some output formats (bayer8, bayer10, rgb565, rgb555, ycbycr) - autoexposure - only highpower mode context used (ie. context B) Signed-off-by: Robert Jarzmik Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/Kconfig | 6 + drivers/media/video/Makefile | 1 + drivers/media/video/mt9m111.c | 960 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 967 insertions(+), 0 deletions(-) create mode 100644 drivers/media/video/mt9m111.c --- linux/drivers/media/video/Kconfig | 6 + linux/drivers/media/video/Makefile | 1 + linux/drivers/media/video/mt9m111.c | 960 ++++++++++++++++++++++++++++++++++++ 3 files changed, 967 insertions(+) create mode 100644 linux/drivers/media/video/mt9m111.c diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4c96b690a..c6516d42c 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -809,6 +809,12 @@ config MT9M001_PCA9536_SWITCH Select this if your MT9M001 camera uses a PCA9536 I2C GPIO extender to switch between 8 and 10 bit datawidth modes +config SOC_CAMERA_MT9M111 + tristate "mt9m001 support" + depends on SOC_CAMERA && I2C + help + This driver supports MT9M111 cameras from Micron + config SOC_CAMERA_MT9V022 tristate "mt9v022 support" depends on SOC_CAMERA && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index bf429b023..44e6ab891 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -138,6 +138,7 @@ obj-$(CONFIG_VIDEO_PXA27x) += pxa_camera.o obj-$(CONFIG_VIDEO_SH_MOBILE_CEU) += sh_mobile_ceu_camera.o obj-$(CONFIG_SOC_CAMERA) += soc_camera.o obj-$(CONFIG_SOC_CAMERA_MT9M001) += mt9m001.o +obj-$(CONFIG_SOC_CAMERA_MT9M111) += mt9m111.o obj-$(CONFIG_SOC_CAMERA_MT9V022) += mt9v022.o obj-$(CONFIG_SOC_CAMERA_PLATFORM) += soc_camera_platform.o diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c new file mode 100644 index 000000000..0c88e5d6d --- /dev/null +++ b/linux/drivers/media/video/mt9m111.c @@ -0,0 +1,960 @@ +/* + * Driver for MT9M111 CMOS Image Sensor from Micron + * + * Copyright (C) 2008, Robert Jarzmik + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * mt9m111 i2c address is 0x5d or 0x48 (depending on SAddr pin) + * The platform has to define i2c_board_info and call i2c_register_board_info() + */ + +/* mt9m111: Sensor register addresses */ +#define MT9M111_CHIP_VERSION 0x000 +#define MT9M111_ROW_START 0x001 +#define MT9M111_COLUMN_START 0x002 +#define MT9M111_WINDOW_HEIGHT 0x003 +#define MT9M111_WINDOW_WIDTH 0x004 +#define MT9M111_HORIZONTAL_BLANKING_B 0x005 +#define MT9M111_VERTICAL_BLANKING_B 0x006 +#define MT9M111_HORIZONTAL_BLANKING_A 0x007 +#define MT9M111_VERTICAL_BLANKING_A 0x008 +#define MT9M111_SHUTTER_WIDTH 0x009 +#define MT9M111_ROW_SPEED 0x00a +#define MT9M111_EXTRA_DELAY 0x00b +#define MT9M111_SHUTTER_DELAY 0x00c +#define MT9M111_RESET 0x00d +#define MT9M111_READ_MODE_B 0x020 +#define MT9M111_READ_MODE_A 0x021 +#define MT9M111_FLASH_CONTROL 0x023 +#define MT9M111_GREEN1_GAIN 0x02b +#define MT9M111_BLUE_GAIN 0x02c +#define MT9M111_RED_GAIN 0x02d +#define MT9M111_GREEN2_GAIN 0x02e +#define MT9M111_GLOBAL_GAIN 0x02f +#define MT9M111_CONTEXT_CONTROL 0x0c8 +#define MT9M111_PAGE_MAP 0x0f0 +#define MT9M111_BYTE_WISE_ADDR 0x0f1 + +#define MT9M111_RESET_SYNC_CHANGES (1 << 15) +#define MT9M111_RESET_RESTART_BAD_FRAME (1 << 9) +#define MT9M111_RESET_SHOW_BAD_FRAMES (1 << 8) +#define MT9M111_RESET_RESET_SOC (1 << 5) +#define MT9M111_RESET_OUTPUT_DISABLE (1 << 4) +#define MT9M111_RESET_CHIP_ENABLE (1 << 3) +#define MT9M111_RESET_ANALOG_STANDBY (1 << 2) +#define MT9M111_RESET_RESTART_FRAME (1 << 1) +#define MT9M111_RESET_RESET_MODE (1 << 0) + +#define MT9M111_RMB_MIRROR_COLS (1 << 1) +#define MT9M111_RMB_MIRROR_ROWS (1 << 0) +#define MT9M111_CTXT_CTRL_RESTART (1 << 15) +#define MT9M111_CTXT_CTRL_DEFECTCOR_B (1 << 12) +#define MT9M111_CTXT_CTRL_RESIZE_B (1 << 10) +#define MT9M111_CTXT_CTRL_CTRL2_B (1 << 9) +#define MT9M111_CTXT_CTRL_GAMMA_B (1 << 8) +#define MT9M111_CTXT_CTRL_XENON_EN (1 << 7) +#define MT9M111_CTXT_CTRL_READ_MODE_B (1 << 3) +#define MT9M111_CTXT_CTRL_LED_FLASH_EN (1 << 2) +#define MT9M111_CTXT_CTRL_VBLANK_SEL_B (1 << 1) +#define MT9M111_CTXT_CTRL_HBLANK_SEL_B (1 << 0) +/* + * mt9m111: Colorpipe register addresses (0x100..0x1ff) + */ +#define MT9M111_OPER_MODE_CTRL 0x106 +#define MT9M111_OUTPUT_FORMAT_CTRL 0x108 +#define MT9M111_REDUCER_XZOOM_B 0x1a0 +#define MT9M111_REDUCER_XSIZE_B 0x1a1 +#define MT9M111_REDUCER_YZOOM_B 0x1a3 +#define MT9M111_REDUCER_YSIZE_B 0x1a4 +#define MT9M111_REDUCER_XZOOM_A 0x1a6 +#define MT9M111_REDUCER_XSIZE_A 0x1a7 +#define MT9M111_REDUCER_YZOOM_A 0x1a9 +#define MT9M111_REDUCER_YSIZE_A 0x1aa + +#define MT9M111_OUTPUT_FORMAT_CTRL2_A 0x13a +#define MT9M111_OUTPUT_FORMAT_CTRL2_B 0x19b + +#define MT9M111_OPMODE_AUTOEXPO_EN (1 << 14) + + +#define MT9M111_OUTFMT_PROCESSED_BAYER (1 << 14) +#define MT9M111_OUTFMT_BYPASS_IFP (1 << 10) +#define MT9M111_OUTFMT_INV_PIX_CLOCK (1 << 9) +#define MT9M111_OUTFMT_RGB (1 << 8) +#define MT9M111_OUTFMT_RGB565 (0x0 << 6) +#define MT9M111_OUTFMT_RGB555 (0x1 << 6) +#define MT9M111_OUTFMT_RGB444x (0x2 << 6) +#define MT9M111_OUTFMT_RGBx444 (0x3 << 6) +#define MT9M111_OUTFMT_TST_RAMP_OFF (0x0 << 4) +#define MT9M111_OUTFMT_TST_RAMP_COL (0x1 << 4) +#define MT9M111_OUTFMT_TST_RAMP_ROW (0x2 << 4) +#define MT9M111_OUTFMT_TST_RAMP_FRAME (0x3 << 4) +#define MT9M111_OUTFMT_SHIFT_3_UP (1 << 3) +#define MT9M111_OUTFMT_AVG_CHROMA (1 << 2) +#define MT9M111_OUTFMT_SWAP_YCbCr_C_Y (1 << 1) +#define MT9M111_OUTFMT_SWAP_RGB_EVEN (1 << 1) +#define MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr (1 << 0) +/* + * mt9m111: Camera control register addresses (0x200..0x2ff not implemented) + */ + +#define reg_read(reg) mt9m111_reg_read(icd, MT9M111_##reg) +#define reg_write(reg, val) mt9m111_reg_write(icd, MT9M111_##reg, (val)) +#define reg_set(reg, val) mt9m111_reg_set(icd, MT9M111_##reg, (val)) +#define reg_clear(reg, val) mt9m111_reg_clear(icd, MT9M111_##reg, (val)) + +#define MT9M111_MIN_DARK_ROWS 8 +#define MT9M111_MIN_DARK_COLS 24 +#define MT9M111_MAX_HEIGHT 1024 +#define MT9M111_MAX_WIDTH 1280 + +#define COL_FMT(_name, _depth, _fourcc, _colorspace) \ + { .name = _name, .depth = _depth, .fourcc = _fourcc, \ + .colorspace = _colorspace } +#define RGB_FMT(_name, _depth, _fourcc) \ + COL_FMT(_name, _depth, _fourcc, V4L2_COLORSPACE_SRGB) + +static const struct soc_camera_data_format mt9m111_colour_formats[] = { + COL_FMT("YCrYCb 8 bit", 8, V4L2_PIX_FMT_YUYV, V4L2_COLORSPACE_JPEG), + RGB_FMT("RGB 565", 16, V4L2_PIX_FMT_RGB565), + RGB_FMT("RGB 555", 16, V4L2_PIX_FMT_RGB555), + RGB_FMT("Bayer (sRGB) 10 bit", 10, V4L2_PIX_FMT_SBGGR16), + RGB_FMT("Bayer (sRGB) 8 bit", 8, V4L2_PIX_FMT_SBGGR8), +}; + +enum mt9m111_context { + HIGHPOWER = 0, + LOWPOWER, +}; + +struct mt9m111 { + struct i2c_client *client; + struct soc_camera_device icd; + int model; /* V4L2_IDENT_MT9M111* codes from v4l2-chip-ident.h */ + enum mt9m111_context context; + unsigned int left, top, width, height; + u32 pixfmt; + unsigned char autoexposure; + unsigned char datawidth; + unsigned int powered:1; + unsigned int hflip:1; + unsigned int vflip:1; + unsigned int swap_rgb_even_odd:1; + unsigned int swap_rgb_red_blue:1; + unsigned int swap_yuv_y_chromas:1; + unsigned int swap_yuv_cb_cr:1; +}; + +static int reg_page_map_set(struct i2c_client *client, const u16 reg) +{ + int ret; + u16 page; + static int lastpage = -1; /* PageMap cache value */ + + page = (reg >> 8); + if (page == lastpage) + return 0; + if (page > 2) + return -EINVAL; + + ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); + if (ret >= 0) + lastpage = page; + return ret; +} + +static int mt9m111_reg_read(struct soc_camera_device *icd, const u16 reg) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct i2c_client *client = mt9m111->client; + int ret; + + ret = reg_page_map_set(client, reg); + if (!ret) + ret = swab16(i2c_smbus_read_word_data(client, (reg & 0xff))); + + dev_dbg(&icd->dev, "read reg.%03x -> %04x\n", reg, ret); + return ret; +} + +static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct i2c_client *client = mt9m111->client; + int ret; + + ret = reg_page_map_set(client, reg); + if (ret >= 0) + ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), + swab16(data)); + dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); + return ret; +} + +static int mt9m111_reg_set(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + int ret; + + ret = mt9m111_reg_read(icd, reg); + if (ret >= 0) + ret = mt9m111_reg_write(icd, reg, ret | data); + return ret; +} + +static int mt9m111_reg_clear(struct soc_camera_device *icd, const u16 reg, + const u16 data) +{ + int ret; + + ret = mt9m111_reg_read(icd, reg); + return mt9m111_reg_write(icd, reg, ret & ~data); +} + +static int mt9m111_set_context(struct soc_camera_device *icd, + enum mt9m111_context ctxt) +{ + int valB = MT9M111_CTXT_CTRL_RESTART | MT9M111_CTXT_CTRL_DEFECTCOR_B + | MT9M111_CTXT_CTRL_RESIZE_B | MT9M111_CTXT_CTRL_CTRL2_B + | MT9M111_CTXT_CTRL_GAMMA_B | MT9M111_CTXT_CTRL_READ_MODE_B + | MT9M111_CTXT_CTRL_VBLANK_SEL_B + | MT9M111_CTXT_CTRL_HBLANK_SEL_B; + int valA = MT9M111_CTXT_CTRL_RESTART; + + if (ctxt == HIGHPOWER) + return reg_write(CONTEXT_CONTROL, valB); + else + return reg_write(CONTEXT_CONTROL, valA); +} + +static int mt9m111_setup_rect(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0, is_raw_format; + int width = mt9m111->width; + int height = mt9m111->height; + + if ((mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR8) + || (mt9m111->pixfmt == V4L2_PIX_FMT_SBGGR16)) + is_raw_format = 1; + else + is_raw_format = 0; + + if (ret >= 0) + ret = reg_write(COLUMN_START, mt9m111->left); + if (ret >= 0) + ret = reg_write(ROW_START, mt9m111->top); + + if (is_raw_format) { + if (ret >= 0) + ret = reg_write(WINDOW_WIDTH, width); + if (ret >= 0) + ret = reg_write(WINDOW_HEIGHT, height); + } else { + if (ret >= 0) + ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); + if (ret >= 0) + ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); + if (ret >= 0) + ret = reg_write(REDUCER_XSIZE_B, width); + if (ret >= 0) + ret = reg_write(REDUCER_YSIZE_B, height); + if (ret >= 0) + ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); + if (ret >= 0) + ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); + if (ret >= 0) + ret = reg_write(REDUCER_XSIZE_A, width); + if (ret >= 0) + ret = reg_write(REDUCER_YSIZE_A, height); + } + + return ret; +} + +static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) +{ + int ret; + + ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); + if (ret >= 0) + ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); + return ret; +} + +static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) +{ + return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_PROCESSED_BAYER); +} + +static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) +{ + + return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); +} + +static int mt9m111_setfmt_rgb565(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB565; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_setfmt_rgb555(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_rgb_red_blue) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_rgb_even_odd) + val |= MT9M111_OUTFMT_SWAP_RGB_EVEN; + val |= MT9M111_OUTFMT_RGB | MT9M111_OUTFMT_RGB555; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int val = 0; + + if (mt9m111->swap_yuv_cb_cr) + val |= MT9M111_OUTFMT_SWAP_YCbCr_Cb_Cr; + if (mt9m111->swap_yuv_y_chromas) + val |= MT9M111_OUTFMT_SWAP_YCbCr_C_Y; + + return mt9m111_setup_pixfmt(icd, val); +} + +static int mt9m111_enable(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); + if (ret >= 0) + mt9m111->powered = 1; + return ret; +} + +static int mt9m111_disable(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); + if (ret >= 0) + mt9m111->powered = 0; + return ret; +} + +static int mt9m111_reset(struct soc_camera_device *icd) +{ + int ret; + + ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); + if (ret >= 0) + ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); + if (ret >= 0) + ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE + | MT9M111_RESET_RESET_SOC); + return ret; +} + +static int mt9m111_start_capture(struct soc_camera_device *icd) +{ + return 0; +} + +static int mt9m111_stop_capture(struct soc_camera_device *icd) +{ + return 0; +} + +static unsigned long mt9m111_query_bus_param(struct soc_camera_device *icd) +{ + return SOCAM_MASTER | SOCAM_PCLK_SAMPLE_RISING | + SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | + SOCAM_DATAWIDTH_8; +} + +static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) +{ + return 0; +} + +static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + switch (pixfmt) { + case V4L2_PIX_FMT_SBGGR8: + ret = mt9m111_setfmt_bayer8(icd); + break; + case V4L2_PIX_FMT_SBGGR16: + ret = mt9m111_setfmt_bayer10(icd); + break; + case V4L2_PIX_FMT_RGB555: + ret = mt9m111_setfmt_rgb555(icd); + break; + case V4L2_PIX_FMT_RGB565: + ret = mt9m111_setfmt_rgb565(icd); + break; + case V4L2_PIX_FMT_YUYV: + ret = mt9m111_setfmt_yuv(icd); + break; + default: + dev_err(&icd->dev, "Pixel format not handled : %x\n", pixfmt); + ret = -EINVAL; + } + + if (ret >= 0) + mt9m111->pixfmt = pixfmt; + + return ret; +} + +static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, + __u32 pixfmt, struct v4l2_rect *rect) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + mt9m111->left = rect->left; + mt9m111->top = rect->top; + mt9m111->width = rect->width; + mt9m111->height = rect->height; + + dev_dbg(&icd->dev, "%s fmt=%x left=%d, top=%d, width=%d, height=%d\n", + __func__, pixfmt, mt9m111->left, mt9m111->top, mt9m111->width, + mt9m111->height); + + ret = mt9m111_setup_rect(icd); + if (ret >= 0) + ret = mt9m111_set_pixfmt(icd, pixfmt); + return ret < 0 ? ret : 0; +} + +static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, + struct v4l2_format *f) +{ + if (f->fmt.pix.height > MT9M111_MAX_HEIGHT) + f->fmt.pix.height = MT9M111_MAX_HEIGHT; + if (f->fmt.pix.width > MT9M111_MAX_WIDTH) + f->fmt.pix.width = MT9M111_MAX_WIDTH; + + return 0; +} + +static int mt9m111_get_chip_id(struct soc_camera_device *icd, + struct v4l2_chip_ident *id) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (id->match_type != V4L2_CHIP_MATCH_I2C_ADDR) + return -EINVAL; + + if (id->match_chip != mt9m111->client->addr) + return -ENODEV; + + id->ident = mt9m111->model; + id->revision = 0; + + return 0; +} + +#ifdef CONFIG_VIDEO_ADV_DEBUG +static int mt9m111_get_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + int val; + + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + return -EINVAL; + if (reg->match_chip != mt9m111->client->addr) + return -ENODEV; + + val = mt9m111_reg_read(icd, reg->reg); + reg->val = (u64)val; + + if (reg->val > 0xffff) + return -EIO; + + return 0; +} + +static int mt9m111_set_register(struct soc_camera_device *icd, + struct v4l2_register *reg) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + if (reg->match_type != V4L2_CHIP_MATCH_I2C_ADDR || reg->reg > 0x2ff) + return -EINVAL; + + if (reg->match_chip != mt9m111->client->addr) + return -ENODEV; + + if (mt9m111_reg_write(icd, reg->reg, reg->val) < 0) + return -EIO; + + return 0; +} +#endif + +static const struct v4l2_queryctrl mt9m111_controls[] = { + { + .id = V4L2_CID_VFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Verticaly", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { + .id = V4L2_CID_HFLIP, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Flip Horizontaly", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 0, + }, { /* gain = 1/32*val (=>gain=1 if val==32) */ + .id = V4L2_CID_GAIN, + .type = V4L2_CTRL_TYPE_INTEGER, + .name = "Gain", + .minimum = 0, + .maximum = 63 * 2 * 2, + .step = 1, + .default_value = 32, + .flags = V4L2_CTRL_FLAG_SLIDER, + }, { + .id = V4L2_CID_EXPOSURE_AUTO, + .type = V4L2_CTRL_TYPE_BOOLEAN, + .name = "Auto Exposure", + .minimum = 0, + .maximum = 1, + .step = 1, + .default_value = 1, + } +}; + +static int mt9m111_video_probe(struct soc_camera_device *); +static void mt9m111_video_remove(struct soc_camera_device *); +static int mt9m111_get_control(struct soc_camera_device *, + struct v4l2_control *); +static int mt9m111_set_control(struct soc_camera_device *, + struct v4l2_control *); +static int mt9m111_resume(struct soc_camera_device *icd); +static int mt9m111_init(struct soc_camera_device *icd); +static int mt9m111_release(struct soc_camera_device *icd); + +static struct soc_camera_ops mt9m111_ops = { + .owner = THIS_MODULE, + .probe = mt9m111_video_probe, + .remove = mt9m111_video_remove, + .init = mt9m111_init, + .resume = mt9m111_resume, + .release = mt9m111_release, + .start_capture = mt9m111_start_capture, + .stop_capture = mt9m111_stop_capture, + .set_fmt_cap = mt9m111_set_fmt_cap, + .try_fmt_cap = mt9m111_try_fmt_cap, + .query_bus_param = mt9m111_query_bus_param, + .set_bus_param = mt9m111_set_bus_param, + .controls = mt9m111_controls, + .num_controls = ARRAY_SIZE(mt9m111_controls), + .get_control = mt9m111_get_control, + .set_control = mt9m111_set_control, + .get_chip_id = mt9m111_get_chip_id, +#ifdef CONFIG_VIDEO_ADV_DEBUG + .get_register = mt9m111_get_register, + .set_register = mt9m111_set_register, +#endif +}; + +static int mt9m111_set_flip(struct soc_camera_device *icd, int flip, int mask) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + if (mt9m111->context == HIGHPOWER) { + if (flip) + ret = reg_set(READ_MODE_B, mask); + else + ret = reg_clear(READ_MODE_B, mask); + } else { + if (flip) + ret = reg_set(READ_MODE_A, mask); + else + ret = reg_clear(READ_MODE_A, mask); + } + + return ret; +} + +static int mt9m111_get_global_gain(struct soc_camera_device *icd) +{ + unsigned int data, gain; + + data = reg_read(GLOBAL_GAIN); + if (data >= 0) + gain = ((data & (1 << 10)) * 2) + | ((data & (1 << 9)) * 2) + | (data & 0x2f); + else + gain = data; + + return gain; +} +static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) +{ + u16 val; + + if (gain > 63 * 2 * 2) + return -EINVAL; + + icd->gain = gain; + if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) + val = (1 << 10) | (1 << 9) | (gain / 4); + else if ((gain >= 64) && (gain < 64 * 2)) + val = (1<<9) | (gain / 2); + else + val = gain; + + return reg_write(GLOBAL_GAIN, val); +} + +static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + if (on) + ret = reg_set(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + else + ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); + + if (ret >= 0) + mt9m111->autoexposure = on; + + return ret; +} +static int mt9m111_get_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int data; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + ctrl->value = !!(data & MT9M111_RMB_MIRROR_ROWS); + break; + case V4L2_CID_HFLIP: + if (mt9m111->context == HIGHPOWER) + data = reg_read(READ_MODE_B); + else + data = reg_read(READ_MODE_A); + + if (data < 0) + return -EIO; + ctrl->value = !!(data & MT9M111_RMB_MIRROR_COLS); + break; + case V4L2_CID_GAIN: + data = mt9m111_get_global_gain(icd); + if (data < 0) + return data; + ctrl->value = data; + break; + case V4L2_CID_EXPOSURE_AUTO: + ctrl->value = mt9m111->autoexposure; + break; + } + return 0; +} + +static int mt9m111_set_control(struct soc_camera_device *icd, + struct v4l2_control *ctrl) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + const struct v4l2_queryctrl *qctrl; + int ret = 0; + + qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); + + if (!qctrl) + return -EINVAL; + + switch (ctrl->id) { + case V4L2_CID_VFLIP: + mt9m111->vflip = ctrl->value; + ret = mt9m111_set_flip(icd, ctrl->value, + MT9M111_RMB_MIRROR_ROWS); + break; + case V4L2_CID_HFLIP: + mt9m111->hflip = ctrl->value; + ret = mt9m111_set_flip(icd, ctrl->value, + MT9M111_RMB_MIRROR_COLS); + break; + case V4L2_CID_GAIN: + ret = mt9m111_set_global_gain(icd, ctrl->value); + break; + case V4L2_CID_EXPOSURE_AUTO: + ret = mt9m111_set_autoexposure(icd, ctrl->value); + break; + default: + ret = -EINVAL; + } + + return ret < 0 ? -EIO : 0; +} + +int mt9m111_restore_state(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + mt9m111_set_context(icd, mt9m111->context); + mt9m111_set_pixfmt(icd, mt9m111->pixfmt); + mt9m111_setup_rect(icd); + mt9m111_set_flip(icd, mt9m111->hflip, MT9M111_RMB_MIRROR_COLS); + mt9m111_set_flip(icd, mt9m111->vflip, MT9M111_RMB_MIRROR_ROWS); + mt9m111_set_global_gain(icd, icd->gain); + mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + return 0; +} + +static int mt9m111_resume(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret = 0; + + if (mt9m111->powered) { + ret = mt9m111_enable(icd); + if (ret >= 0) + mt9m111_reset(icd); + if (ret >= 0) + mt9m111_restore_state(icd); + } + return ret; +} + +static int mt9m111_init(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + int ret; + + mt9m111->context = HIGHPOWER; + ret = mt9m111_enable(icd); + if (ret >= 0) + mt9m111_reset(icd); + if (ret >= 0) + mt9m111_set_context(icd, mt9m111->context); + if (ret >= 0) + mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + if (ret < 0) + dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); + return ret ? -EIO : 0; +} + +static int mt9m111_release(struct soc_camera_device *icd) +{ + int ret; + + ret = mt9m111_disable(icd); + if (ret < 0) + dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); + + return ret ? -EIO : 0; +} + +/* + * Interface active, can use i2c. If it fails, it can indeed mean, that + * this wasn't our capture interface, so, we wait for the right one + */ +static int mt9m111_video_probe(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + s32 data; + int ret; + + /* + * We must have a parent by now. And it cannot be a wrong one. + * So this entire test is completely redundant. + */ + if (!icd->dev.parent || + to_soc_camera_host(icd->dev.parent)->nr != icd->iface) + return -ENODEV; + + ret = mt9m111_enable(icd); + if (ret) + goto ei2c; + ret = mt9m111_reset(icd); + if (ret) + goto ei2c; + + data = reg_read(CHIP_VERSION); + + switch (data) { + case 0x143a: + mt9m111->model = V4L2_IDENT_MT9M111; + icd->formats = mt9m111_colour_formats; + icd->num_formats = ARRAY_SIZE(mt9m111_colour_formats); + break; + default: + ret = -ENODEV; + dev_err(&icd->dev, + "No MT9M111 chip detected, register read %x\n", data); + goto ei2c; + } + + dev_info(&icd->dev, "Detected a MT9M111 chip ID 0x143a\n"); + + ret = soc_camera_video_start(icd); + if (ret) + goto eisis; + + mt9m111->autoexposure = 1; + + mt9m111->swap_rgb_even_odd = 1; + mt9m111->swap_rgb_red_blue = 1; + + return 0; +eisis: +ei2c: + return ret; +} + +static void mt9m111_video_remove(struct soc_camera_device *icd) +{ + struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + + dev_dbg(&icd->dev, "Video %x removed: %p, %p\n", mt9m111->client->addr, + mt9m111->icd.dev.parent, mt9m111->icd.vdev); + soc_camera_video_stop(&mt9m111->icd); +} + +static int mt9m111_probe(struct i2c_client *client, + const struct i2c_device_id *did) +{ + struct mt9m111 *mt9m111; + struct soc_camera_device *icd; + struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent); + struct soc_camera_link *icl = client->dev.platform_data; + int ret; + + if (!icl) { + dev_err(&client->dev, "MT9M111 driver needs platform data\n"); + return -EINVAL; + } + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { + dev_warn(&adapter->dev, + "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); + return -EIO; + } + + mt9m111 = kzalloc(sizeof(struct mt9m111), GFP_KERNEL); + if (!mt9m111) + return -ENOMEM; + + mt9m111->client = client; + i2c_set_clientdata(client, mt9m111); + + /* Second stage probe - when a capture adapter is there */ + icd = &mt9m111->icd; + icd->ops = &mt9m111_ops; + icd->control = &client->dev; + icd->x_min = MT9M111_MIN_DARK_COLS; + icd->y_min = MT9M111_MIN_DARK_ROWS; + icd->x_current = icd->x_min; + icd->y_current = icd->y_min; + icd->width_min = MT9M111_MIN_DARK_ROWS; + icd->width_max = MT9M111_MAX_WIDTH; + icd->height_min = MT9M111_MIN_DARK_COLS; + icd->height_max = MT9M111_MAX_HEIGHT; + icd->y_skip_top = 0; + icd->iface = icl->bus_id; + + ret = soc_camera_device_register(icd); + if (ret) + goto eisdr; + return 0; + +eisdr: + kfree(mt9m111); + return ret; +} + +static int mt9m111_remove(struct i2c_client *client) +{ + struct mt9m111 *mt9m111 = i2c_get_clientdata(client); + soc_camera_device_unregister(&mt9m111->icd); + kfree(mt9m111); + + return 0; +} + +static const struct i2c_device_id mt9m111_id[] = { + { "mt9m111", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mt9m111_id); + +static struct i2c_driver mt9m111_i2c_driver = { + .driver = { + .name = "mt9m111", + }, + .probe = mt9m111_probe, + .remove = mt9m111_remove, + .id_table = mt9m111_id, +}; + +static int __init mt9m111_mod_init(void) +{ + return i2c_add_driver(&mt9m111_i2c_driver); +} + +static void __exit mt9m111_mod_exit(void) +{ + i2c_del_driver(&mt9m111_i2c_driver); +} + +module_init(mt9m111_mod_init); +module_exit(mt9m111_mod_exit); + +MODULE_DESCRIPTION("Micron MT9M111 Camera driver"); +MODULE_AUTHOR("Robert Jarzmik"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 2068653681ec2030c378a0d1e25d1d451f7cd929 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 14 Aug 2008 17:03:18 +0200 Subject: mt9m001, mt9v022: Simplify return code checking i2c_smbus_write_word_data() returns 0 or a negative error, hence no need to check for "> 0". Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/mt9m001.c | 24 ++++++++++++------------ drivers/media/video/mt9v022.c | 28 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) --- linux/drivers/media/video/mt9m001.c | 24 ++++++++++++------------ linux/drivers/media/video/mt9v022.c | 28 ++++++++++++++-------------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index f4742936c..2c2d0903e 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -119,16 +119,16 @@ static int mt9m001_init(struct soc_camera_device *icd) { int ret; - /* Disable chip, synchronous option update */ dev_dbg(icd->vdev->parent, "%s\n", __func__); ret = reg_write(icd, MT9M001_RESET, 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_RESET, 0); - if (ret >= 0) + /* Disable chip, synchronous option update */ + if (!ret) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); - return ret >= 0 ? 0 : -EIO; + return ret; } static int mt9m001_release(struct soc_camera_device *icd) @@ -267,24 +267,24 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, /* Blanking and start values - default... */ ret = reg_write(icd, MT9M001_HORIZONTAL_BLANKING, hblank); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_VERTICAL_BLANKING, vblank); /* The caller provides a supported format, as verified per * call to icd->try_fmt_cap() */ - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_COLUMN_START, rect->left); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_ROW_START, rect->top); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_WINDOW_WIDTH, rect->width - 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9M001_WINDOW_HEIGHT, rect->height + icd->y_skip_top - 1); - if (ret >= 0 && mt9m001->autoexposure) { + if (!ret && mt9m001->autoexposure) { ret = reg_write(icd, MT9M001_SHUTTER_WIDTH, rect->height + icd->y_skip_top + vblank); - if (ret >= 0) { + if (!ret) { const struct v4l2_queryctrl *qctrl = soc_camera_find_qctrl(icd->ops, V4L2_CID_EXPOSURE); @@ -295,7 +295,7 @@ static int mt9m001_set_fmt_cap(struct soc_camera_device *icd, } } - return ret < 0 ? ret : 0; + return ret; } static int mt9m001_try_fmt_cap(struct soc_camera_device *icd, diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index 1ff36edd7..d9b229579 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -141,22 +141,22 @@ static int mt9v022_init(struct soc_camera_device *icd) * plus snapshot mode to disable scan for now */ mt9v022->chip_control |= 0x10; ret = reg_write(icd, MT9V022_CHIP_CONTROL, mt9v022->chip_control); - if (ret >= 0) - reg_write(icd, MT9V022_READ_MODE, 0x300); + if (!ret) + ret = reg_write(icd, MT9V022_READ_MODE, 0x300); /* All defaults */ - if (ret >= 0) + if (!ret) /* AEC, AGC on */ ret = reg_set(icd, MT9V022_AEC_AGC_ENABLE, 0x3); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_MAX_TOTAL_SHUTTER_WIDTH, 480); - if (ret >= 0) + if (!ret) /* default - auto */ ret = reg_clear(icd, MT9V022_BLACK_LEVEL_CALIB_CTRL, 1); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_DIGITAL_TEST_PATTERN, 0); - return ret >= 0 ? 0 : -EIO; + return ret; } static int mt9v022_release(struct soc_camera_device *icd) @@ -352,21 +352,21 @@ static int mt9v022_set_fmt_cap(struct soc_camera_device *icd, rect->height + icd->y_skip_top + 43); } /* Setup frame format: defaults apart from width and height */ - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_COLUMN_START, rect->left); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_ROW_START, rect->top); - if (ret >= 0) + if (!ret) /* Default 94, Phytec driver says: * "width + horizontal blank >= 660" */ ret = reg_write(icd, MT9V022_HORIZONTAL_BLANKING, rect->width > 660 - 43 ? 43 : 660 - rect->width); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_VERTICAL_BLANKING, 45); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_WINDOW_WIDTH, rect->width); - if (ret >= 0) + if (!ret) ret = reg_write(icd, MT9V022_WINDOW_HEIGHT, rect->height + icd->y_skip_top); @@ -717,7 +717,7 @@ static int mt9v022_video_probe(struct soc_camera_device *icd) icd->num_formats = 1; } - if (ret >= 0) + if (!ret) ret = soc_camera_video_start(icd); if (ret < 0) goto eisis; -- cgit v1.2.3 From 4da232f764389ccafbe28832bf57aeae316d465f Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Thu, 14 Aug 2008 17:03:49 +0200 Subject: mt9m111: style cleanup Fix a typo in Kconfig, simplify error checking, further minor cleanup. Signed-off-by: Guennadi Liakhovetski Tested-by: Robert Jarzmik --- drivers/media/video/Kconfig | 2 +- drivers/media/video/mt9m111.c | 86 ++++++++++++++++++++--------------------- 2 files changed, 43 insertions(+), 45 deletions(-) --- linux/drivers/media/video/Kconfig | 2 +- linux/drivers/media/video/mt9m111.c | 86 ++++++++++++++++++------------------- 2 files changed, 43 insertions(+), 45 deletions(-) diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index c6516d42c..f8f7b3b44 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -810,7 +810,7 @@ config MT9M001_PCA9536_SWITCH extender to switch between 8 and 10 bit datawidth modes config SOC_CAMERA_MT9M111 - tristate "mt9m001 support" + tristate "mt9m111 support" depends on SOC_CAMERA && I2C help This driver supports MT9M111 cameras from Micron diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index 0c88e5d6d..d99932631 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -173,7 +173,7 @@ static int reg_page_map_set(struct i2c_client *client, const u16 reg) return -EINVAL; ret = i2c_smbus_write_word_data(client, MT9M111_PAGE_MAP, swab16(page)); - if (ret >= 0) + if (!ret) lastpage = page; return ret; } @@ -200,7 +200,7 @@ static int mt9m111_reg_write(struct soc_camera_device *icd, const u16 reg, int ret; ret = reg_page_map_set(client, reg); - if (ret >= 0) + if (!ret) ret = i2c_smbus_write_word_data(mt9m111->client, (reg & 0xff), swab16(data)); dev_dbg(&icd->dev, "write reg.%03x = %04x -> %d\n", reg, data, ret); @@ -246,7 +246,7 @@ static int mt9m111_set_context(struct soc_camera_device *icd, static int mt9m111_setup_rect(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0, is_raw_format; + int ret, is_raw_format; int width = mt9m111->width; int height = mt9m111->height; @@ -256,32 +256,31 @@ static int mt9m111_setup_rect(struct soc_camera_device *icd) else is_raw_format = 0; - if (ret >= 0) - ret = reg_write(COLUMN_START, mt9m111->left); - if (ret >= 0) + ret = reg_write(COLUMN_START, mt9m111->left); + if (!ret) ret = reg_write(ROW_START, mt9m111->top); if (is_raw_format) { - if (ret >= 0) + if (!ret) ret = reg_write(WINDOW_WIDTH, width); - if (ret >= 0) + if (!ret) ret = reg_write(WINDOW_HEIGHT, height); } else { - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XSIZE_B, width); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YSIZE_B, height); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_XSIZE_A, width); - if (ret >= 0) + if (!ret) ret = reg_write(REDUCER_YSIZE_A, height); } @@ -293,7 +292,7 @@ static int mt9m111_setup_pixfmt(struct soc_camera_device *icd, u16 outfmt) int ret; ret = reg_write(OUTPUT_FORMAT_CTRL2_A, outfmt); - if (ret >= 0) + if (!ret) ret = reg_write(OUTPUT_FORMAT_CTRL2_B, outfmt); return ret; } @@ -305,7 +304,6 @@ static int mt9m111_setfmt_bayer8(struct soc_camera_device *icd) static int mt9m111_setfmt_bayer10(struct soc_camera_device *icd) { - return mt9m111_setup_pixfmt(icd, MT9M111_OUTFMT_BYPASS_IFP); } @@ -356,7 +354,7 @@ static int mt9m111_enable(struct soc_camera_device *icd) int ret; ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); - if (ret >= 0) + if (!ret) mt9m111->powered = 1; return ret; } @@ -367,7 +365,7 @@ static int mt9m111_disable(struct soc_camera_device *icd) int ret; ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); - if (ret >= 0) + if (!ret) mt9m111->powered = 0; return ret; } @@ -377,9 +375,9 @@ static int mt9m111_reset(struct soc_camera_device *icd) int ret; ret = reg_set(RESET, MT9M111_RESET_RESET_MODE); - if (ret >= 0) + if (!ret) ret = reg_set(RESET, MT9M111_RESET_RESET_SOC); - if (ret >= 0) + if (!ret) ret = reg_clear(RESET, MT9M111_RESET_RESET_MODE | MT9M111_RESET_RESET_SOC); return ret; @@ -410,7 +408,7 @@ static int mt9m111_set_bus_param(struct soc_camera_device *icd, unsigned long f) static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; + int ret; switch (pixfmt) { case V4L2_PIX_FMT_SBGGR8: @@ -433,7 +431,7 @@ static int mt9m111_set_pixfmt(struct soc_camera_device *icd, u32 pixfmt) ret = -EINVAL; } - if (ret >= 0) + if (!ret) mt9m111->pixfmt = pixfmt; return ret; @@ -443,7 +441,7 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, __u32 pixfmt, struct v4l2_rect *rect) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); - int ret = 0; + int ret; mt9m111->left = rect->left; mt9m111->top = rect->top; @@ -455,9 +453,9 @@ static int mt9m111_set_fmt_cap(struct soc_camera_device *icd, mt9m111->height); ret = mt9m111_setup_rect(icd); - if (ret >= 0) + if (!ret) ret = mt9m111_set_pixfmt(icd, pixfmt); - return ret < 0 ? ret : 0; + return ret; } static int mt9m111_try_fmt_cap(struct soc_camera_device *icd, @@ -644,7 +642,7 @@ static int mt9m111_set_global_gain(struct soc_camera_device *icd, int gain) if ((gain >= 64 * 2) && (gain < 63 * 2 * 2)) val = (1 << 10) | (1 << 9) | (gain / 4); else if ((gain >= 64) && (gain < 64 * 2)) - val = (1<<9) | (gain / 2); + val = (1 << 9) | (gain / 2); else val = gain; @@ -661,7 +659,7 @@ static int mt9m111_set_autoexposure(struct soc_camera_device *icd, int on) else ret = reg_clear(OPER_MODE_CTRL, MT9M111_OPMODE_AUTOEXPO_EN); - if (ret >= 0) + if (!ret) mt9m111->autoexposure = on; return ret; @@ -711,7 +709,7 @@ static int mt9m111_set_control(struct soc_camera_device *icd, { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); const struct v4l2_queryctrl *qctrl; - int ret = 0; + int ret; qctrl = soc_camera_find_qctrl(&mt9m111_ops, ctrl->id); @@ -739,7 +737,7 @@ static int mt9m111_set_control(struct soc_camera_device *icd, ret = -EINVAL; } - return ret < 0 ? -EIO : 0; + return ret; } int mt9m111_restore_state(struct soc_camera_device *icd) @@ -763,10 +761,10 @@ static int mt9m111_resume(struct soc_camera_device *icd) if (mt9m111->powered) { ret = mt9m111_enable(icd); - if (ret >= 0) - mt9m111_reset(icd); - if (ret >= 0) - mt9m111_restore_state(icd); + if (!ret) + ret = mt9m111_reset(icd); + if (!ret) + ret = mt9m111_restore_state(icd); } return ret; } @@ -778,15 +776,15 @@ static int mt9m111_init(struct soc_camera_device *icd) mt9m111->context = HIGHPOWER; ret = mt9m111_enable(icd); - if (ret >= 0) - mt9m111_reset(icd); - if (ret >= 0) - mt9m111_set_context(icd, mt9m111->context); - if (ret >= 0) - mt9m111_set_autoexposure(icd, mt9m111->autoexposure); - if (ret < 0) + if (!ret) + ret = mt9m111_reset(icd); + if (!ret) + ret = mt9m111_set_context(icd, mt9m111->context); + if (!ret) + ret = mt9m111_set_autoexposure(icd, mt9m111->autoexposure); + if (ret) dev_err(&icd->dev, "mt9m111 init failed: %d\n", ret); - return ret ? -EIO : 0; + return ret; } static int mt9m111_release(struct soc_camera_device *icd) @@ -797,7 +795,7 @@ static int mt9m111_release(struct soc_camera_device *icd) if (ret < 0) dev_err(&icd->dev, "mt9m111 release failed: %d\n", ret); - return ret ? -EIO : 0; + return ret; } /* -- cgit v1.2.3 From 6413c9eb617e2eebe283211c0422e46bbd7289bb Mon Sep 17 00:00:00 2001 From: Stefan Herbrechtsmeier Date: Thu, 14 Aug 2008 17:04:11 +0200 Subject: soc-camera: Move .power and .reset from soc_camera host to sensor driver Make .power and .reset callbacks per camera instead of per host, also move their invocation to camera drivers. Signed-off-by: Stefan Herbrechtsmeier Signed-off-by: Guennadi Liakhovetski --- drivers/media/video/mt9m001.c | 33 +++++++++++++++++++++++++-- drivers/media/video/mt9m111.c | 15 ++++++++++++ drivers/media/video/mt9v022.c | 24 +++++++++++++++++++- drivers/media/video/pxa_camera.c | 24 -------------------- drivers/media/video/sh_mobile_ceu_camera.c | 5 ---- include/asm-arm/arch-pxa/camera.h | 2 - include/media/sh_mobile_ceu.h | 2 - include/media/soc_camera.h | 3 ++ 8 files changed, 71 insertions(+), 37 deletions(-) --- linux/drivers/media/video/mt9m001.c | 33 +++++++++++++++++++++--- linux/drivers/media/video/mt9m111.c | 15 +++++++++++ linux/drivers/media/video/mt9v022.c | 24 ++++++++++++++++- linux/drivers/media/video/pxa_camera.c | 24 ----------------- linux/drivers/media/video/sh_mobile_ceu_camera.c | 5 ---- linux/include/asm-arm/arch-pxa/camera.h | 2 -- linux/include/media/sh_mobile_ceu.h | 2 -- linux/include/media/soc_camera.h | 3 +++ 8 files changed, 71 insertions(+), 37 deletions(-) diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c index 2c2d0903e..228183c54 100644 --- a/linux/drivers/media/video/mt9m001.c +++ b/linux/drivers/media/video/mt9m001.c @@ -117,13 +117,33 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9m001_init(struct soc_camera_device *icd) { + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; int ret; dev_dbg(icd->vdev->parent, "%s\n", __func__); - ret = reg_write(icd, MT9M001_RESET, 1); - if (!ret) - ret = reg_write(icd, MT9M001_RESET, 0); + if (icl->power) { + ret = icl->power(&mt9m001->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + + /* The camera could have been already on, we reset it additionally */ + if (icl->reset) + ret = icl->reset(&mt9m001->client->dev); + else + ret = -ENODEV; + + if (ret < 0) { + /* Either no platform reset, or platform reset failed */ + ret = reg_write(icd, MT9M001_RESET, 1); + if (!ret) + ret = reg_write(icd, MT9M001_RESET, 0); + } /* Disable chip, synchronous option update */ if (!ret) ret = reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); @@ -133,8 +153,15 @@ static int mt9m001_init(struct soc_camera_device *icd) static int mt9m001_release(struct soc_camera_device *icd) { + struct mt9m001 *mt9m001 = container_of(icd, struct mt9m001, icd); + struct soc_camera_link *icl = mt9m001->client->dev.platform_data; + /* Disable the chip */ reg_write(icd, MT9M001_OUTPUT_CONTROL, 0); + + if (icl->power) + icl->power(&mt9m001->client->dev, 0); + return 0; } diff --git a/linux/drivers/media/video/mt9m111.c b/linux/drivers/media/video/mt9m111.c index d99932631..4844486d7 100644 --- a/linux/drivers/media/video/mt9m111.c +++ b/linux/drivers/media/video/mt9m111.c @@ -351,8 +351,18 @@ static int mt9m111_setfmt_yuv(struct soc_camera_device *icd) static int mt9m111_enable(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; + if (icl->power) { + ret = icl->power(&mt9m111->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + ret = reg_set(RESET, MT9M111_RESET_CHIP_ENABLE); if (!ret) mt9m111->powered = 1; @@ -362,11 +372,16 @@ static int mt9m111_enable(struct soc_camera_device *icd) static int mt9m111_disable(struct soc_camera_device *icd) { struct mt9m111 *mt9m111 = container_of(icd, struct mt9m111, icd); + struct soc_camera_link *icl = mt9m111->client->dev.platform_data; int ret; ret = reg_clear(RESET, MT9M111_RESET_CHIP_ENABLE); if (!ret) mt9m111->powered = 0; + + if (icl->power) + icl->power(&mt9m111->client->dev, 0); + return ret; } diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c index d9b229579..0320d006f 100644 --- a/linux/drivers/media/video/mt9v022.c +++ b/linux/drivers/media/video/mt9v022.c @@ -134,8 +134,25 @@ static int reg_clear(struct soc_camera_device *icd, const u8 reg, static int mt9v022_init(struct soc_camera_device *icd) { struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; int ret; + if (icl->power) { + ret = icl->power(&mt9v022->client->dev, 1); + if (ret < 0) { + dev_err(icd->vdev->parent, + "Platform failed to power-on the camera.\n"); + return ret; + } + } + + /* + * The camera could have been already on, we hard-reset it additionally, + * if available. Soft reset is done in video_probe(). + */ + if (icl->reset) + icl->reset(&mt9v022->client->dev); + /* Almost the default mode: master, parallel, simultaneous, and an * undocumented bit 0x200, which is present in table 7, but not in 8, * plus snapshot mode to disable scan for now */ @@ -161,7 +178,12 @@ static int mt9v022_init(struct soc_camera_device *icd) static int mt9v022_release(struct soc_camera_device *icd) { - /* Nothing? */ + struct mt9v022 *mt9v022 = container_of(icd, struct mt9v022, icd); + struct soc_camera_link *icl = mt9v022->client->dev.platform_data; + + if (icl->power) + icl->power(&mt9v022->client->dev, 0); + return 0; } diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index ead87ddaf..6c869fb23 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -629,17 +629,6 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) pdata->init(pcdev->dev); } - if (pdata && pdata->power) { - dev_dbg(pcdev->dev, "%s: Power on camera\n", __func__); - pdata->power(pcdev->dev, 1); - } - - if (pdata && pdata->reset) { - dev_dbg(pcdev->dev, "%s: Releasing camera reset\n", - __func__); - pdata->reset(pcdev->dev, 1); - } - CICR0 = 0x3FF; /* disable all interrupts */ if (pcdev->platform_flags & PXA_CAMERA_PCLK_EN) @@ -660,20 +649,7 @@ static void pxa_camera_activate(struct pxa_camera_dev *pcdev) static void pxa_camera_deactivate(struct pxa_camera_dev *pcdev) { - struct pxacamera_platform_data *board = pcdev->pdata; - clk_disable(pcdev->clk); - - if (board && board->reset) { - dev_dbg(pcdev->dev, "%s: Asserting camera reset\n", - __func__); - board->reset(pcdev->dev, 0); - } - - if (board && board->power) { - dev_dbg(pcdev->dev, "%s: Power off camera\n", __func__); - board->power(pcdev->dev, 0); - } } static irqreturn_t pxa_camera_irq(int irq, void *data) diff --git a/linux/drivers/media/video/sh_mobile_ceu_camera.c b/linux/drivers/media/video/sh_mobile_ceu_camera.c index 318754e73..76838091d 100644 --- a/linux/drivers/media/video/sh_mobile_ceu_camera.c +++ b/linux/drivers/media/video/sh_mobile_ceu_camera.c @@ -304,9 +304,6 @@ static int sh_mobile_ceu_add_device(struct soc_camera_device *icd) "SuperH Mobile CEU driver attached to camera %d\n", icd->devnum); - if (pcdev->pdata->enable_camera) - pcdev->pdata->enable_camera(); - ret = icd->ops->init(icd); if (ret) goto err; @@ -333,8 +330,6 @@ static void sh_mobile_ceu_remove_device(struct soc_camera_device *icd) ceu_write(pcdev, CEIER, 0); ceu_write(pcdev, CAPSR, 1 << 16); /* reset */ icd->ops->release(icd); - if (pcdev->pdata->disable_camera) - pcdev->pdata->disable_camera(); dev_info(&icd->dev, "SuperH Mobile CEU driver detached from camera %d\n", diff --git a/linux/include/asm-arm/arch-pxa/camera.h b/linux/include/asm-arm/arch-pxa/camera.h index 39516ced8..31abe6d51 100644 --- a/linux/include/asm-arm/arch-pxa/camera.h +++ b/linux/include/asm-arm/arch-pxa/camera.h @@ -36,8 +36,6 @@ struct pxacamera_platform_data { int (*init)(struct device *); - int (*power)(struct device *, int); - int (*reset)(struct device *, int); unsigned long flags; unsigned long mclk_10khz; diff --git a/linux/include/media/sh_mobile_ceu.h b/linux/include/media/sh_mobile_ceu.h index 234a4711d..b5dbefea3 100644 --- a/linux/include/media/sh_mobile_ceu.h +++ b/linux/include/media/sh_mobile_ceu.h @@ -5,8 +5,6 @@ struct sh_mobile_ceu_info { unsigned long flags; /* SOCAM_... */ - void (*enable_camera)(void); - void (*disable_camera)(void); }; #endif /* __ASM_SH_MOBILE_CEU_H__ */ diff --git a/linux/include/media/soc_camera.h b/linux/include/media/soc_camera.h index d548de326..c5de7bb19 100644 --- a/linux/include/media/soc_camera.h +++ b/linux/include/media/soc_camera.h @@ -83,6 +83,9 @@ struct soc_camera_link { int bus_id; /* GPIO number to switch between 8 and 10 bit modes */ unsigned int gpio; + /* Optional callbacks to power on or off and reset the sensor */ + int (*power)(struct device *, int); + int (*reset)(struct device *); }; static inline struct soc_camera_device *to_soc_camera_dev(struct device *dev) -- cgit v1.2.3 From 9c75e8157d1db6438ae8f801ceebb25e78a48812 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 12:50:23 +0200 Subject: dpc7146: remove dpc7146 demonstration board driver From: Hans Verkuil Old driver for the dpc7146 demonstration board that is no longer relevant. The last time this was tested on actual hardware was probably around 2002. Since this is a driver for a demonstration board the decision was made (after discussing this with the original author, Michael Hunold) to remove it rather than spending a lot of effort continually updating this driver to stay in sync with the latest internal V4L2 or I2C API. Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Michael Hunold --- linux/drivers/media/video/Kconfig | 15 -- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/dpc7146.c | 409 ------------------------------------ 3 files changed, 425 deletions(-) delete mode 100644 linux/drivers/media/video/dpc7146.c diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 4c96b690a..61735004e 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -709,21 +709,6 @@ config VIDEO_MXB To compile this driver as a module, choose M here: the module will be called mxb. -config VIDEO_DPC - tristate "Philips-Semiconductors 'dpc7146 demonstration board'" - depends on PCI && VIDEO_V4L1 && I2C - select VIDEO_SAA7146_VV - select VIDEO_SAA7111 if VIDEO_HELPER_CHIPS_AUTO - ---help--- - This is a video4linux driver for the 'dpc7146 demonstration - board' by Philips-Semiconductors. It's the reference design - for SAA7146 bases boards, so if you have some unsupported - saa7146 based, analog video card, chances are good that it - will work with this skeleton driver. - - To compile this driver as a module, choose M here: the - module will be called dpc7146. - config VIDEO_HEXIUM_ORION tristate "Hexium HV-PCI6 and Orion frame grabber" depends on PCI && VIDEO_V4L2 && I2C diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index bf429b023..3512b715a 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_VIDEO_DPC) += dpc7146.o obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/linux/drivers/media/video/dpc7146.c b/linux/drivers/media/video/dpc7146.c deleted file mode 100644 index 4bfb3076b..000000000 --- a/linux/drivers/media/video/dpc7146.c +++ /dev/null @@ -1,409 +0,0 @@ -/* - dpc7146.c - v4l2 driver for the dpc7146 demonstration board - - Copyright (C) 2000-2003 Michael Hunold - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#define DEBUG_VARIABLE debug - -#include -#include /* for saa7111a */ -#include "compat.h" - -#define I2C_SAA7111A 0x24 - -/* All unused bytes are reserverd. */ -#define SAA711X_CHIP_VERSION 0x00 -#define SAA711X_ANALOG_INPUT_CONTROL_1 0x02 -#define SAA711X_ANALOG_INPUT_CONTROL_2 0x03 -#define SAA711X_ANALOG_INPUT_CONTROL_3 0x04 -#define SAA711X_ANALOG_INPUT_CONTROL_4 0x05 -#define SAA711X_HORIZONTAL_SYNC_START 0x06 -#define SAA711X_HORIZONTAL_SYNC_STOP 0x07 -#define SAA711X_SYNC_CONTROL 0x08 -#define SAA711X_LUMINANCE_CONTROL 0x09 -#define SAA711X_LUMINANCE_BRIGHTNESS 0x0A -#define SAA711X_LUMINANCE_CONTRAST 0x0B -#define SAA711X_CHROMA_SATURATION 0x0C -#define SAA711X_CHROMA_HUE_CONTROL 0x0D -#define SAA711X_CHROMA_CONTROL 0x0E -#define SAA711X_FORMAT_DELAY_CONTROL 0x10 -#define SAA711X_OUTPUT_CONTROL_1 0x11 -#define SAA711X_OUTPUT_CONTROL_2 0x12 -#define SAA711X_OUTPUT_CONTROL_3 0x13 -#define SAA711X_V_GATE_1_START 0x15 -#define SAA711X_V_GATE_1_STOP 0x16 -#define SAA711X_V_GATE_1_MSB 0x17 -#define SAA711X_TEXT_SLICER_STATUS 0x1A -#define SAA711X_DECODED_BYTES_OF_TS_1 0x1B -#define SAA711X_DECODED_BYTES_OF_TS_2 0x1C -#define SAA711X_STATUS_BYTE 0x1F - -#define DPC_BOARD_CAN_DO_VBI(dev) (dev->revision != 0) - -static int debug; -module_param(debug, int, 0); -MODULE_PARM_DESC(debug, "debug verbosity"); - -static int dpc_num; - -#define DPC_INPUTS 2 -static struct v4l2_input dpc_inputs[DPC_INPUTS] = { - { 0, "Port A", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, - { 1, "Port B", V4L2_INPUT_TYPE_CAMERA, 2, 0, V4L2_STD_PAL_BG|V4L2_STD_NTSC_M, 0 }, -}; - -#define DPC_AUDIOS 0 - -static struct saa7146_extension_ioctls ioctls[] = { - { VIDIOC_G_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_INPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_ENUMINPUT, SAA7146_EXCLUSIVE }, - { VIDIOC_S_STD, SAA7146_AFTER }, - { 0, 0 } -}; - -struct dpc -{ - struct video_device *video_dev; - struct video_device *vbi_dev; - - struct i2c_adapter i2c_adapter; - struct i2c_client *saa7111a; - - int cur_input; /* current input */ -}; - -static int dpc_check_clients(struct device *dev, void *data) -{ - struct dpc* dpc = data; - struct i2c_client *client = i2c_verify_client(dev); - - if( !client ) - return 0; - - if( I2C_SAA7111A == client->addr ) - dpc->saa7111a = client; - - return 0; -} - -/* fixme: add vbi stuff here */ -static int dpc_probe(struct saa7146_dev* dev) -{ - struct dpc* dpc = NULL; - - dpc = kzalloc(sizeof(struct dpc), GFP_KERNEL); - if( NULL == dpc ) { - printk("dpc_v4l2.o: dpc_probe: not enough kernel memory.\n"); - return -ENOMEM; - } - - /* FIXME: enable i2c-port pins, video-port-pins - video port pins should be enabled here ?! */ - saa7146_write(dev, MC1, (MASK_08 | MASK_24 | MASK_10 | MASK_26)); - - dpc->i2c_adapter = (struct i2c_adapter) { - .class = I2C_CLASS_TV_ANALOG, - .name = "dpc7146", - }; - saa7146_i2c_adapter_prepare(dev, &dpc->i2c_adapter, SAA7146_I2C_BUS_BIT_RATE_480); - if(i2c_add_adapter(&dpc->i2c_adapter) < 0) { - DEB_S(("cannot register i2c-device. skipping.\n")); - kfree(dpc); - return -EFAULT; - } - - /* loop through all i2c-devices on the bus and look who is there */ - device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients); - - /* check if all devices are present */ - if (!dpc->saa7111a) { - DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n")); - i2c_del_adapter(&dpc->i2c_adapter); - kfree(dpc); - return -ENODEV; - } - - /* all devices are present, probe was successful */ - DEB_D(("dpc_v4l2.o: dpc_probe succeeded for this device.\n")); - - /* we store the pointer in our private data field */ - dev->ext_priv = dpc; - - return 0; -} - -/* bring hardware to a sane state. this has to be done, just in case someone - wants to capture from this device before it has been properly initialized. - the capture engine would badly fail, because no valid signal arrives on the - saa7146, thus leading to timeouts and stuff. */ -static int dpc_init_done(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_D(("dpc_v4l2.o: dpc_init_done called.\n")); - - /* initialize the helper ics to useful values */ - i2c_smbus_write_byte_data(dpc->saa7111a, 0x00, 0x11); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x02, 0xc0); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x03, 0x30); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x04, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x05, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x06, 0xde); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x07, 0xad); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x08, 0xa8); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x09, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0a, 0x80); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0b, 0x47); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0c, 0x40); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0d, 0x00); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x0e, 0x03); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x10, 0xd0); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x11, 0x1c); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x12, 0xc1); - i2c_smbus_write_byte_data(dpc->saa7111a, 0x13, 0x30); - - i2c_smbus_write_byte_data(dpc->saa7111a, 0x1f, 0x81); - - return 0; -} - -static struct saa7146_ext_vv vv_data; - -/* this function only gets called when the probing was successful */ -static int dpc_attach(struct saa7146_dev* dev, struct saa7146_pci_extension_data *info) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_D(("dpc_v4l2.o: dpc_attach called.\n")); - - /* checking for i2c-devices can be omitted here, because we - already did this in "dpc_vl42_probe" */ - - saa7146_vv_init(dev,&vv_data); - if( 0 != saa7146_register_device(&dpc->video_dev, dev, "dpc", VFL_TYPE_GRABBER)) { - ERR(("cannot register capture v4l2 device. skipping.\n")); - return -1; - } - - /* initialization stuff (vbi) (only for revision > 0 and for extensions which want it)*/ - if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { - if( 0 != saa7146_register_device(&dpc->vbi_dev, dev, "dpc", VFL_TYPE_VBI)) { - ERR(("cannot register vbi v4l2 device. skipping.\n")); - } - } - - i2c_use_client(dpc->saa7111a); - - printk("dpc: found 'dpc7146 demonstration board'-%d.\n",dpc_num); - dpc_num++; - - /* the rest */ - dpc->cur_input = 0; - dpc_init_done(dev); - - return 0; -} - -static int dpc_detach(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - DEB_EE(("dev:%p\n",dev)); - - i2c_release_client(dpc->saa7111a); - - saa7146_unregister_device(&dpc->video_dev,dev); - if( 0 != DPC_BOARD_CAN_DO_VBI(dev)) { - saa7146_unregister_device(&dpc->vbi_dev,dev); - } - saa7146_vv_release(dev); - - dpc_num--; - - i2c_del_adapter(&dpc->i2c_adapter); - kfree(dpc); - return 0; -} - -#ifdef axa -int dpc_vbi_bypass(struct saa7146_dev* dev) -{ - struct dpc* dpc = (struct dpc*)dev->ext_priv; - - int i = 1; - - /* switch bypass in saa7111a */ - if ( 0 != dpc->saa7111a->driver->command(dpc->saa7111a,SAA711X_VBI_BYPASS, &i)) { - printk("dpc_v4l2.o: VBI_BYPASS: could not address saa7111a.\n"); - return -1; - } - - return 0; -} -#endif - -static int dpc_ioctl(struct saa7146_fh *fh, unsigned int cmd, void *arg) -{ - struct saa7146_dev *dev = fh->dev; - struct dpc* dpc = (struct dpc*)dev->ext_priv; -/* - struct saa7146_vv *vv = dev->vv_data; -*/ - switch(cmd) - { - case VIDIOC_ENUMINPUT: - { - struct v4l2_input *i = arg; - DEB_EE(("VIDIOC_ENUMINPUT %d.\n",i->index)); - - if( i->index < 0 || i->index >= DPC_INPUTS) { - return -EINVAL; - } - - memcpy(i, &dpc_inputs[i->index], sizeof(struct v4l2_input)); - - DEB_D(("dpc_v4l2.o: v4l2_ioctl: VIDIOC_ENUMINPUT %d.\n",i->index)); - return 0; - } - case VIDIOC_G_INPUT: - { - int *input = (int *)arg; - *input = dpc->cur_input; - - DEB_D(("dpc_v4l2.o: VIDIOC_G_INPUT: %d\n",*input)); - return 0; - } - case VIDIOC_S_INPUT: - { - int input = *(int *)arg; - - if (input < 0 || input >= DPC_INPUTS) { - return -EINVAL; - } - - dpc->cur_input = input; - - /* fixme: switch input here, switch audio, too! */ -// saa7146_set_hps_source_and_sync(dev, input_port_selection[input].hps_source, input_port_selection[input].hps_sync); - printk("dpc_v4l2.o: VIDIOC_S_INPUT: fixme switch input.\n"); - - return 0; - } - default: -/* - DEB_D(("dpc_v4l2.o: v4l2_ioctl does not handle this ioctl.\n")); -*/ - return -ENOIOCTLCMD; - } - return 0; -} - -static int std_callback(struct saa7146_dev* dev, struct saa7146_standard *std) -{ - return 0; -} - -static struct saa7146_standard standard[] = { - { - .name = "PAL", .id = V4L2_STD_PAL, - .v_offset = 0x17, .v_field = 288, - .h_offset = 0x14, .h_pixels = 680, - .v_max_out = 576, .h_max_out = 768, - }, { - .name = "NTSC", .id = V4L2_STD_NTSC, - .v_offset = 0x16, .v_field = 240, - .h_offset = 0x06, .h_pixels = 708, - .v_max_out = 480, .h_max_out = 640, - }, { - .name = "SECAM", .id = V4L2_STD_SECAM, - .v_offset = 0x14, .v_field = 288, - .h_offset = 0x14, .h_pixels = 720, - .v_max_out = 576, .h_max_out = 768, - } -}; - -static struct saa7146_extension extension; - -static struct saa7146_pci_extension_data dpc = { - .ext_priv = "Multimedia eXtension Board", - .ext = &extension, -}; - -static struct pci_device_id pci_tbl[] = { - { - .vendor = PCI_VENDOR_ID_PHILIPS, - .device = PCI_DEVICE_ID_PHILIPS_SAA7146, - .subvendor = 0x0000, - .subdevice = 0x0000, - .driver_data = (unsigned long)&dpc, - }, { - .vendor = 0, - } -}; - -MODULE_DEVICE_TABLE(pci, pci_tbl); - -static struct saa7146_ext_vv vv_data = { - .inputs = DPC_INPUTS, - .capabilities = V4L2_CAP_VBI_CAPTURE, - .stds = &standard[0], - .num_stds = sizeof(standard)/sizeof(struct saa7146_standard), - .std_callback = &std_callback, - .ioctls = &ioctls[0], - .ioctl = dpc_ioctl, -}; - -static struct saa7146_extension extension = { - .name = "dpc7146 demonstration board", - .flags = SAA7146_USE_I2C_IRQ, - - .pci_tbl = &pci_tbl[0], - .module = THIS_MODULE, - - .probe = dpc_probe, - .attach = dpc_attach, - .detach = dpc_detach, - - .irq_mask = 0, - .irq_func = NULL, -}; - -static int __init dpc_init_module(void) -{ - if( 0 != saa7146_register_extension(&extension)) { - DEB_S(("failed to register extension.\n")); - return -ENODEV; - } - - return 0; -} - -static void __exit dpc_cleanup_module(void) -{ - saa7146_unregister_extension(&extension); -} - -module_init(dpc_init_module); -module_exit(dpc_cleanup_module); - -MODULE_DESCRIPTION("video4linux-2 driver for the 'dpc7146 demonstration board'"); -MODULE_AUTHOR("Michael Hunold "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 59bb2ab87f97424a41cf69511ff79ae8a5ea08b9 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 12:56:12 +0200 Subject: tuner-3036: remove driver From: Hans Verkuil This driver is for VERY old i2c-over-parallel port teletext receiver boxes. Rather then spending effort on converting this driver to V4L2, and since it is extremely unlikely that anyone still uses one of these devices, it was decided to drop it (after discussing this as well with the original author, Phil Blundell). Priority: normal Signed-off-by: Hans Verkuil Signed-off-by: Phil Blundell --- linux/drivers/media/video/Kconfig | 7 -- linux/drivers/media/video/Makefile | 1 - linux/drivers/media/video/tuner-3036.c | 215 --------------------------------- 3 files changed, 223 deletions(-) delete mode 100644 linux/drivers/media/video/tuner-3036.c diff --git a/linux/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig index 61735004e..c315885a6 100644 --- a/linux/drivers/media/video/Kconfig +++ b/linux/drivers/media/video/Kconfig @@ -579,13 +579,6 @@ config VIDEO_SAA5249 To compile this driver as a module, choose M here: the module will be called saa5249. -config TUNER_3036 - tristate "SAB3036 tuner" - depends on I2C && VIDEO_V4L1 - help - Say Y here to include support for Philips SAB3036 compatible tuners. - If in doubt, say N. - config VIDEO_VINO tristate "SGI Vino Video For Linux (EXPERIMENTAL)" depends on I2C && SGI_IP22 && EXPERIMENTAL && VIDEO_V4L2 diff --git a/linux/drivers/media/video/Makefile b/linux/drivers/media/video/Makefile index 3512b715a..22d98ee61 100644 --- a/linux/drivers/media/video/Makefile +++ b/linux/drivers/media/video/Makefile @@ -83,7 +83,6 @@ obj-$(CONFIG_VIDEO_CPIA2) += cpia2/ obj-$(CONFIG_VIDEO_MXB) += mxb.o obj-$(CONFIG_VIDEO_HEXIUM_ORION) += hexium_orion.o obj-$(CONFIG_VIDEO_HEXIUM_GEMINI) += hexium_gemini.o -obj-$(CONFIG_TUNER_3036) += tuner-3036.o obj-$(CONFIG_VIDEO_TUNER) += tuner.o diff --git a/linux/drivers/media/video/tuner-3036.c b/linux/drivers/media/video/tuner-3036.c deleted file mode 100644 index 8b87d75f4..000000000 --- a/linux/drivers/media/video/tuner-3036.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Driver for Philips SAB3036 "CITAC" tuner control chip. - * - * Author: Phil Blundell - * - * The SAB3036 is just about different enough from the chips that - * tuner.c copes with to make it not worth the effort to crowbar - * the support into that file. So instead we have a separate driver. - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include "compat.h" -#include -#include - -#include - -static int debug; /* insmod parameter */ -static int this_adap; - -static struct i2c_client client_template; - -/* Addresses to scan */ -static unsigned short normal_i2c[] = { 0x60, 0x61, I2C_CLIENT_END }; -static unsigned short ignore = I2C_CLIENT_END; - -static struct i2c_client_address_data addr_data = { - .normal_i2c = normal_i2c, - .probe = &ignore, - .ignore = &ignore, -}; - -/* ---------------------------------------------------------------------- */ - -static unsigned char -tuner_getstatus (struct i2c_client *c) -{ - unsigned char byte; - if (i2c_master_recv(c, &byte, 1) != 1) - printk(KERN_ERR "tuner-3036: I/O error.\n"); - return byte; -} - -#define TUNER_FL 0x80 - -static int -tuner_islocked (struct i2c_client *c) -{ - return (tuner_getstatus(c) & TUNER_FL); -} - -/* ---------------------------------------------------------------------- */ - -static void -set_tv_freq(struct i2c_client *c, int freq) -{ - u16 div = ((freq * 20) / 16); - unsigned long give_up = jiffies + HZ; - unsigned char buffer[2]; - - if (debug) - printk(KERN_DEBUG "tuner: setting frequency %dMHz, divisor %x\n", freq / 16, div); - - /* Select high tuning current */ - buffer[0] = 0x29; - buffer[1] = 0x3e; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 1\n"); - - buffer[0] = 0x80 | ((div>>8) & 0x7f); - buffer[1] = div & 0xff; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 2\n"); - - while (!tuner_islocked(c) && time_before(jiffies, give_up)) - schedule(); - - if (!tuner_islocked(c)) - printk(KERN_WARNING "tuner: failed to achieve PLL lock\n"); - - /* Select low tuning current and engage AFC */ - buffer[0] = 0x29; - buffer[1] = 0xb2; - - if (i2c_master_send(c, buffer, 2) != 2) - printk("tuner: i2c i/o error 3\n"); - - if (debug) - printk(KERN_DEBUG "tuner: status %02x\n", tuner_getstatus(c)); -} - -/* ---------------------------------------------------------------------- */ - -static int -tuner_attach(struct i2c_adapter *adap, int addr, int kind) -{ - static unsigned char buffer[] = { 0x29, 0x32, 0x2a, 0, 0x2b, 0 }; - - struct i2c_client *client; - - if (this_adap > 0) - return -1; - this_adap++; - - client_template.adapter = adap; - client_template.addr = addr; - - client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (client == NULL) - return -ENOMEM; - memcpy(client, &client_template, sizeof(struct i2c_client)); - - printk("tuner: SAB3036 found, status %02x\n", tuner_getstatus(client)); - - i2c_attach_client(client); - - if (i2c_master_send(client, buffer, 2) != 2) - printk("tuner: i2c i/o error 1\n"); - if (i2c_master_send(client, buffer+2, 2) != 2) - printk("tuner: i2c i/o error 2\n"); - if (i2c_master_send(client, buffer+4, 2) != 2) - printk("tuner: i2c i/o error 3\n"); - return 0; -} - -static int -tuner_detach(struct i2c_client *c) -{ - return 0; -} - -static int -tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) -{ - int *iarg = (int*)arg; - - switch (cmd) - { - case VIDIOCSFREQ: - set_tv_freq(client, *iarg); - break; - - default: - return -EINVAL; - } - return 0; -} - -static int -tuner_probe(struct i2c_adapter *adap) -{ - this_adap = 0; - if (adap->id == I2C_HW_B_LP) - return i2c_probe(adap, &addr_data, tuner_attach); - return 0; -} - -/* ----------------------------------------------------------------------- */ - -static struct i2c_driver -i2c_driver_tuner = -{ - .driver = { - .name = "sab3036", - }, - .id = I2C_DRIVERID_SAB3036, - .attach_adapter = tuner_probe, - .detach_client = tuner_detach, - .command = tuner_command -}; - -static struct i2c_client client_template = -{ - .driver = &i2c_driver_tuner, - .name = "SAB3036", -}; - -static int __init -tuner3036_init(void) -{ - return i2c_add_driver(&i2c_driver_tuner); -} - -static void __exit -tuner3036_exit(void) -{ - i2c_del_driver(&i2c_driver_tuner); -} - -MODULE_DESCRIPTION("SAB3036 tuner driver"); -MODULE_AUTHOR("Philip Blundell "); -MODULE_LICENSE("GPL"); - -module_param(debug, int, 0); -MODULE_PARM_DESC(debug,"Enable debugging output"); - -module_init(tuner3036_init); -module_exit(tuner3036_exit); -- cgit v1.2.3 From 4a0132136258611e6d3bc1dbe7411503faa638ad Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 13:33:14 +0200 Subject: i2c-id: remove obsolete SAB3036 driver ID From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/include/linux/i2c-id.h | 1 - 1 file changed, 1 deletion(-) diff --git a/linux/include/linux/i2c-id.h b/linux/include/linux/i2c-id.h index 4862398e0..bc35aec9d 100644 --- a/linux/include/linux/i2c-id.h +++ b/linux/include/linux/i2c-id.h @@ -42,7 +42,6 @@ #define I2C_DRIVERID_MGATVO 23 /* Matrox TVOut */ #define I2C_DRIVERID_SAA5249 24 /* SAA5249 and compatibles */ #define I2C_DRIVERID_PCF8583 25 /* real time clock */ -#define I2C_DRIVERID_SAB3036 26 /* SAB3036 tuner */ #define I2C_DRIVERID_TDA7432 27 /* Stereo sound processor */ #define I2C_DRIVERID_TVMIXER 28 /* Mixer driver for tv cards */ #define I2C_DRIVERID_TVAUDIO 29 /* Generic TV sound driver */ -- cgit v1.2.3 From 58df9dfb0cd0e6afde3ae7a49f84d4f216bc3cbf Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sat, 16 Aug 2008 15:55:33 +0200 Subject: aci: remove obsolete sources From: Hans Verkuil The aci.c and aci.h files were copied from the kernel for a Miro radio card. That driver has been removed, so these supported sources can also be removed. In addition some remaining traces of the Miro driver were also deleted. Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/radio/Kconfig | 32 -- linux/sound/oss/aci.c | 713 -------------------------------------- linux/sound/oss/aci.h | 57 --- v4l/Kconfig.sound | 17 - v4l/Makefile | 4 - v4l/Makefile.sound | 19 +- v4l/scripts/make_kconfig.pl | 3 - 7 files changed, 9 insertions(+), 836 deletions(-) delete mode 100644 linux/sound/oss/aci.c delete mode 100644 linux/sound/oss/aci.h diff --git a/linux/drivers/media/radio/Kconfig b/linux/drivers/media/radio/Kconfig index 01ee71e82..1b41b3f77 100644 --- a/linux/drivers/media/radio/Kconfig +++ b/linux/drivers/media/radio/Kconfig @@ -195,38 +195,6 @@ config RADIO_MAESTRO To compile this driver as a module, choose M here: the module will be called radio-maestro. -config RADIO_MIROPCM20 - tristate "miroSOUND PCM20 radio" - depends on ISA && VIDEO_V4L1 && SOUND_ACI_MIXER - ---help--- - Choose Y here if you have this FM radio card. You also need to say Y - to "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20 radio)" (in "Sound") - for this to work. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux API. Information on - this API and pointers to "v4l" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called miropcm20. - -config RADIO_MIROPCM20_RDS - tristate "miroSOUND PCM20 radio RDS user interface (EXPERIMENTAL)" - depends on RADIO_MIROPCM20 && EXPERIMENTAL - ---help--- - Choose Y here if you want to see RDS/RBDS information like - RadioText, Programme Service name, Clock Time and date, Programme - Type and Traffic Announcement/Programme identification. - - It's not possible to read the raw RDS packets from the device, so - the driver cant provide an V4L interface for this. But the - availability of RDS is reported over V4L by the basic driver - already. Here RDS can be read from files in /dev/v4l/rds. - - To compile this driver as a module, choose M here: the - module will be called miropcm20-rds. - config RADIO_SF16FMI tristate "SF16FMI Radio" depends on ISA && VIDEO_V4L2 diff --git a/linux/sound/oss/aci.c b/linux/sound/oss/aci.c deleted file mode 100644 index 4c407b77f..000000000 --- a/linux/sound/oss/aci.c +++ /dev/null @@ -1,713 +0,0 @@ -/* - * Audio Command Interface (ACI) driver (sound/aci.c) - * - * ACI is a protocol used to communicate with the microcontroller on - * some sound cards produced by miro, e.g. the miroSOUND PCM12 and - * PCM20. The ACI has been developed for miro by Norberto Pellicci - * . Special thanks to both him and miro for - * providing the ACI specification. - * - * The main function of the ACI is to control the mixer and to get a - * product identification. On the PCM20, ACI also controls the radio - * tuner on this card, this is supported in the Video for Linux - * miropcm20 driver. - * - - * This is a fullfeatured implementation. Unsupported features - * are bugs... (: - * - * It is not longer necessary to load the mad16 module first. The - * user is currently responsible to set the mad16 mixer correctly. - * - * To toggle the solo mode for full duplex operation just use the OSS - * record switch for the pcm ('wave') controller. Robert - * - - * - * Revision history: - * - * 1995-11-10 Markus Kuhn - * First version written. - * 1995-12-31 Markus Kuhn - * Second revision, general code cleanup. - * 1996-05-16 Hannu Savolainen - * Integrated with other parts of the driver. - * 1996-05-28 Markus Kuhn - * Initialize CS4231A mixer, make ACI first mixer, - * use new private mixer API for solo mode. - * 1998-08-18 Ruurd Reitsma - * Small modification to export ACI functions and - * complete modularisation. - * 2000-06-20 Robert Siemer - * Don't initialize the CS4231A mixer anymore, so the code is - * working again, and other small changes to fit in todays - * kernels. - * 2000-08-26 Robert Siemer - * Clean up and rewrite for 2.4.x. Maybe it's SMP safe now... (: - * ioctl bugfix, and integration of solo-mode into OSS-API, - * added (OSS-limited) equalizer support, return value bugfix, - * changed param aci_reset to reset, new params: ide, wss. - * 2001-04-20 Robert Siemer - * even more cleanups... - * 2001-10-08 Arnaldo Carvalho de Melo - * Get rid of check_region, .bss optimizations, use set_current_state - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include "sound_config.h" -#include "compat.h" - -int aci_port; /* as determined by bit 4 in the OPTi 929 MC4 register */ -static int aci_idcode[2]; /* manufacturer and product ID */ -int aci_version; /* ACI firmware version */ - -EXPORT_SYMBOL(aci_port); -EXPORT_SYMBOL(aci_version); - -#include "aci.h" - - -static int aci_solo; /* status bit of the card that can't be * - * checked with ACI versions prior to 0xb0 */ -static int aci_amp; /* status bit for power-amp/line-out level - but I have no docs about what is what... */ -static int aci_micpreamp=3; /* microphone preamp-level that can't be * - * checked with ACI versions prior to 0xb0 */ - -static int mixer_device; -static struct mutex aci_mutex; - -#ifdef MODULE -static int reset; -module_param(reset, bool, 0); -MODULE_PARM_DESC(reset,"When set to 1, reset aci mixer."); -#else -static int reset = 1; -#endif - -static int ide=-1; -module_param(ide, int, 0); -MODULE_PARM_DESC(ide,"1 enable, 0 disable ide-port - untested" - " default: do nothing"); -static int wss=-1; -module_param(wss, int, 0); -MODULE_PARM_DESC(wss,"change between ACI/WSS-mixer; use 0 and 1 - untested" - " default: do nothing; for PCM1-pro only"); - -#ifdef DEBUG -static void print_bits(unsigned char c) -{ - int j; - printk(KERN_DEBUG "aci: "); - - for (j=7; j>=0; j--) { - printk("%d", (c >> j) & 0x1); - } - - printk("\n"); -} -#endif - -/* - * This busy wait code normally requires less than 15 loops and - * practically always less than 100 loops on my i486/DX2 66 MHz. - * - * Warning: Waiting on the general status flag after reseting the MUTE - * function can take a VERY long time, because the PCM12 does some kind - * of fade-in effect. For this reason, access to the MUTE function has - * not been implemented at all. - * - * - The OSS interface has no mute option. It takes about 3 seconds to - * fade-in on my PCM20. busy_wait() handles it great now... Robert - */ - -static int busy_wait(void) -{ - #define MINTIME 500 - long timeout; - unsigned char byte; - - for (timeout = 1; timeout <= MINTIME+30; timeout++) { - if (((byte=inb(BUSY_REGISTER)) & 1) == 0) { - if (timeout >= MINTIME) - printk(KERN_DEBUG "aci: Got READYFLAG in round %ld.\n", timeout-MINTIME); - return byte; - } - if (timeout >= MINTIME) { - long out=10*HZ; - switch (timeout-MINTIME) { - case 0 ... 9: - out /= 10; - case 10 ... 19: - out /= 10; - case 20 ... 30: - out /= 10; - default: - set_current_state(TASK_UNINTERRUPTIBLE); - schedule_timeout(out); - break; - } - } - } - printk(KERN_WARNING "aci: busy_wait() time out.\n"); - return -EBUSY; -} - -/* The four ACI command types are fucked up. [-: - * implied is: 1w - special case for INIT - * write is: 2w1r - * read is: x(1w1r) where x is 1 or 2 (1 CHECK_SIG, 1 CHECK_STER, - * 1 VERSION, 2 IDCODE) - * the command is only in the first write, rest is protocol overhead - * - * indexed is technically a write and used for STATUS - * and the special case for TUNE is: 3w1r - * - * Here the new general sheme: TUNE --> aci_rw_cmd(x, y, z) - * indexed and write --> aci_rw_cmd(x, y, -1) - * implied and read (x=1) --> aci_rw_cmd(x, -1, -1) - * - * Read (x>=2) is not implemented (only used during initialization). - * Use aci_idcode[2] and aci_version... Robert - */ - -/* Some notes for error detection: theoretically it is possible. - * But it doubles the I/O-traffic from ww(r) to wwwrw(r) in the normal - * case and doesn't seem to be designed for that... Robert - */ - -static inline int aci_rawwrite(unsigned char byte) -{ - if (busy_wait() >= 0) { -#ifdef DEBUG - printk(KERN_DEBUG "aci_rawwrite(%d)\n", byte); -#endif - outb(byte, COMMAND_REGISTER); - return 0; - } else - return -EBUSY; -} - -static inline int aci_rawread(void) -{ - unsigned char byte; - - if (busy_wait() >= 0) { - byte=inb(STATUS_REGISTER); -#ifdef DEBUG - printk(KERN_DEBUG "%d = aci_rawread()\n", byte); -#endif - return byte; - } else - return -EBUSY; -} - - -int aci_rw_cmd(int write1, int write2, int write3) -{ - int write[] = {write1, write2, write3}; - int read = -EINTR, i; - - if (mutex_lock_interruptible(&aci_mutex)) - goto out; - - for (i=0; i<3; i++) { - if (write[i]< 0 || write[i] > 255) - break; - else { - read = aci_rawwrite(write[i]); - if (read < 0) - goto out_up; - } - - } - - read = aci_rawread(); -out_up: mutex_unlock(&aci_mutex); -out: return read; -} - -EXPORT_SYMBOL(aci_rw_cmd); - -static int setvolume(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int vol, ret, uservol, buf; - - __get_user(uservol, arg); - - /* left channel */ - vol = uservol & 0xff; - if (vol > 100) - vol = 100; - vol = SCALE(100, 0x20, vol); - if ((buf=aci_write_cmd(left_index, 0x20 - vol))<0) - return buf; - ret = SCALE(0x20, 100, vol); - - - /* right channel */ - vol = (uservol >> 8) & 0xff; - if (vol > 100) - vol = 100; - vol = SCALE(100, 0x20, vol); - if ((buf=aci_write_cmd(right_index, 0x20 - vol))<0) - return buf; - ret |= SCALE(0x20, 100, vol) << 8; - - __put_user(ret, arg); - - return 0; -} - -static int getvolume(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int vol; - int buf; - - /* left channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, left_index))<0) - return buf; - vol = SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0); - - /* right channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, right_index))<0) - return buf; - vol |= SCALE(0x20, 100, buf < 0x20 ? 0x20-buf : 0) << 8; - - __put_user(vol, arg); - - return 0; -} - - -/* The equalizer is somewhat strange on the ACI. From -12dB to +12dB - * write: 0xff..down.to..0x80==0x00..up.to..0x7f - */ - -static inline unsigned int eq_oss2aci(unsigned int vol) -{ - int boost=0; - unsigned int ret; - - if (vol > 100) - vol = 100; - if (vol > 50) { - vol -= 51; - boost=1; - } - if (boost) - ret=SCALE(49, 0x7e, vol)+1; - else - ret=0xff - SCALE(50, 0x7f, vol); - return ret; -} - -static inline unsigned int eq_aci2oss(unsigned int vol) -{ - if (vol < 0x80) - return SCALE(0x7f, 50, vol) + 50; - else - return SCALE(0x7f, 50, 0xff-vol); -} - - -static int setequalizer(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int buf; - unsigned int vol; - - __get_user(vol, arg); - - /* left channel */ - if ((buf=aci_write_cmd(left_index, eq_oss2aci(vol & 0xff)))<0) - return buf; - - /* right channel */ - if ((buf=aci_write_cmd(right_index, eq_oss2aci((vol>>8) & 0xff)))<0) - return buf; - - /* the ACI equalizer is more precise */ - return 0; -} - -static int getequalizer(int __user *arg, - unsigned char left_index, unsigned char right_index) -{ - int buf; - unsigned int vol; - - /* left channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, left_index))<0) - return buf; - vol = eq_aci2oss(buf); - - /* right channel */ - if ((buf=aci_indexed_cmd(ACI_STATUS, right_index))<0) - return buf; - vol |= eq_aci2oss(buf) << 8; - - __put_user(vol, arg); - - return 0; -} - -static int aci_mixer_ioctl (int dev, unsigned int cmd, void __user * arg) -{ - int vol, buf; - int __user *p = arg; - - switch (cmd) { - case SOUND_MIXER_WRITE_VOLUME: - return setvolume(p, 0x01, 0x00); - case SOUND_MIXER_WRITE_CD: - return setvolume(p, 0x3c, 0x34); - case SOUND_MIXER_WRITE_MIC: - return setvolume(p, 0x38, 0x30); - case SOUND_MIXER_WRITE_LINE: - return setvolume(p, 0x39, 0x31); - case SOUND_MIXER_WRITE_SYNTH: - return setvolume(p, 0x3b, 0x33); - case SOUND_MIXER_WRITE_PCM: - return setvolume(p, 0x3a, 0x32); - case MIXER_WRITE(SOUND_MIXER_RADIO): /* fall through */ - case SOUND_MIXER_WRITE_LINE1: /* AUX1 or radio */ - return setvolume(p, 0x3d, 0x35); - case SOUND_MIXER_WRITE_LINE2: /* AUX2 */ - return setvolume(p, 0x3e, 0x36); - case SOUND_MIXER_WRITE_BASS: /* set band one and two */ - if (aci_idcode[1]=='C') { - if ((buf=setequalizer(p, 0x48, 0x40)) || - (buf=setequalizer(p, 0x49, 0x41))); - return buf; - } - break; - case SOUND_MIXER_WRITE_TREBLE: /* set band six and seven */ - if (aci_idcode[1]=='C') { - if ((buf=setequalizer(p, 0x4d, 0x45)) || - (buf=setequalizer(p, 0x4e, 0x46))); - return buf; - } - break; - case SOUND_MIXER_WRITE_IGAIN: /* MIC pre-amp */ - if (aci_idcode[1]=='B' || aci_idcode[1]=='C') { - __get_user(vol, p); - vol = vol & 0xff; - if (vol > 100) - vol = 100; - vol = SCALE(100, 3, vol); - if ((buf=aci_write_cmd(ACI_WRITE_IGAIN, vol))<0) - return buf; - aci_micpreamp = vol; - vol = SCALE(3, 100, vol); - vol |= (vol << 8); - __put_user(vol, p); - return 0; - } - break; - case SOUND_MIXER_WRITE_OGAIN: /* Power-amp/line-out level */ - if (aci_idcode[1]=='A' || aci_idcode[1]=='B') { - __get_user(buf, p); - buf = buf & 0xff; - if (buf > 50) - vol = 1; - else - vol = 0; - if ((buf=aci_write_cmd(ACI_SET_POWERAMP, vol))<0) - return buf; - aci_amp = vol; - if (aci_amp) - buf = (100 || 100<<8); - else - buf = 0; - __put_user(buf, p); - return 0; - } - break; - case SOUND_MIXER_WRITE_RECSRC: - /* handle solo mode control */ - __get_user(buf, p); - /* unset solo when RECSRC for PCM is requested */ - if (aci_idcode[1]=='B' || aci_idcode[1]=='C') { - vol = !(buf & SOUND_MASK_PCM); - if ((buf=aci_write_cmd(ACI_SET_SOLOMODE, vol))<0) - return buf; - aci_solo = vol; - } - buf = (SOUND_MASK_CD| SOUND_MASK_MIC| SOUND_MASK_LINE| - SOUND_MASK_SYNTH| SOUND_MASK_LINE2); - if (aci_idcode[1] == 'C') /* PCM20 radio */ - buf |= SOUND_MASK_RADIO; - else - buf |= SOUND_MASK_LINE1; - if (!aci_solo) - buf |= SOUND_MASK_PCM; - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_DEVMASK: - buf = (SOUND_MASK_VOLUME | SOUND_MASK_CD | - SOUND_MASK_MIC | SOUND_MASK_LINE | - SOUND_MASK_SYNTH | SOUND_MASK_PCM | - SOUND_MASK_LINE2); - switch (aci_idcode[1]) { - case 'C': /* PCM20 radio */ - buf |= (SOUND_MASK_RADIO | SOUND_MASK_IGAIN | - SOUND_MASK_BASS | SOUND_MASK_TREBLE); - break; - case 'B': /* PCM12 */ - buf |= (SOUND_MASK_LINE1 | SOUND_MASK_IGAIN | - SOUND_MASK_OGAIN); - break; - case 'A': /* PCM1-pro */ - buf |= (SOUND_MASK_LINE1 | SOUND_MASK_OGAIN); - break; - default: - buf |= SOUND_MASK_LINE1; - } - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_STEREODEVS: - buf = (SOUND_MASK_VOLUME | SOUND_MASK_CD | - SOUND_MASK_MIC | SOUND_MASK_LINE | - SOUND_MASK_SYNTH | SOUND_MASK_PCM | - SOUND_MASK_LINE2); - switch (aci_idcode[1]) { - case 'C': /* PCM20 radio */ - buf |= (SOUND_MASK_RADIO | - SOUND_MASK_BASS | SOUND_MASK_TREBLE); - break; - default: - buf |= SOUND_MASK_LINE1; - } - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_RECMASK: - buf = (SOUND_MASK_CD| SOUND_MASK_MIC| SOUND_MASK_LINE| - SOUND_MASK_SYNTH| SOUND_MASK_LINE2| SOUND_MASK_PCM); - if (aci_idcode[1] == 'C') /* PCM20 radio */ - buf |= SOUND_MASK_RADIO; - else - buf |= SOUND_MASK_LINE1; - - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_RECSRC: - buf = (SOUND_MASK_CD | SOUND_MASK_MIC | SOUND_MASK_LINE | - SOUND_MASK_SYNTH | SOUND_MASK_LINE2); - /* do we need aci_solo or can I get it from the ACI? */ - switch (aci_idcode[1]) { - case 'B': /* PCM12 */ - case 'C': /* PCM20 radio */ - if (aci_version >= 0xb0) { - if ((vol=aci_rw_cmd(ACI_STATUS, - ACI_S_GENERAL, -1))<0) - return vol; - if (vol & 0x20) - buf |= SOUND_MASK_PCM; - } - else - if (!aci_solo) - buf |= SOUND_MASK_PCM; - break; - default: - buf |= SOUND_MASK_PCM; - } - if (aci_idcode[1] == 'C') /* PCM20 radio */ - buf |= SOUND_MASK_RADIO; - else - buf |= SOUND_MASK_LINE1; - - __put_user(buf, p); - return 0; - case SOUND_MIXER_READ_CAPS: - __put_user(0, p); - return 0; - case SOUND_MIXER_READ_VOLUME: - return getvolume(p, 0x04, 0x03); - case SOUND_MIXER_READ_CD: - return getvolume(p, 0x0a, 0x09); - case SOUND_MIXER_READ_MIC: - return getvolume(p, 0x06, 0x05); - case SOUND_MIXER_READ_LINE: - return getvolume(p, 0x08, 0x07); - case SOUND_MIXER_READ_SYNTH: - return getvolume(p, 0x0c, 0x0b); - case SOUND_MIXER_READ_PCM: - return getvolume(p, 0x0e, 0x0d); - case MIXER_READ(SOUND_MIXER_RADIO): /* fall through */ - case SOUND_MIXER_READ_LINE1: /* AUX1 */ - return getvolume(p, 0x11, 0x10); - case SOUND_MIXER_READ_LINE2: /* AUX2 */ - return getvolume(p, 0x13, 0x12); - case SOUND_MIXER_READ_BASS: /* get band one */ - if (aci_idcode[1]=='C') { - return getequalizer(p, 0x23, 0x22); - } - break; - case SOUND_MIXER_READ_TREBLE: /* get band seven */ - if (aci_idcode[1]=='C') { - return getequalizer(p, 0x2f, 0x2e); - } - break; - case SOUND_MIXER_READ_IGAIN: /* MIC pre-amp */ - if (aci_idcode[1]=='B' || aci_idcode[1]=='C') { - /* aci_micpreamp or ACI? */ - if (aci_version >= 0xb0) { - if ((buf=aci_indexed_cmd(ACI_STATUS, - ACI_S_READ_IGAIN))<0) - return buf; - } - else - buf=aci_micpreamp; - vol = SCALE(3, 100, buf <= 3 ? buf : 3); - vol |= vol << 8; - __put_user(vol, p); - return 0; - } - break; - case SOUND_MIXER_READ_OGAIN: - if (aci_amp) - buf = (100 || 100<<8); - else - buf = 0; - __put_user(buf, p); - return 0; - } - return -EINVAL; -} - -static struct mixer_operations aci_mixer_operations = -{ - .owner = THIS_MODULE, - .id = "ACI", - .ioctl = aci_mixer_ioctl -}; - -/* - * There is also an internal mixer in the codec (CS4231A or AD1845), - * that deserves no purpose in an ACI based system which uses an - * external ACI controlled stereo mixer. Make sure that this codec - * mixer has the AUX1 input selected as the recording source, that the - * input gain is set near maximum and that the other channels going - * from the inputs to the codec output are muted. - */ - -static int __init attach_aci(void) -{ - char *boardname; - int i, rc = -EBUSY; - - mutex_init(&aci_mutex); - - outb(0xE3, 0xf8f); /* Write MAD16 password */ - aci_port = (inb(0xf90) & 0x10) ? - 0x344: 0x354; /* Get aci_port from MC4_PORT */ - - if (!request_region(aci_port, 3, "sound mixer (ACI)")) { - printk(KERN_NOTICE - "aci: I/O area 0x%03x-0x%03x already used.\n", - aci_port, aci_port+2); - goto out; - } - - /* force ACI into a known state */ - rc = -EFAULT; - for (i=0; i<3; i++) - if (aci_rw_cmd(ACI_ERROR_OP, -1, -1)<0) - goto out_release_region; - - /* official this is one aci read call: */ - rc = -EFAULT; - if ((aci_idcode[0]=aci_rw_cmd(ACI_READ_IDCODE, -1, -1))<0 || - (aci_idcode[1]=aci_rw_cmd(ACI_READ_IDCODE, -1, -1))<0) { - printk(KERN_ERR "aci: Failed to read idcode on 0x%03x.\n", - aci_port); - goto out_release_region; - } - - if ((aci_version=aci_rw_cmd(ACI_READ_VERSION, -1, -1))<0) { - printk(KERN_ERR "aci: Failed to read version on 0x%03x.\n", - aci_port); - goto out_release_region; - } - - if (aci_idcode[0] == 'm') { - /* It looks like a miro sound card. */ - switch (aci_idcode[1]) { - case 'A': - boardname = "PCM1 pro / early PCM12"; - break; - case 'B': - boardname = "PCM12"; - break; - case 'C': - boardname = "PCM20 radio"; - break; - default: - boardname = "unknown miro"; - } - } else { - printk(KERN_WARNING "aci: Warning: unsupported card! - " - "no hardware, no specs...\n"); - boardname = "unknown Cardinal Technologies"; - } - - printk(KERN_INFO " at 0x%03x\n", - aci_version, - aci_idcode[0], aci_idcode[1], - aci_idcode[0], aci_idcode[1], - boardname, aci_port); - - rc = -EBUSY; - if (reset) { - /* first write()s after reset fail with my PCM20 */ - if (aci_rw_cmd(ACI_INIT, -1, -1)<0 || - aci_rw_cmd(ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP)<0 || - aci_rw_cmd(ACI_ERROR_OP, ACI_ERROR_OP, ACI_ERROR_OP)<0) - goto out_release_region; - } - - /* the PCM20 is muted after reset (and reboot) */ - if (aci_rw_cmd(ACI_SET_MUTE, 0x00, -1)<0) - goto out_release_region; - - if (ide>=0) - if (aci_rw_cmd(ACI_SET_IDE, !ide, -1)<0) - goto out_release_region; - - if (wss>=0 && aci_idcode[1]=='A') - if (aci_rw_cmd(ACI_SET_WSS, !!wss, -1)<0) - goto out_release_region; - - mixer_device = sound_install_mixer(MIXER_DRIVER_VERSION, boardname, - &aci_mixer_operations, - sizeof(aci_mixer_operations), NULL); - rc = 0; - if (mixer_device < 0) { - printk(KERN_ERR "aci: Failed to install mixer.\n"); - rc = mixer_device; - goto out_release_region; - } /* else Maybe initialize the CS4231A mixer here... */ -out: return rc; -out_release_region: - release_region(aci_port, 3); - goto out; -} - -static void __exit unload_aci(void) -{ - sound_unload_mixerdev(mixer_device); - release_region(aci_port, 3); -} - -module_init(attach_aci); -module_exit(unload_aci); -MODULE_LICENSE("GPL"); diff --git a/linux/sound/oss/aci.h b/linux/sound/oss/aci.h deleted file mode 100644 index 20102ee08..000000000 --- a/linux/sound/oss/aci.h +++ /dev/null @@ -1,57 +0,0 @@ -#ifndef _ACI_H_ -#define _ACI_H_ - -extern int aci_port; -extern int aci_version; /* ACI firmware version */ -extern int aci_rw_cmd(int write1, int write2, int write3); - -#define aci_indexed_cmd(a, b) aci_rw_cmd(a, b, -1) -#define aci_write_cmd(a, b) aci_rw_cmd(a, b, -1) -#define aci_read_cmd(a) aci_rw_cmd(a,-1, -1) - -#define COMMAND_REGISTER (aci_port) /* write register */ -#define STATUS_REGISTER (aci_port + 1) /* read register */ -#define BUSY_REGISTER (aci_port + 2) /* also used for rds */ - -#define RDS_REGISTER BUSY_REGISTER - -#define ACI_SET_MUTE 0x0d -#define ACI_SET_POWERAMP 0x0f -#define ACI_SET_TUNERMUTE 0xa3 -#define ACI_SET_TUNERMONO 0xa4 -#define ACI_SET_IDE 0xd0 -#define ACI_SET_WSS 0xd1 -#define ACI_SET_SOLOMODE 0xd2 -#define ACI_WRITE_IGAIN 0x03 -#define ACI_WRITE_TUNE 0xa7 -#define ACI_READ_TUNERSTEREO 0xa8 -#define ACI_READ_TUNERSTATION 0xa9 -#define ACI_READ_VERSION 0xf1 -#define ACI_READ_IDCODE 0xf2 -#define ACI_INIT 0xff -#define ACI_STATUS 0xf0 -#define ACI_S_GENERAL 0x00 -#define ACI_S_READ_IGAIN 0x21 -#define ACI_ERROR_OP 0xdf - -/* - * The following macro SCALE can be used to scale one integer volume - * value into another one using only integer arithmetic. If the input - * value x is in the range 0 <= x <= xmax, then the result will be in - * the range 0 <= SCALE(xmax,ymax,x) <= ymax. - * - * This macro has for all xmax, ymax > 0 and all 0 <= x <= xmax the - * following nice properties: - * - * - SCALE(xmax,ymax,xmax) = ymax - * - SCALE(xmax,ymax,0) = 0 - * - SCALE(xmax,ymax,SCALE(ymax,xmax,SCALE(xmax,ymax,x))) = SCALE(xmax,ymax,x) - * - * In addition, the rounding error is minimal and nicely distributed. - * The proofs are left as an exercise to the reader. - */ - -#define SCALE(xmax,ymax,x) (((x)*(ymax)+(xmax)/2)/(xmax)) - - -#endif /* _ACI_H_ */ diff --git a/v4l/Kconfig.sound b/v4l/Kconfig.sound index 658347dec..597c9c72b 100644 --- a/v4l/Kconfig.sound +++ b/v4l/Kconfig.sound @@ -64,23 +64,6 @@ config SOUND_BT878 To compile this driver as a module, choose M here: the module will be called btaudio. -config SOUND_ACI_MIXER - tristate "ACI mixer (miroSOUND PCM1-pro/PCM12/PCM20)" - depends on SOUND_OSS - ---help--- - ACI (Audio Command Interface) is a protocol used to communicate with - the microcontroller on some sound cards produced by miro and - Cardinal Technologies. The main function of the ACI is to control - the mixer and to get a product identification. - - This VoxWare ACI driver currently supports the ACI functions on the - miroSOUND PCM1-pro, PCM12 and PCM20 radio. On the PCM20 radio, ACI - also controls the radio tuner. This is supported in the video4linux - miropcm20 driver (say M or Y here and go back to "Multimedia - devices" -> "Radio Adapters"). - - This driver is also available as a module and will be called aci. - config SOUND_TVMIXER tristate "TV card (bt848) mixer support" depends on SOUND_PRIME && I2C && VIDEO_V4L1 diff --git a/v4l/Makefile b/v4l/Makefile index b43b59867..04e74e8e5 100644 --- a/v4l/Makefile +++ b/v4l/Makefile @@ -109,10 +109,6 @@ ifeq ($(CONFIG_DVB_FIRESAT),m) EXTRA_CFLAGS += -I$(srctree)/drivers/ieee1394/ endif -ifeq ($(CONFIG_SOUND_ACI_MIXER),m) - EXTRA_CFLAGS += -I$(srctree)/sound/oss/ -endif - EXTRA_CFLAGS += -g EXTRA_CFLAGS += $(if $(wildcard $(srctree)/.mm), -DMM_KERNEL) diff --git a/v4l/Makefile.sound b/v4l/Makefile.sound index 0f218b78b..941dbc65c 100644 --- a/v4l/Makefile.sound +++ b/v4l/Makefile.sound @@ -5,7 +5,6 @@ obj-$(CONFIG_SND_BT87X) += snd-bt87x.o # From sound/oss/Makefile -obj-$(CONFIG_SOUND_ACI_MIXER) += aci.o obj-$(CONFIG_SOUND_BT878) += btaudio.o # From sound/i2c/other/Makefile @@ -17,22 +16,22 @@ KDIRA := /lib/modules/$(KERNELRELEASE)/kernel sound-install install-sound:: @dir="sound/pci"; \ - files='snd-bt87x.ko'; \ - echo -e "\nInstalling $(KDIRA)/$$dir files:"; \ - install -d $(KDIRA)/$$dir; \ - for i in $$files;do if [ -e $$i ]; then echo -n "$$i "; \ + files='snd-bt87x.ko'; \ + echo -e "\nInstalling $(KDIRA)/$$dir files:"; \ + install -d $(KDIRA)/$$dir; \ + for i in $$files;do if [ -e $$i ]; then echo -n "$$i "; \ install -m 644 -c $$i $(KDIRA)/$$dir; fi; done; echo; @dir="sound/oss"; \ - files='aci.ko btaudio.ko'; \ - echo -e "\nInstalling $(KDIRA)/$$dir files:"; \ - install -d $(KDIRA)/$$dir; \ + files='btaudio.ko'; \ + echo -e "\nInstalling $(KDIRA)/$$dir files:"; \ + install -d $(KDIRA)/$$dir; \ for i in $$files;do if [ -e $$i ]; then echo -n "$$i "; \ install -m 644 -c $$i $(KDIRA)/$$dir; fi; done; echo; @dir="sound/i2c/other"; \ files='snd-tea575x-tuner.ko'; \ - echo -e "\nInstalling $(KDIRA)/$$dir files:"; \ - install -d $(KDIRA)/$$dir; \ + echo -e "\nInstalling $(KDIRA)/$$dir files:"; \ + install -d $(KDIRA)/$$dir; \ for i in $$files;do if [ -e $$i ]; then echo -n "$$i "; \ install -m 644 -c $$i $(KDIRA)/$$dir; fi; done; echo; diff --git a/v4l/scripts/make_kconfig.pl b/v4l/scripts/make_kconfig.pl index ee649f574..20b94f0c1 100755 --- a/v4l/scripts/make_kconfig.pl +++ b/v4l/scripts/make_kconfig.pl @@ -583,9 +583,6 @@ disable_config('DVB_CINERGYT2_TUNING'); disable_config('DVB_FE_CUSTOMISE'); disable_config('VIDEO_HELPER_CHIPS_AUTO'); -# ACI needs some kernel includes that might not be there -disable_config('SOUND_ACI_MIXER') if (! -e "$kernsrc/sound/oss/sound_config.h"); - # Check dependencies my %newconfig = checkdeps(); -- cgit v1.2.3 From 995c07b049f1633deb6e269cc0e7978b8c0dff4e Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 17 Aug 2008 22:13:31 -0400 Subject: cx18: Add missing lock for when the irq handler manipulates the queues From: Andy Walls cx18: Add missing lock for when the irq handler manipulates the queues. This was a potential source of stream queue corruption. Also changed the name of cx18_queue_find_buf() to cx18_queue_get_buf_irq(). Priority: high Signed-off-by: Andy Walls --- linux/drivers/media/video/cx18/cx18-irq.c | 2 +- linux/drivers/media/video/cx18/cx18-queue.c | 23 +++++++++++++---------- linux/drivers/media/video/cx18/cx18-queue.h | 2 +- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/linux/drivers/media/video/cx18/cx18-irq.c b/linux/drivers/media/video/cx18/cx18-irq.c index 654664783..b9cf609ee 100644 --- a/linux/drivers/media/video/cx18/cx18-irq.c +++ b/linux/drivers/media/video/cx18/cx18-irq.c @@ -61,7 +61,7 @@ static void epu_dma_done(struct cx18 *cx, struct cx18_mailbox *mb) CX18_WARN("Ack struct = %d for %s\n", mb->args[2], s->name); id = read_enc(off); - buf = cx18_queue_find_buf(s, id, read_enc(off + 4)); + buf = cx18_queue_get_buf_irq(s, id, read_enc(off + 4)); CX18_DEBUG_HI_DMA("DMA DONE for %s (buffer %d)\n", s->name, id); if (buf) { cx18_buf_sync_for_cpu(s, buf); diff --git a/linux/drivers/media/video/cx18/cx18-queue.c b/linux/drivers/media/video/cx18/cx18-queue.c index 6990b77c6..8a4dd821f 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.c +++ b/linux/drivers/media/video/cx18/cx18-queue.c @@ -78,12 +78,13 @@ struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q) return buf; } -struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, +struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, u32 bytesused) { struct cx18 *cx = s->cx; struct list_head *p; + spin_lock(&s->qlock); list_for_each(p, &s->q_free.list) { struct cx18_buffer *buf = list_entry(p, struct cx18_buffer, list); @@ -92,17 +93,19 @@ struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, continue; buf->bytesused = bytesused; /* the transport buffers are handled differently, - so there is no need to move them to the full queue */ - if (s->type == CX18_ENC_STREAM_TYPE_TS) - return buf; - s->q_free.buffers--; - s->q_free.length -= s->buf_size; - s->q_full.buffers++; - s->q_full.length += s->buf_size; - s->q_full.bytesused += buf->bytesused; - list_move_tail(&buf->list, &s->q_full.list); + they are not moved to the full queue */ + if (s->type != CX18_ENC_STREAM_TYPE_TS) { + s->q_free.buffers--; + s->q_free.length -= s->buf_size; + s->q_full.buffers++; + s->q_full.length += s->buf_size; + s->q_full.bytesused += buf->bytesused; + list_move_tail(&buf->list, &s->q_full.list); + } + spin_unlock(&s->qlock); return buf; } + spin_unlock(&s->qlock); CX18_ERR("Cannot find buffer %d for stream %s\n", id, s->name); return NULL; } diff --git a/linux/drivers/media/video/cx18/cx18-queue.h b/linux/drivers/media/video/cx18/cx18-queue.h index 91423b986..7f93bb13c 100644 --- a/linux/drivers/media/video/cx18/cx18-queue.h +++ b/linux/drivers/media/video/cx18/cx18-queue.h @@ -46,7 +46,7 @@ void cx18_queue_init(struct cx18_queue *q); void cx18_enqueue(struct cx18_stream *s, struct cx18_buffer *buf, struct cx18_queue *q); struct cx18_buffer *cx18_dequeue(struct cx18_stream *s, struct cx18_queue *q); -struct cx18_buffer *cx18_queue_find_buf(struct cx18_stream *s, u32 id, +struct cx18_buffer *cx18_queue_get_buf_irq(struct cx18_stream *s, u32 id, u32 bytesused); void cx18_flush_queues(struct cx18_stream *s); -- cgit v1.2.3 From 2315f8eef1304343666da0b452b8ec290aa32132 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Aug 2008 09:46:12 +0200 Subject: pxa: fix build error for 2.6.27. From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/pxa_camera.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c index ead87ddaf..4ddd26d6c 100644 --- a/linux/drivers/media/video/pxa_camera.c +++ b/linux/drivers/media/video/pxa_camera.c @@ -36,8 +36,13 @@ #include #include +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27) +#include +#include +#else #include #include +#endif #define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5) #define PXA_CAM_DRV_NAME "pxa27x-camera" -- cgit v1.2.3 From 4589075f331c3f32641ecd0313fe4728a9f75940 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Mon, 18 Aug 2008 09:48:42 +0200 Subject: usbvideo: add proper error check and add release function From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- linux/drivers/media/video/usbvideo/usbvideo.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/linux/drivers/media/video/usbvideo/usbvideo.c b/linux/drivers/media/video/usbvideo/usbvideo.c index 5bda83f7d..4b28a6dfb 100644 --- a/linux/drivers/media/video/usbvideo/usbvideo.c +++ b/linux/drivers/media/video/usbvideo/usbvideo.c @@ -1006,6 +1006,10 @@ allocate_done: EXPORT_SYMBOL(usbvideo_AllocateDevice); +static void usbvideo_dummy_release(struct video_device *vfd) +{ +} + int usbvideo_RegisterVideoDevice(struct uvd *uvd) { char tmp1[20], tmp2[20]; /* Buffers for printing */ @@ -1039,7 +1043,8 @@ int usbvideo_RegisterVideoDevice(struct uvd *uvd) return -EINVAL; } uvd->vdev.parent = &uvd->dev->dev; - if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) == -1) { + uvd->vdev.release = usbvideo_dummy_release; + if (video_register_device(&uvd->vdev, VFL_TYPE_GRABBER, video_nr) < 0) { err("%s: video_register_device failed", __func__); return -EPIPE; } -- cgit v1.2.3 From e9c833f2ec2a668841517edc68cb393e3881594f Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 19 Aug 2008 11:44:07 +0200 Subject: v4l2-ctl: added support to set the pixelformat From: Hans Verkuil Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-ctl.cpp | 37 ++++++++++++++++++++++++++++++++----- 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 5d70ed9f3..9c4160083 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -160,6 +160,7 @@ static const flag_def service_def[] = { #define FmtHeight (1L<<1) #define FmtChromaKey (1L<<2) #define FmtGlobalAlpha (1L<<3) +#define FmtPixelFormat (1L<<4) /* crop specified */ #define CropWidth (1L<<0) @@ -286,8 +287,10 @@ static void usage(void) printf(" --list-formats display supported video formats [VIDIOC_ENUM_FMT]\n"); printf(" -V, --get-fmt-video\n"); printf(" query the video capture format [VIDIOC_G_FMT]\n"); - printf(" -v, --set-fmt-video=width=,height=\n"); + printf(" -v, --set-fmt-video=width=,height=,pixelformat=\n"); printf(" set the video capture format [VIDIOC_S_FMT]\n"); + printf(" pixelformat is either the format index as reported by\n"); + printf(" --list-formats, or the fourcc value as a string\n"); printf(" --verbose turn on verbose ioctl error reporting.\n"); printf("\n"); printf("Uncommon options:\n"); @@ -701,7 +704,7 @@ static void printfbuf(const struct v4l2_framebuffer &fb) printf("\tBase : 0x%p\n", fb.base); printf("\tWidth : %d\n", fb.fmt.width); printf("\tHeight : %d\n", fb.fmt.height); - printf("\tPixel Format : %s\n", fcc2s(fb.fmt.pixelformat).c_str()); + printf("\tPixel Format : '%s'\n", fcc2s(fb.fmt.pixelformat).c_str()); if (!is_ext) { printf("\tBytes per Line: %d\n", fb.fmt.bytesperline); printf("\tSize image : %d\n", fb.fmt.sizeimage); @@ -740,7 +743,7 @@ static void printfmt(struct v4l2_format vfmt) case V4L2_BUF_TYPE_VIDEO_CAPTURE: case V4L2_BUF_TYPE_VIDEO_OUTPUT: printf("\tWidth/Height : %u/%u\n", vfmt.fmt.pix.width, vfmt.fmt.pix.height); - printf("\tPixel Format : %s\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str()); + printf("\tPixel Format : '%s'\n", fcc2s(vfmt.fmt.pix.pixelformat).c_str()); printf("\tField : %s\n", field2s(vfmt.fmt.pix.field).c_str()); printf("\tBytes per Line: %u\n", vfmt.fmt.pix.bytesperline); printf("\tSize Image : %u\n", vfmt.fmt.pix.sizeimage); @@ -798,8 +801,9 @@ static void print_video_formats(int fd, enum v4l2_buf_type type) fmt.index = 0; fmt.type = type; while (ioctl(fd, VIDIOC_ENUM_FMT, &fmt) >= 0) { + printf("\tIndex : %d\n", fmt.index); printf("\tType : %s\n", buftype2s(type).c_str()); - printf("\tPixelformat : %s", fcc2s(fmt.pixelformat).c_str()); + printf("\tPixel Format: '%s'", fcc2s(fmt.pixelformat).c_str()); if (fmt.flags) printf(" (compressed)"); printf("\n"); @@ -1239,6 +1243,7 @@ int main(int argc, char **argv) static const char *const subopts[] = { "width", "height", + "pixelformat", NULL }; @@ -1251,6 +1256,15 @@ int main(int argc, char **argv) vfmt.fmt.pix.height = strtol(value, 0L, 0); set_fmts |= FmtHeight; break; + case 2: + if (strlen(value) == 4) + vfmt.fmt.pix.pixelformat = + v4l2_fourcc(value[0], value[1], + value[2], value[3]); + else + vfmt.fmt.pix.pixelformat = strtol(value, 0L, 0); + set_fmts |= FmtPixelFormat; + break; } } break; @@ -1627,9 +1641,22 @@ int main(int argc, char **argv) in_vfmt.fmt.pix.width = vfmt.fmt.pix.width; if (set_fmts & FmtHeight) in_vfmt.fmt.pix.height = vfmt.fmt.pix.height; + if (set_fmts & FmtPixelFormat) { + in_vfmt.fmt.pix.pixelformat = vfmt.fmt.pix.pixelformat; + if (in_vfmt.fmt.pix.pixelformat < 256) { + struct v4l2_fmtdesc fmt; + + fmt.index = in_vfmt.fmt.pix.pixelformat; + fmt.type = in_vfmt.type; + if (doioctl(fd, VIDIOC_ENUM_FMT, &fmt, "VIDIOC_ENUM_FMT")) + goto set_vid_fmt_error; + in_vfmt.fmt.pix.pixelformat = fmt.pixelformat; + } + } doioctl(fd, VIDIOC_S_FMT, &in_vfmt, "VIDIOC_S_FMT"); } } +set_vid_fmt_error: if (options[OptSetVideoOutFormat]) { struct v4l2_format in_vfmt; @@ -2119,7 +2146,7 @@ int main(int argc, char **argv) while (ioctl(fd, VIDIOC_ENUMSTD, &vs) >= 0) { if (vs.index) printf("\n"); - printf("\tindex : %d\n", vs.index); + printf("\tIndex : %d\n", vs.index); printf("\tID : 0x%016llX\n", (unsigned long long)vs.id); printf("\tName : %s\n", vs.name); printf("\tFrame period: %d/%d\n", -- cgit v1.2.3 From 0d2e3e67923b5566ae9be732381751395acfb42d Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 19 Aug 2008 11:58:32 +0200 Subject: v4l2-ctl: merge strings in the usage message From: Jean Delvare Function calls aren't cheap. By merging the strings printed by the usage() function, we reduce the number of times printf (or actually puts) is called, from 121 to only 4. This makes usage() about twice as fast as before, and also shrinks the binary size a bit (4 kB). Priority: normal Signed-off-by: Jean Delvare Signed-off-by: Hans Verkuil --- v4l2-apps/util/v4l2-ctl.cpp | 244 ++++++++++++++++++++++---------------------- 1 file changed, 122 insertions(+), 122 deletions(-) diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp index 9c4160083..ae9293414 100644 --- a/v4l2-apps/util/v4l2-ctl.cpp +++ b/v4l2-apps/util/v4l2-ctl.cpp @@ -237,128 +237,128 @@ static struct option long_options[] = { static void usage(void) { printf("Usage:\n"); - printf("Common options:\n"); - printf(" --all display all information available\n"); - printf(" -B, --get-fmt-sliced-vbi\n"); - printf(" query the sliced VBI capture format [VIDIOC_G_FMT]\n"); - printf(" -b, --set-fmt-sliced-vbi=\n"); - printf(" set the sliced VBI capture format to [VIDIOC_S_FMT]\n"); - printf(" is a comma separated list of:\n"); - printf(" off: turn off sliced VBI (cannot be combined with other modes)\n"); - printf(" teletext: teletext (PAL/SECAM)\n"); - printf(" cc: closed caption (NTSC)\n"); - printf(" wss: widescreen signal (PAL/SECAM)\n"); - printf(" vps: VPS (PAL/SECAM)\n"); - printf(" -C, --get-ctrl=[,...]\n"); - printf(" get the value of the controls [VIDIOC_G_EXT_CTRLS]\n"); - printf(" -c, --set-ctrl==[,=...]\n"); - printf(" set the controls to the values specified [VIDIOC_S_EXT_CTRLS]\n"); - printf(" -D, --info show driver info [VIDIOC_QUERYCAP]\n"); - printf(" -d, --device= use device instead of /dev/video0\n"); - printf(" if is a single digit, then /dev/video is used\n"); - printf(" -F, --get-freq query the frequency [VIDIOC_G_FREQUENCY]\n"); - printf(" -f, --set-freq=\n"); - printf(" set the frequency to MHz [VIDIOC_S_FREQUENCY]\n"); - printf(" -h, --help display this help message\n"); - printf(" -I, --get-input query the video input [VIDIOC_G_INPUT]\n"); - printf(" -i, --set-input=\n"); - printf(" set the video input to [VIDIOC_S_INPUT]\n"); - printf(" -l, --list-ctrls display all controls and their values [VIDIOC_QUERYCTRL]\n"); - printf(" -L, --list-ctrls-menus\n"); - printf(" display all controls, their values and the menus [VIDIOC_QUERYMENU]\n"); - printf(" -N, --list-outputs display video outputs [VIDIOC_ENUMOUTPUT]\n"); - printf(" -n, --list-inputs display video inputs [VIDIOC_ENUMINPUT]\n"); - printf(" -O, --get-output query the video output [VIDIOC_G_OUTPUT]\n"); - printf(" -o, --set-output=\n"); - printf(" set the video output to [VIDIOC_S_OUTPUT]\n"); - printf(" -S, --get-standard\n"); - printf(" query the video standard [VIDIOC_G_STD]\n"); - printf(" -s, --set-standard=\n"); - printf(" set the video standard to [VIDIOC_S_STD]\n"); - printf(" can be a numerical v4l2_std value, or it can be one of:\n"); - printf(" pal-X (X = B/G/H/N/Nc/I/D/K/M/60) or just 'pal' (V4L2_STD_PAL)\n"); - printf(" ntsc-X (X = M/J/K) or just 'ntsc' (V4L2_STD_NTSC)\n"); - printf(" secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n"); - printf(" --list-standards display supported video standards [VIDIOC_ENUMSTD]\n"); - printf(" -T, --get-tuner query the tuner settings [VIDIOC_G_TUNER]\n"); - printf(" -t, --set-tuner=\n"); - printf(" set the audio mode of the tuner [VIDIOC_S_TUNER]\n"); - printf(" Possible values: mono, stereo, lang2, lang1, bilingual\n"); - printf(" --list-formats display supported video formats [VIDIOC_ENUM_FMT]\n"); - printf(" -V, --get-fmt-video\n"); - printf(" query the video capture format [VIDIOC_G_FMT]\n"); - printf(" -v, --set-fmt-video=width=,height=,pixelformat=\n"); - printf(" set the video capture format [VIDIOC_S_FMT]\n"); - printf(" pixelformat is either the format index as reported by\n"); - printf(" --list-formats, or the fourcc value as a string\n"); - printf(" --verbose turn on verbose ioctl error reporting.\n"); - printf("\n"); - printf("Uncommon options:\n"); - printf(" --get-fmt-video-out\n"); - printf(" query the video output format [VIDIOC_G_FMT]\n"); - printf(" --set-fmt-video-out=width=,height=\n"); - printf(" set the video output format [VIDIOC_S_FMT]\n"); - printf(" --get-fmt-overlay\n"); - printf(" query the video overlay format [VIDIOC_G_FMT]\n"); - printf(" --get-fmt-output-overlay\n"); - printf(" query the video output overlay format [VIDIOC_G_FMT]\n"); - printf(" --set-fmt-output-overlay=chromakey=,global_alpha=\n"); - printf(" set the video output overlay format [VIDIOC_S_FMT]\n"); - printf(" --get-sliced-vbi-cap\n"); - printf(" query the sliced VBI capture capabilities [VIDIOC_G_SLICED_VBI_CAP]\n"); - printf(" --get-sliced-vbi-out-cap\n"); - printf(" query the sliced VBI output capabilities [VIDIOC_G_SLICED_VBI_CAP]\n"); - printf(" --get-fmt-sliced-vbi-out\n"); - printf(" query the sliced VBI output format [VIDIOC_G_FMT]\n"); - printf(" --set-fmt-sliced-vbi-out=\n"); - printf(" set the sliced VBI output format to [VIDIOC_S_FMT]\n"); - printf(" is a comma separated list of:\n"); - printf(" off: turn off sliced VBI (cannot be combined with other modes)\n"); - printf(" teletext: teletext (PAL/SECAM)\n"); - printf(" cc: closed caption (NTSC)\n"); - printf(" wss: widescreen signal (PAL/SECAM)\n"); - printf(" vps: VPS (PAL/SECAM)\n"); - printf(" --get-fmt-vbi query the VBI capture format [VIDIOC_G_FMT]\n"); - printf(" --get-fmt-vbi-out query the VBI output format [VIDIOC_G_FMT]\n"); - printf(" --overlay= turn overlay on (1) or off (0) (VIDIOC_OVERLAY)\n"); - printf(" --get-fbuf query the overlay framebuffer data [VIDIOC_G_FBUF]\n"); - printf(" --set-fbuf=chromakey=<0/1>,global_alpha=<0/1>,local_alpha=<0/1>,local_inv_alpha=<0/1>\n"); - printf(" set the overlay framebuffer [VIDIOC_S_FBUF]\n"); - printf(" --get-cropcap query the crop capabilities [VIDIOC_CROPCAP]\n"); - printf(" --get-crop query the video capture crop window [VIDIOC_G_CROP]\n"); - printf(" --set-crop=top=,left=,width=,height=\n"); - printf(" set the video capture crop window [VIDIOC_S_CROP]\n"); - printf(" --get-cropcap-output\n"); - printf(" query the crop capabilities for video output [VIDIOC_CROPCAP]\n"); - printf(" --get-crop-output query the video output crop window [VIDIOC_G_CROP]\n"); - printf(" --set-crop-output=top=,left=,width=,height=\n"); - printf(" set the video output crop window [VIDIOC_S_CROP]\n"); - printf(" --get-cropcap-overlay\n"); - printf(" query the crop capabilities for video overlay [VIDIOC_CROPCAP]\n"); - printf(" --get-crop-overlay query the video overlay crop window [VIDIOC_G_CROP]\n"); - printf(" --set-crop-overlay=top=,left=,width=,height=\n"); - printf(" set the video overlay crop window [VIDIOC_S_CROP]\n"); - printf(" --get-cropcap-output-overlay\n"); - printf(" query the crop capabilities for video output overlays [VIDIOC_CROPCAP]\n"); - printf(" --get-crop-output-overlay\n"); - printf(" query the video output overlay crop window [VIDIOC_G_CROP]\n"); - printf(" --set-crop-output-overlay=top=,left=,width=,height=\n"); - printf(" set the video output overlay crop window [VIDIOC_S_CROP]\n"); - printf(" --get-audio-input query the audio input [VIDIOC_G_AUDIO]\n"); - printf(" --set-audio-input=\n"); - printf(" set the audio input to [VIDIOC_S_AUDIO]\n"); - printf(" --get-audio-output query the audio output [VIDIOC_G_AUDOUT]\n"); - printf(" --set-audio-output=\n"); - printf(" set the audio output to [VIDIOC_S_AUDOUT]\n"); - printf(" --list-audio-outputs\n"); - printf(" display audio outputs [VIDIOC_ENUMAUDOUT]\n"); - printf(" --list-audio-inputs\n"); - printf(" display audio inputs [VIDIOC_ENUMAUDIO]\n"); - printf("\n"); - printf("Expert options:\n"); - printf(" --streamoff turn the stream off [VIDIOC_STREAMOFF]\n"); - printf(" --streamon turn the stream on [VIDIOC_STREAMOFF]\n"); - printf(" --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n"); + printf("Common options:\n" + " --all display all information available\n" + " -B, --get-fmt-sliced-vbi\n" + " query the sliced VBI capture format [VIDIOC_G_FMT]\n" + " -b, --set-fmt-sliced-vbi=\n" + " set the sliced VBI capture format to [VIDIOC_S_FMT]\n" + " is a comma separated list of:\n" + " off: turn off sliced VBI (cannot be combined with other modes)\n" + " teletext: teletext (PAL/SECAM)\n" + " cc: closed caption (NTSC)\n" + " wss: widescreen signal (PAL/SECAM)\n" + " vps: VPS (PAL/SECAM)\n" + " -C, --get-ctrl=[,...]\n" + " get the value of the controls [VIDIOC_G_EXT_CTRLS]\n" + " -c, --set-ctrl==[,=...]\n" + " set the controls to the values specified [VIDIOC_S_EXT_CTRLS]\n" + " -D, --info show driver info [VIDIOC_QUERYCAP]\n" + " -d, --device= use device instead of /dev/video0\n" + " if is a single digit, then /dev/video is used\n" + " -F, --get-freq query the frequency [VIDIOC_G_FREQUENCY]\n" + " -f, --set-freq=\n" + " set the frequency to MHz [VIDIOC_S_FREQUENCY]\n" + " -h, --help display this help message\n" + " -I, --get-input query the video input [VIDIOC_G_INPUT]\n" + " -i, --set-input=\n" + " set the video input to [VIDIOC_S_INPUT]\n" + " -l, --list-ctrls display all controls and their values [VIDIOC_QUERYCTRL]\n" + " -L, --list-ctrls-menus\n" + " display all controls, their values and the menus [VIDIOC_QUERYMENU]\n" + " -N, --list-outputs display video outputs [VIDIOC_ENUMOUTPUT]\n" + " -n, --list-inputs display video inputs [VIDIOC_ENUMINPUT]\n" + " -O, --get-output query the video output [VIDIOC_G_OUTPUT]\n" + " -o, --set-output=\n" + " set the video output to [VIDIOC_S_OUTPUT]\n" + " -S, --get-standard\n" + " query the video standard [VIDIOC_G_STD]\n" + " -s, --set-standard=\n" + " set the video standard to [VIDIOC_S_STD]\n" + " can be a numerical v4l2_std value, or it can be one of:\n" + " pal-X (X = B/G/H/N/Nc/I/D/K/M/60) or just 'pal' (V4L2_STD_PAL)\n" + " ntsc-X (X = M/J/K) or just 'ntsc' (V4L2_STD_NTSC)\n" + " secam-X (X = B/G/H/D/K/L/Lc) or just 'secam' (V4L2_STD_SECAM)\n" + " --list-standards display supported video standards [VIDIOC_ENUMSTD]\n" + " -T, --get-tuner query the tuner settings [VIDIOC_G_TUNER]\n" + " -t, --set-tuner=\n" + " set the audio mode of the tuner [VIDIOC_S_TUNER]\n" + " Possible values: mono, stereo, lang2, lang1, bilingual\n" + " --list-formats display supported video formats [VIDIOC_ENUM_FMT]\n" + " -V, --get-fmt-video\n" + " query the video capture format [VIDIOC_G_FMT]\n" + " -v, --set-fmt-video=width=,height=,pixelformat=\n" + " set the video capture format [VIDIOC_S_FMT]\n" + " pixelformat is either the format index as reported by\n" + " --list-formats, or the fourcc value as a string\n" + " --verbose turn on verbose ioctl error reporting.\n" + "\n"); + printf("Uncommon options:\n" + " --get-fmt-video-out\n" + " query the video output format [VIDIOC_G_FMT]\n" + " --set-fmt-video-out=width=,height=\n" + " set the video output format [VIDIOC_S_FMT]\n" + " --get-fmt-overlay\n" + " query the video overlay format [VIDIOC_G_FMT]\n" + " --get-fmt-output-overlay\n" + " query the video output overlay format [VIDIOC_G_FMT]\n" + " --set-fmt-output-overlay=chromakey=,global_alpha=\n" + " set the video output overlay format [VIDIOC_S_FMT]\n" + " --get-sliced-vbi-cap\n" + " query the sliced VBI capture capabilities [VIDIOC_G_SLICED_VBI_CAP]\n" + " --get-sliced-vbi-out-cap\n" + " query the sliced VBI output capabilities [VIDIOC_G_SLICED_VBI_CAP]\n" + " --get-fmt-sliced-vbi-out\n" + " query the sliced VBI output format [VIDIOC_G_FMT]\n" + " --set-fmt-sliced-vbi-out=\n" + " set the sliced VBI output format to [VIDIOC_S_FMT]\n" + " is a comma separated list of:\n" + " off: turn off sliced VBI (cannot be combined with other modes)\n" + " teletext: teletext (PAL/SECAM)\n" + " cc: closed caption (NTSC)\n" + " wss: widescreen signal (PAL/SECAM)\n" + " vps: VPS (PAL/SECAM)\n" + " --get-fmt-vbi query the VBI capture format [VIDIOC_G_FMT]\n" + " --get-fmt-vbi-out query the VBI output format [VIDIOC_G_FMT]\n" + " --overlay= turn overlay on (1) or off (0) (VIDIOC_OVERLAY)\n" + " --get-fbuf query the overlay framebuffer data [VIDIOC_G_FBUF]\n" + " --set-fbuf=chromakey=<0/1>,global_alpha=<0/1>,local_alpha=<0/1>,local_inv_alpha=<0/1>\n" + " set the overlay framebuffer [VIDIOC_S_FBUF]\n" + " --get-cropcap query the crop capabilities [VIDIOC_CROPCAP]\n" + " --get-crop query the video capture crop window [VIDIOC_G_CROP]\n" + " --set-crop=top=,left=,width=,height=\n" + " set the video capture crop window [VIDIOC_S_CROP]\n" + " --get-cropcap-output\n" + " query the crop capabilities for video output [VIDIOC_CROPCAP]\n" + " --get-crop-output query the video output crop window [VIDIOC_G_CROP]\n" + " --set-crop-output=top=,left=,width=,height=\n" + " set the video output crop window [VIDIOC_S_CROP]\n" + " --get-cropcap-overlay\n" + " query the crop capabilities for video overlay [VIDIOC_CROPCAP]\n" + " --get-crop-overlay query the video overlay crop window [VIDIOC_G_CROP]\n" + " --set-crop-overlay=top=,left=,width=,height=\n" + " set the video overlay crop window [VIDIOC_S_CROP]\n" + " --get-cropcap-output-overlay\n" + " query the crop capabilities for video output overlays [VIDIOC_CROPCAP]\n" + " --get-crop-output-overlay\n" + " query the video output overlay crop window [VIDIOC_G_CROP]\n" + " --set-crop-output-overlay=top=,left=,width=,height=\n" + " set the video output overlay crop window [VIDIOC_S_CROP]\n" + " --get-audio-input query the audio input [VIDIOC_G_AUDIO]\n" + " --set-audio-input=\n" + " set the audio input to [VIDIOC_S_AUDIO]\n" + " --get-audio-output query the audio output [VIDIOC_G_AUDOUT]\n" + " --set-audio-output=\n" + " set the audio output to [VIDIOC_S_AUDOUT]\n" + " --list-audio-outputs\n" + " display audio outputs [VIDIOC_ENUMAUDOUT]\n" + " --list-audio-inputs\n" + " display audio inputs [VIDIOC_ENUMAUDIO]\n" + "\n"); + printf("Expert options:\n" + " --streamoff turn the stream off [VIDIOC_STREAMOFF]\n" + " --streamon turn the stream on [VIDIOC_STREAMOFF]\n" + " --log-status log the board status in the kernel log [VIDIOC_LOG_STATUS]\n"); exit(0); } -- cgit v1.2.3 From ef6ddad0c79749035c10a209ee823028aca9c5b3 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 20 Aug 2008 09:07:22 +0200 Subject: capture_example: Don't change the format by default From: Jean Delvare Don't change the capture format by default. This lets the user select the capture pixel format and resolution using v4l2-ctl. The old behavior (forcing the format to 640x480 YUYV) can still be obtained by passing -f. Priority: normal Signed-off-by: Jean Delvare Signed-off-by: Hans Verkuil --- v4l2-apps/test/capture_example.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/v4l2-apps/test/capture_example.c b/v4l2-apps/test/capture_example.c index 7e967e891..d7a223808 100644 --- a/v4l2-apps/test/capture_example.c +++ b/v4l2-apps/test/capture_example.c @@ -46,6 +46,7 @@ static int fd = -1; struct buffer * buffers = NULL; static unsigned int n_buffers = 0; static int out_buf = 0; +static int force_format; static void errno_exit(const char *s) { @@ -500,16 +501,22 @@ static void init_device(void) CLEAR(fmt); - fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - fmt.fmt.pix.width = 640; - fmt.fmt.pix.height = 480; - fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; - fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; + fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (force_format) { + fmt.fmt.pix.width = 640; + fmt.fmt.pix.height = 480; + fmt.fmt.pix.pixelformat = V4L2_PIX_FMT_YUYV; + fmt.fmt.pix.field = V4L2_FIELD_INTERLACED; - if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) - errno_exit("VIDIOC_S_FMT"); + if (-1 == xioctl(fd, VIDIOC_S_FMT, &fmt)) + errno_exit("VIDIOC_S_FMT"); - /* Note VIDIOC_S_FMT may change width and height. */ + /* Note VIDIOC_S_FMT may change width and height. */ + } else { + /* Preserve original settings as set by v4l2-ctl for example */ + if (-1 == xioctl(fd, VIDIOC_G_FMT, &fmt)) + errno_exit("VIDIOC_G_FMT"); + } /* Buggy driver paranoia. */ min = fmt.fmt.pix.width * 2; @@ -577,11 +584,12 @@ static void usage(FILE *fp, int argc, char **argv) "-r | --read Use read() calls\n" "-u | --userp Use application allocated buffers\n" "-o | --output Outputs stream to stdout\n" + "-f | --format Force format to 640x480 YUYV\n" "", argv[0]); } -static const char short_options [] = "d:hmruo"; +static const char short_options[] = "d:hmruof"; static const struct option long_options [] = { @@ -591,6 +599,7 @@ long_options [] = { { "read", no_argument, NULL, 'r' }, { "userp", no_argument, NULL, 'u' }, { "output", no_argument, NULL, 'o' }, + { "format", no_argument, NULL, 'f' }, { 0, 0, 0, 0 } }; @@ -637,6 +646,10 @@ int main(int argc, char **argv) out_buf++; break; + case 'f': + force_format++; + break; + default: usage(stderr, argc, argv); exit(EXIT_FAILURE); -- cgit v1.2.3 From 5e205c91d2868551f704cbcfcaed6a39e3702160 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Wed, 20 Aug 2008 09:08:10 +0200 Subject: capture_example: code cleanups From: Hans Verkuil Just fixed a bunch of checkpatch warnings and tightened up the code. Priority: normal Signed-off-by: Hans Verkuil --- v4l2-apps/test/capture_example.c | 82 +++++++++++++++------------------------- 1 file changed, 31 insertions(+), 51 deletions(-) diff --git a/v4l2-apps/test/capture_example.c b/v4l2-apps/test/capture_example.c index d7a223808..a15ef3c09 100644 --- a/v4l2-apps/test/capture_example.c +++ b/v4l2-apps/test/capture_example.c @@ -36,23 +36,21 @@ typedef enum { } io_method; struct buffer { - void * start; - size_t length; + void *start; + size_t length; }; -static char * dev_name = NULL; -static io_method io = IO_METHOD_MMAP; -static int fd = -1; -struct buffer * buffers = NULL; -static unsigned int n_buffers = 0; -static int out_buf = 0; +static char *dev_name; +static io_method io = IO_METHOD_MMAP; +static int fd = -1; +struct buffer *buffers; +static unsigned int n_buffers; +static int out_buf; static int force_format; static void errno_exit(const char *s) { - fprintf(stderr, "%s error %d, %s\n", - s, errno, strerror(errno)); - + fprintf(stderr, "%s error %d, %s\n", s, errno, strerror(errno)); exit(EXIT_FAILURE); } @@ -100,7 +98,6 @@ static int read_frame(void) } process_image(buffers[0].start, buffers[0].length); - break; case IO_METHOD_MMAP: @@ -130,7 +127,6 @@ static int read_frame(void) if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); - break; case IO_METHOD_USERPTR: @@ -155,17 +151,16 @@ static int read_frame(void) } for (i = 0; i < n_buffers; ++i) - if (buf.m.userptr == (unsigned long) buffers[i].start + if (buf.m.userptr == (unsigned long)buffers[i].start && buf.length == buffers[i].length) break; assert(i < n_buffers); - process_image((void *) buf.m.userptr, buf.bytesused); + process_image((void *)buf.m.userptr, buf.bytesused); if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); - break; } @@ -196,7 +191,6 @@ static void mainloop(void) if (-1 == r) { if (EINTR == errno) continue; - errno_exit("select"); } @@ -207,7 +201,6 @@ static void mainloop(void) if (read_frame()) break; - /* EAGAIN - continue select loop. */ } } @@ -225,10 +218,8 @@ static void stop_capturing(void) case IO_METHOD_MMAP: case IO_METHOD_USERPTR: type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (-1 == xioctl(fd, VIDIOC_STREAMOFF, &type)) errno_exit("VIDIOC_STREAMOFF"); - break; } } @@ -248,20 +239,16 @@ static void start_capturing(void) struct v4l2_buffer buf; CLEAR(buf); - - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_MMAP; - buf.index = i; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_MMAP; + buf.index = i; if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); } - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON"); - break; case IO_METHOD_USERPTR: @@ -269,22 +256,18 @@ static void start_capturing(void) struct v4l2_buffer buf; CLEAR(buf); - - buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - buf.memory = V4L2_MEMORY_USERPTR; - buf.index = i; - buf.m.userptr = (unsigned long) buffers[i].start; - buf.length = buffers[i].length; + buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buf.memory = V4L2_MEMORY_USERPTR; + buf.index = i; + buf.m.userptr = (unsigned long)buffers[i].start; + buf.length = buffers[i].length; if (-1 == xioctl(fd, VIDIOC_QBUF, &buf)) errno_exit("VIDIOC_QBUF"); } - type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - if (-1 == xioctl(fd, VIDIOC_STREAMON, &type)) errno_exit("VIDIOC_STREAMON"); - break; } } @@ -337,9 +320,9 @@ static void init_mmap(void) CLEAR(req); - req.count = 4; - req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - req.memory = V4L2_MEMORY_MMAP; + req.count = 4; + req.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + req.memory = V4L2_MEMORY_MMAP; if (-1 == xioctl(fd, VIDIOC_REQBUFS, &req)) { if (EINVAL == errno) { @@ -458,7 +441,6 @@ static void init_device(void) dev_name); exit(EXIT_FAILURE); } - break; case IO_METHOD_MMAP: @@ -468,7 +450,6 @@ static void init_device(void) dev_name); exit(EXIT_FAILURE); } - break; } @@ -592,14 +573,14 @@ static void usage(FILE *fp, int argc, char **argv) static const char short_options[] = "d:hmruof"; static const struct option -long_options [] = { - { "device", required_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - { "mmap", no_argument, NULL, 'm' }, - { "read", no_argument, NULL, 'r' }, - { "userp", no_argument, NULL, 'u' }, - { "output", no_argument, NULL, 'o' }, - { "format", no_argument, NULL, 'f' }, +long_options[] = { + { "device", required_argument, NULL, 'd' }, + { "help", no_argument, NULL, 'h' }, + { "mmap", no_argument, NULL, 'm' }, + { "read", no_argument, NULL, 'r' }, + { "userp", no_argument, NULL, 'u' }, + { "output", no_argument, NULL, 'o' }, + { "format", no_argument, NULL, 'f' }, { 0, 0, 0, 0 } }; @@ -612,8 +593,7 @@ int main(int argc, char **argv) int c; c = getopt_long(argc, argv, - short_options, long_options, - &idx); + short_options, long_options, &idx); if (-1 == c) break; -- cgit v1.2.3