提交 7fcaa9aa 编写于 作者: L Linus Torvalds

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

* '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
...@@ -294,6 +294,7 @@ ...@@ -294,6 +294,7 @@
<!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml"> <!ENTITY sub-srggb10 SYSTEM "v4l/pixfmt-srggb10.xml">
<!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml"> <!ENTITY sub-srggb8 SYSTEM "v4l/pixfmt-srggb8.xml">
<!ENTITY sub-y10 SYSTEM "v4l/pixfmt-y10.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-pixfmt SYSTEM "v4l/pixfmt.xml">
<!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml"> <!ENTITY sub-cropcap SYSTEM "v4l/vidioc-cropcap.xml">
<!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml"> <!ENTITY sub-dbg-g-register SYSTEM "v4l/vidioc-dbg-g-register.xml">
......
...@@ -34,7 +34,7 @@ ...@@ -34,7 +34,7 @@
<varlistentry> <varlistentry>
<term><parameter>request</parameter></term> <term><parameter>request</parameter></term>
<listitem> <listitem>
<para>MEDIA_IOC_ENUM_LINKS</para> <para>MEDIA_IOC_SETUP_LINK</para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
......
<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>
...@@ -696,6 +696,7 @@ information.</para> ...@@ -696,6 +696,7 @@ information.</para>
&sub-packed-yuv; &sub-packed-yuv;
&sub-grey; &sub-grey;
&sub-y10; &sub-y10;
&sub-y12;
&sub-y16; &sub-y16;
&sub-yuyv; &sub-yuyv;
&sub-uyvy; &sub-uyvy;
......
...@@ -456,6 +456,23 @@ ...@@ -456,6 +456,23 @@
<entry>b<subscript>1</subscript></entry> <entry>b<subscript>1</subscript></entry>
<entry>b<subscript>0</subscript></entry> <entry>b<subscript>0</subscript></entry>
</row> </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"> <row id="V4L2-MBUS-FMT-SGRBG8-1X8">
<entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry> <entry>V4L2_MBUS_FMT_SGRBG8_1X8</entry>
<entry>0x3002</entry> <entry>0x3002</entry>
...@@ -473,6 +490,23 @@ ...@@ -473,6 +490,23 @@
<entry>g<subscript>1</subscript></entry> <entry>g<subscript>1</subscript></entry>
<entry>g<subscript>0</subscript></entry> <entry>g<subscript>0</subscript></entry>
</row> </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"> <row id="V4L2-MBUS-FMT-SBGGR10-DPCM8-1X8">
<entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry> <entry>V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8</entry>
<entry>0x300b</entry> <entry>0x300b</entry>
...@@ -2159,6 +2193,31 @@ ...@@ -2159,6 +2193,31 @@
<entry>u<subscript>1</subscript></entry> <entry>u<subscript>1</subscript></entry>
<entry>u<subscript>0</subscript></entry> <entry>u<subscript>0</subscript></entry>
</row> </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"> <row id="V4L2-MBUS-FMT-UYVY8-1X16">
<entry>V4L2_MBUS_FMT_UYVY8_1X16</entry> <entry>V4L2_MBUS_FMT_UYVY8_1X16</entry>
<entry>0x200f</entry> <entry>0x200f</entry>
......
...@@ -37,7 +37,7 @@ Generic scaling / cropping scheme ...@@ -37,7 +37,7 @@ Generic scaling / cropping scheme
-1'- -1'-
In the above chart minuses and slashes represent "real" data amounts, points and 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. mapped back onto the client's source plane.
Such a configuration can be produced by user requests: Such a configuration can be produced by user requests:
...@@ -65,7 +65,7 @@ Do not touch input rectangle - it is already optimal. ...@@ -65,7 +65,7 @@ Do not touch input rectangle - it is already optimal.
1. Calculate current sensor scales: 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 2. Calculate "effective" input crop (sensor subwindow) - CEU crop scaled back at
current sensor scales onto input window - this is user S_CROP: current sensor scales onto input window - this is user S_CROP:
...@@ -80,7 +80,7 @@ window: ...@@ -80,7 +80,7 @@ window:
4. Calculate sensor output window by applying combined scales to real input 4. Calculate sensor output window by applying combined scales to real input
window: 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. 5. Apply iterative sensor S_FMT for sensor output window.
......
...@@ -533,16 +533,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq) ...@@ -533,16 +533,7 @@ int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
if (tda_fail(ret)) if (tda_fail(ret))
goto fail; goto fail;
regs[R_MPD] = (0x77 & pd); regs[R_MPD] = (0x7f & pd);
switch (priv->mode) {
case TDA18271_ANALOG:
regs[R_MPD] &= ~0x08;
break;
case TDA18271_DIGITAL:
regs[R_MPD] |= 0x08;
break;
}
div = ((d * (freq / 1000)) << 7) / 125; div = ((d * (freq / 1000)) << 7) / 125;
......
...@@ -579,8 +579,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq) ...@@ -579,8 +579,8 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
#define RF3 2 #define RF3 2
u32 rf_default[3]; u32 rf_default[3];
u32 rf_freq[3]; u32 rf_freq[3];
u8 prog_cal[3]; s32 prog_cal[3];
u8 prog_tab[3]; s32 prog_tab[3];
i = tda18271_lookup_rf_band(fe, &freq, NULL); 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) ...@@ -602,32 +602,33 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
return bcal; return bcal;
tda18271_calc_rf_cal(fe, &rf_freq[rf]); tda18271_calc_rf_cal(fe, &rf_freq[rf]);
prog_tab[rf] = regs[R_EB14]; prog_tab[rf] = (s32)regs[R_EB14];
if (1 == bcal) 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 else
prog_cal[rf] = prog_tab[rf]; prog_cal[rf] = prog_tab[rf];
switch (rf) { switch (rf) {
case RF1: case RF1:
map[i].rf_a1 = 0; 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; map[i].rf1 = rf_freq[RF1] / 1000;
break; break;
case RF2: case RF2:
dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) - dividend = (prog_cal[RF2] - prog_tab[RF2] -
(s32)(prog_cal[RF1] + prog_tab[RF1]); prog_cal[RF1] + prog_tab[RF1]);
divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000; divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
map[i].rf_a1 = (dividend / divisor); map[i].rf_a1 = (dividend / divisor);
map[i].rf2 = rf_freq[RF2] / 1000; map[i].rf2 = rf_freq[RF2] / 1000;
break; break;
case RF3: case RF3:
dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) - dividend = (prog_cal[RF3] - prog_tab[RF3] -
(s32)(prog_cal[RF2] + prog_tab[RF2]); prog_cal[RF2] + prog_tab[RF2]);
divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000; divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
map[i].rf_a2 = (dividend / divisor); 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; map[i].rf3 = rf_freq[RF3] / 1000;
break; break;
default: default:
......
...@@ -229,8 +229,7 @@ static struct tda18271_map tda18271c2_km[] = { ...@@ -229,8 +229,7 @@ static struct tda18271_map tda18271c2_km[] = {
static struct tda18271_map tda18271_rf_band[] = { static struct tda18271_map tda18271_rf_band[] = {
{ .rfmax = 47900, .val = 0x00 }, { .rfmax = 47900, .val = 0x00 },
{ .rfmax = 61100, .val = 0x01 }, { .rfmax = 61100, .val = 0x01 },
/* { .rfmax = 152600, .val = 0x02 }, */ { .rfmax = 152600, .val = 0x02 },
{ .rfmax = 121200, .val = 0x02 },
{ .rfmax = 164700, .val = 0x03 }, { .rfmax = 164700, .val = 0x03 },
{ .rfmax = 203500, .val = 0x04 }, { .rfmax = 203500, .val = 0x04 },
{ .rfmax = 457800, .val = 0x05 }, { .rfmax = 457800, .val = 0x05 },
...@@ -448,7 +447,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { ...@@ -448,7 +447,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
{ .rfmax = 150000, .val = 0xb0 }, { .rfmax = 150000, .val = 0xb0 },
{ .rfmax = 151000, .val = 0xb1 }, { .rfmax = 151000, .val = 0xb1 },
{ .rfmax = 152000, .val = 0xb7 }, { .rfmax = 152000, .val = 0xb7 },
{ .rfmax = 153000, .val = 0xbd }, { .rfmax = 152600, .val = 0xbd },
{ .rfmax = 154000, .val = 0x20 }, { .rfmax = 154000, .val = 0x20 },
{ .rfmax = 155000, .val = 0x22 }, { .rfmax = 155000, .val = 0x22 },
{ .rfmax = 156000, .val = 0x24 }, { .rfmax = 156000, .val = 0x24 },
...@@ -459,7 +458,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { ...@@ -459,7 +458,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
{ .rfmax = 161000, .val = 0x2d }, { .rfmax = 161000, .val = 0x2d },
{ .rfmax = 163000, .val = 0x2e }, { .rfmax = 163000, .val = 0x2e },
{ .rfmax = 164000, .val = 0x2f }, { .rfmax = 164000, .val = 0x2f },
{ .rfmax = 165000, .val = 0x30 }, { .rfmax = 164700, .val = 0x30 },
{ .rfmax = 166000, .val = 0x11 }, { .rfmax = 166000, .val = 0x11 },
{ .rfmax = 167000, .val = 0x12 }, { .rfmax = 167000, .val = 0x12 },
{ .rfmax = 168000, .val = 0x13 }, { .rfmax = 168000, .val = 0x13 },
...@@ -510,7 +509,8 @@ static struct tda18271_map tda18271c2_rf_cal[] = { ...@@ -510,7 +509,8 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
{ .rfmax = 236000, .val = 0x1b }, { .rfmax = 236000, .val = 0x1b },
{ .rfmax = 237000, .val = 0x1c }, { .rfmax = 237000, .val = 0x1c },
{ .rfmax = 240000, .val = 0x1d }, { .rfmax = 240000, .val = 0x1d },
{ .rfmax = 242000, .val = 0x1f }, { .rfmax = 242000, .val = 0x1e },
{ .rfmax = 244000, .val = 0x1f },
{ .rfmax = 247000, .val = 0x20 }, { .rfmax = 247000, .val = 0x20 },
{ .rfmax = 249000, .val = 0x21 }, { .rfmax = 249000, .val = 0x21 },
{ .rfmax = 252000, .val = 0x22 }, { .rfmax = 252000, .val = 0x22 },
...@@ -624,7 +624,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = { ...@@ -624,7 +624,7 @@ static struct tda18271_map tda18271c2_rf_cal[] = {
{ .rfmax = 453000, .val = 0x93 }, { .rfmax = 453000, .val = 0x93 },
{ .rfmax = 454000, .val = 0x94 }, { .rfmax = 454000, .val = 0x94 },
{ .rfmax = 456000, .val = 0x96 }, { .rfmax = 456000, .val = 0x96 },
{ .rfmax = 457000, .val = 0x98 }, { .rfmax = 457800, .val = 0x98 },
{ .rfmax = 461000, .val = 0x11 }, { .rfmax = 461000, .val = 0x11 },
{ .rfmax = 468000, .val = 0x12 }, { .rfmax = 468000, .val = 0x12 },
{ .rfmax = 472000, .val = 0x13 }, { .rfmax = 472000, .val = 0x13 },
......
...@@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug, ...@@ -38,7 +38,7 @@ MODULE_PARM_DESC(debug,
DEBSTATUS); DEBSTATUS);
#define DRIVER_VERSION "0.1" #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>" #define DRIVER_AUTHOR "Patrick Boettcher <patrick.boettcher@desy.de>"
struct flexcop_pci { struct flexcop_pci {
......
...@@ -362,7 +362,7 @@ config DVB_USB_LME2510 ...@@ -362,7 +362,7 @@ config DVB_USB_LME2510
config DVB_USB_TECHNISAT_USB2 config DVB_USB_TECHNISAT_USB2
tristate "Technisat DVB-S/S2 USB2.0 support" tristate "Technisat DVB-S/S2 USB2.0 support"
depends on DVB_USB depends on DVB_USB
select DVB_STB0899 if !DVB_FE_CUSTOMISE select DVB_STV090x if !DVB_FE_CUSTOMISE
select DVB_STB6100 if !DVB_FE_CUSTOMISE select DVB_STV6110x if !DVB_FE_CUSTOMISE
help help
Say Y here to support the Technisat USB2 DVB-S/S2 device Say Y here to support the Technisat USB2 DVB-S/S2 device
...@@ -2162,7 +2162,7 @@ struct dibx000_agc_config dib7090_agc_config[2] = { ...@@ -2162,7 +2162,7 @@ struct dibx000_agc_config dib7090_agc_config[2] = {
.agc1_pt3 = 98, .agc1_pt3 = 98,
.agc1_slope1 = 0, .agc1_slope1 = 0,
.agc1_slope2 = 167, .agc1_slope2 = 167,
.agc1_pt1 = 98, .agc2_pt1 = 98,
.agc2_pt2 = 255, .agc2_pt2 = 255,
.agc2_slope1 = 104, .agc2_slope1 = 104,
.agc2_slope2 = 0, .agc2_slope2 = 0,
...@@ -2440,11 +2440,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap) ...@@ -2440,11 +2440,11 @@ static int tfe7090pvr_frontend0_attach(struct dvb_usb_adapter *adap)
dib0700_set_i2c_speed(adap->dev, 340); dib0700_set_i2c_speed(adap->dev, 340);
adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]); adap->fe = dvb_attach(dib7000p_attach, &adap->dev->i2c_adap, 0x90, &tfe7090pvr_dib7000p_config[0]);
dib7090_slave_reset(adap->fe);
if (adap->fe == NULL) if (adap->fe == NULL)
return -ENODEV; return -ENODEV;
dib7090_slave_reset(adap->fe);
return 0; return 0;
} }
......
...@@ -378,7 +378,6 @@ EXPORT_SYMBOL_GPL(media_entity_create_link); ...@@ -378,7 +378,6 @@ EXPORT_SYMBOL_GPL(media_entity_create_link);
static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
{ {
const u32 mask = MEDIA_LNK_FL_ENABLED;
int ret; int ret;
/* Notify both entities. */ /* Notify both entities. */
...@@ -395,7 +394,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) ...@@ -395,7 +394,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags)
return ret; return ret;
} }
link->flags = (link->flags & ~mask) | (flags & mask); link->flags = flags;
link->reverse->flags = link->flags; link->reverse->flags = link->flags;
return 0; return 0;
...@@ -417,6 +416,7 @@ static int __media_entity_setup_link_notify(struct media_link *link, u32 flags) ...@@ -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) int __media_entity_setup_link(struct media_link *link, u32 flags)
{ {
const u32 mask = MEDIA_LNK_FL_ENABLED;
struct media_device *mdev; struct media_device *mdev;
struct media_entity *source, *sink; struct media_entity *source, *sink;
int ret = -EBUSY; int ret = -EBUSY;
...@@ -424,6 +424,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags) ...@@ -424,6 +424,10 @@ int __media_entity_setup_link(struct media_link *link, u32 flags)
if (link == NULL) if (link == NULL)
return -EINVAL; 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) if (link->flags & MEDIA_LNK_FL_IMMUTABLE)
return link->flags == flags ? 0 : -EINVAL; return link->flags == flags ? 0 : -EINVAL;
......
...@@ -875,7 +875,7 @@ config MX3_VIDEO ...@@ -875,7 +875,7 @@ config MX3_VIDEO
config VIDEO_MX3 config VIDEO_MX3
tristate "i.MX3x Camera Sensor Interface driver" tristate "i.MX3x Camera Sensor Interface driver"
depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA depends on VIDEO_DEV && MX3_IPU && SOC_CAMERA
select VIDEOBUF_DMA_CONTIG select VIDEOBUF2_DMA_CONTIG
select MX3_VIDEO select MX3_VIDEO
---help--- ---help---
This is a v4l2 driver for the i.MX3x Camera Sensor Interface This is a v4l2 driver for the i.MX3x Camera Sensor Interface
......
...@@ -350,9 +350,17 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister) ...@@ -350,9 +350,17 @@ void cx18_streams_cleanup(struct cx18 *cx, int unregister)
/* No struct video_device, but can have buffers allocated */ /* No struct video_device, but can have buffers allocated */
if (type == CX18_ENC_STREAM_TYPE_IDX) { if (type == CX18_ENC_STREAM_TYPE_IDX) {
/* If the module params didn't inhibit IDX ... */
if (cx->stream_buffers[type] != 0) { if (cx->stream_buffers[type] != 0) {
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; continue;
} }
......
...@@ -22,6 +22,7 @@ config VIDEO_CX23885 ...@@ -22,6 +22,7 @@ config VIDEO_CX23885
select DVB_CX24116 if !DVB_FE_CUSTOMISE select DVB_CX24116 if !DVB_FE_CUSTOMISE
select DVB_STV0900 if !DVB_FE_CUSTOMISE select DVB_STV0900 if !DVB_FE_CUSTOMISE
select DVB_DS3000 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_MT2131 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
......
...@@ -298,7 +298,7 @@ static unsigned long imx074_query_bus_param(struct soc_camera_device *icd) ...@@ -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, static int imx074_set_bus_param(struct soc_camera_device *icd,
unsigned long flags) unsigned long flags)
{ {
return -1; return -EINVAL;
} }
static struct soc_camera_ops imx074_ops = { static struct soc_camera_ops imx074_ops = {
......
...@@ -215,20 +215,21 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel) ...@@ -215,20 +215,21 @@ static u32 isp_set_xclk(struct isp_device *isp, u32 xclk, u8 xclksel)
} }
switch (xclksel) { switch (xclksel) {
case 0: case ISP_XCLK_A:
isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
ISPTCTRL_CTRL_DIVA_MASK, ISPTCTRL_CTRL_DIVA_MASK,
divisor << ISPTCTRL_CTRL_DIVA_SHIFT); divisor << ISPTCTRL_CTRL_DIVA_SHIFT);
dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n", dev_dbg(isp->dev, "isp_set_xclk(): cam_xclka set to %d Hz\n",
currentxclk); currentxclk);
break; break;
case 1: case ISP_XCLK_B:
isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL, isp_reg_clr_set(isp, OMAP3_ISP_IOMEM_MAIN, ISP_TCTRL_CTRL,
ISPTCTRL_CTRL_DIVB_MASK, ISPTCTRL_CTRL_DIVB_MASK,
divisor << ISPTCTRL_CTRL_DIVB_SHIFT); divisor << ISPTCTRL_CTRL_DIVB_SHIFT);
dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n", dev_dbg(isp->dev, "isp_set_xclk(): cam_xclkb set to %d Hz\n",
currentxclk); currentxclk);
break; break;
case ISP_XCLK_NONE:
default: default:
omap3isp_put(isp); omap3isp_put(isp);
dev_dbg(isp->dev, "ISP_ERR: isp_set_xclk(): Invalid requested " 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) ...@@ -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? */ /* 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); omap3isp_get(isp);
/* Stopping the clock. */ /* 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); omap3isp_put(isp);
isp->xclk_divisor[xclksel] = divisor; isp->xclk_divisor[xclksel - 1] = divisor;
omap3isp_put(isp); omap3isp_put(isp);
...@@ -285,7 +286,8 @@ static void isp_power_settings(struct isp_device *isp, int idle) ...@@ -285,7 +286,8 @@ static void isp_power_settings(struct isp_device *isp, int idle)
*/ */
void omap3isp_configure_bridge(struct isp_device *isp, void omap3isp_configure_bridge(struct isp_device *isp,
enum ccdc_input_entity input, 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; u32 ispctrl_val;
...@@ -298,9 +300,9 @@ void omap3isp_configure_bridge(struct isp_device *isp, ...@@ -298,9 +300,9 @@ void omap3isp_configure_bridge(struct isp_device *isp,
switch (input) { switch (input) {
case CCDC_INPUT_PARALLEL: case CCDC_INPUT_PARALLEL:
ispctrl_val |= ISPCTRL_PAR_SER_CLK_SEL_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->clk_pol << ISPCTRL_PAR_CLK_POL_SHIFT;
ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT; ispctrl_val |= pdata->bridge << ISPCTRL_PAR_BRIDGE_SHIFT;
shift += pdata->data_lane_shift * 2;
break; break;
case CCDC_INPUT_CSI2A: case CCDC_INPUT_CSI2A:
...@@ -319,6 +321,8 @@ void omap3isp_configure_bridge(struct isp_device *isp, ...@@ -319,6 +321,8 @@ void omap3isp_configure_bridge(struct isp_device *isp,
return; return;
} }
ispctrl_val |= ((shift/2) << ISPCTRL_SHIFT_SHIFT) & ISPCTRL_SHIFT_MASK;
ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK; ispctrl_val &= ~ISPCTRL_SYNC_DETECT_MASK;
ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE; ispctrl_val |= ISPCTRL_SYNC_DETECT_VSRISE;
...@@ -658,6 +662,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use) ...@@ -658,6 +662,8 @@ int omap3isp_pipeline_pm_use(struct media_entity *entity, int use)
/* Apply power change to connected non-nodes. */ /* Apply power change to connected non-nodes. */
ret = isp_pipeline_pm_power(entity, change); ret = isp_pipeline_pm_power(entity, change);
if (ret < 0)
entity->use_count -= change;
mutex_unlock(&entity->parent->graph_mutex); mutex_unlock(&entity->parent->graph_mutex);
...@@ -872,6 +878,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) ...@@ -872,6 +878,9 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
} }
} }
if (failure < 0)
isp->needs_reset = true;
return failure; return failure;
} }
...@@ -884,7 +893,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe) ...@@ -884,7 +893,8 @@ static int isp_pipeline_disable(struct isp_pipeline *pipe)
* single-shot or continuous mode. * single-shot or continuous mode.
* *
* Return 0 if successful, or the return value of the failed video::s_stream * 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, int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
enum isp_pipeline_stream_state state) enum isp_pipeline_stream_state state)
...@@ -895,7 +905,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, ...@@ -895,7 +905,9 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
ret = isp_pipeline_disable(pipe); ret = isp_pipeline_disable(pipe);
else else
ret = isp_pipeline_enable(pipe, state); ret = isp_pipeline_enable(pipe, state);
pipe->stream_state = state;
if (ret == 0 || state == ISP_PIPELINE_STREAM_STOPPED)
pipe->stream_state = state;
return ret; return ret;
} }
...@@ -1481,6 +1493,10 @@ void omap3isp_put(struct isp_device *isp) ...@@ -1481,6 +1493,10 @@ void omap3isp_put(struct isp_device *isp)
if (--isp->ref_count == 0) { if (--isp->ref_count == 0) {
isp_disable_interrupts(isp); isp_disable_interrupts(isp);
isp_save_ctx(isp); isp_save_ctx(isp);
if (isp->needs_reset) {
isp_reset(isp);
isp->needs_reset = false;
}
isp_disable_clocks(isp); isp_disable_clocks(isp);
} }
mutex_unlock(&isp->isp_mutex); mutex_unlock(&isp->isp_mutex);
......
...@@ -132,7 +132,6 @@ struct isp_reg { ...@@ -132,7 +132,6 @@ struct isp_reg {
/** /**
* struct isp_parallel_platform_data - Parallel interface platform data * 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 * @data_lane_shift: Data lane shifter
* 0 - CAMEXT[13:0] -> CAM[13:0] * 0 - CAMEXT[13:0] -> CAM[13:0]
* 1 - CAMEXT[13:2] -> CAM[11:0] * 1 - CAMEXT[13:2] -> CAM[11:0]
...@@ -146,7 +145,6 @@ struct isp_reg { ...@@ -146,7 +145,6 @@ struct isp_reg {
* ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian * ISPCTRL_PAR_BRIDGE_BENDIAN - Big endian
*/ */
struct isp_parallel_platform_data { struct isp_parallel_platform_data {
unsigned int width;
unsigned int data_lane_shift:2; unsigned int data_lane_shift:2;
unsigned int clk_pol:1; unsigned int clk_pol:1;
unsigned int bridge:4; unsigned int bridge:4;
...@@ -262,6 +260,7 @@ struct isp_device { ...@@ -262,6 +260,7 @@ struct isp_device {
/* ISP Obj */ /* ISP Obj */
spinlock_t stat_lock; /* common lock for statistic drivers */ spinlock_t stat_lock; /* common lock for statistic drivers */
struct mutex isp_mutex; /* For handling ref_count field */ struct mutex isp_mutex; /* For handling ref_count field */
bool needs_reset;
int has_context; int has_context;
int ref_count; int ref_count;
unsigned int autoidle; unsigned int autoidle;
...@@ -311,11 +310,12 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe, ...@@ -311,11 +310,12 @@ int omap3isp_pipeline_set_stream(struct isp_pipeline *pipe,
enum isp_pipeline_stream_state state); enum isp_pipeline_stream_state state);
void omap3isp_configure_bridge(struct isp_device *isp, void omap3isp_configure_bridge(struct isp_device *isp,
enum ccdc_input_entity input, 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_NONE 0
#define ISP_XCLK_A 0 #define ISP_XCLK_A 1
#define ISP_XCLK_B 1 #define ISP_XCLK_B 2
struct isp_device *omap3isp_get(struct isp_device *isp); struct isp_device *omap3isp_get(struct isp_device *isp);
void omap3isp_put(struct isp_device *isp); void omap3isp_put(struct isp_device *isp);
......
...@@ -43,6 +43,12 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh, ...@@ -43,6 +43,12 @@ __ccdc_get_format(struct isp_ccdc_device *ccdc, struct v4l2_subdev_fh *fh,
static const unsigned int ccdc_fmts[] = { static const unsigned int ccdc_fmts[] = {
V4L2_MBUS_FMT_Y8_1X8, 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_SGRBG10_1X10,
V4L2_MBUS_FMT_SRGGB10_1X10, V4L2_MBUS_FMT_SRGGB10_1X10,
V4L2_MBUS_FMT_SBGGR10_1X10, V4L2_MBUS_FMT_SBGGR10_1X10,
...@@ -1110,21 +1116,38 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc) ...@@ -1110,21 +1116,38 @@ static void ccdc_configure(struct isp_ccdc_device *ccdc)
struct isp_parallel_platform_data *pdata = NULL; struct isp_parallel_platform_data *pdata = NULL;
struct v4l2_subdev *sensor; struct v4l2_subdev *sensor;
struct v4l2_mbus_framefmt *format; 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; struct media_pad *pad;
unsigned long flags; unsigned long flags;
unsigned int shift;
u32 syn_mode; u32 syn_mode;
u32 ccdc_pattern; u32 ccdc_pattern;
if (ccdc->input == CCDC_INPUT_PARALLEL) { pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]);
pad = media_entity_remote_source(&ccdc->pads[CCDC_PAD_SINK]); sensor = media_entity_to_v4l2_subdev(pad->entity);
sensor = media_entity_to_v4l2_subdev(pad->entity); if (ccdc->input == CCDC_INPUT_PARALLEL)
pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv) pdata = &((struct isp_v4l2_subdevs_group *)sensor->host_priv)
->bus.parallel; ->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_config_sync_if(ccdc, &ccdc->syncif);
/* CCDC_PAD_SINK */ /* CCDC_PAD_SINK */
...@@ -1338,7 +1361,7 @@ static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc, ...@@ -1338,7 +1361,7 @@ static int ccdc_sbl_wait_idle(struct isp_ccdc_device *ccdc,
* @ccdc: Pointer to ISP CCDC device. * @ccdc: Pointer to ISP CCDC device.
* @event: Pointing which event trigger handler * @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. * zero otherwise.
*/ */
static int __ccdc_handle_stopping(struct isp_ccdc_device *ccdc, u32 event) 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) ...@@ -1618,7 +1641,7 @@ static int ccdc_video_queue(struct isp_video *video, struct isp_buffer *buffer)
ccdc_set_outaddr(ccdc, buffer->isp_addr); 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 * on the next CCDC interrupt if running in continuous mode (or when
* starting the stream). * starting the stream).
*/ */
......
...@@ -755,7 +755,7 @@ static struct preview_update update_attrs[] = { ...@@ -755,7 +755,7 @@ static struct preview_update update_attrs[] = {
* @configs - pointer to update config structure. * @configs - pointer to update config structure.
* @config - return pointer to appropriate structure field. * @config - return pointer to appropriate structure field.
* @bit - for which feature to return pointers. * @bit - for which feature to return pointers.
* Return size of coresponding prev_params member * Return size of corresponding prev_params member
*/ */
static u32 static u32
__preview_get_ptrs(struct prev_params *params, void **param, __preview_get_ptrs(struct prev_params *params, void **param,
......
...@@ -339,7 +339,7 @@ static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf) ...@@ -339,7 +339,7 @@ static int isp_video_buffer_prepare_user(struct isp_video_buffer *buf)
up_read(&current->mm->mmap_sem); up_read(&current->mm->mmap_sem);
if (ret != buf->npages) { if (ret != buf->npages) {
buf->npages = ret; buf->npages = ret < 0 ? 0 : ret;
isp_video_buffer_cleanup(buf); isp_video_buffer_cleanup(buf);
return -EFAULT; return -EFAULT;
} }
...@@ -408,8 +408,8 @@ static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf) ...@@ -408,8 +408,8 @@ static int isp_video_buffer_prepare_pfnmap(struct isp_video_buffer *buf)
* isp_video_buffer_prepare_vm_flags - Get VMA flags for a userspace address * 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 * 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 * that their flags match. The only flag that we need to care for at the moment
* VM_PFNMAP. * is VM_PFNMAP.
* *
* The buffer vm_flags field is set to the first VMA flags. * The buffer vm_flags field is set to the first VMA flags.
* *
......
...@@ -714,19 +714,50 @@ static void resizer_print_status(struct isp_res_device *res) ...@@ -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 * iw and ih are the input width and height after cropping. Those equations need
* to be satisfied exactly for the resizer to work correctly. * 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 * - 8-phase, 4-tap mode
* hrsz = ((iw - 7) * 256 - 16 - 32 * sph) / (ow - 1) * hrsz = ((iw - 7) * 256 + 255 - 16 - 32 * sph) / (ow - 1)
* vrsz = ((ih - 4) * 256 - 16 - 32 * spv) / (oh - 1) * vrsz = ((ih - 4) * 256 + 255 - 16 - 32 * spv) / (oh - 1)
* - 4-phase, 7-tap mode * - 4-phase, 7-tap mode
* hrsz = ((iw - 7) * 256 - 32 - 64 * sph) / (ow - 1) * hrsz = ((iw - 7) * 256 + 255 - 32 - 64 * sph) / (ow - 1)
* vrsz = ((ih - 7) * 256 - 32 - 64 * spv) / (oh - 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 * 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 ratio * cropped input size is not bigger than the uncropped input size.
* 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. * 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 * 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 * 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, ...@@ -775,6 +806,8 @@ static void resizer_calc_ratios(struct isp_res_device *res,
unsigned int max_width; unsigned int max_width;
unsigned int max_height; unsigned int max_height;
unsigned int width_alignment; unsigned int width_alignment;
unsigned int width;
unsigned int height;
/* /*
* Clamp the output height based on the hardware capabilities and * Clamp the output height based on the hardware capabilities and
...@@ -786,19 +819,22 @@ static void resizer_calc_ratios(struct isp_res_device *res, ...@@ -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); max_height = min_t(unsigned int, max_height, MAX_OUT_HEIGHT);
output->height = clamp(output->height, min_height, max_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); / (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, ratio->vert = clamp_t(unsigned int, ratio->vert,
MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
if (ratio->vert <= MID_RESIZE_VALUE) { if (ratio->vert <= MID_RESIZE_VALUE) {
upscaled_height = (output->height - 1) * ratio->vert upscaled_height = (output->height - 1) * ratio->vert
+ 32 * spv + 16; + 32 * spv + 16;
input->height = (upscaled_height >> 8) + 4; height = (upscaled_height >> 8) + 4;
} else { } else {
upscaled_height = (output->height - 1) * ratio->vert upscaled_height = (output->height - 1) * ratio->vert
+ 64 * spv + 32; + 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, ...@@ -854,20 +890,29 @@ static void resizer_calc_ratios(struct isp_res_device *res,
max_width & ~(width_alignment - 1)); max_width & ~(width_alignment - 1));
output->width = ALIGN(output->width, width_alignment); 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); / (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, ratio->horz = clamp_t(unsigned int, ratio->horz,
MIN_RESIZE_VALUE, MAX_RESIZE_VALUE); MIN_RESIZE_VALUE, MAX_RESIZE_VALUE);
if (ratio->horz <= MID_RESIZE_VALUE) { if (ratio->horz <= MID_RESIZE_VALUE) {
upscaled_width = (output->width - 1) * ratio->horz upscaled_width = (output->width - 1) * ratio->horz
+ 32 * sph + 16; + 32 * sph + 16;
input->width = (upscaled_width >> 8) + 7; width = (upscaled_width >> 8) + 7;
} else { } else {
upscaled_width = (output->width - 1) * ratio->horz upscaled_width = (output->width - 1) * ratio->horz
+ 64 * sph + 32; + 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;
} }
/* /*
......
...@@ -131,9 +131,9 @@ struct ispstat { ...@@ -131,9 +131,9 @@ struct ispstat {
struct ispstat_generic_config { struct ispstat_generic_config {
/* /*
* Fields must be in the same order as in: * Fields must be in the same order as in:
* - isph3a_aewb_config * - omap3isp_h3a_aewb_config
* - isph3a_af_config * - omap3isp_h3a_af_config
* - isphist_config * - omap3isp_hist_config
*/ */
u32 buf_size; u32 buf_size;
u16 config_counter; u16 config_counter;
......
...@@ -47,29 +47,59 @@ ...@@ -47,29 +47,59 @@
static struct isp_format_info formats[] = { static struct isp_format_info formats[] = {
{ V4L2_MBUS_FMT_Y8_1X8, V4L2_MBUS_FMT_Y8_1X8, { 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_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_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_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_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_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_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_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_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_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_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_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 * const struct isp_format_info *
...@@ -85,6 +115,37 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code) ...@@ -85,6 +115,37 @@ omap3isp_video_format_info(enum v4l2_mbus_pixelcode code)
return NULL; 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 * isp_video_mbus_to_pix - Convert v4l2_mbus_framefmt to v4l2_pix_format
* @video: ISP video instance * @video: ISP video instance
...@@ -235,6 +296,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) ...@@ -235,6 +296,7 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
return -EPIPE; return -EPIPE;
while (1) { while (1) {
unsigned int shifter_link;
/* Retrieve the sink format */ /* Retrieve the sink format */
pad = &subdev->entity.pads[0]; pad = &subdev->entity.pads[0];
if (!(pad->flags & MEDIA_PAD_FL_SINK)) if (!(pad->flags & MEDIA_PAD_FL_SINK))
...@@ -263,6 +325,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) ...@@ -263,6 +325,10 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
return -ENOSPC; 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 */ /* Retrieve the source format */
pad = media_entity_remote_source(pad); pad = media_entity_remote_source(pad);
if (pad == NULL || if (pad == NULL ||
...@@ -278,10 +344,24 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe) ...@@ -278,10 +344,24 @@ static int isp_video_validate_pipeline(struct isp_pipeline *pipe)
return -EPIPE; return -EPIPE;
/* Check if the two ends match */ /* Check if the two ends match */
if (fmt_source.format.code != fmt_sink.format.code || if (fmt_source.format.width != fmt_sink.format.width ||
fmt_source.format.width != fmt_sink.format.width ||
fmt_source.format.height != fmt_sink.format.height) fmt_source.format.height != fmt_sink.format.height)
return -EPIPE; 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; return 0;
......
...@@ -49,6 +49,8 @@ struct v4l2_pix_format; ...@@ -49,6 +49,8 @@ struct v4l2_pix_format;
* bits. Identical to @code if the format is 10 bits wide or less. * bits. Identical to @code if the format is 10 bits wide or less.
* @uncompressed: V4L2 media bus format code for the corresponding uncompressed * @uncompressed: V4L2 media bus format code for the corresponding uncompressed
* format. Identical to @code if the format is not DPCM compressed. * 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 * @pixelformat: V4L2 pixel format FCC identifier
* @bpp: Bits per pixel * @bpp: Bits per pixel
*/ */
...@@ -56,6 +58,7 @@ struct isp_format_info { ...@@ -56,6 +58,7 @@ struct isp_format_info {
enum v4l2_mbus_pixelcode code; enum v4l2_mbus_pixelcode code;
enum v4l2_mbus_pixelcode truncated; enum v4l2_mbus_pixelcode truncated;
enum v4l2_mbus_pixelcode uncompressed; enum v4l2_mbus_pixelcode uncompressed;
enum v4l2_mbus_pixelcode flavor;
u32 pixelformat; u32 pixelformat;
unsigned int bpp; unsigned int bpp;
}; };
......
...@@ -527,7 +527,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, ...@@ -527,7 +527,7 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
if (ret) if (ret)
return 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; return -EBUSY;
frame = &ctx->d_frame; frame = &ctx->d_frame;
...@@ -539,8 +539,10 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv, ...@@ -539,8 +539,10 @@ static int fimc_cap_s_fmt_mplane(struct file *file, void *priv,
return -EINVAL; return -EINVAL;
} }
for (i = 0; i < frame->fmt->colplanes; i++) for (i = 0; i < frame->fmt->colplanes; i++) {
frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; frame->payload[i] =
(pix->width * pix->height * frame->fmt->depth[i]) >> 3;
}
/* Output DMA frame pixel size and offsets. */ /* Output DMA frame pixel size and offsets. */
frame->f_width = pix->plane_fmt[0].bytesperline * 8 frame->f_width = pix->plane_fmt[0].bytesperline * 8
......
...@@ -361,10 +361,20 @@ static void fimc_capture_irq_handler(struct fimc_dev *fimc) ...@@ -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_cap *cap = &fimc->vid_cap;
struct fimc_vid_buffer *v_buf; struct fimc_vid_buffer *v_buf;
struct timeval *tv;
struct timespec ts;
if (!list_empty(&cap->active_buf_q) && if (!list_empty(&cap->active_buf_q) &&
test_bit(ST_CAPT_RUN, &fimc->state)) { test_bit(ST_CAPT_RUN, &fimc->state)) {
ktime_get_real_ts(&ts);
v_buf = active_queue_pop(cap); 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); vb2_buffer_done(&v_buf->vb, VB2_BUF_STATE_DONE);
} }
...@@ -758,7 +768,7 @@ static void fimc_unlock(struct vb2_queue *vq) ...@@ -758,7 +768,7 @@ static void fimc_unlock(struct vb2_queue *vq)
mutex_unlock(&ctx->fimc_dev->lock); mutex_unlock(&ctx->fimc_dev->lock);
} }
struct vb2_ops fimc_qops = { static struct vb2_ops fimc_qops = {
.queue_setup = fimc_queue_setup, .queue_setup = fimc_queue_setup,
.buf_prepare = fimc_buf_prepare, .buf_prepare = fimc_buf_prepare,
.buf_queue = fimc_buf_queue, .buf_queue = fimc_buf_queue,
...@@ -927,23 +937,23 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv, ...@@ -927,23 +937,23 @@ int fimc_vidioc_try_fmt_mplane(struct file *file, void *priv,
pix->num_planes = fmt->memplanes; pix->num_planes = fmt->memplanes;
pix->colorspace = V4L2_COLORSPACE_JPEG; 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", for (i = 0; i < pix->num_planes; ++i) {
i, bpl, fmt->depth[i], pix->width, pix->height); u32 bpl = pix->plane_fmt[i].bytesperline;
u32 *sizeimage = &pix->plane_fmt[i].sizeimage;
if (!bpl || (bpl * 8 / fmt->depth[i]) > pix->width) if (fmt->colplanes > 1 && (bpl == 0 || bpl < pix->width))
bpl = (pix->width * fmt->depth[0]) >> 3; bpl = pix->width; /* Planar */
if (!pix->plane_fmt[i].sizeimage) if (fmt->colplanes == 1 && /* Packed */
pix->plane_fmt[i].sizeimage = pix->height * bpl; (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", pix->plane_fmt[i].bytesperline = mod_x;
i, pix->plane_fmt[i].bytesperline, *sizeimage = (pix->width * pix->height * fmt->depth[i]) / 8;
pix->plane_fmt[i].sizeimage);
} }
return 0; return 0;
...@@ -965,7 +975,7 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, ...@@ -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); 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); v4l2_err(&fimc->m2m.v4l2_dev, "queue (%d) busy\n", f->type);
return -EBUSY; return -EBUSY;
} }
...@@ -985,8 +995,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv, ...@@ -985,8 +995,10 @@ static int fimc_m2m_s_fmt_mplane(struct file *file, void *priv,
if (!frame->fmt) if (!frame->fmt)
return -EINVAL; return -EINVAL;
for (i = 0; i < frame->fmt->colplanes; i++) for (i = 0; i < frame->fmt->colplanes; i++) {
frame->payload[i] = pix->plane_fmt[i].bytesperline * pix->height; frame->payload[i] =
(pix->width * pix->height * frame->fmt->depth[i]) / 8;
}
frame->f_width = pix->plane_fmt[0].bytesperline * 8 / frame->f_width = pix->plane_fmt[0].bytesperline * 8 /
frame->fmt->depth[0]; frame->fmt->depth[0];
...@@ -1750,7 +1762,7 @@ static int __devexit fimc_remove(struct platform_device *pdev) ...@@ -1750,7 +1762,7 @@ static int __devexit fimc_remove(struct platform_device *pdev)
} }
/* Image pixel limits, similar across several FIMC HW revisions. */ /* 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] = { [0] = {
.scaler_en_w = 3264, .scaler_en_w = 3264,
.scaler_dis_w = 8192, .scaler_dis_w = 8192,
...@@ -1775,6 +1787,14 @@ static struct fimc_pix_limit s5p_pix_limit[3] = { ...@@ -1775,6 +1787,14 @@ static struct fimc_pix_limit s5p_pix_limit[3] = {
.out_rot_en_w = 1280, .out_rot_en_w = 1280,
.out_rot_dis_w = 1920, .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 = { static struct samsung_fimc_variant fimc0_variant_s5p = {
...@@ -1827,7 +1847,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = { ...@@ -1827,7 +1847,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv210 = {
.pix_limit = &s5p_pix_limit[2], .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, .pix_hoff = 1,
.has_inp_rot = 1, .has_inp_rot = 1,
.has_out_rot = 1, .has_out_rot = 1,
...@@ -1840,7 +1860,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = { ...@@ -1840,7 +1860,7 @@ static struct samsung_fimc_variant fimc0_variant_s5pv310 = {
.pix_limit = &s5p_pix_limit[1], .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, .pix_hoff = 1,
.has_cistatus2 = 1, .has_cistatus2 = 1,
.has_mainscaler_ext = 1, .has_mainscaler_ext = 1,
...@@ -1848,7 +1868,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv310 = { ...@@ -1848,7 +1868,7 @@ static struct samsung_fimc_variant fimc2_variant_s5pv310 = {
.min_out_pixsize = 16, .min_out_pixsize = 16,
.hor_offs_align = 1, .hor_offs_align = 1,
.out_buf_count = 32, .out_buf_count = 32,
.pix_limit = &s5p_pix_limit[2], .pix_limit = &s5p_pix_limit[3],
}; };
/* S5PC100 */ /* S5PC100 */
...@@ -1874,12 +1894,12 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = { ...@@ -1874,12 +1894,12 @@ static struct samsung_fimc_driverdata fimc_drvdata_s5pv210 = {
}; };
/* S5PV310, S5PC210 */ /* S5PV310, S5PC210 */
static struct samsung_fimc_driverdata fimc_drvdata_s5pv310 = { static struct samsung_fimc_driverdata fimc_drvdata_exynos4 = {
.variant = { .variant = {
[0] = &fimc0_variant_s5pv310, [0] = &fimc0_variant_exynos4,
[1] = &fimc0_variant_s5pv310, [1] = &fimc0_variant_exynos4,
[2] = &fimc0_variant_s5pv310, [2] = &fimc0_variant_exynos4,
[3] = &fimc2_variant_s5pv310, [3] = &fimc2_variant_exynos4,
}, },
.num_entities = 4, .num_entities = 4,
.lclk_frequency = 166000000UL, .lclk_frequency = 166000000UL,
...@@ -1893,8 +1913,8 @@ static struct platform_device_id fimc_driver_ids[] = { ...@@ -1893,8 +1913,8 @@ static struct platform_device_id fimc_driver_ids[] = {
.name = "s5pv210-fimc", .name = "s5pv210-fimc",
.driver_data = (unsigned long)&fimc_drvdata_s5pv210, .driver_data = (unsigned long)&fimc_drvdata_s5pv210,
}, { }, {
.name = "s5pv310-fimc", .name = "exynos4-fimc",
.driver_data = (unsigned long)&fimc_drvdata_s5pv310, .driver_data = (unsigned long)&fimc_drvdata_exynos4,
}, },
{}, {},
}; };
......
...@@ -922,7 +922,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int ...@@ -922,7 +922,7 @@ static int sh_mobile_ceu_get_formats(struct soc_camera_device *icd, unsigned int
/* Try 2560x1920, 1280x960, 640x480, 320x240 */ /* Try 2560x1920, 1280x960, 640x480, 320x240 */
mf.width = 2560 >> shift; mf.width = 2560 >> shift;
mf.height = 1920 >> 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); s_mbus_fmt, &mf);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1224,7 +1224,7 @@ static int client_s_fmt(struct soc_camera_device *icd, ...@@ -1224,7 +1224,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
struct v4l2_cropcap cap; struct v4l2_cropcap cap;
int ret; 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); s_mbus_fmt, mf);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1254,7 +1254,7 @@ static int client_s_fmt(struct soc_camera_device *icd, ...@@ -1254,7 +1254,7 @@ static int client_s_fmt(struct soc_camera_device *icd,
tmp_h = min(2 * tmp_h, max_height); tmp_h = min(2 * tmp_h, max_height);
mf->width = tmp_w; mf->width = tmp_w;
mf->height = tmp_h; 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); s_mbus_fmt, mf);
dev_geo(dev, "Camera scaled to %ux%u\n", dev_geo(dev, "Camera scaled to %ux%u\n",
mf->width, mf->height); mf->width, mf->height);
...@@ -1658,7 +1658,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, ...@@ -1658,7 +1658,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
mf.code = xlate->code; mf.code = xlate->code;
mf.colorspace = pix->colorspace; 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) if (ret < 0)
return ret; return ret;
...@@ -1682,7 +1682,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd, ...@@ -1682,7 +1682,7 @@ static int sh_mobile_ceu_try_fmt(struct soc_camera_device *icd,
*/ */
mf.width = 2560; mf.width = 2560;
mf.height = 1920; 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); try_mbus_fmt, &mf);
if (ret < 0) { if (ret < 0) {
/* Shouldn't actually happen... */ /* Shouldn't actually happen... */
......
...@@ -38,6 +38,8 @@ struct sh_csi2 { ...@@ -38,6 +38,8 @@ struct sh_csi2 {
void __iomem *base; void __iomem *base;
struct platform_device *pdev; struct platform_device *pdev;
struct sh_csi2_client_config *client; 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, static int sh_csi2_try_fmt(struct v4l2_subdev *sd,
...@@ -208,6 +210,7 @@ static int sh_csi2_notify(struct notifier_block *nb, ...@@ -208,6 +210,7 @@ static int sh_csi2_notify(struct notifier_block *nb,
case BUS_NOTIFY_BOUND_DRIVER: case BUS_NOTIFY_BOUND_DRIVER:
snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s", snprintf(priv->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s%s",
dev_name(v4l2_dev->dev), ".mipi-csi"); dev_name(v4l2_dev->dev), ".mipi-csi");
priv->subdev.grp_id = (long)icd;
ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev); ret = v4l2_device_register_subdev(v4l2_dev, &priv->subdev);
dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret); dev_dbg(dev, "%s(%p): ret(register_subdev) = %d\n", __func__, priv, ret);
if (ret < 0) if (ret < 0)
...@@ -215,6 +218,8 @@ static int sh_csi2_notify(struct notifier_block *nb, ...@@ -215,6 +218,8 @@ static int sh_csi2_notify(struct notifier_block *nb,
priv->client = pdata->clients + i; 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->set_bus_param = sh_csi2_set_bus_param;
icd->ops->query_bus_param = sh_csi2_query_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, ...@@ -226,8 +231,10 @@ static int sh_csi2_notify(struct notifier_block *nb,
priv->client = NULL; priv->client = NULL;
/* Driver is about to be unbound */ /* Driver is about to be unbound */
icd->ops->set_bus_param = NULL; icd->ops->set_bus_param = priv->set_bus_param;
icd->ops->query_bus_param = NULL; 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); v4l2_device_unregister_subdev(&priv->subdev);
......
...@@ -996,10 +996,11 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd) ...@@ -996,10 +996,11 @@ static void soc_camera_free_i2c(struct soc_camera_device *icd)
{ {
struct i2c_client *client = struct i2c_client *client =
to_i2c_client(to_soc_camera_control(icd)); to_i2c_client(to_soc_camera_control(icd));
struct i2c_adapter *adap = client->adapter;
dev_set_drvdata(&icd->dev, NULL); dev_set_drvdata(&icd->dev, NULL);
v4l2_device_unregister_subdev(i2c_get_clientdata(client)); v4l2_device_unregister_subdev(i2c_get_clientdata(client));
i2c_unregister_device(client); i2c_unregister_device(client);
i2c_put_adapter(client->adapter); i2c_put_adapter(adap);
} }
#else #else
#define soc_camera_init_i2c(icd, icl) (-ENODEV) #define soc_camera_init_i2c(icd, icl) (-ENODEV)
...@@ -1071,6 +1072,9 @@ static int soc_camera_probe(struct device *dev) ...@@ -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 */ /* At this point client .probe() should have run already */
ret = soc_camera_init_user_formats(icd); ret = soc_camera_init_user_formats(icd);
if (ret < 0) if (ret < 0)
...@@ -1092,7 +1096,6 @@ static int soc_camera_probe(struct device *dev) ...@@ -1092,7 +1096,6 @@ static int soc_camera_probe(struct device *dev)
goto evidstart; goto evidstart;
/* Try to improve our guess of a reasonable window format */ /* 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)) { if (!v4l2_subdev_call(sd, video, g_mbus_fmt, &mf)) {
icd->user_width = mf.width; icd->user_width = mf.width;
icd->user_height = mf.height; icd->user_height = mf.height;
......
...@@ -389,7 +389,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) ...@@ -389,7 +389,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
video_get(vdev); video_get(vdev);
mutex_unlock(&videodev_lock); mutex_unlock(&videodev_lock);
#if defined(CONFIG_MEDIA_CONTROLLER) #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); entity = media_entity_get(&vdev->entity);
if (!entity) { if (!entity) {
ret = -EBUSY; ret = -EBUSY;
...@@ -415,7 +416,8 @@ static int v4l2_open(struct inode *inode, struct file *filp) ...@@ -415,7 +416,8 @@ static int v4l2_open(struct inode *inode, struct file *filp)
/* decrease the refcount in case of an error */ /* decrease the refcount in case of an error */
if (ret) { if (ret) {
#if defined(CONFIG_MEDIA_CONTROLLER) #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); media_entity_put(entity);
#endif #endif
video_put(vdev); video_put(vdev);
...@@ -437,7 +439,8 @@ static int v4l2_release(struct inode *inode, struct file *filp) ...@@ -437,7 +439,8 @@ static int v4l2_release(struct inode *inode, struct file *filp)
mutex_unlock(vdev->lock); mutex_unlock(vdev->lock);
} }
#if defined(CONFIG_MEDIA_CONTROLLER) #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); media_entity_put(&vdev->entity);
#endif #endif
/* decrease the refcount unconditionally since the release() /* decrease the refcount unconditionally since the release()
...@@ -686,7 +689,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr, ...@@ -686,7 +689,8 @@ int __video_register_device(struct video_device *vdev, int type, int nr,
#if defined(CONFIG_MEDIA_CONTROLLER) #if defined(CONFIG_MEDIA_CONTROLLER)
/* Part 5: Register the entity. */ /* 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.type = MEDIA_ENT_T_DEVNODE_V4L;
vdev->entity.name = vdev->name; vdev->entity.name = vdev->name;
vdev->entity.v4l.major = VIDEO_MAJOR; vdev->entity.v4l.major = VIDEO_MAJOR;
...@@ -733,7 +737,8 @@ void video_unregister_device(struct video_device *vdev) ...@@ -733,7 +737,8 @@ void video_unregister_device(struct video_device *vdev)
return; return;
#if defined(CONFIG_MEDIA_CONTROLLER) #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); media_device_unregister_entity(&vdev->entity);
#endif #endif
......
...@@ -37,6 +37,9 @@ module_param(debug, int, 0644); ...@@ -37,6 +37,9 @@ module_param(debug, int, 0644);
#define call_qop(q, op, args...) \ #define call_qop(q, op, args...) \
(((q)->ops->op) ? ((q)->ops->op(args)) : 0) (((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 * __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, ...@@ -51,7 +54,7 @@ static int __vb2_buf_mem_alloc(struct vb2_buffer *vb,
for (plane = 0; plane < vb->num_planes; ++plane) { for (plane = 0; plane < vb->num_planes; ++plane) {
mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane], mem_priv = call_memop(q, plane, alloc, q->alloc_ctx[plane],
plane_sizes[plane]); plane_sizes[plane]);
if (!mem_priv) if (IS_ERR_OR_NULL(mem_priv))
goto free; goto free;
/* Associate allocator private data with this plane */ /* Associate allocator private data with this plane */
...@@ -284,7 +287,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) ...@@ -284,7 +287,7 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b)
struct vb2_queue *q = vb->vb2_queue; struct vb2_queue *q = vb->vb2_queue;
int ret = 0; 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)); memcpy(b, &vb->v4l2_buf, offsetof(struct v4l2_buffer, m));
b->input = vb->v4l2_buf.input; b->input = vb->v4l2_buf.input;
b->reserved = vb->v4l2_buf.reserved; b->reserved = vb->v4l2_buf.reserved;
...@@ -313,7 +316,10 @@ static int __fill_v4l2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b) ...@@ -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->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) { switch (vb->state) {
case VB2_BUF_STATE_QUEUED: case VB2_BUF_STATE_QUEUED:
...@@ -519,6 +525,7 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req) ...@@ -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); num_buffers = min_t(unsigned int, req->count, VIDEO_MAX_FRAME);
memset(plane_sizes, 0, sizeof(plane_sizes)); memset(plane_sizes, 0, sizeof(plane_sizes));
memset(q->alloc_ctx, 0, sizeof(q->alloc_ctx)); 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. * 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) ...@@ -560,8 +567,6 @@ int vb2_reqbufs(struct vb2_queue *q, struct v4l2_requestbuffers *req)
ret = num_buffers; ret = num_buffers;
} }
q->memory = req->memory;
/* /*
* Return the number of successfully allocated buffers * Return the number of successfully allocated buffers
* to the userspace. * to the userspace.
...@@ -715,6 +720,8 @@ static int __fill_vb2_buffer(struct vb2_buffer *vb, struct v4l2_buffer *b, ...@@ -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.field = b->field;
vb->v4l2_buf.timestamp = b->timestamp; vb->v4l2_buf.timestamp = b->timestamp;
vb->v4l2_buf.input = b->input;
vb->v4l2_buf.flags = b->flags & ~V4L2_BUFFER_STATE_FLAGS;
return 0; return 0;
} }
......
...@@ -46,7 +46,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size) ...@@ -46,7 +46,7 @@ static void *vb2_dma_contig_alloc(void *alloc_ctx, unsigned long size)
GFP_KERNEL); GFP_KERNEL);
if (!buf->vaddr) { if (!buf->vaddr) {
dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n", dev_err(conf->dev, "dma_alloc_coherent of size %ld failed\n",
buf->size); size);
kfree(buf); kfree(buf);
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
......
...@@ -47,7 +47,7 @@ enum v4l2_mbus_pixelcode { ...@@ -47,7 +47,7 @@ enum v4l2_mbus_pixelcode {
V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007, V4L2_MBUS_FMT_RGB565_2X8_BE = 0x1007,
V4L2_MBUS_FMT_RGB565_2X8_LE = 0x1008, 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_Y8_1X8 = 0x2001,
V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002, V4L2_MBUS_FMT_UYVY8_1_5X8 = 0x2002,
V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003, V4L2_MBUS_FMT_VYUY8_1_5X8 = 0x2003,
...@@ -60,6 +60,7 @@ enum v4l2_mbus_pixelcode { ...@@ -60,6 +60,7 @@ enum v4l2_mbus_pixelcode {
V4L2_MBUS_FMT_Y10_1X10 = 0x200a, V4L2_MBUS_FMT_Y10_1X10 = 0x200a,
V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b, V4L2_MBUS_FMT_YUYV10_2X10 = 0x200b,
V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c, V4L2_MBUS_FMT_YVYU10_2X10 = 0x200c,
V4L2_MBUS_FMT_Y12_1X12 = 0x2013,
V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f, V4L2_MBUS_FMT_UYVY8_1X16 = 0x200f,
V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010, V4L2_MBUS_FMT_VYUY8_1X16 = 0x2010,
V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011, V4L2_MBUS_FMT_YUYV8_1X16 = 0x2011,
...@@ -67,9 +68,11 @@ enum v4l2_mbus_pixelcode { ...@@ -67,9 +68,11 @@ enum v4l2_mbus_pixelcode {
V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d, V4L2_MBUS_FMT_YUYV10_1X20 = 0x200d,
V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e, V4L2_MBUS_FMT_YVYU10_1X20 = 0x200e,
/* Bayer - next is 0x3013 */ /* Bayer - next is 0x3015 */
V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001, V4L2_MBUS_FMT_SBGGR8_1X8 = 0x3001,
V4L2_MBUS_FMT_SGBRG8_1X8 = 0x3013,
V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002, V4L2_MBUS_FMT_SGRBG8_1X8 = 0x3002,
V4L2_MBUS_FMT_SRGGB8_1X8 = 0x3014,
V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b, V4L2_MBUS_FMT_SBGGR10_DPCM8_1X8 = 0x300b,
V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c, V4L2_MBUS_FMT_SGBRG10_DPCM8_1X8 = 0x300c,
V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009, V4L2_MBUS_FMT_SGRBG10_DPCM8_1X8 = 0x3009,
......
...@@ -308,6 +308,7 @@ struct v4l2_pix_format { ...@@ -308,6 +308,7 @@ struct v4l2_pix_format {
#define V4L2_PIX_FMT_Y4 v4l2_fourcc('Y', '0', '4', ' ') /* 4 Greyscale */ #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_Y6 v4l2_fourcc('Y', '0', '6', ' ') /* 6 Greyscale */
#define V4L2_PIX_FMT_Y10 v4l2_fourcc('Y', '1', '0', ' ') /* 10 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 */ #define V4L2_PIX_FMT_Y16 v4l2_fourcc('Y', '1', '6', ' ') /* 16 Greyscale */
/* Palette formats */ /* Palette formats */
......
...@@ -163,7 +163,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev); ...@@ -163,7 +163,7 @@ v4l2_device_register_subdev_nodes(struct v4l2_device *v4l2_dev);
({ \ ({ \
struct v4l2_subdev *__sd; \ struct v4l2_subdev *__sd; \
__v4l2_device_call_subdevs_until_err_p(v4l2_dev, __sd, cond, o, \ __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 /* Call the specified callback for all subdevs matching grp_id (if 0, then
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册