Philip Avinash | 22 May 2013 09:10
Picon
Favicon

[PATCH 00/11] Convert GPIO Davinci to platform driver

GPIO Davinci driver converted to platform driver to support DT booting.
In this patch series
- Cleaned gpio Davinci driver code with proper commenting style and appropriate
  variable names.
- Create platform driver for GPIO Davinci in da8xx and dm* platforms and removed
  gpio related member updation in davinci_soc_info structure.
- DT support added for da850 board and tested on da850 EVM.
- Remove soc_info reference in the gpio davinci driver and start uses
  gpiolib interface.

This sereise based on [1] and is avilable at [2].
1. http://gitorious.org/linux-davinci/linux-davinci/trees/davinci-for-v3.10/soc
2. https://github.com/avinashphilip/am335x_linux/commits/linux_davinci_v3.10_soc_gpio

KV Sujith (6):
  ARM: davinci: GPIO: Add platform data structure
  gpio: davinci: Modify to platform driver
  ARM: davinci: da8xx: creation of gpio platform device
  gpio: davinci: DT changes for driver
  ARM: davinci: da850: add GPIO DT entries
  ARM: davinci: da850 evm: add GPIO DT data

Philip Avinash (5):
  gpio: davinci: coding style correction
  ARM: davinci: creation of gpio platform device for dm platforms
  ARM: davinci: da8xx: gpio device creation
  ARM: davinci: create davinci gpio device for dm platforms
  ARM: davinci: start using gpiolib support

 .../devicetree/bindings/gpio/gpio-davinci.txt      |   26 ++
(Continue reading)

Manjunathappa, Prakash | 21 May 2013 16:07
Picon
Favicon

[PATCH 0/3] pinctrl: pinctrl-single: Add full fledge support to configure multiple pins of different modules

Based function-mask and submask preoperties patch allocates and registers pins.
Patch is fixes the issue reported and discussed here:
http://www.spinics.net/lists/arm-kernel/msg235213.html

Applies on top of 3.10-rc2 of linus's tree.

Tested on da850-evm.

Manjunathappa, Prakash (3):
  pinctrl: pinctrl-single: enhance to configure multiple pins of
    different     modules
  pinctrl: pinctrl-single: pin names for pinctrl-single.bits
  ARM: davinci: da850: adopt to pinctrl-single driver to configure
    multiple     pins

 .../devicetree/bindings/pinctrl/pinctrl-single.txt |    3 +-
 arch/arm/boot/dts/da850.dtsi                       |    2 +-
 drivers/pinctrl/pinctrl-single.c                   |  215 ++++++++++++++++----
 3 files changed, 179 insertions(+), 41 deletions(-)

--

-- 
1.7.4.1

achun liu | 17 May 2013 09:30
Picon

can't get right data from ISP ISIF

hi,all,

I use the OV8810 chip,the output formats is RAW 8bit bggr, my data flow is 'CSI2A->IPIPEIF->ISIF->SDRAM',but all of the data get from SDRAM is 0, the data get from CSI2A is right when I use 'CSI2A->SDRAM', I don't know this is why,the following is the register debug:

[   96.365966] : -------------IPIPEIF Register dump-------------
[   96.366027] : ###IPIPEIF CFG1=0x00000000
[   96.366027] : ###IPIPEIF CFG2=0x00000000

[   96.366027] : ###ISIF SYNCEN=0x00000001
[   96.366058] : ###ISIF CADU=0x00000000
[   96.366058] : ###ISIF CADL=0x00000000
[   96.366058] : ###ISIF MODESET=0x00002000
[   96.366088] : ###ISIF CCOLP=0x00000000
[   96.366088] : ###ISIF SPH=0x00000000
[   96.366088] : ###ISIF LNH=0x0000077f
[   96.366119] : ###ISIF LNV=0x00000437
[   96.366119] : ###ISIF VDINT0=0x00000437
[   96.366119] : ###ISIF HSIZE=0x0000003c
[   96.366149] : ###ISP5 SYSCONFIG=0x00000021
[   96.366149] : ###ISP5 CTRL=0x0190c7f8
[   96.366149] : ###ISP5 IRQSTATUS(0)=0x00000000
[   96.366180] : ###ISP5 IRQENABLE_SET(0)=0x800c8001
[   96.366180] : ###ISP5 IRQENABLE_CLR(0)=0x800c8001
[   96.366180] : -----------------------------------------------


[   96.366943] : -------------CSI2 Register dump-------------
[   96.366943] : ###CSI2 SYSCONFIG=0x00001000
[   96.366943] : ###CSI2 SYSSTATUS=0x00000001
[   96.366973] : ###CSI2 IRQENABLE=0x00007b01
[   96.366973] : ###CSI2 IRQSTATUS=0x00000000
[   96.366973] : ###CSI2 CTRL=0x0029a811
[   96.367004] : ###CSI2 DBG_H=0x00000000
[   96.367004] : ###CSI2 COMPLEXIO_CFG=0x4a000321
[   96.367004] : ###CSI2 COMPLEXIO_IRQSTATUS=0x00000000
[   96.367034] : ###CSI2 SHORT_PACKET=0x00000000
[   96.367034] : ###CSI2 COMPLEXIO_IRQENABLE=0x07ffffff
[   96.367034] : ###CSI2 DBG_P=0x00000000
[   96.367065] : ###CSI2 TIMING=0x7fffe1ff
[   96.367065] : ###CSI2 CTX_CTRL1(0)=0x000100c9
[   96.367065] : ###CSI2 CTX_CTRL2(0)=0x0000012a
[   96.367095] : ###CSI2 CTX_DAT_OFST(0)=0x00000000
[   96.367095] : ###CSI2 CTX_PING_ADDR(0)=0x00000000
[   96.367095] : ###CSI2 CTX_PONG_ADDR(0)=0x00000000
[   96.367126] : ###CSI2 CTX_IRQENABLE(0)=0x00000002
[   96.367126] : ###CSI2 CTX_IRQSTATUS(0)=0x00000000
[   96.367126] : ###CSI2 CTX_CTRL3(0)=0x00000000


[   98.375671] : -------------ISS HL Register dump-------------
[   98.383239] : ###ISS HL_REVISION=0x40000103
[   98.389282] : ###ISS HL_SYSCONFIG=0x00000028
[   98.395385] : ###ISS HL_IRQSTATUS_5=0x00000000
[   98.401641] : ###ISS HL_IRQENABLE_5_SET=0x00000031

[   98.431610] : ###ISS HL_IRQENABLE_5_CLR=0x00000031
[   98.438262] : ###ISS CTRL=0x00000003
[   98.453063] : ###ISS CLKCTRL=0xf0000006
[   98.458709] : ###ISS CLKSTAT=0xf0000006
[   98.464324] : -----------------------------------------------

thank you,

BR,

Lyc.

<div><div dir="ltr">hi,all,<br><br>I use the OV8810 chip,the output formats is RAW 8bit bggr, my data flow is 'CSI2A-&gt;IPIPEIF-&gt;ISIF-&gt;SDRAM',but all of the data get from SDRAM is 0, the data get from CSI2A is right when I use 'CSI2A-&gt;SDRAM', I don't know this is why,the following is the register debug:<br><br>[&nbsp;&nbsp; 96.365966] : -------------IPIPEIF Register dump-------------<br>[&nbsp;&nbsp; 96.366027] : ###IPIPEIF CFG1=0x00000000<br>[&nbsp;&nbsp; 96.366027] : ###IPIPEIF CFG2=0x00000000<br><br>[&nbsp;&nbsp; 96.366027] : ###ISIF SYNCEN=0x00000001<br>[&nbsp;&nbsp; 96.366058] : ###ISIF CADU=0x00000000<br>
[&nbsp;&nbsp; 96.366058] : ###ISIF CADL=0x00000000<br>[&nbsp;&nbsp; 96.366058] : ###ISIF MODESET=0x00002000<br>[&nbsp;&nbsp; 96.366088] : ###ISIF CCOLP=0x00000000<br>[&nbsp;&nbsp; 96.366088] : ###ISIF SPH=0x00000000<br>[&nbsp;&nbsp; 96.366088] : ###ISIF LNH=0x0000077f<br>
[&nbsp;&nbsp; 96.366119] : ###ISIF LNV=0x00000437<br>[&nbsp;&nbsp; 96.366119] : ###ISIF VDINT0=0x00000437<br>[&nbsp;&nbsp; 96.366119] : ###ISIF HSIZE=0x0000003c<br>[&nbsp;&nbsp; 96.366149] : ###ISP5 SYSCONFIG=0x00000021<br>[&nbsp;&nbsp; 96.366149] : ###ISP5 CTRL=0x0190c7f8<br>
[&nbsp;&nbsp; 96.366149] : ###ISP5 IRQSTATUS(0)=0x00000000<br>[&nbsp;&nbsp; 96.366180] : ###ISP5 IRQENABLE_SET(0)=0x800c8001<br>[&nbsp;&nbsp; 96.366180] : ###ISP5 IRQENABLE_CLR(0)=0x800c8001<br>[&nbsp;&nbsp; 96.366180] : -----------------------------------------------<br><br><br>[&nbsp;&nbsp; 96.366943] : -------------CSI2 Register dump-------------<br>[&nbsp;&nbsp; 96.366943] : ###CSI2 SYSCONFIG=0x00001000<br>[&nbsp;&nbsp; 96.366943] : ###CSI2 SYSSTATUS=0x00000001<br>[&nbsp;&nbsp; 96.366973] : ###CSI2 IRQENABLE=0x00007b01<br>[&nbsp;&nbsp; 96.366973] : ###CSI2 IRQSTATUS=0x00000000<br>
[&nbsp;&nbsp; 96.366973] : ###CSI2 CTRL=0x0029a811<br>[&nbsp;&nbsp; 96.367004] : ###CSI2 DBG_H=0x00000000<br>[&nbsp;&nbsp; 96.367004] : ###CSI2 COMPLEXIO_CFG=0x4a000321<br>[&nbsp;&nbsp; 96.367004] : ###CSI2 COMPLEXIO_IRQSTATUS=0x00000000<br>[&nbsp;&nbsp; 96.367034] : ###CSI2 SHORT_PACKET=0x00000000<br>
[&nbsp;&nbsp; 96.367034] : ###CSI2 COMPLEXIO_IRQENABLE=0x07ffffff<br>[&nbsp;&nbsp; 96.367034] : ###CSI2 DBG_P=0x00000000<br>[&nbsp;&nbsp; 96.367065] : ###CSI2 TIMING=0x7fffe1ff<br>[&nbsp;&nbsp; 96.367065] : ###CSI2 CTX_CTRL1(0)=0x000100c9<br>[&nbsp;&nbsp; 96.367065] : ###CSI2 CTX_CTRL2(0)=0x0000012a<br>
[&nbsp;&nbsp; 96.367095] : ###CSI2 CTX_DAT_OFST(0)=0x00000000<br>[&nbsp;&nbsp; 96.367095] : ###CSI2 CTX_PING_ADDR(0)=0x00000000<br>[&nbsp;&nbsp; 96.367095] : ###CSI2 CTX_PONG_ADDR(0)=0x00000000<br>[&nbsp;&nbsp; 96.367126] : ###CSI2 CTX_IRQENABLE(0)=0x00000002<br>
[&nbsp;&nbsp; 96.367126] : ###CSI2 CTX_IRQSTATUS(0)=0x00000000<br>[&nbsp;&nbsp; 96.367126] : ###CSI2 CTX_CTRL3(0)=0x00000000<br><br><br>[&nbsp;&nbsp; 98.375671] : -------------ISS HL Register dump-------------<br>[&nbsp;&nbsp; 98.383239] : ###ISS HL_REVISION=0x40000103<br>
[&nbsp;&nbsp; 98.389282] : ###ISS HL_SYSCONFIG=0x00000028<br>[&nbsp;&nbsp; 98.395385] : ###ISS HL_IRQSTATUS_5=0x00000000<br>[&nbsp;&nbsp; 98.401641] : ###ISS HL_IRQENABLE_5_SET=0x00000031<br><br>[&nbsp;&nbsp; 98.431610] : ###ISS HL_IRQENABLE_5_CLR=0x00000031<br>
[&nbsp;&nbsp; 98.438262] : ###ISS CTRL=0x00000003<br>[&nbsp;&nbsp; 98.453063] : ###ISS CLKCTRL=0xf0000006<br>[&nbsp;&nbsp; 98.458709] : ###ISS CLKSTAT=0xf0000006<br>[&nbsp;&nbsp; 98.464324] : -----------------------------------------------<br><br>thank you,<br><br>BR,<br><br>Lyc.<br><br>
</div></div>
Kaori Lee | 16 May 2013 15:20
Picon

<div></div>
Kaori Lee | 16 May 2013 15:20
Picon

(unknown)

<div></div>
Jose Pablo Carballo | 11 May 2013 04:30
Gravatar

Patch for vpfe_remove()

Hi,

In file drivers/media/platform/davinci/vpfe_capture.c, function vpfe_remove():

diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 28d019d..f0f272f 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
<at> <at> -2045,6 +2045,7 <at> <at> static int vpfe_remove(struct platform_device *pdev)
        kfree(vpfe_dev->sd);
        v4l2_device_unregister(&vpfe_dev->v4l2_dev);
        video_unregister_device(vpfe_dev->video_dev);
+       video_device_release(vpfe_dev->video_dev);
        kfree(vpfe_dev);
        kfree(ccdc_cfg);
        return 0;


According to my understanding, the story of vpfe_dev->video_dev is as follows:

1. It starts to exist at vpfe_probe(), through the function video_device_alloc():

vfd = video_device_alloc();
...
vfd->release = video_device_release;
...
vpfe_dev->video_dev = vfd;
...
ret = video_register_device(vpfe_dev->video_dev,
   VFL_TYPE_GRABBER, -1);


Note that video_device_alloc() is fundamentally a call to kzalloc(), and video_device_release() is the respective call to kfree().

2. It ends to exist in vpfe_remove():

video_unregister_device(vpfe_dev->video_dev);
...
kfree(vpfe_dev);  <- I believe this won't free the memory pointed by vpfe_dev->video_dev


If you look at the implementation of video_unregister_device(), you would notice it doesn't call video_device_release(). Unless that calls happens automatically at some point, given that vpfe_dev->video_dev->release points to video_device_release(), the explicit call to video_device_release() is needed. Another hint to this, is that if you look at the error handling logic at the vpfe_probe() function, you will see the proposed chain of events do happen:

probe_out_v4l2_unregister:
v4l2_device_unregister(&vpfe_dev->v4l2_dev);
probe_out_video_release:
if (!video_is_registered(vpfe_dev->video_dev))
video_device_release(vpfe_dev->video_dev);    <- Explicitly freed this memory

Thanks,
JP
<div><div dir="ltr">Hi,<div><br></div>
<div>
<span>In file&nbsp;drivers/media/platform/≤/span><span>davinci/vpfe_capture.c, function vpfe_remove():</span>
</div>
<div>
<br><div>
<div>diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c</div>
<div>index 28d019d..f0f272f 100644</div>
<div>--- a/drivers/media/platform/davinci/vpfe_capture.c</div>
<div>+++ b/drivers/media/platform/davinci/vpfe_capture.c</div>
<div> <at>  <at>  -2045,6 +2045,7  <at>  <at>  static int vpfe_remove(struct platform_device *pdev)</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; kfree(vpfe_dev-&gt;sd);</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; v4l2_device_unregister(&amp;vpfe_dev-&gt;v4l2_dev);</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; video_unregister_device(vpfe_dev-&gt;video_dev);</div>
<div>+ &nbsp; &nbsp; &nbsp; video_device_release(vpfe_dev-&gt;video_dev);</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; kfree(vpfe_dev);</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; kfree(ccdc_cfg);</div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; return 0;</div>
</div>
<div><br></div>
<div><br></div>
<div>According to my understanding, the story of vpfe_dev-&gt;video_dev is as follows:</div>
<div><br></div>
<div>1. It starts to exist at vpfe_probe(), through the function video_device_alloc():</div>
<div><br></div>
<div>vfd = video_device_alloc();<br>
</div>
<div>...</div>
<div>vfd-&gt;release<span class="">		</span>= video_device_release;<br>
</div>
<div>...</div>
<div>
vpfe_dev-&gt;video_dev<span class="">	</span>= vfd;<br>
</div>
<div>...</div>
<div>
<div>ret = video_register_device(vpfe_dev-&gt;video_dev,</div>
<div>
<span class="">			</span> &nbsp; &nbsp;VFL_TYPE_GRABBER, -1);</div>
<div><br></div>
</div>
<div><br></div>
<div>Note that video_device_alloc() is fundamentally a call to kzalloc(), and video_device_release() is the respective call to kfree().</div>
<div><br></div>
<div>
2. It ends to exist in vpfe_remove():</div>
<div><br></div>
<div>
<div>video_unregister_device(vpfe_dev-&gt;video_dev);</div>
<div>...</div>
</div>
<div>kfree(vpfe_dev); &nbsp;&lt;- I believe this won't free the memory pointed by vpfe_dev-&gt;video_dev<br>
</div>
<div><br></div>
<div><br></div>
<div>If you look at the implementation of video_unregister_device(), you would notice it doesn't call video_device_release(). Unless that calls happens automatically at some point, given that vpfe_dev-&gt;video_dev-&gt;release points to video_device_release(), the explicit call to video_device_release() is needed. Another hint to this, is that if you look at the error handling logic at the vpfe_probe() function, you will see the proposed chain of events do happen:</div>
<div><br></div>
<div>
<div>probe_out_v4l2_unregister:</div>
<div>
<span class="">	</span>v4l2_device_unregister(&amp;vpfe_dev-&gt;v4l2_dev);</div>
<div>probe_out_video_release:</div>
<div>
<span class="">	</span>if (!video_is_registered(vpfe_dev-&gt;video_dev))</div>
<div>
<span class="">		</span>video_device_release(vpfe_dev-&gt;video_dev); &nbsp; &nbsp;&lt;- Explicitly freed this memory</div>
</div>
<div><br></div>
<div>Thanks,</div>
<div>JP</div>
</div>
</div></div>
Jose Pablo Carballo | 9 May 2013 19:28
Gravatar

Patch for vpfe_probe()

Hi,

On file drivers/media/platform/davinci/vpfe_capture.c, function vpfe_probe():

diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c
index 28d019d..1d9a12d 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
<at> <at> -1866,6 +1866,8 <at> <at> static int vpfe_probe(struct platform_device *pdev)
                goto probe_free_dev_mem;
        }
 
+       mutex_lock(&ccdc_lock);
+
        /* Allocate memory for ccdc configuration */
        ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);
        if (NULL == ccdc_cfg) {
<at> <at> -1874,8 +1876,6 <at> <at> static int vpfe_probe(struct platform_device *pdev)
                goto probe_free_lock;
        }
 
-       mutex_lock(&ccdc_lock);
-
        strncpy(ccdc_cfg->name, vpfe_cfg->ccdc, 32);
        /* Get VINT0 irq resource */
        res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);

The check NULL == ccdc_cfg takes the function to probe_free_lock on error, which unlocks the mutex that has not been previously locked.

JP
<div><div dir="ltr">Hi,<div><br></div>
<div>On file&nbsp;drivers/media/platform/davinci/vpfe_capture.c, function vpfe_probe():</div>
<div><br></div>
<blockquote>
<div>
<div>diff --git a/drivers/media/platform/davinci/vpfe_capture.c b/drivers/media/platform/davinci/vpfe_capture.c</div>
</div>
<div><div>index 28d019d..1d9a12d 100644</div></div>
<div>
<div>--- a/drivers/media/platform/davinci/vpfe_capture.c</div>
</div>
<div><div>+++ b/drivers/media/platform/davinci/vpfe_capture.c</div></div>
<div><div> <at>  <at>  -1866,6 +1866,8  <at>  <at>  static int vpfe_probe(struct platform_device *pdev)</div></div>
<div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto probe_free_dev_mem;</div>
</div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<div><div>&nbsp;</div></div>
<div><div>+ &nbsp; &nbsp; &nbsp; mutex_lock(&amp;ccdc_lock);</div></div>
<div><div>+</div></div>
<div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; /* Allocate memory for ccdc configuration */</div>
</div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; ccdc_cfg = kmalloc(sizeof(struct ccdc_config), GFP_KERNEL);</div></div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; if (NULL == ccdc_cfg) {</div></div>
<div>
<div> <at>  <at>  -1874,8 +1876,6  <at>  <at>  static int vpfe_probe(struct platform_device *pdev)</div>
</div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto probe_free_lock;</div></div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; }</div></div>
<div><div>&nbsp;</div></div>
<div><div>- &nbsp; &nbsp; &nbsp; mutex_lock(&amp;ccdc_lock);</div></div>
<div><div>-</div></div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; strncpy(ccdc_cfg-&gt;name, vpfe_cfg-&gt;ccdc, 32);</div></div>
<div><div>&nbsp; &nbsp; &nbsp; &nbsp; /* Get VINT0 irq resource */</div></div>
<div>
<div>&nbsp; &nbsp; &nbsp; &nbsp; res1 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);</div>
</div>
</blockquote>
<div><div><br></div></div>
<div>The check NULL == ccdc_cfg takes the function to probe_free_lock on error, which unlocks the mutex that has not been previously locked.</div>
<div><br></div>
<div>JP</div>
</div></div>
Todd Fischer | 7 May 2013 00:28
Gravatar

video processing front end mutex usage and parameter passing

Hi,

In reviewing vpfe_capture.c, we are seeing some code that seems wrong.  
We don't fully understand when the VPFE device lock needs to be held, 
but it seems the lock is not used consistently.  Also in some cases we 
found a pointer to a structure was passed in as a parameter and instead 
of accessing the contents of the structure the value of the pointer 
parameter that is local to the function was modified (effectively doing 
nothing).   The code has been in the kernel for 3+ years.

Below is an example of what we think needs to be changed.   We haven't 
tested the changes as we are still trying to verify the mutex usage.

Can someone familiar with the VPFE code give us some feedback if we are 
on the right track?

Todd

diff --git a/drivers/media/platform/davinci/vpfe_capture.c 
b/drivers/media/platform/davinci/vpfe_capture.c
index 28d019d..dc050b5 100644
--- a/drivers/media/platform/davinci/vpfe_capture.c
+++ b/drivers/media/platform/davinci/vpfe_capture.c
 <at>  <at>  -945,7 +945,9  <at>  <at>  static int vpfe_g_fmt_vid_cap(struct file *file, 
void *priv,

         v4l2_dbg(1, debug, &vpfe_dev->v4l2_dev, "vpfe_g_fmt_vid_cap\n");
         /* Fill in the information about format */
-       *fmt = vpfe_dev->fmt;
+       mutex_lock(&vpfe_dev->lock);
+       memcpy(fmt, vpfe_dev->fmt, sizeof(struct v4l2_format));
+       mutex_unlock(&vpfe_dev->lock);
         return ret;
  }

 <at>  <at>  -1001,7 +1003,7  <at>  <at>  static int vpfe_s_fmt_vid_cap(struct file *file, 
void *priv,

         /* First detach any IRQ if currently attached */
         vpfe_detach_irq(vpfe_dev);
-       vpfe_dev->fmt = *fmt;
+       memcpy(vpfe_dev->fmt, fmt, sizeof(struct v4l2_format));
         /* set image capture parameters in the ccdc */
         ret = vpfe_config_ccdc_image_format(vpfe_dev);
         mutex_unlock(&vpfe_dev->lock);

Prabhakar Lad | 26 Apr 2013 10:05
Picon
Gravatar

[PATCH] media: i2c: tvp7002: enable TVP7002 decoder for media controller based usage

From: Lad, Prabhakar <prabhakar.csengg@...>

This patch enables tvp7002 decoder driver for media controller
based usage by adding v4l2_subdev_pad_ops  operations support
for enum_mbus_code, set_pad_format, get_pad_format and media_entity_init()
on probe and media_entity_cleanup() on remove.

The device supports 1 output pad and no input pads.

Signed-off-by: Lad, Prabhakar <prabhakar.csengg@...>
---
 drivers/media/i2c/tvp7002.c |  125 +++++++++++++++++++++++++++++++++++++++++--
 include/media/tvp7002.h     |    2 +
 2 files changed, 122 insertions(+), 5 deletions(-)

diff --git a/drivers/media/i2c/tvp7002.c b/drivers/media/i2c/tvp7002.c
index 027809c..b212d41 100644
--- a/drivers/media/i2c/tvp7002.c
+++ b/drivers/media/i2c/tvp7002.c
 <at>  <at>  -424,6 +424,8  <at>  <at>  struct tvp7002 {
 	int streaming;

 	const struct tvp7002_timings_definition *current_timings;
+	struct media_pad pad;
+	struct v4l2_mbus_framefmt format;
 };

 /*
 <at>  <at>  -880,6 +882,93  <at>  <at>  static const struct v4l2_ctrl_ops tvp7002_ctrl_ops = {
 	.s_ctrl = tvp7002_s_ctrl,
 };

+/*
+ * tvp7002_enum_mbus_code() - Enum supported digital video format on pad
+ *  <at> sd: pointer to standard V4L2 sub-device structure
+ *  <at> fh: file handle for the subdev
+ *  <at> code: pointer to subdev enum mbus code struct
+ *
+ * Enumerate supported digital video formats for pad.
+ */
+static int
+tvp7002_enum_mbus_code(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_mbus_code_enum *code)
+{
+	/* Check pad index is valid */
+	if (code->pad != 0)
+		return -EINVAL;
+
+	/* Check requested format index is within range */
+	if (code->index != 0)
+		return -EINVAL;
+
+	code->code = V4L2_MBUS_FMT_YUYV10_1X20;
+
+	return 0;
+}
+
+/*
+ * tvp7002_set_pad_format() - set video format on pad
+ *  <at> sd: pointer to standard V4L2 sub-device structure
+ *  <at> fh: file handle for the subdev
+ *  <at> fmt: pointer to subdev format struct
+ *
+ * set video format for pad.
+*/
+static int
+tvp7002_set_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_format *fmt)
+{
+	struct tvp7002 *tvp7002 = to_tvp7002(sd);
+
+	/* Check pad index is valid */
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	if (fmt->format.field != tvp7002->current_timings->scanmode ||
+	    fmt->format.code != V4L2_MBUS_FMT_YUYV10_1X20 ||
+	    fmt->format.colorspace != tvp7002->current_timings->color_space ||
+	    fmt->format.width != tvp7002->current_timings->timings.bt.width ||
+	    fmt->format.height != tvp7002->current_timings->timings.bt.height)
+		return -EINVAL;
+
+	tvp7002->format = fmt->format;
+
+	return 0;
+}
+
+/*
+ * tvp7002_get_pad_format() - get video format on pad
+ *  <at> sd: pointer to standard V4L2 sub-device structure
+ *  <at> fh: file handle for the subdev
+ *  <at> fmt: pointer to subdev format struct
+ *
+ * get video format for pad.
+ */
+static int
+tvp7002_get_pad_format(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh,
+		       struct v4l2_subdev_format *fmt)
+{
+	struct tvp7002 *tvp7002 = to_tvp7002(sd);
+
+	/* Check pad index is valid */
+	if (fmt->pad != 0)
+		return -EINVAL;
+
+	if (fmt->which == V4L2_SUBDEV_FORMAT_ACTIVE) {
+		fmt->format = tvp7002->format;
+		return 0;
+	}
+
+	fmt->format.code = V4L2_MBUS_FMT_YUYV10_1X20;
+	fmt->format.width = tvp7002->current_timings->timings.bt.width;
+	fmt->format.height = tvp7002->current_timings->timings.bt.height;
+	fmt->format.field = tvp7002->current_timings->scanmode;
+	fmt->format.colorspace = tvp7002->current_timings->color_space;
+
+	return 0;
+}
+
 /* V4L2 core operation handlers */
 static const struct v4l2_subdev_core_ops tvp7002_core_ops = {
 	.g_chip_ident = tvp7002_g_chip_ident,
 <at>  <at>  -910,10 +999,18  <at>  <at>  static const struct v4l2_subdev_video_ops tvp7002_video_ops = {
 	.enum_mbus_fmt = tvp7002_enum_mbus_fmt,
 };

+/* media pad related operation handlers */
+static const struct v4l2_subdev_pad_ops tvp7002_pad_ops = {
+	.enum_mbus_code = tvp7002_enum_mbus_code,
+	.get_fmt = tvp7002_get_pad_format,
+	.set_fmt = tvp7002_set_pad_format,
+};
+
 /* V4L2 top level operation handlers */
 static const struct v4l2_subdev_ops tvp7002_ops = {
 	.core = &tvp7002_core_ops,
 	.video = &tvp7002_video_ops,
+	.pad = &tvp7002_pad_ops,
 };

 /*
 <at>  <at>  -993,19 +1090,35  <at>  <at>  static int tvp7002_probe(struct i2c_client *c, const struct i2c_device_id *id)
 	timings = device->current_timings->timings;
 	error = tvp7002_s_dv_timings(sd, &timings);

+#if defined(CONFIG_MEDIA_CONTROLLER)
+	strlcpy(sd->name, TVP7002_MODULE_NAME, sizeof(sd->name));
+	device->pad.flags = MEDIA_PAD_FL_SOURCE;
+	device->sd.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
+	device->sd.entity.flags |= MEDIA_ENT_T_V4L2_SUBDEV_DECODER;
+
+	error = media_entity_init(&device->sd.entity, 1, &device->pad, 0);
+	if (error < 0)
+		return error;
+#endif
+
 	v4l2_ctrl_handler_init(&device->hdl, 1);
 	v4l2_ctrl_new_std(&device->hdl, &tvp7002_ctrl_ops,
 			V4L2_CID_GAIN, 0, 255, 1, 0);
 	sd->ctrl_handler = &device->hdl;
 	if (device->hdl.error) {
-		int err = device->hdl.error;
-
-		v4l2_ctrl_handler_free(&device->hdl);
-		return err;
+		error = device->hdl.error;
+		goto done;
 	}
 	v4l2_ctrl_handler_setup(&device->hdl);

 	return 0;
+
+done:
+	v4l2_ctrl_handler_free(&device->hdl);
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&device->sd.entity);
+#endif
+	return error;
 }

 /*
 <at>  <at>  -1022,7 +1135,9  <at>  <at>  static int tvp7002_remove(struct i2c_client *c)

 	v4l2_dbg(1, debug, sd, "Removing tvp7002 adapter"
 				"on address 0x%x\n", c->addr);
-
+#if defined(CONFIG_MEDIA_CONTROLLER)
+	media_entity_cleanup(&device->sd.entity);
+#endif
 	v4l2_device_unregister_subdev(sd);
 	v4l2_ctrl_handler_free(&device->hdl);
 	return 0;
diff --git a/include/media/tvp7002.h b/include/media/tvp7002.h
index ee43534..7123048 100644
--- a/include/media/tvp7002.h
+++ b/include/media/tvp7002.h
 <at>  <at>  -26,6 +26,8  <at>  <at> 
 #ifndef _TVP7002_H_
 #define _TVP7002_H_
 
+#define TVP7002_MODULE_NAME "tvp7002"
+
 /* Platform-dependent data
  *
  * clk_polarity:
--

-- 
1.7.4.1

Prabhakar Lad | 24 Apr 2013 06:56
Picon
Gravatar

Re: dm365 linux 2.6.37 network performance

Ccing Dlos and Mugunthan

Hi Ben,

On Tue, Apr 23, 2013 at 4:31 PM, Ben Wang <benfounder@...> wrote:
> Hi Lad,
>
> I am a engineer working on dm365. Currently I am using linux kernel
> 2.6.37. But I found the network performance is not as good as the one
> on kernel 2.6.18.
>
> Here is the test results I got.
>
> With kernel 2.6.18
> # ./iperf -c 192.168.1.70 -w 32768 -d -t 60
> ------------------------------------------------------------
> Server listening on TCP port 5001
> TCP window size: 64.0 KByte (WARNING: requested 32.0 KByte)
> ------------------------------------------------------------
> ------------------------------------------------------------
> Client connecting to 192.168.1.70, TCP port 5001
> TCP window size: 64.0 KByte (WARNING: requested 32.0 KByte)
> ------------------------------------------------------------
> [  5] local 192.168.1.99 port 4578 connected with 192.168.1.70 port 5001
> [  4] local 192.168.1.99 port 5001 connected with 192.168.1.70 port 4509
> [ ID] Interval       Transfer     Bandwidth
> [  5]  0.0-60.0 sec    325 MBytes  45.4 Mbitsc
> [  4]  0.0-59.9 sec    353 MBytes  49.4 Mbitsc
>
>
> With kernel 2.6.37
> ./iperf -c 192.168.1.70 -w 32768 -d -t 60
> ------------------------------------------------------------
> Server listening on TCP port 5001
> TCP window size: 64.0 KByte (WARNING: requested 32.0 KByte)
> ------------------------------------------------------------
> ------------------------------------------------------------
> Client connecting to 192.168.1.70, TCP port 5001
> TCP window size: 64.0 KByte (WARNING: requested 32.0 KByte)
> ------------------------------------------------------------
> [  3] local 192.168.1.77 port 55370 connected with 192.168.1.70 port 5001
> [  5] local 192.168.1.77 port 5001 connected with 192.168.1.70 port 4624
> [ ID] Interval       Transfer     Bandwidth
> [  3]  0.0-60.0 sec    248 MBytes  34.6 Mbitsc
> [  5]  0.0-60.0 sec    127 MBytes  17.7 Mbitsc
>
> I compared the source code of 2.6.37 with 2.6.32. The driver for dm365
> emac part changed dramatically. I suspect the somewhere make the
> performance drop.
>
> So can you take a look at it? Our project is blocked on this performance issue.
>

I would have loved to help you but unfortunately I am not a
network driver expert I am good at multimedia only.

Regards,
--Prabhakar

> Thanks a lot,
> Ben
Darryl | 18 Apr 2013 15:22
Favicon

davinci and camera

We are on Linux-2.6.33.9 with real-time patches and attempting to add 
the Aptina MT9M131 (which seems to look mostly match the MT9M111 driver 
in that version of the kernel, so I'm using it) so that we can capture 
images on the CPU's VPIF (there is also a vpif_capture driver in these 
kernel sources.

QUESTION:  The 'Documentation/video4linux/soc-camera.txt' file 
references two required drivers: a host driver and a sensor driver. Do 
mt9m111 and vpif_capture correspond to these, respectively?

Toward the end of this email, I discuss the changes I have made to the 
board file and kernel configuration to allow usage of these drivers.

QUESTION:  Assuming a 'yes' to the previous question, in what order will 
I need to probe these drivers?

I have observed that when I "modprobe mt9m111", the "soc_camera" module 
(dependency) is loaded and "soc_camera_pdrv_probe" is successful, using 
the camera link and and platform devices from the board file.  However, 
when the mt9m111 probe runs, it expects platform data for the device to 
contain a pointer to, I think, the "struct soc_camera_device" created by 
"soc_camera_pdrv_probe", but this pointer is NULL!  As a point of 
reference, I notice that in newer kernels (I have a copy of 3.7-rc8) 
expect that pointer to be a pointer to the link from the board file, but 
the diff of soc_camera.c doesn't look sufficient to get that pointer set.

On the other hand, if I "modprobe vpif_capture", it fails because it 
wants to register a V4L2 subdevice for which there is no device, I 
suppose because the "primary" device  should be created by mt9m111.

So, the primary problem I see is the NULL pointer that mt9m111's probe 
function receives.

Can anyone offer some help??

==============================

Config and board file changes:

- enabled the .config for the camera
- added an I2C entry for the 111 in the board file
- added added the "struct soc_camera_link" in the board file
   the bus_id and i2c_adapter_id are set to 0,
   board info points to the i2c_board_info for the  111
   set the 'module_name' to "mt9m111"
   added entries for the power and reset functions (which are controlled 
by GPIOs)
- added a "struct platform_device" in the board file
   the name is "soc-camera-pdrv" (a requirement of soc_camera)
   point the dev.platform_data to the camera link structure
- wrote a function that does all the registration and added it to the 
board initialization function

- enabled the .configs for the VPIF
- struct vpif_subdev_info
- struct vpif_input
- vpif_capture_config
- wrote a function that calls the da850_register_vpif and 
da850_register_vpif_capture functions and added it to the board 
initialization function

QUESTION:  What order do I probe


Gmane