summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@infradead.org>2008-08-22 10:22:44 -0300
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-08-22 10:22:44 -0300
commitb5ff2cd5cc913156858a0b15a186144f146c89d7 (patch)
treeedd0f29cf926feb480533f9880c60e9a833ac3fb
parent14eb37189ae76c7f329e1eb00c023198f6b3a33d (diff)
parent0fb7c2db703c043604353078f2b9fec995f60eeb (diff)
downloadmediapointer-dvb-s2-b5ff2cd5cc913156858a0b15a186144f146c89d7.tar.gz
mediapointer-dvb-s2-b5ff2cd5cc913156858a0b15a186144f146c89d7.tar.bz2
merge: http://linuxtv.org/hg/~jfrancois/gspca/
From: Mauro Carvalho Chehab <mchehab@infradead.org> Priority: normal Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--linux/drivers/media/radio/Kconfig32
-rw-r--r--linux/drivers/media/video/Kconfig28
-rw-r--r--linux/drivers/media/video/Makefile3
-rw-r--r--linux/drivers/media/video/cx18/cx18-irq.c2
-rw-r--r--linux/drivers/media/video/cx18/cx18-queue.c23
-rw-r--r--linux/drivers/media/video/cx18/cx18-queue.h2
-rw-r--r--linux/drivers/media/video/dpc7146.c409
-rw-r--r--linux/drivers/media/video/mt9m001.c55
-rw-r--r--linux/drivers/media/video/mt9m111.c973
-rw-r--r--linux/drivers/media/video/mt9v022.c52
-rw-r--r--linux/drivers/media/video/pxa_camera.c29
-rw-r--r--linux/drivers/media/video/saa7134/saa7134-core.c52
-rw-r--r--linux/drivers/media/video/sh_mobile_ceu_camera.c5
-rw-r--r--linux/drivers/media/video/tuner-3036.c215
-rw-r--r--linux/drivers/media/video/usbvideo/usbvideo.c7
-rw-r--r--linux/drivers/media/video/v4l2-dev.c2
-rw-r--r--linux/drivers/media/video/v4l2-ioctl.c2
-rw-r--r--linux/include/asm-arm/arch-pxa/camera.h2
-rw-r--r--linux/include/linux/i2c-id.h1
-rw-r--r--linux/include/linux/ivtv.h6
-rw-r--r--linux/include/linux/ivtvfb.h6
-rw-r--r--linux/include/linux/videodev2.h4
-rw-r--r--linux/include/media/sh_mobile_ceu.h2
-rw-r--r--linux/include/media/soc_camera.h3
-rw-r--r--linux/include/media/v4l2-chip-ident.h1
-rw-r--r--linux/sound/oss/aci.c713
-rw-r--r--linux/sound/oss/aci.h57
-rw-r--r--v4l/Kconfig.sound17
-rw-r--r--v4l/Makefile4
-rw-r--r--v4l/Makefile.sound19
-rwxr-xr-xv4l/scripts/make_kconfig.pl3
-rw-r--r--v4l2-apps/test/capture_example.c111
-rw-r--r--v4l2-apps/util/v4l2-ctl.cpp275
33 files changed, 1332 insertions, 1783 deletions
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
- <file:Documentation/video4linux/API.html>.
-
- 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/drivers/media/video/Kconfig b/linux/drivers/media/video/Kconfig
index 4c96b690a..7b2925808 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
@@ -709,21 +702,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
@@ -809,6 +787,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 "mt9m111 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..5656cfecf 100644
--- a/linux/drivers/media/video/Makefile
+++ b/linux/drivers/media/video/Makefile
@@ -83,8 +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
@@ -138,6 +136,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/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);
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 <michael@mihu.de>
-
- 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 <media/saa7146_vv.h>
-#include <linux/video_decoder.h> /* 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 <michael@mihu.de>");
-MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/video/mt9m001.c b/linux/drivers/media/video/mt9m001.c
index f4742936c..228183c54 100644
--- a/linux/drivers/media/video/mt9m001.c
+++ b/linux/drivers/media/video/mt9m001.c
@@ -117,24 +117,51 @@ 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;
- /* Disable chip, synchronous option update */
dev_dbg(icd->vdev->parent, "%s\n", __func__);
- ret = reg_write(icd, MT9M001_RESET, 1);
- if (ret >= 0)
- ret = reg_write(icd, MT9M001_RESET, 0);
- if (ret >= 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);
- return ret >= 0 ? 0 : -EIO;
+ return ret;
}
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;
}
@@ -267,24 +294,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 +322,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/mt9m111.c b/linux/drivers/media/video/mt9m111.c
new file mode 100644
index 000000000..4844486d7
--- /dev/null
+++ b/linux/drivers/media/video/mt9m111.c
@@ -0,0 +1,973 @@
+/*
+ * Driver for MT9M111 CMOS Image Sensor from Micron
+ *
+ * Copyright (C) 2008, Robert Jarzmik <robert.jarzmik@free.fr>
+ *
+ * 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 <linux/videodev2.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/log2.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+
+#include <media/v4l2-common.h>
+#include <media/v4l2-chip-ident.h>
+#include <media/soc_camera.h>
+
+/*
+ * 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)
+ 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)
+ 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, 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;
+
+ ret = reg_write(COLUMN_START, mt9m111->left);
+ if (!ret)
+ ret = reg_write(ROW_START, mt9m111->top);
+
+ if (is_raw_format) {
+ if (!ret)
+ ret = reg_write(WINDOW_WIDTH, width);
+ if (!ret)
+ ret = reg_write(WINDOW_HEIGHT, height);
+ } else {
+ if (!ret)
+ ret = reg_write(REDUCER_XZOOM_B, MT9M111_MAX_WIDTH);
+ if (!ret)
+ ret = reg_write(REDUCER_YZOOM_B, MT9M111_MAX_HEIGHT);
+ if (!ret)
+ ret = reg_write(REDUCER_XSIZE_B, width);
+ if (!ret)
+ ret = reg_write(REDUCER_YSIZE_B, height);
+ if (!ret)
+ ret = reg_write(REDUCER_XZOOM_A, MT9M111_MAX_WIDTH);
+ if (!ret)
+ ret = reg_write(REDUCER_YZOOM_A, MT9M111_MAX_HEIGHT);
+ if (!ret)
+ ret = reg_write(REDUCER_XSIZE_A, width);
+ if (!ret)
+ 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)
+ 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);
+ 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;
+ return ret;
+}
+
+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;
+}
+
+static int mt9m111_reset(struct soc_camera_device *icd)
+{
+ int ret;
+
+ ret = reg_set(RESET, MT9M111_RESET_RESET_MODE);
+ if (!ret)
+ ret = reg_set(RESET, MT9M111_RESET_RESET_SOC);
+ if (!ret)
+ 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;
+
+ 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)
+ 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;
+
+ 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)
+ ret = mt9m111_set_pixfmt(icd, pixfmt);
+ return ret;
+}
+
+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)
+ 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;
+
+ 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;
+}
+
+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)
+ ret = mt9m111_reset(icd);
+ if (!ret)
+ ret = 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)
+ 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;
+}
+
+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;
+}
+
+/*
+ * 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");
diff --git a/linux/drivers/media/video/mt9v022.c b/linux/drivers/media/video/mt9v022.c
index 1ff36edd7..0320d006f 100644
--- a/linux/drivers/media/video/mt9v022.c
+++ b/linux/drivers/media/video/mt9v022.c
@@ -134,34 +134,56 @@ 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 */
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)
{
- /* 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;
}
@@ -352,21 +374,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 +739,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;
diff --git a/linux/drivers/media/video/pxa_camera.c b/linux/drivers/media/video/pxa_camera.c
index ead87ddaf..ee2fb7baa 100644
--- a/linux/drivers/media/video/pxa_camera.c
+++ b/linux/drivers/media/video/pxa_camera.c
@@ -36,8 +36,13 @@
#include <linux/videodev2.h>
#include <asm/dma.h>
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
+#include <mach/pxa-regs.h>
+#include <mach/camera.h>
+#else
#include <asm/arch/pxa-regs.h>
#include <asm/arch/camera.h>
+#endif
#define PXA_CAM_VERSION_CODE KERNEL_VERSION(0, 0, 5)
#define PXA_CAM_DRV_NAME "pxa27x-camera"
@@ -629,17 +634,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 +654,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/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)
{
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/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 <philb@gnu.org>
- *
- * 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 <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/delay.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/init.h>
-
-#include <linux/i2c.h>
-#include "compat.h"
-#include <linux/videodev.h>
-#include <media/v4l2-common.h>
-
-#include <media/tuner.h>
-
-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 <philb@gnu.org>");
-MODULE_LICENSE("GPL");
-
-module_param(debug, int, 0);
-MODULE_PARM_DESC(debug,"Enable debugging output");
-
-module_init(tuner3036_init);
-module_exit(tuner3036_exit);
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;
}
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 */
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,
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/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 */
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 <linux/compiler.h> /* need __user */
-#else
-#define __user
-#endif
+#include <linux/compiler.h>
#include <linux/types.h>
/* 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 <linux/compiler.h> /* need __user */
-#else
-#define __user
-#endif
+#include <linux/compiler.h>
#include <linux/types.h>
/* Framebuffer external API */
diff --git a/linux/include/linux/videodev2.h b/linux/include/linux/videodev2.h
index 8ce0d35f0..4fd194ce3 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 <linux/time.h> /* need struct timeval */
-#include <linux/compiler.h> /* need __user */
#else
-#define __user
#include <sys/time.h>
#endif
+#include <linux/compiler.h>
#include <linux/ioctl.h>
#include <linux/types.h>
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)
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 */
};
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
- * <pellicci@home.com>. 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 <mskuhn@cip.informatik.uni-erlangen.de>
- * 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 <R.A.Reitsma@wbmt.tudelft.nl>
- * Small modification to export ACI functions and
- * complete modularisation.
- * 2000-06-20 Robert Siemer <Robert.Siemer@gmx.de>
- * 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 <acme@conectiva.com.br>
- * Get rid of check_region, .bss optimizations, use set_current_state
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/proc_fs.h>
-#include <linux/slab.h>
-#include <linux/mutex.h>
-
-#include <asm/io.h>
-#include <asm/uaccess.h>
-#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 "<ACI 0x%02x, id %02x/%02x \"%c/%c\", (%s)> 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();
diff --git a/v4l2-apps/test/capture_example.c b/v4l2-apps/test/capture_example.c
index 7e967e891..a15ef3c09 100644
--- a/v4l2-apps/test/capture_example.c
+++ b/v4l2-apps/test/capture_example.c
@@ -36,22 +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);
}
@@ -99,7 +98,6 @@ static int read_frame(void)
}
process_image(buffers[0].start, buffers[0].length);
-
break;
case IO_METHOD_MMAP:
@@ -129,7 +127,6 @@ static int read_frame(void)
if (-1 == xioctl(fd, VIDIOC_QBUF, &buf))
errno_exit("VIDIOC_QBUF");
-
break;
case IO_METHOD_USERPTR:
@@ -154,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;
}
@@ -195,7 +191,6 @@ static void mainloop(void)
if (-1 == r) {
if (EINTR == errno)
continue;
-
errno_exit("select");
}
@@ -206,7 +201,6 @@ static void mainloop(void)
if (read_frame())
break;
-
/* EAGAIN - continue select loop. */
}
}
@@ -224,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;
}
}
@@ -247,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:
@@ -268,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;
}
}
@@ -336,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) {
@@ -457,7 +441,6 @@ static void init_device(void)
dev_name);
exit(EXIT_FAILURE);
}
-
break;
case IO_METHOD_MMAP:
@@ -467,7 +450,6 @@ static void init_device(void)
dev_name);
exit(EXIT_FAILURE);
}
-
break;
}
@@ -500,16 +482,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,20 +565,22 @@ 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 [] = {
- { "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' },
+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 }
};
@@ -603,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;
@@ -637,6 +626,10 @@ int main(int argc, char **argv)
out_buf++;
break;
+ case 'f':
+ force_format++;
+ break;
+
default:
usage(stderr, argc, argv);
exit(EXIT_FAILURE);
diff --git a/v4l2-apps/util/v4l2-ctl.cpp b/v4l2-apps/util/v4l2-ctl.cpp
index 5d70ed9f3..ae9293414 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)
@@ -236,126 +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=<mode>\n");
- printf(" set the sliced VBI capture format to <mode> [VIDIOC_S_FMT]\n");
- printf(" <mode> 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=<ctrl>[,<ctrl>...]\n");
- printf(" get the value of the controls [VIDIOC_G_EXT_CTRLS]\n");
- printf(" -c, --set-ctrl=<ctrl>=<val>[,<ctrl>=<val>...]\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=<dev> use device <dev> instead of /dev/video0\n");
- printf(" if <dev> is a single digit, then /dev/video<dev> is used\n");
- printf(" -F, --get-freq query the frequency [VIDIOC_G_FREQUENCY]\n");
- printf(" -f, --set-freq=<freq>\n");
- printf(" set the frequency to <freq> 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=<num>\n");
- printf(" set the video input to <num> [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=<num>\n");
- printf(" set the video output to <num> [VIDIOC_S_OUTPUT]\n");
- printf(" -S, --get-standard\n");
- printf(" query the video standard [VIDIOC_G_STD]\n");
- printf(" -s, --set-standard=<num>\n");
- printf(" set the video standard to <num> [VIDIOC_S_STD]\n");
- printf(" <num> 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=<mode>\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=<w>,height=<h>\n");
- printf(" set the video capture format [VIDIOC_S_FMT]\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=<w>,height=<h>\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=<key>,global_alpha=<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=<mode>\n");
- printf(" set the sliced VBI output format to <mode> [VIDIOC_S_FMT]\n");
- printf(" <mode> 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=<on> 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=<x>,left=<y>,width=<w>,height=<h>\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=<x>,left=<y>,width=<w>,height=<h>\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=<x>,left=<y>,width=<w>,height=<h>\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=<x>,left=<y>,width=<w>,height=<h>\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=<num>\n");
- printf(" set the audio input to <num> [VIDIOC_S_AUDIO]\n");
- printf(" --get-audio-output query the audio output [VIDIOC_G_AUDOUT]\n");
- printf(" --set-audio-output=<num>\n");
- printf(" set the audio output to <num> [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=<mode>\n"
+ " set the sliced VBI capture format to <mode> [VIDIOC_S_FMT]\n"
+ " <mode> 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=<ctrl>[,<ctrl>...]\n"
+ " get the value of the controls [VIDIOC_G_EXT_CTRLS]\n"
+ " -c, --set-ctrl=<ctrl>=<val>[,<ctrl>=<val>...]\n"
+ " set the controls to the values specified [VIDIOC_S_EXT_CTRLS]\n"
+ " -D, --info show driver info [VIDIOC_QUERYCAP]\n"
+ " -d, --device=<dev> use device <dev> instead of /dev/video0\n"
+ " if <dev> is a single digit, then /dev/video<dev> is used\n"
+ " -F, --get-freq query the frequency [VIDIOC_G_FREQUENCY]\n"
+ " -f, --set-freq=<freq>\n"
+ " set the frequency to <freq> 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=<num>\n"
+ " set the video input to <num> [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=<num>\n"
+ " set the video output to <num> [VIDIOC_S_OUTPUT]\n"
+ " -S, --get-standard\n"
+ " query the video standard [VIDIOC_G_STD]\n"
+ " -s, --set-standard=<num>\n"
+ " set the video standard to <num> [VIDIOC_S_STD]\n"
+ " <num> 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=<mode>\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=<w>,height=<h>,pixelformat=<f>\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=<w>,height=<h>\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=<key>,global_alpha=<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=<mode>\n"
+ " set the sliced VBI output format to <mode> [VIDIOC_S_FMT]\n"
+ " <mode> 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=<on> 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=<x>,left=<y>,width=<w>,height=<h>\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=<x>,left=<y>,width=<w>,height=<h>\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=<x>,left=<y>,width=<w>,height=<h>\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=<x>,left=<y>,width=<w>,height=<h>\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=<num>\n"
+ " set the audio input to <num> [VIDIOC_S_AUDIO]\n"
+ " --get-audio-output query the audio output [VIDIOC_G_AUDOUT]\n"
+ " --set-audio-output=<num>\n"
+ " set the audio output to <num> [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);
}
@@ -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",