Merge branch 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Apr 2011 22:17:52 +0000 (15:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 27 Apr 2011 22:17:52 +0000 (15:17 -0700)
* 'v4l_for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (42 commits)
  [media] media: vb2: correct queue initialization order
  [media] media: vb2: fix incorrect v4l2_buffer->flags handling
  [media] s5p-fimc: Add support for the buffer timestamps and sequence
  [media] s5p-fimc: Fix bytesperline and plane payload setup
  [media] s5p-fimc: Do not allow changing format after REQBUFS
  [media] s5p-fimc: Fix FIMC3 pixel limits on Exynos4
  [media] tda18271: update tda18271c2_rf_cal as per NXP's rev.04 datasheet
  [media] tda18271: update tda18271_rf_band as per NXP's rev.04 datasheet
  [media] tda18271: fix bad calculation of main post divider byte
  [media] tda18271: prog_cal and prog_tab variables should be s32, not u8
  [media] tda18271: fix calculation bug in tda18271_rf_tracking_filters_init
  [media] omap3isp: queue: Don't corrupt buf->npages when get_user_pages() fails
  [media] v4l: Don't register media entities for subdev device nodes
  [media] omap3isp: Don't increment node entity use count when poweron fails
  [media] omap3isp: lane shifter support
  [media] omap3isp: ccdc: support Y10/12, 8-bit bayer fmts
  [media] media: add missing 8-bit bayer formats and Y12
  [media] v4l: add V4L2_PIX_FMT_Y12 format
  cx23885: Fix stv0367 Kconfig dependency
  [media] omap3isp: Use isp xclk defines
  ...

Fix up trivial conflict (spelink errurs) in drivers/media/video/omap3isp/isp.c

37 files changed:
Documentation/DocBook/media-entities.tmpl
Documentation/DocBook/v4l/media-ioc-setup-link.xml
Documentation/DocBook/v4l/pixfmt-y12.xml [new file with mode: 0644]
Documentation/DocBook/v4l/pixfmt.xml
Documentation/DocBook/v4l/subdev-formats.xml
Documentation/video4linux/sh_mobile_ceu_camera.txt
drivers/media/common/tuners/tda18271-common.c
drivers/media/common/tuners/tda18271-fe.c
drivers/media/common/tuners/tda18271-maps.c
drivers/media/dvb/b2c2/flexcop-pci.c
drivers/media/dvb/dvb-usb/Kconfig
drivers/media/dvb/dvb-usb/dib0700_devices.c
drivers/media/media-entity.c
drivers/media/video/Kconfig
drivers/media/video/cx18/cx18-streams.c
drivers/media/video/cx23885/Kconfig
drivers/media/video/imx074.c
drivers/media/video/omap3isp/isp.c
drivers/media/video/omap3isp/isp.h
drivers/media/video/omap3isp/ispccdc.c
drivers/media/video/omap3isp/isppreview.c
drivers/media/video/omap3isp/ispqueue.c
drivers/media/video/omap3isp/ispresizer.c
drivers/media/video/omap3isp/ispstat.h
drivers/media/video/omap3isp/ispvideo.c
drivers/media/video/omap3isp/ispvideo.h
drivers/media/video/s5p-fimc/fimc-capture.c
drivers/media/video/s5p-fimc/fimc-core.c
drivers/media/video/sh_mobile_ceu_camera.c
drivers/media/video/sh_mobile_csi2.c
drivers/media/video/soc_camera.c
drivers/media/video/v4l2-dev.c
drivers/media/video/videobuf2-core.c
drivers/media/video/videobuf2-dma-contig.c
include/linux/v4l2-mediabus.h
include/linux/videodev2.h
include/media/v4l2-device.h

index 5d259c6..fea63b4 100644 (file)
 <!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
 <!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
 <!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.xml">
+<!ENTITY sub-y12 SYSTEM "v4l/pixfmt-y12.xml">
 <!ENTITY sub-pixfmt SYSTEM "v4l/pixfmt.xml">
 <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
 <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
index 2331e76..cec97af 100644 (file)
@@ -34,7 +34,7 @@
       <varlistentry>
        <term><parameter>request</parameter></term>
        <listitem>
-         <para>MEDIA_IOC_ENUM_LINKS</para>
+         <para>MEDIA_IOC_SETUP_LINK</para>
        </listitem>
       </varlistentry>
       <varlistentry>
diff --git a/Documentation/DocBook/v4l/pixfmt-y12.xml b/Documentation/DocBook/v4l/pixfmt-y12.xml
new file mode 100644 (file)
index 0000000..ff417b8
--- /dev/null
@@ -0,0 +1,79 @@
+<refentry id="V4L2-PIX-FMT-Y12">
+  <refmeta>
+    <refentrytitle>V4L2_PIX_FMT_Y12 ('Y12 ')</refentrytitle>
+    &manvol;
+  </refmeta>
+  <refnamediv>
+    <refname><constant>V4L2_PIX_FMT_Y12</constant></refname>
+    <refpurpose>Grey-scale image</refpurpose>
+  </refnamediv>
+  <refsect1>
+    <title>Description</title>
+
+    <para>This is a grey-scale image with a depth of 12 bits per pixel. Pixels
+are stored in 16-bit words with unused high bits padded with 0. The least
+significant byte is stored at lower memory addresses (little-endian).</para>
+
+    <example>
+      <title><constant>V4L2_PIX_FMT_Y12</constant> 4 &times; 4
+pixel image</title>
+
+      <formalpara>
+       <title>Byte Order.</title>
+       <para>Each cell is one byte.
+         <informaltable frame="none">
+           <tgroup cols="9" align="center">
+             <colspec align="left" colwidth="2*" />
+             <tbody valign="top">
+               <row>
+                 <entry>start&nbsp;+&nbsp;0:</entry>
+                 <entry>Y'<subscript>00low</subscript></entry>
+                 <entry>Y'<subscript>00high</subscript></entry>
+                 <entry>Y'<subscript>01low</subscript></entry>
+                 <entry>Y'<subscript>01high</subscript></entry>
+                 <entry>Y'<subscript>02low</subscript></entry>
+                 <entry>Y'<subscript>02high</subscript></entry>
+                 <entry>Y'<subscript>03low</subscript></entry>
+                 <entry>Y'<subscript>03high</subscript></entry>
+               </row>
+               <row>
+                 <entry>start&nbsp;+&nbsp;8:</entry>
+                 <entry>Y'<subscript>10low</subscript></entry>
+                 <entry>Y'<subscript>10high</subscript></entry>
+                 <entry>Y'<subscript>11low</subscript></entry>
+                 <entry>Y'<subscript>11high</subscript></entry>
+                 <entry>Y'<subscript>12low</subscript></entry>
+                 <entry>Y'<subscript>12high</subscript></entry>
+                 <entry>Y'<subscript>13low</subscript></entry>
+                 <entry>Y'<subscript>13high</subscript></entry>
+               </row>
+               <row>
+                 <entry>start&nbsp;+&nbsp;16:</entry>
+                 <entry>Y'<subscript>20low</subscript></entry>
+                 <entry>Y'<subscript>20high</subscript></entry>
+                 <entry>Y'<subscript>21low</subscript></entry>
+                 <entry>Y'<subscript>21high</subscript></entry>
+                 <entry>Y'<subscript>22low</subscript></entry>
+                 <entry>Y'<subscript>22high</subscript></entry>
+                 <entry>Y'<subscript>23low</subscript></entry>
+                 <entry>Y'<subscript>23high</subscript></entry>
+               </row>
+               <row>
+                 <entry>start&nbsp;+&nbsp;24:</entry>
+                 <entry>Y'<subscript>30low</subscript></entry>
+                 <entry>Y'<subscript>30high</subscript></entry>
+                 <entry>Y'<subscript>31low</subscript></entry>
+                 <entry>Y'<subscript>31high</subscript></entry>
+                 <entry>Y'<subscript>32low</subscript></entry>
+                 <entry>Y'<subscript>32high</subscript></entry>
+                 <entry>Y'<subscript>33low</subscript></entry>
+                 <entry>Y'<subscript>33high</subscript></entry>
+               </row>
+             </tbody>
+           </tgroup>
+         </informaltable>
+       </para>
+      </formalpara>
+    </example>
+  </refsect1>
+</refentry>
index c6fdcbb..40af4be 100644 (file)
@@ -696,6 +696,7 @@ information.</para>
     &sub-packed-yuv;
     &sub-grey;
     &sub-y10;
+    &sub-y12;
     &sub-y16;
     &sub-yuyv;
     &sub-uyvy;
index 7041127..d7ccd25 100644 (file)
              <entry>b<subscript>1</subscript></entry>
              <entry>b<subscript>0</subscript></entry>
            </row>
+           <row id="V4L2-MBUS-FMT-SGBRG8-1X8">
+             <entry>V4L2_MBUS_FMT_SGBRG8_1X8</entry>
+             <entry>0x3013</entry>
+             <entry></entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>g<subscript>7</subscript></entry>
+             <entry>g<subscript>6</subscript></entry>
+             <entry>g<subscript>5</subscript></entry>
+             <entry>g<subscript>4</subscript></entry>
+             <entry>g<subscript>3</subscript></entry>
+             <entry>g<subscript>2</subscript></entry>
+             <entry>g<subscript>1</subscript></entry>
+             <entry>g<subscript>0</subscript></entry>
+           </row>
            <row id="V4L2-MBUS-FMT-SGRBG8-1X8">
              <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry>
              <entry>0x3002</entry>
              <entry>g<subscript>1</subscript></entry>
              <entry>g<subscript>0</subscript></entry>
            </row>
+           <row id="V4L2-MBUS-FMT-SRGGB8-1X8">
+             <entry>V4L2_MBUS_FMT_SRGGB8_1X8</entry>
+             <entry>0x3014</entry>
+             <entry></entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>r<subscript>7</subscript></entry>
+             <entry>r<subscript>6</subscript></entry>
+             <entry>r<subscript>5</subscript></entry>
+             <entry>r<subscript>4</subscript></entry>
+             <entry>r<subscript>3</subscript></entry>
+             <entry>r<subscript>2</subscript></entry>
+             <entry>r<subscript>1</subscript></entry>
+             <entry>r<subscript>0</subscript></entry>
+           </row>
            <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8">
              <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry>
              <entry>0x300b</entry>
              <entry>u<subscript>1</subscript></entry>
              <entry>u<subscript>0</subscript></entry>
            </row>
+           <row id="V4L2-MBUS-FMT-Y12-1X12">
+             <entry>V4L2_MBUS_FMT_Y12_1X12</entry>
+             <entry>0x2013</entry>
+             <entry></entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>-</entry>
+             <entry>y<subscript>11</subscript></entry>
+             <entry>y<subscript>10</subscript></entry>
+             <entry>y<subscript>9</subscript></entry>
+             <entry>y<subscript>8</subscript></entry>
+             <entry>y<subscript>7</subscript></entry>
+             <entry>y<subscript>6</subscript></entry>
+             <entry>y<subscript>5</subscript></entry>
+             <entry>y<subscript>4</subscript></entry>
+             <entry>y<subscript>3</subscript></entry>
+             <entry>y<subscript>2</subscript></entry>
+             <entry>y<subscript>1</subscript></entry>
+             <entry>y<subscript>0</subscript></entry>
+           </row>
            <row id="V4L2-MBUS-FMT-UYVY8-1X16">
              <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry>
              <entry>0x200f</entry>
index cb47e72..1e96ce6 100644 (file)
@@ -37,7 +37,7 @@ Generic scaling / cropping scheme
 -1'-
 
 In the above chart minuses and slashes represent "real" data amounts, points and
-accents represent "useful" data, basically, CEU scaled amd cropped output,
+accents represent "useful" data, basically, CEU scaled and cropped output,
 mapped back onto the client's source plane.
 
 Such a configuration can be produced by user requests:
@@ -65,7 +65,7 @@ Do not touch input rectangle - it is already optimal.
 
 1. Calculate current sensor scales:
 
-       scale_s = ((3') - (3)) / ((2') - (2))
+       scale_s = ((2') - (2)) / ((3') - (3))
 
 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
 current sensor scales onto input window - this is user S_CROP:
@@ -80,7 +80,7 @@ window:
 4. Calculate sensor output window by applying combined scales to real input
 window:
 
-       width_s_out = ((2') - (2)) / scale_comb
+       width_s_out = ((7') - (7)) = ((2') - (2)) / scale_comb
 
 5. Apply iterative sensor S_FMT for sensor output window.
 
index 5466d47..aae40e5 100644 (file)
@@ -533,16 +533,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
        if (tda_fail(ret))
                goto fail;
 
-       regs[R_MPD]   = (0x77 & pd);
-
-       switch (priv->mode) {
-       case TDA18271_ANALOG:
-               regs[R_MPD]  &= ~0x08;
-               break;
-       case TDA18271_DIGITAL:
-               regs[R_MPD]  |=  0x08;
-               break;
-       }
+       regs[R_MPD]   = (0x7f & pd);
 
        div =  ((d * (freq / 1000)) << 7) / 125;
 
index 9ad4454..d884f5e 100644 (file)
@@ -579,8 +579,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
 #define RF3 2
        u32 rf_default[3];
        u32 rf_freq[3];
-       u8 prog_cal[3];
-       u8 prog_tab[3];
+       s32 prog_cal[3];
+       s32 prog_tab[3];
 
        i = tda18271_lookup_rf_band(fe, &freq, NULL);
 
@@ -602,32 +602,33 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
                        return bcal;
 
                tda18271_calc_rf_cal(fe, &rf_freq[rf]);
-               prog_tab[rf] = regs[R_EB14];
+               prog_tab[rf] = (s32)regs[R_EB14];
 
                if (1 == bcal)
-                       prog_cal[rf] = tda18271_calibrate_rf(fe, rf_freq[rf]);
+                       prog_cal[rf] =
+                               (s32)tda18271_calibrate_rf(fe, rf_freq[rf]);
                else
                        prog_cal[rf] = prog_tab[rf];
 
                switch (rf) {
                case RF1:
                        map[i].rf_a1 = 0;
-                       map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]);
+                       map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]);
                        map[i].rf1   = rf_freq[RF1] / 1000;
                        break;
                case RF2:
-                       dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) -
-                                  (s32)(prog_cal[RF1] + prog_tab[RF1]);
+                       dividend = (prog_cal[RF2] - prog_tab[RF2] -
+                                   prog_cal[RF1] + prog_tab[RF1]);
                        divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
                        map[i].rf_a1 = (dividend / divisor);
                        map[i].rf2   = rf_freq[RF2] / 1000;
                        break;
                case RF3:
-                       dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) -
-                                  (s32)(prog_cal[RF2] + prog_tab[RF2]);
+                       dividend = (prog_cal[RF3] - prog_tab[RF3] -
+                                   prog_cal[RF2] + prog_tab[RF2]);
                        divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
                        map[i].rf_a2 = (dividend / divisor);
-                       map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]);
+                       map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]);
                        map[i].rf3   = rf_freq[RF3] / 1000;
                        break;
                default:
index e7f84c7..3d5b6ab 100644 (file)
@@ -229,8 +229,7 @@ static struct tda18271_map tda18271c2_km[] = {
 static struct tda18271_map tda18271_rf_band[] = {
        { .rfmax =  47900, .val = 0x00 },
        { .rfmax =  61100, .val = 0x01 },
-/*     { .rfmax = 152600, .val = 0x02 }, */
-       { .rfmax = 121200, .val = 0x02 },
+       { .rfmax = 152600, .val = 0x02 },
        { .rfmax = 164700, .val = 0x03 },
        { .rfmax = 203500, .val = 0x04 },
        { .rfmax = 457800, .val = 0x05 },
@@ -448,7 +447,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
        { .rfmax = 150000, .val = 0xb0 },
        { .rfmax = 151000, .val = 0xb1 },
        { .rfmax = 152000, .val = 0xb7 },
-       { .rfmax = 153000, .val = 0xbd },
+       { .rfmax = 152600, .val = 0xbd },
        { .rfmax = 154000, .val = 0x20 },
        { .rfmax = 155000, .val = 0x22 },
        { .rfmax = 156000, .val = 0x24 },
@@ -459,7 +458,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
        { .rfmax = 161000, .val = 0x2d },
        { .rfmax = 163000, .val = 0x2e },
        { .rfmax = 164000, .val = 0x2f },
-       { .rfmax = 165000, .val = 0x30 },
+       { .rfmax = 164700, .val = 0x30 },
        { .rfmax = 166000, .val = 0x11 },
        { .rfmax = 167000, .val = 0x12 },
        { .rfmax = 168000, .val = 0x13 },
@@ -510,7 +509,8 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
        { .rfmax = 236000, .val = 0x1b },
        { .rfmax = 237000, .val = 0x1c },
        { .rfmax = 240000, .val = 0x1d },
-       { .rfmax = 242000, .val = 0x1f },
+       { .rfmax = 242000, .val = 0x1e },
+       { .rfmax = 244000, .val = 0x1f },
        { .rfmax = 247000, .val = 0x20 },
        { .rfmax = 249000, .val = 0x21 },
        { .rfmax = 252000, .val = 0x22 },
@@ -624,7 +624,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
        { .rfmax = 453000, .val = 0x93 },
        { .rfmax = 454000, .val = 0x94 },
        { .rfmax = 456000, .val = 0x96 },
-       { .rfmax = 457000, .val = 0x98 },
+       { .rfmax = 457800, .val = 0x98 },
        { .rfmax = 461000, .val = 0x11 },
        { .rfmax = 468000, .val = 0x12 },
        { .rfmax = 472000, .val = 0x13 },
index 9552540..03f96d6 100644 (file)
@@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug,
        DEBSTATUS);
 
 #define DRIVER_VERSION "0.1"
-#define DRIVER_NAME "Technisat/B2C2 FlexCop II/IIb/III Digital TV PCI Driver"
+#define DRIVER_NAME "flexcop-pci"
 #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
 
 struct flexcop_pci {
index fe4f894..ccbd39a 100644 (file)
@@ -362,7 +362,7 @@ config DVB_USB_LME2510
 config DVB_USB_TECHNISAT_USB2
        tristate "Technisat DVB-S/S2 USB2.0 support"
        depends on DVB_USB
-       select DVB_STB0899 if !DVB_FE_CUSTOMISE
-       select DVB_STB6100 if !DVB_FE_CUSTOMISE
+       select DVB_STV090x if !DVB_FE_CUSTOMISE
+       select DVB_STV6110x if !DVB_FE_CUSTOMISE
        help
          Say Y here to support the Technisat USB2 DVB-S/S2 device
index 97af266..65214af 100644 (file)
@@ -2162,7 +2162,7 @@ struct dibx000_agc_config dib7090_agc_config[2] = {
                .agc1_pt3       = 98,
                .agc1_slope1    = 0,
                .agc1_slope2    = 167,
-               .agc1_pt1       = 98,
+               .agc2_pt1       = 98,
                .agc2_pt2       = 255,
                .agc2_slope1    = 104,
                .agc2_slope2    = 0,
@@ -2440,11 +2440,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
        dib0700_set_i2c_speed(adap->dev, 340);
        adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
 
-       dib7090_slave_reset(adap->fe);
-
        if (adap->fe == NULL)
                return -ENODEV;
 
+       dib7090_slave_reset(adap->fe);
+
        return 0;
 }
 
index 23640ed..056138f 100644 (file)
@@ -378,7 +378,6 @@ EXPORT_SYMBOL_GPL(media_entity_create_link);
 
 static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
 {
-       const u32 mask = MEDIA_LNK_FL_ENABLED;
        int ret;
 
        /* Notify both entities. */
@@ -395,7 +394,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
                return ret;
        }
 
-       link->flags = (link->flags & ~mask) | (flags & mask);
+       link->flags = flags;
        link->reverse->flags = link->flags;
 
        return 0;
@@ -417,6 +416,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
  */
 int __media_entity_setup_link(struct media_link *link, u32 flags)
 {
+       const u32 mask = MEDIA_LNK_FL_ENABLED;
        struct media_device *mdev;
        struct media_entity *source, *sink;
        int ret = -EBUSY;
@@ -424,6 +424,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
        if (link == NULL)
                return -EINVAL;
 
+       /* The non-modifiable link flags must not be modified. */
+       if ((link->flags & ~mask) != (flags & ~mask))
+               return -EINVAL;
+
        if (link->flags & MEDIA_LNK_FL_IMMUTABLE)
                return link->flags == flags ? 0 : -EINVAL;
 
index 4498b94..00f51dd 100644 (file)
@@ -875,7 +875,7 @@ config MX3_VIDEO
 config VIDEO_MX3
        tristate "i.MX3x Camera Sensor Interface driver"
        depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
-       select VIDEOBUF_DMA_CONTIG
+       select VIDEOBUF2_DMA_CONTIG
        select MX3_VIDEO
        ---help---
          This is a v4l2 driver for the i.MX3x Camera Sensor Interface
index c6e2ca3..6fbc356 100644 (file)
@@ -350,9 +350,17 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
 
                /* No struct video_device, but can have buffers allocated */
                if (type == CX18_ENC_STREAM_TYPE_IDX) {
+                       /* If the module params didn't inhibit IDX ... */
                        if (cx->stream_buffers[type] != 0) {
                                cx->stream_buffers[type] = 0;
-                               cx18_stream_free(&cx->streams[type]);
+                               /*
+                                * Before calling cx18_stream_free(),
+                                * check if the IDX stream was actually set up.
+                                * Needed, since the cx18_probe() error path
+                                * exits through here as well as normal clean up
+                                */
+                               if (cx->streams[type].buffers != 0)
+                                       cx18_stream_free(&cx->streams[type]);
                        }
                        continue;
                }
index 3b6e7f2..caab1bf 100644 (file)
@@ -22,6 +22,7 @@ config VIDEO_CX23885
        select DVB_CX24116 if !DVB_FE_CUSTOMISE
        select DVB_STV0900 if !DVB_FE_CUSTOMISE
        select DVB_DS3000 if !DVB_FE_CUSTOMISE
+       select DVB_STV0367 if !DVB_FE_CUSTOMISE
        select MEDIA_TUNER_MT2131 if !MEDIA_TUNER_CUSTOMISE
        select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
        select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
index 1a11691..0382ea7 100644 (file)
@@ -298,7 +298,7 @@ static unsigned long imx074_query_bus_param(struct soc_camera_device *icd)
 static int imx074_set_bus_param(struct soc_camera_device *icd,
                                 unsigned long flags)
 {
-       return -1;
+       return -EINVAL;
 }
 
 static struct soc_camera_ops imx074_ops = {
index 503bd79..472a693 100644 (file)
@@ -215,20 +215,21 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
        }
 
        switch (xclksel) {
-       case 0:
+       case ISP_XCLK_A:
                isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
                                ISPTCTRL_CTRL_DIVA_MASK,
                                divisor << ISPTCTRL_CTRL_DIVA_SHIFT);
                dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n",
                        currentxclk);
                break;
-       case 1:
+       case ISP_XCLK_B:
                isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
                                ISPTCTRL_CTRL_DIVB_MASK,
                                divisor << ISPTCTRL_CTRL_DIVB_SHIFT);
                dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n",
                        currentxclk);
                break;
+       case ISP_XCLK_NONE:
        default:
                omap3isp_put(isp);
                dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested "
@@ -237,13 +238,13 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
        }
 
        /* Do we go from stable whatever to clock? */
-       if (divisor >= 2 && isp->xclk_divisor[xclksel] < 2)
+       if (divisor >= 2 && isp->xclk_divisor[xclksel - 1] < 2)
                omap3isp_get(isp);
        /* Stopping the clock. */
-       else if (divisor < 2 && isp->xclk_divisor[xclksel] >= 2)
+       else if (divisor < 2 && isp->xclk_divisor[xclksel - 1] >= 2)
                omap3isp_put(isp);
 
-       isp->xclk_divisor[xclksel] = divisor;
+       isp->xclk_divisor[xclksel - 1] = divisor;
 
        omap3isp_put(isp);
 
@@ -285,7 +286,8 @@ static void isp_power_settings(struct isp_device *isp, int idle)
  */
 void omap3isp_configure_bridge(struct isp_device *isp,
                               enum ccdc_input_entity input,
-                              const struct isp_parallel_platform_data *pdata)
+                              const struct isp_parallel_platform_data *pdata,
+                              unsigned int shift)
 {
        u32 ispctrl_val;
 
@@ -298,9 +300,9 @@ void omap3isp_configure_bridge(struct isp_device *isp,
        switch (input) {
        case CCDC_INPUT_PARALLEL:
                ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_PARALLEL;
-               ispctrl_val |= pdata->data_lane_shift << ISPCTRL_SHIFT_SHIFT;
                ispctrl_val |= pdata->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
                ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
+               shift += pdata->data_lane_shift * 2;
                break;
 
        case CCDC_INPUT_CSI2A:
@@ -319,6 +321,8 @@ void omap3isp_configure_bridge(struct isp_device *isp,
                return;
        }
 
+       ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK;
+
        ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
        ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
 
@@ -658,6 +662,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
 
        /* Apply power change to connected non-nodes. */
        ret = isp_pipeline_pm_power(entity, change);
+       if (ret < 0)
+               entity->use_count -= change;
 
        mutex_unlock(&entity->parent->graph_mutex);
 
@@ -872,6 +878,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
                }
        }
 
+       if (failure < 0)
+               isp->needs_reset = true;
+
        return failure;
 }
 
@@ -884,7 +893,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
  * single-shot or continuous mode.
  *
  * Return 0 if successful, or the return value of the failed video::s_stream
- * operation otherwise.
+ * operation otherwise. The pipeline state is not updated when the operation
+ * fails, except when stopping the pipeline.
  */
 int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
                                 enum isp_pipeline_stream_state state)
@@ -895,7 +905,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
                ret = isp_pipeline_disable(pipe);
        else
                ret = isp_pipeline_enable(pipe, state);
-       pipe->stream_state = state;
+
+       if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED)
+               pipe->stream_state = state;
 
        return ret;
 }
@@ -1481,6 +1493,10 @@ void omap3isp_put(struct isp_device *isp)
        if (--isp->ref_count == 0) {
                isp_disable_interrupts(isp);
                isp_save_ctx(isp);
+               if (isp->needs_reset) {
+                       isp_reset(isp);
+                       isp->needs_reset = false;
+               }
                isp_disable_clocks(isp);
        }
        mutex_unlock(&isp->isp_mutex);
index cf5214e..2620c40 100644 (file)
@@ -132,7 +132,6 @@ struct isp_reg {
 
 /**
  * struct isp_parallel_platform_data - Parallel interface platform data
- * @width: Parallel bus width in bits (8, 10, 11 or 12)
  * @data_lane_shift: Data lane shifter
  *             0 - CAMEXT[13:0] -> CAM[13:0]
  *             1 - CAMEXT[13:2] -> CAM[11:0]
@@ -146,7 +145,6 @@ struct isp_reg {
  *             ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian
  */
 struct isp_parallel_platform_data {
-       unsigned int width;
        unsigned int data_lane_shift:2;
        unsigned int clk_pol:1;
        unsigned int bridge:4;
@@ -262,6 +260,7 @@ struct isp_device {
        /* ISP Obj */
        spinlock_t stat_lock;   /* common lock for statistic drivers */
        struct mutex isp_mutex; /* For handling ref_count field */
+       bool needs_reset;
        int has_context;
        int ref_count;
        unsigned int autoidle;
@@ -311,11 +310,12 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
                                 enum isp_pipeline_stream_state state);
 void omap3isp_configure_bridge(struct isp_device *isp,
                               enum ccdc_input_entity input,
-                              const struct isp_parallel_platform_data *pdata);
+                              const struct isp_parallel_platform_data *pdata,
+                              unsigned int shift);
 
-#define ISP_XCLK_NONE                  -1
-#define ISP_XCLK_A                     0
-#define ISP_XCLK_B                     1
+#define ISP_XCLK_NONE                  0
+#define ISP_XCLK_A                     1
+#define ISP_XCLK_B                     2
 
 struct isp_device *omap3isp_get(struct isp_device *isp);
 void omap3isp_put(struct isp_device *isp);
index 5ff9d14..39d501b 100644 (file)
@@ -43,6 +43,12 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
 
 static const unsigned int ccdc_fmts[] = {
        V4L2_MBUS_FMT_Y8_1X8,
+       V4L2_MBUS_FMT_Y10_1X10,
+       V4L2_MBUS_FMT_Y12_1X12,
+       V4L2_MBUS_FMT_SGRBG8_1X8,
+       V4L2_MBUS_FMT_SRGGB8_1X8,
+       V4L2_MBUS_FMT_SBGGR8_1X8,
+       V4L2_MBUS_FMT_SGBRG8_1X8,
        V4L2_MBUS_FMT_SGRBG10_1X10,
        V4L2_MBUS_FMT_SRGGB10_1X10,
        V4L2_MBUS_FMT_SBGGR10_1X10,
@@ -1110,21 +1116,38 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
        struct isp_parallel_platform_data *pdata = NULL;
        struct v4l2_subdev *sensor;
        struct v4l2_mbus_framefmt *format;
+       const struct isp_format_info *fmt_info;
+       struct v4l2_subdev_format fmt_src;
+       unsigned int depth_out;
+       unsigned int depth_in = 0;
        struct media_pad *pad;
        unsigned long flags;
+       unsigned int shift;
        u32 syn_mode;
        u32 ccdc_pattern;
 
-       if (ccdc->input == CCDC_INPUT_PARALLEL) {
-               pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
-               sensor = media_entity_to_v4l2_subdev(pad->entity);
+       pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
+       sensor = media_entity_to_v4l2_subdev(pad->entity);
+       if (ccdc->input == CCDC_INPUT_PARALLEL)
                pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
                        ->bus.parallel;
+
+       /* Compute shift value for lane shifter to configure the bridge. */
+       fmt_src.pad = pad->index;
+       fmt_src.which = V4L2_SUBDEV_FORMAT_ACTIVE;
+       if (!v4l2_subdev_call(sensor, pad, get_fmt, NULL, &fmt_src)) {
+               fmt_info = omap3isp_video_format_info(fmt_src.format.code);
+               depth_in = fmt_info->bpp;
        }
 
-       omap3isp_configure_bridge(isp, ccdc->input, pdata);
+       fmt_info = omap3isp_video_format_info
+               (isp->isp_ccdc.formats[CCDC_PAD_SINK].code);
+       depth_out = fmt_info->bpp;
+
+       shift = depth_in - depth_out;
+       omap3isp_configure_bridge(isp, ccdc->input, pdata, shift);
 
-       ccdc->syncif.datsz = pdata ? pdata->width : 10;
+       ccdc->syncif.datsz = depth_out;
        ccdc_config_sync_if(ccdc, &ccdc->syncif);
 
        /* CCDC_PAD_SINK */
@@ -1338,7 +1361,7 @@ static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
  * @ccdc: Pointer to ISP CCDC device.
  * @event: Pointing which event trigger handler
  *
- * Return 1 when the event and stopping request combination is satisfyied,
+ * Return 1 when the event and stopping request combination is satisfied,
  * zero otherwise.
  */
 static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event)
@@ -1618,7 +1641,7 @@ static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
 
        ccdc_set_outaddr(ccdc, buffer->isp_addr);
 
-       /* We now have a buffer queued on the output, restart the pipeline in
+       /* We now have a buffer queued on the output, restart the pipeline
         * on the next CCDC interrupt if running in continuous mode (or when
         * starting the stream).
         */
index 2b16988..aba537a 100644 (file)
@@ -755,7 +755,7 @@ static struct preview_update update_attrs[] = {
  * @configs - pointer to update config structure.
  * @config - return pointer to appropriate structure field.
  * @bit - for which feature to return pointers.
- * Return size of coresponding prev_params member
+ * Return size of corresponding prev_params member
  */
 static u32
 __preview_get_ptrs(struct prev_params *params, void **param,
index 8fddc58..9c31714 100644 (file)
@@ -339,7 +339,7 @@ static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
        up_read(&current->mm->mmap_sem);
 
        if (ret != buf->npages) {
-               buf->npages = ret;
+               buf->npages = ret < 0 ? 0 : ret;
                isp_video_buffer_cleanup(buf);
                return -EFAULT;
        }
@@ -408,8 +408,8 @@ done:
  * isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address
  *
  * This function locates the VMAs for the buffer's userspace address and checks
- * that their flags match. The onlflag that we need to care for at the moment is
- * VM_PFNMAP.
+ * that their flags match. The only flag that we need to care for at the moment
+ * is VM_PFNMAP.
  *
  * The buffer vm_flags field is set to the first VMA flags.
  *
index 653f88b..0bb0f8c 100644 (file)
@@ -714,19 +714,50 @@ static void resizer_print_status(struct isp_res_device *res)
  * iw and ih are the input width and height after cropping. Those equations need
  * to be satisfied exactly for the resizer to work correctly.
  *
- * Reverting the equations, we can compute the resizing ratios with
+ * The equations can't be easily reverted, as the >> 8 operation is not linear.
+ * In addition, not all input sizes can be achieved for a given output size. To
+ * get the highest input size lower than or equal to the requested input size,
+ * we need to compute the highest resizing ratio that satisfies the following
+ * inequality (taking the 4-tap mode width equation as an example)
+ *
+ *     iw >= (32 * sph + (ow - 1) * hrsz + 16) >> 8 - 7
+ *
+ * (where iw is the requested input width) which can be rewritten as
+ *
+ *       iw - 7            >= (32 * sph + (ow - 1) * hrsz + 16) >> 8
+ *      (iw - 7) << 8      >=  32 * sph + (ow - 1) * hrsz + 16 - b
+ *     ((iw - 7) << 8) + b >=  32 * sph + (ow - 1) * hrsz + 16
+ *
+ * where b is the value of the 8 least significant bits of the right hand side
+ * expression of the last inequality. The highest resizing ratio value will be
+ * achieved when b is equal to its maximum value of 255. That resizing ratio
+ * value will still satisfy the original inequality, as b will disappear when
+ * the expression will be shifted right by 8.
+ *
+ * The reverted the equations thus become
  *
  * - 8-phase, 4-tap mode
- *     hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1)
- *     vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1)
+ *     hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
+ *     vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1)
  * - 4-phase, 7-tap mode
- *     hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1)
- *     vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 1)
+ *     hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1)
+ *     vrsz = ((ih - 7) * 256 + 255 - 32 - 64 * spv) / (oh - 1)
  *
- * The ratios are integer values, and must be rounded down to ensure that the
- * cropped input size is not bigger than the uncropped input size. As the ratio
- * in 7-tap mode is always smaller than the ratio in 4-tap mode, we can use the
- * 7-tap mode equations to compute a ratio approximation.
+ * The ratios are integer values, and are rounded down to ensure that the
+ * cropped input size is not bigger than the uncropped input size.
+ *
+ * As the number of phases/taps, used to select the correct equations to compute
+ * the ratio, depends on the ratio, we start with the 4-tap mode equations to
+ * compute an approximation of the ratio, and switch to the 7-tap mode equations
+ * if the approximation is higher than the ratio threshold.
+ *
+ * As the 7-tap mode equations will return a ratio smaller than or equal to the
+ * 4-tap mode equations, the resulting ratio could become lower than or equal to
+ * the ratio threshold. This 'equations loop' isn't an issue as long as the
+ * correct equations are used to compute the final input size. Starting with the
+ * 4-tap mode equations ensure that, in case of values resulting in a 'ratio
+ * loop', the smallest of the ratio values will be used, never exceeding the
+ * requested input size.
  *
  * We first clamp the output size according to the hardware capabilitie to avoid
  * auto-cropping the input more than required to satisfy the TRM equations. The
@@ -775,6 +806,8 @@ static void resizer_calc_ratios(struct isp_res_device *res,
        unsigned int max_width;
        unsigned int max_height;
        unsigned int width_alignment;
+       unsigned int width;
+       unsigned int height;
 
        /*
         * Clamp the output height based on the hardware capabilities and
@@ -786,19 +819,22 @@ static void resizer_calc_ratios(struct isp_res_device *res,
        max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
        output->height = clamp(output->height, min_height, max_height);
 
-       ratio->vert = ((input->height - 7) * 256 - 32 - 64 * spv)
+       ratio->vert = ((input->height - 4) * 256 + 255 - 16 - 32 * spv)
                    / (output->height - 1);
+       if (ratio->vert > MID_RESIZE_VALUE)
+               ratio->vert = ((input->height - 7) * 256 + 255 - 32 - 64 * spv)
+                           / (output->height - 1);
        ratio->vert = clamp_t(unsigned int, ratio->vert,
                              MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
 
        if (ratio->vert <= MID_RESIZE_VALUE) {
                upscaled_height = (output->height - 1) * ratio->vert
                                + 32 * spv + 16;
-               input->height = (upscaled_height >> 8) + 4;
+               height = (upscaled_height >> 8) + 4;
        } else {
                upscaled_height = (output->height - 1) * ratio->vert
                                + 64 * spv + 32;
-               input->height = (upscaled_height >> 8) + 7;
+               height = (upscaled_height >> 8) + 7;
        }
 
        /*
@@ -854,20 +890,29 @@ static void resizer_calc_ratios(struct isp_res_device *res,
                              max_width & ~(width_alignment - 1));
        output->width = ALIGN(output->width, width_alignment);
 
-       ratio->horz = ((input->width - 7) * 256 - 32 - 64 * sph)
+       ratio->horz = ((input->width - 7) * 256 + 255 - 16 - 32 * sph)
                    / (output->width - 1);
+       if (ratio->horz > MID_RESIZE_VALUE)
+               ratio->horz = ((input->width - 7) * 256 + 255 - 32 - 64 * sph)
+                           / (output->width - 1);
        ratio->horz = clamp_t(unsigned int, ratio->horz,
                              MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
 
        if (ratio->horz <= MID_RESIZE_VALUE) {
                upscaled_width = (output->width - 1) * ratio->horz
                               + 32 * sph + 16;
-               input->width = (upscaled_width >> 8) + 7;
+               width = (upscaled_width >> 8) + 7;
        } else {
                upscaled_width = (output->width - 1) * ratio->horz
                               + 64 * sph + 32;
-               input->width = (upscaled_width >> 8) + 7;
+               width = (upscaled_width >> 8) + 7;
        }
+
+       /* Center the new crop rectangle. */
+       input->left += (input->width - width) / 2;
+       input->top += (input->height - height) / 2;
+       input->width = width;
+       input->height = height;
 }
 
 /*
index 820950c..d86da94 100644 (file)
@@ -131,9 +131,9 @@ struct ispstat {
 struct ispstat_generic_config {
        /*
         * Fields must be in the same order as in:
-        *  - isph3a_aewb_config
-        *  - isph3a_af_config
-        *  - isphist_config
+        *  - omap3isp_h3a_aewb_config
+        *  - omap3isp_h3a_af_config
+        *  - omap3isp_hist_config
         */
        u32 buf_size;
        u16 config_counter;
index 208a7ec..9cd8f1a 100644 (file)
 
 static struct isp_format_info formats[] = {
        { V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
-         V4L2_MBUS_FMT_Y8_1X8, V4L2_PIX_FMT_GREY, 8, },
+         V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8,
+         V4L2_PIX_FMT_GREY, 8, },
+       { V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y10_1X10,
+         V4L2_MBUS_FMT_Y10_1X10, V4L2_MBUS_FMT_Y8_1X8,
+         V4L2_PIX_FMT_Y10, 10, },
+       { V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y10_1X10,
+         V4L2_MBUS_FMT_Y12_1X12, V4L2_MBUS_FMT_Y8_1X8,
+         V4L2_PIX_FMT_Y12, 12, },
+       { V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
+         V4L2_MBUS_FMT_SBGGR8_1X8, V4L2_MBUS_FMT_SBGGR8_1X8,
+         V4L2_PIX_FMT_SBGGR8, 8, },
+       { V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
+         V4L2_MBUS_FMT_SGBRG8_1X8, V4L2_MBUS_FMT_SGBRG8_1X8,
+         V4L2_PIX_FMT_SGBRG8, 8, },
+       { V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
+         V4L2_MBUS_FMT_SGRBG8_1X8, V4L2_MBUS_FMT_SGRBG8_1X8,
+         V4L2_PIX_FMT_SGRBG8, 8, },
+       { V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
+         V4L2_MBUS_FMT_SRGGB8_1X8, V4L2_MBUS_FMT_SRGGB8_1X8,
+         V4L2_PIX_FMT_SRGGB8, 8, },
        { V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8,
-         V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
+         V4L2_MBUS_FMT_SGRBG10_1X10, 0,
+         V4L2_PIX_FMT_SGRBG10DPCM8, 8, },
        { V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
-         V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_PIX_FMT_SBGGR10, 10, },
+         V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR8_1X8,
+         V4L2_PIX_FMT_SBGGR10, 10, },
        { V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG10_1X10,
-         V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_PIX_FMT_SGBRG10, 10, },
+         V4L2_MBUS_FMT_SGBRG10_1X10, V4L2_MBUS_FMT_SGBRG8_1X8,
+         V4L2_PIX_FMT_SGBRG10, 10, },
        { V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG10_1X10,
-         V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_PIX_FMT_SGRBG10, 10, },
+         V4L2_MBUS_FMT_SGRBG10_1X10, V4L2_MBUS_FMT_SGRBG8_1X8,
+         V4L2_PIX_FMT_SGRBG10, 10, },
        { V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
-         V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_PIX_FMT_SRGGB10, 10, },
+         V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB8_1X8,
+         V4L2_PIX_FMT_SRGGB10, 10, },
        { V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR10_1X10,
-         V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_PIX_FMT_SBGGR12, 12, },
+         V4L2_MBUS_FMT_SBGGR12_1X12, V4L2_MBUS_FMT_SBGGR8_1X8,
+         V4L2_PIX_FMT_SBGGR12, 12, },
        { V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG10_1X10,
-         V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_PIX_FMT_SGBRG12, 12, },
+         V4L2_MBUS_FMT_SGBRG12_1X12, V4L2_MBUS_FMT_SGBRG8_1X8,
+         V4L2_PIX_FMT_SGBRG12, 12, },
        { V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG10_1X10,
-         V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_PIX_FMT_SGRBG12, 12, },
+         V4L2_MBUS_FMT_SGRBG12_1X12, V4L2_MBUS_FMT_SGRBG8_1X8,
+         V4L2_PIX_FMT_SGRBG12, 12, },
        { V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB10_1X10,
-         V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_PIX_FMT_SRGGB12, 12, },
+         V4L2_MBUS_FMT_SRGGB12_1X12, V4L2_MBUS_FMT_SRGGB8_1X8,
+         V4L2_PIX_FMT_SRGGB12, 12, },
        { V4L2_MBUS_FMT_UYVY8_1X16, V4L2_MBUS_FMT_UYVY8_1X16,
-         V4L2_MBUS_FMT_UYVY8_1X16, V4L2_PIX_FMT_UYVY, 16, },
+         V4L2_MBUS_FMT_UYVY8_1X16, 0,
+         V4L2_PIX_FMT_UYVY, 16, },
        { V4L2_MBUS_FMT_YUYV8_1X16, V4L2_MBUS_FMT_YUYV8_1X16,
-         V4L2_MBUS_FMT_YUYV8_1X16, V4L2_PIX_FMT_YUYV, 16, },
+         V4L2_MBUS_FMT_YUYV8_1X16, 0,
+         V4L2_PIX_FMT_YUYV, 16, },
 };
 
 const struct isp_format_info *
@@ -85,6 +115,37 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
        return NULL;
 }
 
+/*
+ * Decide whether desired output pixel code can be obtained with
+ * the lane shifter by shifting the input pixel code.
+ * @in: input pixelcode to shifter
+ * @out: output pixelcode from shifter
+ * @additional_shift: # of bits the sensor's LSB is offset from CAMEXT[0]
+ *
+ * return true if the combination is possible
+ * return false otherwise
+ */
+static bool isp_video_is_shiftable(enum v4l2_mbus_pixelcode in,
+               enum v4l2_mbus_pixelcode out,
+               unsigned int additional_shift)
+{
+       const struct isp_format_info *in_info, *out_info;
+
+       if (in == out)
+               return true;
+
+       in_info = omap3isp_video_format_info(in);
+       out_info = omap3isp_video_format_info(out);
+
+       if ((in_info->flavor == 0) || (out_info->flavor == 0))
+               return false;
+
+       if (in_info->flavor != out_info->flavor)
+               return false;
+
+       return in_info->bpp - out_info->bpp + additional_shift <= 6;
+}
+
 /*
  * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
  * @video: ISP video instance
@@ -235,6 +296,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
                return -EPIPE;
 
        while (1) {
+               unsigned int shifter_link;
                /* Retrieve the sink format */
                pad = &subdev->entity.pads[0];
                if (!(pad->flags & MEDIA_PAD_FL_SINK))
@@ -263,6 +325,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
                                return -ENOSPC;
                }
 
+               /* If sink pad is on CCDC, the link has the lane shifter
+                * in the middle of it. */
+               shifter_link = subdev == &isp->isp_ccdc.subdev;
+
                /* Retrieve the source format */
                pad = media_entity_remote_source(pad);
                if (pad == NULL ||
@@ -278,10 +344,24 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
                        return -EPIPE;
 
                /* Check if the two ends match */
-               if (fmt_source.format.code != fmt_sink.format.code ||
-                   fmt_source.format.width != fmt_sink.format.width ||
+               if (fmt_source.format.width != fmt_sink.format.width ||
                    fmt_source.format.height != fmt_sink.format.height)
                        return -EPIPE;
+
+               if (shifter_link) {
+                       unsigned int parallel_shift = 0;
+                       if (isp->isp_ccdc.input == CCDC_INPUT_PARALLEL) {
+                               struct isp_parallel_platform_data *pdata =
+                                       &((struct isp_v4l2_subdevs_group *)
+                                             subdev->host_priv)->bus.parallel;
+                               parallel_shift = pdata->data_lane_shift * 2;
+                       }
+                       if (!isp_video_is_shiftable(fmt_source.format.code,
+                                               fmt_sink.format.code,
+                                               parallel_shift))
+                               return -EPIPE;
+               } else if (fmt_source.format.code != fmt_sink.format.code)
+                       return -EPIPE;
        }
 
        return 0;
index 524a1ac..911bea6 100644 (file)
@@ -49,6 +49,8 @@ struct v4l2_pix_format;
  *     bits. Identical to @code if the format is 10 bits wide or less.
  * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
  *     format. Identical to @code if the format is not DPCM compressed.
+ * @flavor: V4L2 media bus format code for the same pixel layout but
+ *     shifted to be 8 bits per pixel. =0 if format is not shiftable.
  * @pixelformat: V4L2 pixel format FCC identifier
  * @bpp: Bits per pixel
  */
@@ -56,6 +58,7 @@ struct isp_format_info {
        enum v4l2_mbus_pixelcode code;
        enum v4l2_mbus_pixelcode truncated;
        enum v4l2_mbus_pixelcode uncompressed;
+       enum v4l2_mbus_pixelcode flavor;
        u32 pixelformat;
        unsigned int bpp;
 };
index 95f8b4e..d142b40 100644 (file)
@@ -527,7 +527,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
        if (ret)
                return ret;
 
-       if (vb2_is_streaming(&fimc->vid_cap.vbq) || fimc_capture_active(fimc))
+       if (vb2_is_busy(&fimc->vid_cap.vbq) || fimc_capture_active(fimc))
                return -EBUSY;
 
        frame = &ctx->d_frame;
@@ -539,8 +539,10 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
                return -EINVAL;
        }
 
-       for (i = 0; i < frame->fmt->colplanes; i++)
-               frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
+       for (i = 0; i < frame->fmt->colplanes; i++) {
+               frame->payload[i] =
+                       (pix->width * pix->height * frame->fmt->depth[i]) >> 3;
+       }
 
        /* Output DMA frame pixel size and offsets. */
        frame->f_width = pix->plane_fmt[0].bytesperline * 8
index 6c919b3..dc91a85 100644 (file)
@@ -361,10 +361,20 @@ static void fimc_capture_irq_handler(struct fimc_dev *fimc)
 {
        struct fimc_vid_cap *cap = &fimc->vid_cap;
        struct fimc_vid_buffer *v_buf;
+       struct timeval *tv;
+       struct timespec ts;
 
        if (!list_empty(&cap->active_buf_q) &&
            test_bit(ST_CAPT_RUN, &fimc->state)) {
+               ktime_get_real_ts(&ts);
+
                v_buf = active_queue_pop(cap);
+
+               tv = &v_buf->vb.v4l2_buf.timestamp;
+               tv->tv_sec = ts.tv_sec;
+               tv->tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+               v_buf->vb.v4l2_buf.sequence = cap->frame_count++;
+
                vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
        }
 
@@ -758,7 +768,7 @@ static void fimc_unlock(struct vb2_queue *vq)
        mutex_unlock(&ctx->fimc_dev->lock);
 }
 
-struct vb2_ops fimc_qops = {
+static struct vb2_ops fimc_qops = {
        .queue_setup     = fimc_queue_setup,
        .buf_prepare     = fimc_buf_prepare,
        .buf_queue       = fimc_buf_queue,
@@ -927,23 +937,23 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
        pix->num_planes = fmt->memplanes;
        pix->colorspace = V4L2_COLORSPACE_JPEG;
 
-       for (i = 0; i < pix->num_planes; ++i) {
-               int bpl = pix->plane_fmt[i].bytesperline;
 
-               dbg("[%d] bpl: %d, depth: %d, w: %d, h: %d",
-                   i, bpl, fmt->depth[i], pix->width, pix->height);
+       for (i = 0; i < pix->num_planes; ++i) {
+               u32 bpl = pix->plane_fmt[i].bytesperline;
+               u32 *sizeimage = &pix->plane_fmt[i].sizeimage;
 
-               if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width)
-                       bpl = (pix->width * fmt->depth[0]) >> 3;
+               if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
+                       bpl = pix->width; /* Planar */
 
-               if (!pix->plane_fmt[i].sizeimage)
-                       pix->plane_fmt[i].sizeimage = pix->height * bpl;
+               if (fmt->colplanes == 1 && /* Packed */
+                   (bpl == 0 || ((bpl * 8) / fmt->depth[i]) < pix->width))
+                       bpl = (pix->width * fmt->depth[0]) / 8;
 
-               pix->plane_fmt[i].bytesperline = bpl;
+               if (i == 0) /* Same bytesperline for each plane. */
+                       mod_x = bpl;
 
-               dbg("[%d]: bpl: %d, sizeimage: %d",
-                   i, pix->plane_fmt[i].bytesperline,
-                   pix->plane_fmt[i].sizeimage);
+               pix->plane_fmt[i].bytesperline = mod_x;
+               *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8;
        }
 
        return 0;
@@ -965,7 +975,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
 
        vq = v4l2_m2m_get_vq(ctx->m2m_ctx, f->type);
 
-       if (vb2_is_streaming(vq)) {
+       if (vb2_is_busy(vq)) {
                v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type);
                return -EBUSY;
        }
@@ -985,8 +995,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
        if (!frame->fmt)
                return -EINVAL;
 
-       for (i = 0; i < frame->fmt->colplanes; i++)
-               frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height;
+       for (i = 0; i < frame->fmt->colplanes; i++) {
+               frame->payload[i] =
+                       (pix->width * pix->height * frame->fmt->depth[i]) / 8;
+       }
 
        frame->f_width  = pix->plane_fmt[0].bytesperline * 8 /
                frame->fmt->depth[0];
@@ -1750,7 +1762,7 @@ static int __devexit fimc_remove(struct platform_device *pdev)
 }
 
 /* Image pixel limits, similar across several FIMC HW revisions. */
-static struct fimc_pix_limit s5p_pix_limit[3] = {
+static struct fimc_pix_limit s5p_pix_limit[4] = {
        [0] = {
                .scaler_en_w    = 3264,
                .scaler_dis_w   = 8192,
@@ -1775,6 +1787,14 @@ static struct fimc_pix_limit s5p_pix_limit[3] = {
                .out_rot_en_w   = 1280,
                .out_rot_dis_w  = 1920,
        },
+       [3] = {
+               .scaler_en_w    = 1920,
+               .scaler_dis_w   = 8192,
+               .in_rot_en_h    = 1366,
+               .in_rot_dis_w   = 8192,
+               .out_rot_en_w   = 1366,
+               .out_rot_dis_w  = 1920,
+       },
 };
 
 static struct samsung_fimc_variant fimc0_variant_s5p = {
@@ -1827,7 +1847,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
        .pix_limit       = &s5p_pix_limit[2],
 };
 
-static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
+static struct samsung_fimc_variant fimc0_variant_exynos4 = {
        .pix_hoff        = 1,
        .has_inp_rot     = 1,
        .has_out_rot     = 1,
@@ -1840,7 +1860,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
        .pix_limit       = &s5p_pix_limit[1],
 };
 
-static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
+static struct samsung_fimc_variant fimc2_variant_exynos4 = {
        .pix_hoff        = 1,
        .has_cistatus2   = 1,
        .has_mainscaler_ext = 1,
@@ -1848,7 +1868,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
        .min_out_pixsize = 16,
        .hor_offs_align  = 1,
        .out_buf_count   = 32,
-       .pix_limit       = &s5p_pix_limit[2],
+       .pix_limit       = &s5p_pix_limit[3],
 };
 
 /* S5PC100 */
@@ -1874,12 +1894,12 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = {
 };
 
 /* S5PV310, S5PC210 */
-static struct samsung_fimc_driverdata fimc_drvdata_s5pv310 = {
+static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = {
        .variant = {
-               [0] = &fimc0_variant_s5pv310,
-               [1] = &fimc0_variant_s5pv310,
-               [2] = &fimc0_variant_s5pv310,
-               [3] = &fimc2_variant_s5pv310,
+               [0] = &fimc0_variant_exynos4,
+               [1] = &fimc0_variant_exynos4,
+               [2] = &fimc0_variant_exynos4,
+               [3] = &fimc2_variant_exynos4,
        },
        .num_entities = 4,
        .lclk_frequency = 166000000UL,
@@ -1893,8 +1913,8 @@ static struct platform_device_id fimc_driver_ids[] = {
                .name           = "s5pv210-fimc",
                .driver_data    = (unsigned long)&fimc_drvdata_s5pv210,
        }, {
-               .name           = "s5pv310-fimc",
-               .driver_data    = (unsigned long)&fimc_drvdata_s5pv310,
+               .name           = "exynos4-fimc",
+               .driver_data    = (unsigned long)&fimc_drvdata_exynos4,
        },
        {},
 };
index 3fe54bf..134e86b 100644 (file)
@@ -922,7 +922,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
                        /* Try 2560x1920, 1280x960, 640x480, 320x240 */
                        mf.width        = 2560 >> shift;
                        mf.height       = 1920 >> shift;
-                       ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video,
+                       ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
                                                         s_mbus_fmt, &mf);
                        if (ret < 0)
                                return ret;
@@ -1224,7 +1224,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
        struct v4l2_cropcap cap;
        int ret;
 
-       ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video,
+       ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
                                         s_mbus_fmt, mf);
        if (ret < 0)
                return ret;
@@ -1254,7 +1254,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
                tmp_h = min(2 * tmp_h, max_height);
                mf->width = tmp_w;
                mf->height = tmp_h;
-               ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video,
+               ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
                                                 s_mbus_fmt, mf);
                dev_geo(dev, "Camera scaled to %ux%u\n",
                        mf->width, mf->height);
@@ -1658,7 +1658,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
        mf.code         = xlate->code;
        mf.colorspace   = pix->colorspace;
 
-       ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video, try_mbus_fmt, &mf);
+       ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video, try_mbus_fmt, &mf);
        if (ret < 0)
                return ret;
 
@@ -1682,7 +1682,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
                         */
                        mf.width = 2560;
                        mf.height = 1920;
-                       ret = v4l2_device_call_until_err(sd->v4l2_dev, 0, video,
+                       ret = v4l2_device_call_until_err(sd->v4l2_dev, (long)icd, video,
                                                         try_mbus_fmt, &mf);
                        if (ret < 0) {
                                /* Shouldn't actually happen... */
index dd1b81b..98b8748 100644 (file)
@@ -38,6 +38,8 @@ struct sh_csi2 {
        void __iomem                    *base;
        struct platform_device          *pdev;
        struct sh_csi2_client_config    *client;
+       unsigned long (*query_bus_param)(struct soc_camera_device *);
+       int (*set_bus_param)(struct soc_camera_device *, unsigned long);
 };
 
 static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
@@ -208,6 +210,7 @@ static int sh_csi2_notify(struct notifier_block *nb,
        case BUS_NOTIFY_BOUND_DRIVER:
                snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s",
                         dev_name(v4l2_dev->dev), ".mipi-csi");
+               priv->subdev.grp_id = (long)icd;
                ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev);
                dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
                if (ret < 0)
@@ -215,6 +218,8 @@ static int sh_csi2_notify(struct notifier_block *nb,
 
                priv->client = pdata->clients + i;
 
+               priv->set_bus_param             = icd->ops->set_bus_param;
+               priv->query_bus_param           = icd->ops->query_bus_param;
                icd->ops->set_bus_param         = sh_csi2_set_bus_param;
                icd->ops->query_bus_param       = sh_csi2_query_bus_param;
 
@@ -226,8 +231,10 @@ static int sh_csi2_notify(struct notifier_block *nb,
                priv->client = NULL;
 
                /* Driver is about to be unbound */
-               icd->ops->set_bus_param         = NULL;
-               icd->ops->query_bus_param       = NULL;
+               icd->ops->set_bus_param         = priv->set_bus_param;
+               icd->ops->query_bus_param       = priv->query_bus_param;
+               priv->set_bus_param             = NULL;
+               priv->query_bus_param           = NULL;
 
                v4l2_device_unregister_subdev(&priv->subdev);
 
index 4628448..3973f9a 100644 (file)
@@ -996,10 +996,11 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
 {
        struct i2c_client *client =
                to_i2c_client(to_soc_camera_control(icd));
+       struct i2c_adapter *adap = client->adapter;
        dev_set_drvdata(&icd->dev, NULL);
        v4l2_device_unregister_subdev(i2c_get_clientdata(client));
        i2c_unregister_device(client);
-       i2c_put_adapter(client->adapter);
+       i2c_put_adapter(adap);
 }
 #else
 #define soc_camera_init_i2c(icd, icl)  (-ENODEV)
@@ -1071,6 +1072,9 @@ static int soc_camera_probe(struct device *dev)
                }
        }
 
+       sd = soc_camera_to_subdev(icd);
+       sd->grp_id = (long)icd;
+
        /* At this point client .probe() should have run already */
        ret = soc_camera_init_user_formats(icd);
        if (ret < 0)
@@ -1092,7 +1096,6 @@ static int soc_camera_probe(struct device *dev)
                goto evidstart;
 
        /* Try to improve our guess of a reasonable window format */
-       sd = soc_camera_to_subdev(icd);
        if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
                icd->user_width         = mf.width;
                icd->user_height        = mf.height;
index 498e674..6dc7196 100644 (file)
@@ -389,7 +389,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
        video_get(vdev);
        mutex_unlock(&videodev_lock);
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
+       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+           vdev->vfl_type != VFL_TYPE_SUBDEV) {
                entity = media_entity_get(&vdev->entity);
                if (!entity) {
                        ret = -EBUSY;
@@ -415,7 +416,8 @@ err:
        /* decrease the refcount in case of an error */
        if (ret) {
 #if defined(CONFIG_MEDIA_CONTROLLER)
-               if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
+               if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+                   vdev->vfl_type != VFL_TYPE_SUBDEV)
                        media_entity_put(entity);
 #endif
                video_put(vdev);
@@ -437,7 +439,8 @@ static int v4l2_release(struct inode *inode, struct file *filp)
                        mutex_unlock(vdev->lock);
        }
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
+       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+           vdev->vfl_type != VFL_TYPE_SUBDEV)
                media_entity_put(&vdev->entity);
 #endif
        /* decrease the refcount unconditionally since the release()
@@ -686,7 +689,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
        /* Part 5: Register the entity. */
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev) {
+       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+           vdev->vfl_type != VFL_TYPE_SUBDEV) {
                vdev->entity.type = MEDIA_ENT_T_DEVNODE_V4L;
                vdev->entity.name = vdev->name;
                vdev->entity.v4l.major = VIDEO_MAJOR;
@@ -733,7 +737,8 @@ void video_unregister_device(struct video_device *vdev)
                return;
 
 #if defined(CONFIG_MEDIA_CONTROLLER)
-       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev)
+       if (vdev->v4l2_dev && vdev->v4l2_dev->mdev &&
+           vdev->vfl_type != VFL_TYPE_SUBDEV)
                media_device_unregister_entity(&vdev->entity);
 #endif
 
index 6698c77..6ba1461 100644 (file)
@@ -37,6 +37,9 @@ module_param(debug, int, 0644);
 #define call_qop(q, op, args...)                                       \
        (((q)->ops->op) ? ((q)->ops->op(args)) : 0)
 
+#define V4L2_BUFFER_STATE_FLAGS        (V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED | \
+                                V4L2_BUF_FLAG_DONE | V4L2_BUF_FLAG_ERROR)
+
 /**
  * __vb2_buf_mem_alloc() - allocate video memory for the given buffer
  */
@@ -51,7 +54,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb,
        for (plane = 0; plane < vb->num_planes; ++plane) {
                mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane],
                                        plane_sizes[plane]);
-               if (!mem_priv)
+               if (IS_ERR_OR_NULL(mem_priv))
                        goto free;
 
                /* Associate allocator private data with this plane */
@@ -284,7 +287,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
        struct vb2_queue *q = vb->vb2_queue;
        int ret = 0;
 
-       /* Copy back data such as timestamp, input, etc. */
+       /* Copy back data such as timestamp, flags, input, etc. */
        memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
        b->input = vb->v4l2_buf.input;
        b->reserved = vb->v4l2_buf.reserved;
@@ -313,7 +316,10 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
                        b->m.userptr = vb->v4l2_planes[0].m.userptr;
        }
 
-       b->flags = 0;
+       /*
+        * Clear any buffer state related flags.
+        */
+       b->flags &= ~V4L2_BUFFER_STATE_FLAGS;
 
        switch (vb->state) {
        case VB2_BUF_STATE_QUEUED:
@@ -519,6 +525,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
        num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
        memset(plane_sizes, 0, sizeof(plane_sizes));
        memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx));
+       q->memory = req->memory;
 
        /*
         * Ask the driver how many buffers and planes per buffer it requires.
@@ -560,8 +567,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
                ret = num_buffers;
        }
 
-       q->memory = req->memory;
-
        /*
         * Return the number of successfully allocated buffers
         * to the userspace.
@@ -715,6 +720,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b,
 
        vb->v4l2_buf.field = b->field;
        vb->v4l2_buf.timestamp = b->timestamp;
+       vb->v4l2_buf.input = b->input;
+       vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS;
 
        return 0;
 }
index 58205d5..a790a5f 100644 (file)
@@ -46,7 +46,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
                                        GFP_KERNEL);
        if (!buf->vaddr) {
                dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
-                       buf->size);
+                       size);
                kfree(buf);
                return ERR_PTR(-ENOMEM);
        }
index 7054a7a..de5c159 100644 (file)
@@ -47,7 +47,7 @@ enum v4l2_mbus_pixelcode {
        V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007,
        V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008,
 
-       /* YUV (including grey) - next is 0x2013 */
+       /* YUV (including grey) - next is 0x2014 */
        V4L2_MBUS_FMT_Y8_1X8 = 0x2001,
        V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
        V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003,
@@ -60,6 +60,7 @@ enum v4l2_mbus_pixelcode {
        V4L2_MBUS_FMT_Y10_1X10 = 0x200a,
        V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b,
        V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c,
+       V4L2_MBUS_FMT_Y12_1X12 = 0x2013,
        V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f,
        V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010,
        V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011,
@@ -67,9 +68,11 @@ enum v4l2_mbus_pixelcode {
        V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d,
        V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
 
-       /* Bayer - next is 0x3013 */
+       /* Bayer - next is 0x3015 */
        V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
+       V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013,
        V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002,
+       V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014,
        V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b,
        V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c,
        V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009,
index aa6c393..be82c8e 100644 (file)
@@ -308,6 +308,7 @@ struct v4l2_pix_format {
 #define V4L2_PIX_FMT_Y4      v4l2_fourcc('Y', '0', '4', ' ') /*  4  Greyscale     */
 #define V4L2_PIX_FMT_Y6      v4l2_fourcc('Y', '0', '6', ' ') /*  6  Greyscale     */
 #define V4L2_PIX_FMT_Y10     v4l2_fourcc('Y', '1', '0', ' ') /* 10  Greyscale     */
+#define V4L2_PIX_FMT_Y12     v4l2_fourcc('Y', '1', '2', ' ') /* 12  Greyscale     */
 #define V4L2_PIX_FMT_Y16     v4l2_fourcc('Y', '1', '6', ' ') /* 16  Greyscale     */
 
 /* Palette formats */
index bd102cf..d61febf 100644 (file)
@@ -163,7 +163,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
 ({                                                                     \
        struct v4l2_subdev *__sd;                                       \
        __v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \
-                                               f, args...);            \
+                                               f , ##args);            \
 })
 
 /* Call the specified callback for all subdevs matching grp_id (if 0, then