Commit 1046a2c4 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media

* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-media: (144 commits)
  [media] saa7134.h: Suppress compiler warnings when CONFIG_VIDEO_SAA7134_RC is not set
  [media] it913x [VER 1.07] Support for single ITE 9135 devices
  [media] Support for Terratec G1
  [media] cx25821: off by one in cx25821_vidioc_s_input()
  [media] media: tea5764: reconcile Kconfig symbol and macro
  [media] omap_vout: Add poll() support
  [media] omap3isp: preview: Add crop support on the sink pad
  [media] omap3isp: preview: Rename min/max input/output sizes defines
  [media] omap3isp: preview: Remove horizontal averager support
  [media] omap3isp: Report the ISP revision through the media controller API
  [media] omap3isp: ccdc: remove redundant operation
  [media] omap3isp: Fix memory leaks in initialization error paths
  [media] omap3isp: Add missing mutex_destroy() calls
  [media] omap3isp: Move *_init_entities() functions to the init/cleanup section
  [media] omap3isp: Move media_entity_cleanup() from unregister() to cleanup()
  [media] MFC: Change MFC firmware binary name
  [media] vb2: add vb2_get_unmapped_area in vb2 core
  [media] v4l: Add v4l2 subdev driver for S5K6AAFX sensor
  [media] v4l: Add AUTO option for the V4L2_CID_POWER_LINE_FREQUENCY control
  [media] media: ov6650: stylistic improvements
  ...
parents 46e85f5f b3f4e1eb
......@@ -2486,6 +2486,9 @@ ioctls.</para>
<listitem>
<para>Flash API. <xref linkend="flash-controls" /></para>
</listitem>
<listitem>
<para>&VIDIOC-CREATE-BUFS; and &VIDIOC-PREPARE-BUF; ioctls.</para>
</listitem>
</itemizedlist>
</section>
......
......@@ -232,8 +232,9 @@ control is deprecated. New drivers and applications should use the
<entry>Enables a power line frequency filter to avoid
flicker. Possible values for <constant>enum v4l2_power_line_frequency</constant> are:
<constant>V4L2_CID_POWER_LINE_FREQUENCY_DISABLED</constant> (0),
<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1) and
<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2).</entry>
<constant>V4L2_CID_POWER_LINE_FREQUENCY_50HZ</constant> (1),
<constant>V4L2_CID_POWER_LINE_FREQUENCY_60HZ</constant> (2) and
<constant>V4L2_CID_POWER_LINE_FREQUENCY_AUTO</constant> (3).</entry>
</row>
<row>
<entry><constant>V4L2_CID_HUE_AUTO</constant></entry>
......
......@@ -927,6 +927,33 @@ ioctl is called.</entry>
Applications set or clear this flag before calling the
<constant>VIDIOC_QBUF</constant> ioctl.</entry>
</row>
<row>
<entry><constant>V4L2_BUF_FLAG_PREPARED</constant></entry>
<entry>0x0400</entry>
<entry>The buffer has been prepared for I/O and can be queued by the
application. Drivers set or clear this flag when the
<link linkend="vidioc-querybuf">VIDIOC_QUERYBUF</link>, <link
linkend="vidioc-qbuf">VIDIOC_PREPARE_BUF</link>, <link
linkend="vidioc-qbuf">VIDIOC_QBUF</link> or <link
linkend="vidioc-qbuf">VIDIOC_DQBUF</link> ioctl is called.</entry>
</row>
<row>
<entry><constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant></entry>
<entry>0x0400</entry>
<entry>Caches do not have to be invalidated for this buffer.
Typically applications shall use this flag if the data captured in the buffer
is not going to be touched by the CPU, instead the buffer will, probably, be
passed on to a DMA-capable hardware unit for further processing or output.
</entry>
</row>
<row>
<entry><constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant></entry>
<entry>0x0800</entry>
<entry>Caches do not have to be cleaned for this buffer.
Typically applications shall use this flag for output buffers if the data
in this buffer has not been created by the CPU but by some DMA-capable unit,
in which case caches have not been used.</entry>
</row>
</tbody>
</tgroup>
</table>
......
......@@ -469,6 +469,7 @@ and discussions on the V4L mailing list.</revremark>
&sub-close;
&sub-ioctl;
<!-- All ioctls go here. -->
&sub-create-bufs;
&sub-cropcap;
&sub-dbg-g-chip-ident;
&sub-dbg-g-register;
......@@ -511,6 +512,7 @@ and discussions on the V4L mailing list.</revremark>
&sub-queryctrl;
&sub-query-dv-preset;
&sub-querystd;
&sub-prepare-buf;
&sub-reqbufs;
&sub-s-hw-freq-seek;
&sub-streamon;
......
<refentry id="vidioc-create-bufs">
<refmeta>
<refentrytitle>ioctl VIDIOC_CREATE_BUFS</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_CREATE_BUFS</refname>
<refpurpose>Create buffers for Memory Mapped or User Pointer I/O</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_create_buffers *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_CREATE_BUFS</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>This ioctl is used to create buffers for <link linkend="mmap">memory
mapped</link> or <link linkend="userp">user pointer</link>
I/O. It can be used as an alternative or in addition to the
<constant>VIDIOC_REQBUFS</constant> ioctl, when a tighter control over buffers
is required. This ioctl can be called multiple times to create buffers of
different sizes.</para>
<para>To allocate device buffers applications initialize relevant fields of
the <structname>v4l2_create_buffers</structname> structure. They set the
<structfield>type</structfield> field in the
<structname>v4l2_format</structname> structure, embedded in this
structure, to the respective stream or buffer type.
<structfield>count</structfield> must be set to the number of required buffers.
<structfield>memory</structfield> specifies the required I/O method. The
<structfield>format</structfield> field shall typically be filled in using
either the <constant>VIDIOC_TRY_FMT</constant> or
<constant>VIDIOC_G_FMT</constant> ioctl(). Additionally, applications can adjust
<structfield>sizeimage</structfield> fields to fit their specific needs. The
<structfield>reserved</structfield> array must be zeroed.</para>
<para>When the ioctl is called with a pointer to this structure the driver
will attempt to allocate up to the requested number of buffers and store the
actual number allocated and the starting index in the
<structfield>count</structfield> and the <structfield>index</structfield> fields
respectively. On return <structfield>count</structfield> can be smaller than
the number requested. The driver may also increase buffer sizes if required,
however, it will not update <structfield>sizeimage</structfield> field values.
The user has to use <constant>VIDIOC_QUERYBUF</constant> to retrieve that
information.</para>
<table pgwide="1" frame="none" id="v4l2-create-buffers">
<title>struct <structname>v4l2_create_buffers</structname></title>
<tgroup cols="3">
&cs-str;
<tbody valign="top">
<row>
<entry>__u32</entry>
<entry><structfield>index</structfield></entry>
<entry>The starting buffer index, returned by the driver.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>count</structfield></entry>
<entry>The number of buffers requested or granted.</entry>
</row>
<row>
<entry>&v4l2-memory;</entry>
<entry><structfield>memory</structfield></entry>
<entry>Applications set this field to
<constant>V4L2_MEMORY_MMAP</constant> or
<constant>V4L2_MEMORY_USERPTR</constant>.</entry>
</row>
<row>
<entry>&v4l2-format;</entry>
<entry><structfield>format</structfield></entry>
<entry>Filled in by the application, preserved by the driver.</entry>
</row>
<row>
<entry>__u32</entry>
<entry><structfield>reserved</structfield>[8]</entry>
<entry>A place holder for future extensions.</entry>
</row>
</tbody>
</tgroup>
</table>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>ENOMEM</errorcode></term>
<listitem>
<para>No memory to allocate buffers for <link linkend="mmap">memory
mapped</link> I/O.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The buffer type (<structfield>type</structfield> field) or the
requested I/O method (<structfield>memory</structfield>) is not
supported.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
<refentry id="vidioc-prepare-buf">
<refmeta>
<refentrytitle>ioctl VIDIOC_PREPARE_BUF</refentrytitle>
&manvol;
</refmeta>
<refnamediv>
<refname>VIDIOC_PREPARE_BUF</refname>
<refpurpose>Prepare a buffer for I/O</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcprototype>
<funcdef>int <function>ioctl</function></funcdef>
<paramdef>int <parameter>fd</parameter></paramdef>
<paramdef>int <parameter>request</parameter></paramdef>
<paramdef>struct v4l2_buffer *<parameter>argp</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Arguments</title>
<variablelist>
<varlistentry>
<term><parameter>fd</parameter></term>
<listitem>
<para>&fd;</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>request</parameter></term>
<listitem>
<para>VIDIOC_PREPARE_BUF</para>
</listitem>
</varlistentry>
<varlistentry>
<term><parameter>argp</parameter></term>
<listitem>
<para></para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
<refsect1>
<title>Description</title>
<para>Applications can optionally call the
<constant>VIDIOC_PREPARE_BUF</constant> ioctl to pass ownership of the buffer
to the driver before actually enqueuing it, using the
<constant>VIDIOC_QBUF</constant> ioctl, and to prepare it for future I/O.
Such preparations may include cache invalidation or cleaning. Performing them
in advance saves time during the actual I/O. In case such cache operations are
not required, the application can use one of
<constant>V4L2_BUF_FLAG_NO_CACHE_INVALIDATE</constant> and
<constant>V4L2_BUF_FLAG_NO_CACHE_CLEAN</constant> flags to skip the respective
step.</para>
<para>The <structname>v4l2_buffer</structname> structure is
specified in <xref linkend="buffer" />.</para>
</refsect1>
<refsect1>
&return-value;
<variablelist>
<varlistentry>
<term><errorcode>EBUSY</errorcode></term>
<listitem>
<para>File I/O is in progress.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><errorcode>EINVAL</errorcode></term>
<listitem>
<para>The buffer <structfield>type</structfield> is not
supported, or the <structfield>index</structfield> is out of bounds,
or no buffers have been allocated yet, or the
<structfield>userptr</structfield> or
<structfield>length</structfield> are invalid.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>
</refentry>
......@@ -394,9 +394,9 @@ static int pcm990_camera_set_bus_param(struct soc_camera_link *link,
}
if (flags & SOCAM_DATAWIDTH_8)
gpio_set_value(gpio_bus_switch, 1);
gpio_set_value_cansleep(gpio_bus_switch, 1);
else
gpio_set_value(gpio_bus_switch, 0);
gpio_set_value_cansleep(gpio_bus_switch, 0);
return 0;
}
......
......@@ -933,7 +933,7 @@ static struct platform_device ap4evb_camera = {
static struct sh_csi2_client_config csi2_clients[] = {
{
.phy = SH_CSI2_PHY_MAIN,
.lanes = 3,
.lanes = 0, /* default: 2 lanes */
.channel = 0,
.pdev = &ap4evb_camera,
},
......
......@@ -1223,9 +1223,10 @@ static struct soc_camera_platform_info camera_info = {
.width = 640,
.height = 480,
},
.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
SOCAM_DATA_ACTIVE_HIGH,
.mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
V4L2_MBUS_DATA_ACTIVE_HIGH,
.mbus_type = V4L2_MBUS_PARALLEL,
.set_capture = camera_set_capture,
};
......
......@@ -345,9 +345,10 @@ static struct soc_camera_platform_info camera_info = {
.width = 640,
.height = 480,
},
.bus_param = SOCAM_PCLK_SAMPLE_RISING | SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_MASTER | SOCAM_DATAWIDTH_8 |
SOCAM_DATA_ACTIVE_HIGH,
.mbus_param = V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_MASTER |
V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_HSYNC_ACTIVE_HIGH |
V4L2_MBUS_DATA_ACTIVE_HIGH,
.mbus_type = V4L2_MBUS_PARALLEL,
.set_capture = camera_set_capture,
};
......@@ -501,8 +502,7 @@ static struct i2c_board_info ap325rxa_i2c_camera[] = {
};
static struct ov772x_camera_info ov7725_info = {
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP | \
OV772X_FLAG_8BIT,
.flags = OV772X_FLAG_VFLIP | OV772X_FLAG_HFLIP,
.edgectrl = OV772X_AUTO_EDGECTRL(0xf, 0),
};
......
......@@ -448,9 +448,7 @@ static struct i2c_board_info migor_i2c_camera[] = {
},
};
static struct ov772x_camera_info ov7725_info = {
.flags = OV772X_FLAG_8BIT,
};
static struct ov772x_camera_info ov7725_info;
static struct soc_camera_link ov7725_link = {
.power = ov7725_power,
......
......@@ -1307,6 +1307,7 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
ipu_submit_buffer(ichan, descnew, sgnew, ichan->active_buffer) < 0) {
callback = descnew->txd.callback;
callback_param = descnew->txd.callback_param;
list_del_init(&descnew->list);
spin_unlock(&ichan->lock);
if (callback)
callback(callback_param);
......@@ -1428,39 +1429,58 @@ static int __idmac_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
{
struct idmac_channel *ichan = to_idmac_chan(chan);
struct idmac *idmac = to_idmac(chan->device);
struct ipu *ipu = to_ipu(idmac);
struct list_head *list, *tmp;
unsigned long flags;
int i;
/* Only supports DMA_TERMINATE_ALL */
if (cmd != DMA_TERMINATE_ALL)
return -ENXIO;
switch (cmd) {
case DMA_PAUSE:
spin_lock_irqsave(&ipu->lock, flags);
ipu_ic_disable_task(ipu, chan->chan_id);
ipu_disable_channel(idmac, ichan,
ichan->status >= IPU_CHANNEL_ENABLED);
/* Return all descriptors into "prepared" state */
list_for_each_safe(list, tmp, &ichan->queue)
list_del_init(list);
tasklet_disable(&to_ipu(idmac)->tasklet);
ichan->sg[0] = NULL;
ichan->sg[1] = NULL;
/* ichan->queue is modified in ISR, have to spinlock */
spin_lock_irqsave(&ichan->lock, flags);
list_splice_init(&ichan->queue, &ichan->free_list);
spin_unlock_irqrestore(&ipu->lock, flags);
if (ichan->desc)
for (i = 0; i < ichan->n_tx_desc; i++) {
struct idmac_tx_desc *desc = ichan->desc + i;
if (list_empty(&desc->list))
/* Descriptor was prepared, but not submitted */
list_add(&desc->list, &ichan->free_list);
ichan->status = IPU_CHANNEL_INITIALIZED;
break;
case DMA_TERMINATE_ALL:
ipu_disable_channel(idmac, ichan,
ichan->status >= IPU_CHANNEL_ENABLED);
async_tx_clear_ack(&desc->txd);
}
tasklet_disable(&ipu->tasklet);
ichan->sg[0] = NULL;
ichan->sg[1] = NULL;
spin_unlock_irqrestore(&ichan->lock, flags);
/* ichan->queue is modified in ISR, have to spinlock */
spin_lock_irqsave(&ichan->lock, flags);
list_splice_init(&ichan->queue, &ichan->free_list);
tasklet_enable(&to_ipu(idmac)->tasklet);
if (ichan->desc)
for (i = 0; i < ichan->n_tx_desc; i++) {
struct idmac_tx_desc *desc = ichan->desc + i;
if (list_empty(&desc->list))
/* Descriptor was prepared, but not submitted */
list_add(&desc->list, &ichan->free_list);
ichan->status = IPU_CHANNEL_INITIALIZED;
async_tx_clear_ack(&desc->txd);
}
ichan->sg[0] = NULL;
ichan->sg[1] = NULL;
spin_unlock_irqrestore(&ichan->lock, flags);
tasklet_enable(&ipu->tasklet);
ichan->status = IPU_CHANNEL_INITIALIZED;
break;
default:
return -ENOSYS;
}
return 0;
}
......@@ -1663,7 +1683,6 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
struct idmac_channel *ichan = ipu->channel + i;
idmac_control(&ichan->dma_chan, DMA_TERMINATE_ALL, 0);
idmac_prep_slave_sg(&ichan->dma_chan, NULL, 0, DMA_NONE, 0);
}
dma_async_device_unregister(&idmac->dma);
......
......@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
ccflags-y += -Idrivers/media/common/tuners/
# For the staging CI driver cxd2099
ccflags-y += -Idrivers/staging/cxd2099/
ccflags-y += -Idrivers/staging/media/cxd2099/
......@@ -102,6 +102,7 @@ obj-$(CONFIG_DVB_USB_IT913X) += dvb-usb-it913x.o
dvb-usb-mxl111sf-objs = mxl111sf.o mxl111sf-phy.o mxl111sf-i2c.o mxl111sf-gpio.o
obj-$(CONFIG_DVB_USB_MXL111SF) += dvb-usb-mxl111sf.o
obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-demod.o
obj-$(CONFIG_DVB_USB_MXL111SF) += mxl111sf-tuner.o
ccflags-y += -Idrivers/media/dvb/dvb-core/ -Idrivers/media/dvb/frontends/
......
......@@ -37,6 +37,7 @@
#define USB_VID_HAUPPAUGE 0x2040
#define USB_VID_HYPER_PALTEK 0x1025
#define USB_VID_INTEL 0x8086
#define USB_VID_ITETECH 0x048d
#define USB_VID_KWORLD 0xeb2a
#define USB_VID_KWORLD_2 0x1b80
#define USB_VID_KYE 0x0458
......@@ -126,6 +127,7 @@
#define USB_PID_GRANDTEC_DVBT_USB_COLD 0x0fa0
#define USB_PID_GRANDTEC_DVBT_USB_WARM 0x0fa1
#define USB_PID_INTEL_CE9500 0x9500
#define USB_PID_ITETECH_IT9135 0x9135
#define USB_PID_KWORLD_399U 0xe399
#define USB_PID_KWORLD_399U_2 0xe400
#define USB_PID_KWORLD_395U 0xe396
......
......@@ -60,6 +60,17 @@ struct it913x_state {
u8 id;
};
struct ite_config {
u8 chip_ver;
u16 chip_type;
u32 firmware;
u8 tuner_id_0;
u8 tuner_id_1;
u8 dual_mode;
};
struct ite_config it913x_config;
static int it913x_bulk_write(struct usb_device *dev,
u8 *snd, int len, u8 pipe)
{
......@@ -191,18 +202,23 @@ static int it913x_read_reg(struct usb_device *udev, u32 reg)
static u32 it913x_query(struct usb_device *udev, u8 pro)
{
int ret;
u32 res = 0;
u8 data[4];
ret = it913x_io(udev, READ_LONG, pro, CMD_DEMOD_READ,
0x1222, 0, &data[0], 1);
if (data[0] == 0x1) {
ret = it913x_io(udev, READ_SHORT, pro,
0x1222, 0, &data[0], 3);
it913x_config.chip_ver = data[0];
it913x_config.chip_type = (u16)(data[2] << 8) + data[1];
info("Chip Version=%02x Chip Type=%04x", it913x_config.chip_ver,
it913x_config.chip_type);
ret |= it913x_io(udev, READ_SHORT, pro,
CMD_QUERYINFO, 0, 0x1, &data[0], 4);
res = (data[0] << 24) + (data[1] << 16) +
it913x_config.firmware = (data[0] << 24) + (data[1] << 16) +
(data[2] << 8) + data[3];
}
return (ret < 0) ? 0 : res;
return (ret < 0) ? 0 : it913x_config.firmware;
}
static int it913x_pid_filter_ctrl(struct dvb_usb_adapter *adap, int onoff)
......@@ -336,26 +352,35 @@ static int it913x_identify_state(struct usb_device *udev,
int *cold)
{
int ret = 0, firm_no;
u8 reg, adap, ep, tun0, tun1;
u8 reg, remote;
firm_no = it913x_return_status(udev);
ep = it913x_read_reg(udev, 0x49ac);
adap = it913x_read_reg(udev, 0x49c5);
tun0 = it913x_read_reg(udev, 0x49d0);
info("No. Adapters=%x Endpoints=%x Tuner Type=%x", adap, ep, tun0);
/* checnk for dual mode */
it913x_config.dual_mode = it913x_read_reg(udev, 0x49c5);
/* TODO different remotes */
remote = it913x_read_reg(udev, 0x49ac); /* Remote */
if (remote == 0)
props->rc.core.rc_codes = NULL;
/* TODO at the moment tuner_id is always assigned to 0x38 */
it913x_config.tuner_id_0 = it913x_read_reg(udev, 0x49d0);
info("Dual mode=%x Remote=%x Tuner Type=%x", it913x_config.dual_mode
, remote, it913x_config.tuner_id_0);
if (firm_no > 0) {
*cold = 0;
return 0;
}
if (adap > 2) {
tun1 = it913x_read_reg(udev, 0x49e0);
if (it913x_config.dual_mode) {
it913x_config.tuner_id_1 = it913x_read_reg(udev, 0x49e0);
ret = it913x_wr_reg(udev, DEV_0, GPIOH1_EN, 0x1);
ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_ON, 0x1);
ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x1);
msleep(50); /* Delay noticed reset cycle ? */
msleep(50);
ret |= it913x_wr_reg(udev, DEV_0, GPIOH1_O, 0x0);
msleep(50);
reg = it913x_read_reg(udev, GPIOH1_O);
......@@ -366,14 +391,19 @@ static int it913x_identify_state(struct usb_device *udev,
ret = it913x_wr_reg(udev, DEV_0,
GPIOH1_O, 0x0);
}
props->num_adapters = 2;
} else
props->num_adapters = 1;
reg = it913x_read_reg(udev, IO_MUX_POWER_CLK);
ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1);
if (it913x_config.dual_mode) {
ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, CHIP2_I2C_ADDR);
ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x1);
} else {
ret |= it913x_wr_reg(udev, DEV_0, 0x4bfb, 0x0);
ret |= it913x_wr_reg(udev, DEV_0, CLK_O_EN, 0x0);
}
*cold = 1;
......@@ -403,13 +433,11 @@ static int it913x_download_firmware(struct usb_device *udev,
const struct firmware *fw)
{
int ret = 0, i;
u8 packet_size, dlen, tun1;
u8 packet_size, dlen;
u8 *fw_data;
packet_size = 0x29;
tun1 = it913x_read_reg(udev, 0x49e0);
ret = it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_100);
info("FRM Starting Firmware Download");
......@@ -444,11 +472,12 @@ static int it913x_download_firmware(struct usb_device *udev,
ret |= it913x_wr_reg(udev, DEV_0, I2C_CLK, I2C_CLK_400);
/* Tuner function */
ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
if (it913x_config.dual_mode)
ret |= it913x_wr_reg(udev, DEV_0_DMOD , 0xec4c, 0xa0);
ret |= it913x_wr_reg(udev, DEV_0, PADODPU, 0x0);
ret |= it913x_wr_reg(udev, DEV_0, AGC_O_D, 0x0);
if (tun1 > 0) {
if (it913x_config.dual_mode) {
ret |= it913x_wr_reg(udev, DEV_1, PADODPU, 0x0);
ret |= it913x_wr_reg(udev, DEV_1, AGC_O_D, 0x0);
}
......@@ -475,9 +504,28 @@ static int it913x_frontend_attach(struct dvb_usb_adapter *adap)
u8 adf = it913x_read_reg(udev, IO_MUX_POWER_CLK);
u8 adap_addr = I2C_BASE_ADDR + (adap->id << 5);
u16 ep_size = adap->props.fe[0].stream.u.bulk.buffersize;
u8 tuner_id, tuner_type;
if (adap->id == 0)
tuner_id = it913x_config.tuner_id_0;
else
tuner_id = it913x_config.tuner_id_1;
/* TODO we always use IT9137 possible references here*/
/* Documentation suggests don't care */
switch (tuner_id) {
case 0x51:
case 0x52:
case 0x60:
case 0x61:
case 0x62:
default:
case 0x38:
tuner_type = IT9137;
}
adap->fe_adap[0].fe = dvb_attach(it913x_fe_attach,
&adap->dev->i2c_adap, adap_addr, adf, IT9137);
&adap->dev->i2c_adap, adap_addr, adf, tuner_type);
if (adap->id == 0 && adap->fe_adap[0].fe) {
ret = it913x_wr_reg(udev, DEV_0_DMOD, MP2_SW_RST, 0x1);
......@@ -533,6 +581,7 @@ static int it913x_probe(struct usb_interface *intf,
static struct usb_device_id it913x_table[] = {
{ USB_DEVICE(USB_VID_KWORLD_2, USB_PID_KWORLD_UB499_2T_T09) },
{ USB_DEVICE(USB_VID_ITETECH, USB_PID_ITETECH_IT9135) },
{} /* Terminating entry */
};
......@@ -608,12 +657,14 @@ static struct dvb_usb_device_properties it913x_properties = {
.rc_codes = RC_MAP_KWORLD_315U,
},
.i2c_algo = &it913x_i2c_algo,
.num_device_descs = 1,
.num_device_descs = 2,
.devices = {
{ "Kworld UB499-2T T09(IT9137)",
{ &it913x_table[0], NULL },
},
{ "ITE 9135 Generic",
{ &it913x_table[1], NULL },
},
}
};
......@@ -647,5 +698,5 @@ module_exit(it913x_module_exit);
MODULE_AUTHOR("Malcolm Priestley <tvboxspy@gmail.com>");
MODULE_DESCRIPTION("it913x USB 2 Driver");
MODULE_VERSION("1.06");
MODULE_VERSION("1.07");
MODULE_LICENSE("GPL");
This diff is collapsed.
/*
* mxl111sf-demod.h - driver for the MaxLinear MXL111SF DVB-T demodulator
*
* Copyright (C) 2010 Michael Krufky <mkrufky@kernellabs.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; 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.
*/
#ifndef __MXL111SF_DEMOD_H__
#define __MXL111SF_DEMOD_H__
#include "dvb_frontend.h"
#include "mxl111sf.h"
struct mxl111sf_demod_config {
int (*read_reg)(struct mxl111sf_state *state, u8 addr, u8 *data);
int (*write_reg)(struct mxl111sf_state *state, u8 addr, u8 data);
int (*program_regs)(struct mxl111sf_state *state,
struct mxl111sf_reg_ctrl_info *ctrl_reg_info);
};
#if defined(CONFIG_DVB_USB_MXL111SF) || \
(defined(CONFIG_DVB_USB_MXL111SF_MODULE) && defined(MODULE))
extern
struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
struct mxl111sf_demod_config *cfg);
#else
static inline
struct dvb_frontend *mxl111sf_demod_attach(struct mxl111sf_state *mxl_state,
struct mxl111sf_demod_config *cfg)
{
printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_USB_MXL111SF */
#endif /* __MXL111SF_DEMOD_H__ */
/*
* Local variables:
* c-basic-offset: 8
* End:
*/
......@@ -17,6 +17,7 @@
#include "mxl111sf-i2c.h"
#include "mxl111sf-gpio.h"
#include "mxl111sf-demod.h"
#include "mxl111sf-tuner.h"
#include "lgdt3305.h"
......@@ -362,6 +363,22 @@ static int mxl111sf_ep6_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
return ret;
}
static int mxl111sf_ep4_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff)
{
struct dvb_usb_device *d = adap->dev;
struct mxl111sf_state *state = d->priv;
int ret = 0;
deb_info("%s(%d)\n", __func__, onoff);
if (onoff) {
ret = mxl111sf_enable_usb_output(state);
mxl_fail(ret);
}
return ret;
}
/* ------------------------------------------------------------------------ */
static struct lgdt3305_config hauppauge_lgdt3305_config = {
......@@ -438,6 +455,70 @@ static int mxl111sf_lgdt3305_frontend_attach(struct dvb_usb_adapter *adap)
return ret;
}
static struct mxl111sf_demod_config mxl_demod_config = {
.read_reg = mxl111sf_read_reg,
.write_reg = mxl111sf_write_reg,
.program_regs = mxl111sf_ctrl_program_regs,
};
static int mxl111sf_attach_demod(struct dvb_usb_adapter *adap)
{
struct dvb_usb_device *d = adap->dev;
struct mxl111sf_state *state = d->priv;
int fe_id = adap->num_frontends_initialized;
struct mxl111sf_adap_state *adap_state = adap->fe_adap[fe_id].priv;
int ret;
deb_adv("%s()\n", __func__);
/* save a pointer to the dvb_usb_device in device state */
state->d = d;
adap_state->alt_mode = (dvb_usb_mxl111sf_isoc) ? 1 : 2;
state->alt_mode = adap_state->alt_mode;
if (usb_set_interface(adap->dev->udev, 0, state->alt_mode) < 0)
err("set interface failed");
state->gpio_mode = MXL111SF_GPIO_MOD_DVBT;
adap_state->gpio_mode = state->gpio_mode;
adap_state->device_mode = MXL_SOC_MODE;
adap_state->ep6_clockphase = 1;
ret = mxl1x1sf_soft_reset(state);
if (mxl_fail(ret))
goto fail;
ret = mxl111sf_init_tuner_demod(state);
if (mxl_fail(ret))
goto fail;
ret = mxl1x1sf_set_device_mode(state, adap_state->device_mode);
if (mxl_fail(ret))
goto fail;
ret = mxl111sf_enable_usb_output(state);
if (mxl_fail(ret))
goto fail;
ret = mxl1x1sf_top_master_ctrl(state, 1);
if (mxl_fail(ret))
goto fail;
/* dont care if this fails */
mxl111sf_init_port_expander(state);
adap->fe_adap[fe_id].fe = dvb_attach(mxl111sf_demod_attach, state,
&mxl_demod_config);
if (adap->fe_adap[fe_id].fe) {
adap_state->fe_init = adap->fe_adap[fe_id].fe->ops.init;
adap->fe_adap[fe_id].fe->ops.init = mxl111sf_adap_fe_init;
adap_state->fe_sleep = adap->fe_adap[fe_id].fe->ops.sleep;
adap->fe_adap[fe_id].fe->ops.sleep = mxl111sf_adap_fe_sleep;
return 0;
}
ret = -EIO;
fail:
return ret;
}
static inline int mxl111sf_set_ant_path(struct mxl111sf_state *state,
int antpath)
{
......@@ -567,7 +648,8 @@ struct i2c_algorithm mxl111sf_i2c_algo = {
#endif
};
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties;
static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties;
static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties;
static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties;
......@@ -580,8 +662,14 @@ static int mxl111sf_probe(struct usb_interface *intf,
if (((dvb_usb_mxl111sf_isoc) &&
(0 == dvb_usb_device_init(intf,
&mxl111sf_dvbt_isoc_properties,
THIS_MODULE, &d, adapter_nr) ||
0 == dvb_usb_device_init(intf,
&mxl111sf_atsc_isoc_properties,
THIS_MODULE, &d, adapter_nr))) ||
0 == dvb_usb_device_init(intf,
&mxl111sf_dvbt_bulk_properties,
THIS_MODULE, &d, adapter_nr) ||
0 == dvb_usb_device_init(intf,
&mxl111sf_atsc_bulk_properties,
THIS_MODULE, &d, adapter_nr) || 0) {
......@@ -669,6 +757,36 @@ static struct usb_device_id mxl111sf_table[] = {
MODULE_DEVICE_TABLE(usb, mxl111sf_table);
#define MXL111SF_EP4_BULK_STREAMING_CONFIG \
.streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
.stream = { \
.type = USB_BULK, \
.count = 5, \
.endpoint = 0x04, \
.u = { \
.bulk = { \
.buffersize = 8192, \
} \
} \
}
/* FIXME: works for v6 but not v8 silicon */
#define MXL111SF_EP4_ISOC_STREAMING_CONFIG \
.streaming_ctrl = mxl111sf_ep4_streaming_ctrl, \
.stream = { \
.type = USB_ISOC, \
.count = 5, \
.endpoint = 0x04, \
.u = { \
.isoc = { \
.framesperurb = 96, \
/* FIXME: v6 SILICON: */ \
.framesize = 564, \
.interval = 1, \
} \
} \
}
#define MXL111SF_EP6_BULK_STREAMING_CONFIG \
.streaming_ctrl = mxl111sf_ep6_streaming_ctrl, \
.stream = { \
......@@ -712,7 +830,7 @@ MODULE_DEVICE_TABLE(usb, mxl111sf_table);
.generic_bulk_ctrl_endpoint_response = MXL_EP1_REG_READ, \
.size_of_priv = sizeof(struct mxl111sf_state)
static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
static struct dvb_usb_device_properties mxl111sf_dvbt_bulk_properties = {
MXL111SF_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
......@@ -723,10 +841,106 @@ static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
.fe = {{
.size_of_priv = sizeof(struct mxl111sf_adap_state),
.frontend_attach = mxl111sf_attach_demod,
.tuner_attach = mxl111sf_attach_tuner,
MXL111SF_EP4_BULK_STREAMING_CONFIG,
} },
},
},
.num_device_descs = 4,
.devices = {
{ "Hauppauge 126xxx DVBT (bulk)",
{ NULL },
{ &mxl111sf_table[4], &mxl111sf_table[8],
NULL },
},
{ "Hauppauge 117xxx DVBT (bulk)",
{ NULL },
{ &mxl111sf_table[15], &mxl111sf_table[18],
NULL },
},
{ "Hauppauge 138xxx DVBT (bulk)",
{ NULL },
{ &mxl111sf_table[20], &mxl111sf_table[22],
&mxl111sf_table[24], &mxl111sf_table[26],
NULL },
},
{ "Hauppauge 126xxx (tp-bulk)",
{ NULL },
{ &mxl111sf_table[28], &mxl111sf_table[30],
NULL },
},
}
};
static struct dvb_usb_device_properties mxl111sf_dvbt_isoc_properties = {
MXL111SF_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.adapter = {
{
.fe_ioctl_override = mxl111sf_fe_ioctl_override,
.num_frontends = 1,
.fe = {{
.size_of_priv = sizeof(struct mxl111sf_adap_state),
.frontend_attach = mxl111sf_attach_demod,
.tuner_attach = mxl111sf_attach_tuner,
MXL111SF_EP4_ISOC_STREAMING_CONFIG,
} },
},
},
.num_device_descs = 4,
.devices = {
{ "Hauppauge 126xxx DVBT (isoc)",
{ NULL },
{ &mxl111sf_table[4], &mxl111sf_table[8],
NULL },
},
{ "Hauppauge 117xxx DVBT (isoc)",
{ NULL },
{ &mxl111sf_table[15], &mxl111sf_table[18],
NULL },
},
{ "Hauppauge 138xxx DVBT (isoc)",
{ NULL },
{ &mxl111sf_table[20], &mxl111sf_table[22],
&mxl111sf_table[24], &mxl111sf_table[26],
NULL },
},
{ "Hauppauge 126xxx (tp-isoc)",
{ NULL },
{ &mxl111sf_table[28], &mxl111sf_table[30],
NULL },
},
}
};
static struct dvb_usb_device_properties mxl111sf_atsc_bulk_properties = {
MXL111SF_DEFAULT_DEVICE_PROPERTIES,
.num_adapters = 1,
.adapter = {
{
.fe_ioctl_override = mxl111sf_fe_ioctl_override,
.num_frontends = 2,
.fe = {{
.size_of_priv = sizeof(struct mxl111sf_adap_state),
.frontend_attach = mxl111sf_lgdt3305_frontend_attach,
.tuner_attach = mxl111sf_attach_tuner,
MXL111SF_EP6_BULK_STREAMING_CONFIG,
},
{
.size_of_priv = sizeof(struct mxl111sf_adap_state),
.frontend_attach = mxl111sf_attach_demod,
.tuner_attach = mxl111sf_attach_tuner,
MXL111SF_EP4_BULK_STREAMING_CONFIG,
}},
},
},
......@@ -776,7 +990,7 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
.adapter = {
{
.fe_ioctl_override = mxl111sf_fe_ioctl_override,
.num_frontends = 1,
.num_frontends = 2,
.fe = {{
.size_of_priv = sizeof(struct mxl111sf_adap_state),
......@@ -784,6 +998,14 @@ static struct dvb_usb_device_properties mxl111sf_atsc_isoc_properties = {
.tuner_attach = mxl111sf_attach_tuner,
MXL111SF_EP6_ISOC_STREAMING_CONFIG,
},
{
.size_of_priv = sizeof(struct mxl111sf_adap_state),
.frontend_attach = mxl111sf_attach_demod,
.tuner_attach = mxl111sf_attach_tuner,
MXL111SF_EP4_ISOC_STREAMING_CONFIG,
}},
},
},
......
......@@ -133,7 +133,7 @@ extern int dvb_usb_mxl111sf_debug;
/* The following allows the mxl_fail() macro defined below to work
* in externel modules, such as mxl111sf-tuner.ko, even though
* dvb_usb_mxl111sf_debug is not defined within those modules */
#ifdef __MXL111SF_TUNER_H__
#if (defined(__MXL111SF_TUNER_H__)) || (defined(__MXL111SF_DEMOD_H__))
#define MXL_ADV_DEBUG_ENABLED MXL_ADV_DBG
#else
#define MXL_ADV_DEBUG_ENABLED dvb_usb_mxl111sf_debug
......
......@@ -11,4 +11,4 @@ ccflags-y += -Idrivers/media/dvb/frontends/
ccflags-y += -Idrivers/media/common/tuners/
# For the staging CI driver cxd2099
ccflags-y += -Idrivers/staging/cxd2099/
ccflags-y += -Idrivers/staging/media/cxd2099/
......@@ -128,8 +128,10 @@ struct tea5764_write_regs {
u16 rdsbbl; /* PAUSEDET & RDSBBL */
} __attribute__ ((packed));
#ifndef RADIO_TEA5764_XTAL
#ifdef CONFIG_RADIO_TEA5764_XTAL
#define RADIO_TEA5764_XTAL 1
#else
#define RADIO_TEA5764_XTAL 0
#endif
static int radio_nr = -1;
......
......@@ -517,6 +517,13 @@ config VIDEO_NOON010PC30
source "drivers/media/video/m5mols/Kconfig"
config VIDEO_S5K6AA
tristate "Samsung S5K6AAFX sensor support"
depends on I2C && VIDEO_V4L2 && VIDEO_V4L2_SUBDEV_API
---help---
This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M
camera sensor with an embedded SoC image signal processor.
comment "Flash devices"
config VIDEO_ADP1653
......@@ -736,6 +743,8 @@ source "drivers/media/video/cx88/Kconfig"
source "drivers/media/video/cx23885/Kconfig"
source "drivers/media/video/cx25821/Kconfig"
source "drivers/media/video/au0828/Kconfig"
source "drivers/media/video/ivtv/Kconfig"
......
......@@ -72,6 +72,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o
obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o
obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o
obj-$(CONFIG_VIDEO_M5MOLS) += m5mols/
obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o
obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o
obj-$(CONFIG_SOC_CAMERA_IMX074) += imx074.o
......@@ -104,6 +105,7 @@ obj-$(CONFIG_VIDEO_CX88) += cx88/
obj-$(CONFIG_VIDEO_EM28XX) += em28xx/
obj-$(CONFIG_VIDEO_TLG2300) += tlg2300/
obj-$(CONFIG_VIDEO_CX231XX) += cx231xx/
obj-$(CONFIG_VIDEO_CX25821) += cx25821/
obj-$(CONFIG_VIDEO_USBVISION) += usbvision/
obj-$(CONFIG_VIDEO_PVRUSB2) += pvrusb2/
obj-$(CONFIG_VIDEO_CPIA2) += cpia2/
......
......@@ -94,6 +94,7 @@ struct atmel_isi {
unsigned int irq;
struct isi_platform_data *pdata;
u16 width_flags; /* max 12 bits */
struct list_head video_buffer_list;
struct frame_buffer *active;
......@@ -248,9 +249,9 @@ static int atmel_isi_wait_status(struct atmel_isi *isi, int wait_reset)
/* ------------------------------------------------------------------
Videobuf operations
------------------------------------------------------------------*/
static int queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[],
void *alloc_ctxs[])
static int queue_setup(struct vb2_queue *vq, const struct v4l2_format *fmt,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
struct soc_camera_device *icd = soc_camera_from_vb2q(vq);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
......@@ -647,50 +648,42 @@ static bool isi_camera_packing_supported(const struct soc_mbus_pixelfmt *fmt)
fmt->packing == SOC_MBUS_PACKING_EXTEND16);
}
static unsigned long make_bus_param(struct atmel_isi *isi)
{
unsigned long flags;
/*
* Platform specified synchronization and pixel clock polarities are
* only a recommendation and are only used during probing. Atmel ISI
* camera interface only works in master mode, i.e., uses HSYNC and
* VSYNC signals from the sensor
*/
flags = SOCAM_MASTER |
SOCAM_HSYNC_ACTIVE_HIGH |
SOCAM_HSYNC_ACTIVE_LOW |
SOCAM_VSYNC_ACTIVE_HIGH |
SOCAM_VSYNC_ACTIVE_LOW |
SOCAM_PCLK_SAMPLE_RISING |
SOCAM_PCLK_SAMPLE_FALLING |
SOCAM_DATA_ACTIVE_HIGH;
if (isi->pdata->data_width_flags & ISI_DATAWIDTH_10)
flags |= SOCAM_DATAWIDTH_10;
if (isi->pdata->data_width_flags & ISI_DATAWIDTH_8)
flags |= SOCAM_DATAWIDTH_8;
if (flags & SOCAM_DATAWIDTH_MASK)
return flags;
return 0;
}
#define ISI_BUS_PARAM (V4L2_MBUS_MASTER | \
V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
V4L2_MBUS_HSYNC_ACTIVE_LOW | \
V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
V4L2_MBUS_VSYNC_ACTIVE_LOW | \
V4L2_MBUS_PCLK_SAMPLE_RISING | \
V4L2_MBUS_PCLK_SAMPLE_FALLING | \
V4L2_MBUS_DATA_ACTIVE_HIGH)
static int isi_camera_try_bus_param(struct soc_camera_device *icd,
unsigned char buswidth)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct atmel_isi *isi = ici->priv;
unsigned long camera_flags;
struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
unsigned long common_flags;
int ret;
camera_flags = icd->ops->query_bus_param(icd);
ret = soc_camera_bus_param_compatible(camera_flags,
make_bus_param(isi));
if (!ret)
return -EINVAL;
return 0;
ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
if (!ret) {
common_flags = soc_mbus_config_compatible(&cfg,
ISI_BUS_PARAM);
if (!common_flags) {
dev_warn(icd->parent,
"Flags incompatible: camera 0x%x, host 0x%x\n",
cfg.flags, ISI_BUS_PARAM);
return -EINVAL;
}
} else if (ret != -ENOIOCTLCMD) {
return ret;
}
if ((1 << (buswidth - 1)) & isi->width_flags)
return 0;
return -EINVAL;
}
......@@ -812,59 +805,71 @@ static int isi_camera_querycap(struct soc_camera_host *ici,
static int isi_camera_set_bus_param(struct soc_camera_device *icd, u32 pixfmt)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct atmel_isi *isi = ici->priv;
unsigned long bus_flags, camera_flags, common_flags;
struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
unsigned long common_flags;
int ret;
u32 cfg1 = 0;
camera_flags = icd->ops->query_bus_param(icd);
bus_flags = make_bus_param(isi);
common_flags = soc_camera_bus_param_compatible(camera_flags, bus_flags);
dev_dbg(icd->parent, "Flags cam: 0x%lx host: 0x%lx common: 0x%lx\n",
camera_flags, bus_flags, common_flags);
if (!common_flags)
return -EINVAL;
ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
if (!ret) {
common_flags = soc_mbus_config_compatible(&cfg,
ISI_BUS_PARAM);
if (!common_flags) {
dev_warn(icd->parent,
"Flags incompatible: camera 0x%x, host 0x%x\n",
cfg.flags, ISI_BUS_PARAM);
return -EINVAL;
}
} else if (ret != -ENOIOCTLCMD) {
return ret;
} else {
common_flags = ISI_BUS_PARAM;
}
dev_dbg(icd->parent, "Flags cam: 0x%x host: 0x%x common: 0x%lx\n",
cfg.flags, ISI_BUS_PARAM, common_flags);
/* Make choises, based on platform preferences */
if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
(common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
if (isi->pdata->hsync_act_low)
common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
else
common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
}
if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
(common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
if (isi->pdata->vsync_act_low)
common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
else
common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
}
if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
(common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
(common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
if (isi->pdata->pclk_act_falling)
common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
else
common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
}
ret = icd->ops->set_bus_param(icd, common_flags);
if (ret < 0) {
dev_dbg(icd->parent, "Camera set_bus_param(%lx) returned %d\n",
cfg.flags = common_flags;
ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
if (ret < 0 && ret != -ENOIOCTLCMD) {
dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
common_flags, ret);
return ret;
}
/* set bus param for ISI */
if (common_flags & SOCAM_HSYNC_ACTIVE_LOW)
if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)
cfg1 |= ISI_CFG1_HSYNC_POL_ACTIVE_LOW;
if (common_flags & SOCAM_VSYNC_ACTIVE_LOW)
if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)
cfg1 |= ISI_CFG1_VSYNC_POL_ACTIVE_LOW;
if (common_flags & SOCAM_PCLK_SAMPLE_FALLING)
if (common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)
cfg1 |= ISI_CFG1_PIXCLK_POL_ACTIVE_FALLING;
if (isi->pdata->has_emb_sync)
......@@ -983,6 +988,11 @@ static int __devinit atmel_isi_probe(struct platform_device *pdev)
goto err_ioremap;
}
if (pdata->data_width_flags & ISI_DATAWIDTH_8)
isi->width_flags = 1 << 7;
if (pdata->data_width_flags & ISI_DATAWIDTH_10)
isi->width_flags |= 1 << 9;
isi_writel(isi, ISI_CTRL, ISI_CTRL_DIS);
irq = platform_get_irq(pdev, 0);
......
......@@ -1085,6 +1085,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
setup.addr = ADDR_UNSET;
setup.type = cx->options.tuner;
setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
if (cx->options.radio > 0)
setup.mode_mask |= T_RADIO;
setup.tuner_callback = (setup.type == TUNER_XC2028) ?
cx18_reset_tuner_gpio : NULL;
cx18_call_all(cx, tuner, s_type_addr, &setup);
......
......@@ -1312,7 +1312,7 @@ int cx25821_vidioc_s_input(struct file *file, void *priv, unsigned int i)
return err;
}
if (i > 2) {
if (i >= CX25821_NR_INPUT) {
dprintk(1, "%s(): -EINVAL\n", __func__);
return -EINVAL;
}
......
......@@ -98,6 +98,7 @@
#define CX25821_BOARD_CONEXANT_ATHENA10 1
#define MAX_VID_CHANNEL_NUM 12
#define VID_CHANNEL_NUM 8
#define CX25821_NR_INPUT 2
struct cx25821_fmt {
char *name;
......@@ -196,7 +197,7 @@ struct cx25821_board {
unsigned char radio_addr;
u32 clk_freq;
struct cx25821_input input[2];
struct cx25821_input input[CX25821_NR_INPUT];
};
struct cx25821_subid {
......
......@@ -1923,6 +1923,8 @@ struct usb_device_id em28xx_id_table[] = {
.driver_info = EM2860_BOARD_TERRATEC_AV350 },
{ USB_DEVICE(0x0ccd, 0x0096),
.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
{ USB_DEVICE(0x0ccd, 0x10AF),
.driver_info = EM2860_BOARD_TERRATEC_GRABBY },
{ USB_DEVICE(0x0fd9, 0x0033),
.driver_info = EM2860_BOARD_ELGATO_VIDEO_CAPTURE},
{ USB_DEVICE(0x185b, 0x2870),
......
......@@ -12,11 +12,11 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/v4l2-mediabus.h>
#include <linux/slab.h>
#include <linux/videodev2.h>
#include <media/soc_camera.h>
#include <media/soc_mediabus.h>
#include <media/v4l2-subdev.h>
#include <media/v4l2-chip-ident.h>
......@@ -267,6 +267,17 @@ static int imx074_g_chip_ident(struct v4l2_subdev *sd,
return 0;
}
static int imx074_g_mbus_config(struct v4l2_subdev *sd,
struct v4l2_mbus_config *cfg)
{
cfg->type = V4L2_MBUS_CSI2;
cfg->flags = V4L2_MBUS_CSI2_2_LANE |
V4L2_MBUS_CSI2_CHANNEL_0 |
V4L2_MBUS_CSI2_CONTINUOUS_CLOCK;
return 0;
}
static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
.s_stream = imx074_s_stream,
.s_mbus_fmt = imx074_s_fmt,
......@@ -275,6 +286,7 @@ static struct v4l2_subdev_video_ops imx074_subdev_video_ops = {
.enum_mbus_fmt = imx074_enum_fmt,
.g_crop = imx074_g_crop,
.cropcap = imx074_cropcap,
.g_mbus_config = imx074_g_mbus_config,
};
static struct v4l2_subdev_core_ops imx074_subdev_core_ops = {
......@@ -286,28 +298,7 @@ static struct v4l2_subdev_ops imx074_subdev_ops = {
.video = &imx074_subdev_video_ops,
};
/*
* We have to provide soc-camera operations, but we don't have anything to say
* there. The MIPI CSI2 driver will provide .query_bus_param and .set_bus_param
*/
static unsigned long imx074_query_bus_param(struct soc_camera_device *icd)
{
return 0;
}
static int imx074_set_bus_param(struct soc_camera_device *icd,
unsigned long flags)
{
return -EINVAL;
}
static struct soc_camera_ops imx074_ops = {
.query_bus_param = imx074_query_bus_param,
.set_bus_param = imx074_set_bus_param,
};
static int imx074_video_probe(struct soc_camera_device *icd,
struct i2c_client *client)
static int imx074_video_probe(struct i2c_client *client)
{
int ret;
u16 id;
......@@ -417,17 +408,10 @@ static int imx074_probe(struct i2c_client *client,
const struct i2c_device_id *did)
{
struct imx074 *priv;
struct soc_camera_device *icd = client->dev.platform_data;
struct i2c_adapter *adapter = to_i2c_adapter(client->dev.parent);
struct soc_camera_link *icl;
struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
int ret;
if (!icd) {
dev_err(&client->dev, "IMX074: missing soc-camera data!\n");
return -EINVAL;
}
icl = to_soc_camera_link(icd);
if (!icl) {
dev_err(&client->dev, "IMX074: missing platform data!\n");
return -EINVAL;
......@@ -445,12 +429,10 @@ static int imx074_probe(struct i2c_client *client,
v4l2_i2c_subdev_init(&priv->subdev, client, &imx074_subdev_ops);
icd->ops = &imx074_ops;
priv->fmt = &imx074_colour_fmts[0];
ret = imx074_video_probe(icd, client);
ret = imx074_video_probe(client);
if (ret < 0) {
icd->ops = NULL;
kfree(priv);
return ret;
}
......@@ -461,10 +443,8 @@ static int imx074_probe(struct i2c_client *client,
static int imx074_remove(struct i2c_client *client)
{
struct imx074 *priv = to_imx074(client);
struct soc_camera_device *icd = client->dev.platform_data;
struct soc_camera_link *icl = to_soc_camera_link(icd);
struct soc_camera_link *icl = soc_camera_i2c_to_link(client);
icd->ops = NULL;
if (icl->free_bus)
icl->free_bus(icl);
kfree(priv);
......
......@@ -1180,6 +1180,8 @@ static int __devinit ivtv_probe(struct pci_dev *pdev,
setup.addr = ADDR_UNSET;
setup.type = itv->options.tuner;
setup.mode_mask = T_ANALOG_TV; /* matches TV tuners */
if (itv->options.radio > 0)
setup.mode_mask |= T_RADIO;
setup.tuner_callback = (setup.type == TUNER_XC2028) ?
ivtv_reset_tuner_gpio : NULL;
ivtv_call_all(itv, tuner, s_type_addr, &setup);
......
......@@ -883,7 +883,8 @@ static int mcam_read_setup(struct mcam_camera *cam)
* Videobuf2 interface code.
*/
static int mcam_vb_queue_setup(struct vb2_queue *vq, unsigned int *nbufs,
static int mcam_vb_queue_setup(struct vb2_queue *vq,
const struct v4l2_format *fmt, unsigned int *nbufs,
unsigned int *num_planes, unsigned int sizes[],
void *alloc_ctxs[])
{
......
......@@ -738,9 +738,10 @@ static const struct v4l2_ioctl_ops m2mtest_ioctl_ops = {
* Queue operations
*/
static int m2mtest_queue_setup(struct vb2_queue *vq, unsigned int *nbuffers,
unsigned int *nplanes, unsigned int sizes[],
void *alloc_ctxs[])
static int m2mtest_queue_setup(struct vb2_queue *vq,
const struct v4l2_format *fmt,
unsigned int *nbuffers, unsigned int *nplanes,
unsigned int sizes[], void *alloc_ctxs[])
{
struct m2mtest_ctx *ctx = vb2_get_drv_priv(vq);
struct m2mtest_q_data *q_data;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -78,11 +78,10 @@
#define CSI_IRQ_MASK (CSISR_SFF_OR_INT | CSISR_RFF_OR_INT | \
CSISR_STATFF_INT | CSISR_RXFF_INT | CSISR_SOF_INT)
#define CSI_BUS_FLAGS (SOCAM_MASTER | SOCAM_HSYNC_ACTIVE_HIGH | \
SOCAM_VSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_LOW | \
SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \
SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATA_ACTIVE_LOW | \
SOCAM_DATAWIDTH_8)
#define CSI_BUS_FLAGS (V4L2_MBUS_MASTER | V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
V4L2_MBUS_VSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_LOW | \
V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
V4L2_MBUS_DATA_ACTIVE_HIGH | V4L2_MBUS_DATA_ACTIVE_LOW)
#define MAX_VIDEO_MEM 16 /* Video memory limit in megabytes */
......@@ -490,59 +489,73 @@ static int mx1_camera_set_crop(struct soc_camera_device *icd,
static int mx1_camera_set_bus_param(struct soc_camera_device *icd, __u32 pixfmt)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx1_camera_dev *pcdev = ici->priv;
unsigned long camera_flags, common_flags;
struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
unsigned long common_flags;
unsigned int csicr1;
int ret;
camera_flags = icd->ops->query_bus_param(icd);
/* MX1 supports only 8bit buswidth */
common_flags = soc_camera_bus_param_compatible(camera_flags,
CSI_BUS_FLAGS);
if (!common_flags)
return -EINVAL;
ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
if (!ret) {
common_flags = soc_mbus_config_compatible(&cfg, CSI_BUS_FLAGS);
if (!common_flags) {
dev_warn(icd->parent,
"Flags incompatible: camera 0x%x, host 0x%x\n",
cfg.flags, CSI_BUS_FLAGS);
return -EINVAL;
}
} else if (ret != -ENOIOCTLCMD) {
return ret;
} else {
common_flags = CSI_BUS_FLAGS;
}
/* Make choises, based on platform choice */
if ((common_flags & SOCAM_VSYNC_ACTIVE_HIGH) &&
(common_flags & SOCAM_VSYNC_ACTIVE_LOW)) {
if ((common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_VSYNC_ACTIVE_LOW)) {
if (!pcdev->pdata ||
pcdev->pdata->flags & MX1_CAMERA_VSYNC_HIGH)
common_flags &= ~SOCAM_VSYNC_ACTIVE_LOW;
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_LOW;
else
common_flags &= ~SOCAM_VSYNC_ACTIVE_HIGH;
common_flags &= ~V4L2_MBUS_VSYNC_ACTIVE_HIGH;
}
if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
(common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
(common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
if (!pcdev->pdata ||
pcdev->pdata->flags & MX1_CAMERA_PCLK_RISING)
common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
else
common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
}
if ((common_flags & SOCAM_DATA_ACTIVE_HIGH) &&
(common_flags & SOCAM_DATA_ACTIVE_LOW)) {
if ((common_flags & V4L2_MBUS_DATA_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)) {
if (!pcdev->pdata ||
pcdev->pdata->flags & MX1_CAMERA_DATA_HIGH)
common_flags &= ~SOCAM_DATA_ACTIVE_LOW;
common_flags &= ~V4L2_MBUS_DATA_ACTIVE_LOW;
else
common_flags &= ~SOCAM_DATA_ACTIVE_HIGH;
common_flags &= ~V4L2_MBUS_DATA_ACTIVE_HIGH;
}
ret = icd->ops->set_bus_param(icd, common_flags);
if (ret < 0)
cfg.flags = common_flags;
ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
if (ret < 0 && ret != -ENOIOCTLCMD) {
dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
common_flags, ret);
return ret;
}
csicr1 = __raw_readl(pcdev->base + CSICR1);
if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
csicr1 |= CSICR1_REDGE;
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_SOF_POL;
if (common_flags & SOCAM_DATA_ACTIVE_LOW)
if (common_flags & V4L2_MBUS_DATA_ACTIVE_LOW)
csicr1 |= CSICR1_DATA_POL;
__raw_writel(csicr1, pcdev->base + CSICR1);
......
......@@ -686,16 +686,15 @@ static void mx2_camera_init_videobuf(struct videobuf_queue *q,
icd, &icd->video_lock);
}
#define MX2_BUS_FLAGS (SOCAM_DATAWIDTH_8 | \
SOCAM_MASTER | \
SOCAM_VSYNC_ACTIVE_HIGH | \
SOCAM_VSYNC_ACTIVE_LOW | \
SOCAM_HSYNC_ACTIVE_HIGH | \
SOCAM_HSYNC_ACTIVE_LOW | \
SOCAM_PCLK_SAMPLE_RISING | \
SOCAM_PCLK_SAMPLE_FALLING | \
SOCAM_DATA_ACTIVE_HIGH | \
SOCAM_DATA_ACTIVE_LOW)
#define MX2_BUS_FLAGS (V4L2_MBUS_MASTER | \
V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
V4L2_MBUS_VSYNC_ACTIVE_LOW | \
V4L2_MBUS_HSYNC_ACTIVE_HIGH | \
V4L2_MBUS_HSYNC_ACTIVE_LOW | \
V4L2_MBUS_PCLK_SAMPLE_RISING | \
V4L2_MBUS_PCLK_SAMPLE_FALLING | \
V4L2_MBUS_DATA_ACTIVE_HIGH | \
V4L2_MBUS_DATA_ACTIVE_LOW)
static int mx27_camera_emma_prp_reset(struct mx2_camera_dev *pcdev)
{
......@@ -770,46 +769,59 @@ static void mx27_camera_emma_buf_init(struct soc_camera_device *icd,
static int mx2_camera_set_bus_param(struct soc_camera_device *icd,
__u32 pixfmt)
{
struct soc_camera_host *ici =
to_soc_camera_host(icd->parent);
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct soc_camera_host *ici = to_soc_camera_host(icd->parent);
struct mx2_camera_dev *pcdev = ici->priv;
unsigned long camera_flags, common_flags;
int ret = 0;
struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
unsigned long common_flags;
int ret;
int bytesperline;
u32 csicr1 = pcdev->csicr1;
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
MX2_BUS_FLAGS);
if (!common_flags)
return -EINVAL;
ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
if (!ret) {
common_flags = soc_mbus_config_compatible(&cfg, MX2_BUS_FLAGS);
if (!common_flags) {
dev_warn(icd->parent,
"Flags incompatible: camera 0x%x, host 0x%x\n",
cfg.flags, MX2_BUS_FLAGS);
return -EINVAL;
}
} else if (ret != -ENOIOCTLCMD) {
return ret;
} else {
common_flags = MX2_BUS_FLAGS;
}
if ((common_flags & SOCAM_HSYNC_ACTIVE_HIGH) &&
(common_flags & SOCAM_HSYNC_ACTIVE_LOW)) {
if ((common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH) &&
(common_flags & V4L2_MBUS_HSYNC_ACTIVE_LOW)) {
if (pcdev->platform_flags & MX2_CAMERA_HSYNC_HIGH)
common_flags &= ~SOCAM_HSYNC_ACTIVE_LOW;
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_LOW;
else
common_flags &= ~SOCAM_HSYNC_ACTIVE_HIGH;
common_flags &= ~V4L2_MBUS_HSYNC_ACTIVE_HIGH;
}
if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
(common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
(common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
if (pcdev->platform_flags & MX2_CAMERA_PCLK_SAMPLE_RISING)
common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
else
common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
}
ret = icd->ops->set_bus_param(icd, common_flags);
if (ret < 0)
cfg.flags = common_flags;
ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
if (ret < 0 && ret != -ENOIOCTLCMD) {
dev_dbg(icd->parent, "camera s_mbus_config(0x%lx) returned %d\n",
common_flags, ret);
return ret;
}
if (common_flags & SOCAM_PCLK_SAMPLE_RISING)
if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING)
csicr1 |= CSICR1_REDGE;
if (common_flags & SOCAM_VSYNC_ACTIVE_HIGH)
if (common_flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_SOF_POL;
if (common_flags & SOCAM_HSYNC_ACTIVE_HIGH)
if (common_flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
csicr1 |= CSICR1_HSYNC_POL;
if (pcdev->platform_flags & MX2_CAMERA_SWAP16)
csicr1 |= CSICR1_SWAP16_EN;
......
This diff is collapsed.
......@@ -833,6 +833,15 @@ static void omap_vout_buffer_release(struct videobuf_queue *q,
/*
* File operations
*/
static unsigned int omap_vout_poll(struct file *file,
struct poll_table_struct *wait)
{
struct omap_vout_device *vout = file->private_data;
struct videobuf_queue *q = &vout->vbq;
return videobuf_poll_stream(file, q, wait);
}
static void omap_vout_vm_open(struct vm_area_struct *vma)
{
struct omap_vout_device *vout = vma->vm_private_data;
......@@ -1861,6 +1870,7 @@ static const struct v4l2_ioctl_ops vout_ioctl_ops = {
static const struct v4l2_file_operations omap_vout_fops = {
.owner = THIS_MODULE,
.poll = omap_vout_poll,
.unlocked_ioctl = video_ioctl2,
.mmap = omap_vout_mmap,
.open = omap_vout_open,
......
......@@ -102,10 +102,10 @@
/* end of OMAP1 Camera Interface registers */
#define SOCAM_BUS_FLAGS (SOCAM_MASTER | \
SOCAM_HSYNC_ACTIVE_HIGH | SOCAM_VSYNC_ACTIVE_HIGH | \
SOCAM_PCLK_SAMPLE_RISING | SOCAM_PCLK_SAMPLE_FALLING | \
SOCAM_DATA_ACTIVE_HIGH | SOCAM_DATAWIDTH_8)
#define SOCAM_BUS_FLAGS (V4L2_MBUS_MASTER | \
V4L2_MBUS_HSYNC_ACTIVE_HIGH | V4L2_MBUS_VSYNC_ACTIVE_HIGH | \
V4L2_MBUS_PCLK_SAMPLE_RISING | V4L2_MBUS_PCLK_SAMPLE_FALLING | \
V4L2_MBUS_DATA_ACTIVE_HIGH)
#define FIFO_SIZE ((THRESHOLD_MASK >> THRESHOLD_SHIFT) + 1)
......@@ -1438,41 +1438,55 @@ static int omap1_cam_querycap(struct soc_camera_host *ici,
static int omap1_cam_set_bus_param(struct soc_camera_device *icd,
__u32 pixfmt)
{
struct v4l2_subdev *sd = soc_camera_to_subdev(icd);
struct device *dev = icd->parent;
struct soc_camera_host *ici = to_soc_camera_host(dev);
struct omap1_cam_dev *pcdev = ici->priv;
const struct soc_camera_format_xlate *xlate;
const struct soc_mbus_pixelfmt *fmt;
unsigned long camera_flags, common_flags;
struct v4l2_mbus_config cfg = {.type = V4L2_MBUS_PARALLEL,};
unsigned long common_flags;
u32 ctrlclock, mode;
int ret;
camera_flags = icd->ops->query_bus_param(icd);
common_flags = soc_camera_bus_param_compatible(camera_flags,
SOCAM_BUS_FLAGS);
if (!common_flags)
return -EINVAL;
ret = v4l2_subdev_call(sd, video, g_mbus_config, &cfg);
if (!ret) {
common_flags = soc_mbus_config_compatible(&cfg, SOCAM_BUS_FLAGS);
if (!common_flags) {
dev_warn(dev,
"Flags incompatible: camera 0x%x, host 0x%x\n",
cfg.flags, SOCAM_BUS_FLAGS);
return -EINVAL;
}
} else if (ret != -ENOIOCTLCMD) {
return ret;
} else {
common_flags = SOCAM_BUS_FLAGS;
}
/* Make choices, possibly based on platform configuration */
if ((common_flags & SOCAM_PCLK_SAMPLE_RISING) &&
(common_flags & SOCAM_PCLK_SAMPLE_FALLING)) {
if ((common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) &&
(common_flags & V4L2_MBUS_PCLK_SAMPLE_FALLING)) {
if (!pcdev->pdata ||
pcdev->pdata->flags & OMAP1_CAMERA_LCLK_RISING)
common_flags &= ~SOCAM_PCLK_SAMPLE_FALLING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_FALLING;
else
common_flags &= ~SOCAM_PCLK_SAMPLE_RISING;
common_flags &= ~V4L2_MBUS_PCLK_SAMPLE_RISING;
}
ret = icd->ops->set_bus_param(icd, common_flags);
if (ret < 0)
cfg.flags = common_flags;
ret = v4l2_subdev_call(sd, video, s_mbus_config, &cfg);
if (ret < 0 && ret != -ENOIOCTLCMD) {
dev_dbg(dev, "camera s_mbus_config(0x%lx) returned %d\n",
common_flags, ret);
return ret;
}
ctrlclock = CAM_READ_CACHE(pcdev, CTRLCLOCK);
if (ctrlclock & LCLK_EN)
CAM_WRITE(pcdev, CTRLCLOCK, ctrlclock & ~LCLK_EN);
if (common_flags & SOCAM_PCLK_SAMPLE_RISING) {
if (common_flags & V4L2_MBUS_PCLK_SAMPLE_RISING) {
dev_dbg(dev, "CTRLCLOCK_REG |= POLCLK\n");
ctrlclock |= POLCLK;
} else {
......@@ -1565,10 +1579,10 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
pcdev->clk = clk;
pcdev->pdata = pdev->dev.platform_data;
pcdev->pflags = pcdev->pdata->flags;
if (pcdev->pdata)
if (pcdev->pdata) {
pcdev->pflags = pcdev->pdata->flags;
pcdev->camexclk = pcdev->pdata->camexclk_khz * 1000;
}
switch (pcdev->camexclk) {
case 6000000:
......@@ -1578,6 +1592,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
case 24000000:
break;
default:
/* pcdev->camexclk != 0 => pcdev->pdata != NULL */
dev_warn(&pdev->dev,
"Incorrect sensor clock frequency %ld kHz, "
"should be one of 0, 6, 8, 9.6, 12 or 24 MHz, "
......@@ -1585,8 +1600,7 @@ static int __init omap1_cam_probe(struct platform_device *pdev)
pcdev->pdata->camexclk_khz);
pcdev->camexclk = 0;
case 0:
dev_info(&pdev->dev,
"Not providing sensor clock\n");
dev_info(&pdev->dev, "Not providing sensor clock\n");
}
INIT_LIST_HEAD(&pcdev->capture);
......@@ -1716,5 +1730,5 @@ MODULE_PARM_DESC(sg_mode, "videobuf mode, 0: dma-contig (default), 1: dma-sg");
MODULE_DESCRIPTION("OMAP1 Camera Interface driver");
MODULE_AUTHOR("Janusz Krzysztofik <jkrzyszt@tis.icnet.pl>");
MODULE_LICENSE("GPL v2");
MODULE_LICENSE(DRIVER_VERSION);
MODULE_VERSION(DRIVER_VERSION);
MODULE_ALIAS("platform:" DRIVER_NAME);
......@@ -1704,6 +1704,7 @@ static int isp_register_entities(struct isp_device *isp)
isp->media_dev.dev = isp->dev;
strlcpy(isp->media_dev.model, "TI OMAP3 ISP",
sizeof(isp->media_dev.model));
isp->media_dev.hw_revision = isp->revision;
isp->media_dev.link_notify = isp_pipeline_link_notify;
ret = media_device_register(&isp->media_dev);
if (ret < 0) {
......@@ -2210,6 +2211,8 @@ static int isp_probe(struct platform_device *pdev)
regulator_put(isp->isp_csiphy2.vdd);
regulator_put(isp->isp_csiphy1.vdd);
platform_set_drvdata(pdev, NULL);
mutex_destroy(&isp->isp_mutex);
kfree(isp);
return ret;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment