Re: [PATCH] V4L: s5c73m3: Add format propagation for TRY formats
Hi Laurent, Thank you for the review. On 08/09/2013 12:58 AM, Laurent Pinchart wrote: Hello, On Wednesday 24 July 2013 16:57:32 Sylwester Nawrocki wrote: From: Andrzej Hajda a.ha...@samsung.com Resolution set on ISP pad of S5C73M3-OIF subdev should be propagated to source pad for TRY and ACTIVE formats. The patch adds missing propagation for TRY format. I might be missing something, but where's the propagation for the ACTIVE format ? In case of active format there are no separate containers for the format of each pad, instead they shares common fields, precisely .oif_pix_size and .mbus_code. This way there is no need for extra code for format propagation. Regards Andrzej Signed-off-by: Andrzej Hajda a.ha...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com --- drivers/media/i2c/s5c73m3/s5c73m3-core.c |5 + 1 file changed, 5 insertions(+) diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 825ea86..b76ec0e 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -,6 +,11 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, if (fmt-which == V4L2_SUBDEV_FORMAT_TRY) { mf = v4l2_subdev_get_try_format(fh, fmt-pad); *mf = fmt-format; +if (fmt-pad == OIF_ISP_PAD) { +mf = v4l2_subdev_get_try_format(fh, OIF_SOURCE_PAD); +mf-width = fmt-format.width; +mf-height = fmt-format.height; +} } else { switch (fmt-pad) { case OIF_ISP_PAD: -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] qv4l2: change m_scaledFrame to m_scaledSize
Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/capture-win-qt.cpp | 12 ++-- utils/qv4l2/capture-win-qt.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp index f746379..82c618c 100644 --- a/utils/qv4l2/capture-win-qt.cpp +++ b/utils/qv4l2/capture-win-qt.cpp @@ -24,8 +24,8 @@ CaptureWinQt::CaptureWinQt() : { CaptureWin::buildWindow(m_videoSurface); - m_scaledFrame.setWidth(0); - m_scaledFrame.setHeight(0); + m_scaledSize.setWidth(0); + m_scaledSize.setHeight(0); } CaptureWinQt::~CaptureWinQt() @@ -39,9 +39,9 @@ void CaptureWinQt::resizeEvent(QResizeEvent *event) return; QPixmap img = QPixmap::fromImage(*m_frame); - m_scaledFrame = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), + m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), QSize(m_frame-width(), m_frame-height())); - img = img.scaled(m_scaledFrame.width(), m_scaledFrame.height(), Qt::IgnoreAspectRatio); + img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); m_videoSurface.setPixmap(img); QWidget::resizeEvent(event); } @@ -56,7 +56,7 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char * if (m_frame-width() != width || m_frame-height() != height || m_frame-format() != dstFmt) { delete m_frame; m_frame = new QImage(width, height, dstFmt); - m_scaledFrame = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), + m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), QSize(m_frame-width(), m_frame-height())); } @@ -68,7 +68,7 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char * m_information.setText(info); QPixmap img = QPixmap::fromImage(*m_frame); - img = img.scaled(m_scaledFrame.width(), m_scaledFrame.height(), Qt::IgnoreAspectRatio); + img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); m_videoSurface.setPixmap(img); } diff --git a/utils/qv4l2/capture-win-qt.h b/utils/qv4l2/capture-win-qt.h index 6029109..9faa12f 100644 --- a/utils/qv4l2/capture-win-qt.h +++ b/utils/qv4l2/capture-win-qt.h @@ -48,6 +48,6 @@ private: QImage *m_frame; QLabel m_videoSurface; - QSize m_scaledFrame; + QSize m_scaledSize; }; #endif -- 1.8.4.rc1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] qv4l2: add cropping and qt opimization
Adds cropping to CaptureWin. It also optimizes Qt renderer to make it perform as expected with cropping and scaling. Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/capture-win-gl.cpp | 27 +++-- utils/qv4l2/capture-win-gl.h | 1 + utils/qv4l2/capture-win-qt.cpp | 89 -- utils/qv4l2/capture-win-qt.h | 17 +++- utils/qv4l2/capture-win.cpp| 57 ++- utils/qv4l2/capture-win.h | 20 +++--- utils/qv4l2/general-tab.cpp| 57 --- utils/qv4l2/general-tab.h | 5 +++ utils/qv4l2/qv4l2.cpp | 7 utils/qv4l2/qv4l2.h| 1 + 10 files changed, 216 insertions(+), 65 deletions(-) diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp index 27ff3d3..d1828cf 100644 --- a/utils/qv4l2/capture-win-gl.cpp +++ b/utils/qv4l2/capture-win-gl.cpp @@ -261,6 +261,18 @@ void CaptureWinGLEngine::changeShader() glClear(GL_COLOR_BUFFER_BIT); } +void CaptureWinGLEngine::paintFrame() +{ + float crop = (float)CaptureWin::cropHeight(m_frameWidth, m_frameHeight) / m_frameHeight; + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, crop); glVertex2f(0.0, 0); + glTexCoord2f(1.0f, crop); glVertex2f(m_frameWidth, 0); + glTexCoord2f(1.0f, 1.0f - crop); glVertex2f(m_frameWidth, m_frameHeight); + glTexCoord2f(0.0f, 1.0f - crop); glVertex2f(0, m_frameHeight); + glEnd(); +} + void CaptureWinGLEngine::paintGL() { if (m_frameWidth 1 || m_frameHeight 1) { @@ -271,12 +283,7 @@ void CaptureWinGLEngine::paintGL() changeShader(); if (m_frameData == NULL) { - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight); - glEnd(); + paintFrame(); return; } @@ -329,13 +336,7 @@ void CaptureWinGLEngine::paintGL() checkError(Default paint); break; } - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight); - glEnd(); + paintFrame(); } void CaptureWinGLEngine::configureTexture(size_t idx) diff --git a/utils/qv4l2/capture-win-gl.h b/utils/qv4l2/capture-win-gl.h index 0c3ff8b..5a7fb3d 100644 --- a/utils/qv4l2/capture-win-gl.h +++ b/utils/qv4l2/capture-win-gl.h @@ -65,6 +65,7 @@ private: void clearShader(); void changeShader(); + void paintFrame(); void configureTexture(size_t idx); void checkError(const char *msg); diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp index 82c618c..cc21364 100644 --- a/utils/qv4l2/capture-win-qt.cpp +++ b/utils/qv4l2/capture-win-qt.cpp @@ -20,12 +20,19 @@ #include capture-win-qt.h CaptureWinQt::CaptureWinQt() : - m_frame(new QImage(0, 0, QImage::Format_Invalid)) + m_frame(new QImage(0, 0, QImage::Format_Invalid)), + m_data(NULL), + m_supportedFormat(false), + m_filled(false) { CaptureWin::buildWindow(m_videoSurface); m_scaledSize.setWidth(0); m_scaledSize.setHeight(0); + m_crop.crop = 0; + m_crop.height = 0; + m_crop.offset = 0; + m_crop.bytes = 0; } CaptureWinQt::~CaptureWinQt() @@ -33,46 +40,88 @@ CaptureWinQt::~CaptureWinQt() delete m_frame; } -void CaptureWinQt::resizeEvent(QResizeEvent *event) +void CaptureWinQt::resizeScaleCrop() { - if (m_frame-bits() == NULL) - return; - - QPixmap img = QPixmap::fromImage(*m_frame); m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), - QSize(m_frame-width(), m_frame-height())); - img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); - m_videoSurface.setPixmap(img); - QWidget::resizeEvent(event); + QSize(m_frame-width(), m_frame-height())); + + if (!m_crop.bytes || m_crop.crop != cropHeight(m_frame-width(), m_frame-height())) { + m_crop.crop = cropHeight(m_frame-width(), m_frame-height()); + m_crop.height = m_frame-height() - (m_crop.crop * 2); + m_crop.offset = m_crop.crop * (m_frame-depth() / 8) * m_frame-width(); + + // Even though the values above can be valid, it might be that there is no + // data at all. This makes sure that it is. + m_crop.bytes = m_crop.height *
[PATCH 0/2] qv4l2: add cropping and qt opimization
Add cropping to CaptureWin as well as optimizing the Qt renderer. There is also other fixes and tweaks to the code itself. Cropping allows removal of letterboxing from the video display. Qt optimization no longer needs to copy the frame data for every frame and scaling or cropping is only performed when required. This was required to make cropping work efficent and should improve general performance. A consequence is that the Qt renderer has been rewritten. Some of the changes/improvements: - Update, add and fix status tips - Add cropping to CaptureWin - Optimized Qt renderer - Code cleanup Cropping options: - None - Top and Bottom Lines - Widescreen 14:9 - Widescreen 16:9 - Cinema 1.85:1 - Cinema 1.39:1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] V4L: s5c73m3: Add format propagation for TRY formats
Hi Andrzej, On Friday 09 August 2013 08:24:10 Andrzej Hajda wrote: On 08/09/2013 12:58 AM, Laurent Pinchart wrote: On Wednesday 24 July 2013 16:57:32 Sylwester Nawrocki wrote: From: Andrzej Hajda a.ha...@samsung.com Resolution set on ISP pad of S5C73M3-OIF subdev should be propagated to source pad for TRY and ACTIVE formats. The patch adds missing propagation for TRY format. I might be missing something, but where's the propagation for the ACTIVE format ? In case of active format there are no separate containers for the format of each pad, instead they shares common fields, precisely .oif_pix_size and .mbus_code. This way there is no need for extra code for format propagation. I got confused by the s5c73m3_oif_get_fmt() implementation that retrieves the pixel code and frame size from different internal state fields for the soruce pad. The code looks correct. Signed-off-by: Andrzej Hajda a.ha...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com --- drivers/media/i2c/s5c73m3/s5c73m3-core.c |5 + 1 file changed, 5 insertions(+) diff --git a/drivers/media/i2c/s5c73m3/s5c73m3-core.c b/drivers/media/i2c/s5c73m3/s5c73m3-core.c index 825ea86..b76ec0e 100644 --- a/drivers/media/i2c/s5c73m3/s5c73m3-core.c +++ b/drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -,6 +,11 @@ static int s5c73m3_oif_set_fmt(struct v4l2_subdev *sd, if (fmt-which == V4L2_SUBDEV_FORMAT_TRY) { mf = v4l2_subdev_get_try_format(fh, fmt-pad); *mf = fmt-format; + if (fmt-pad == OIF_ISP_PAD) { + mf = v4l2_subdev_get_try_format(fh, OIF_SOURCE_PAD); + mf-width = fmt-format.width; + mf-height = fmt-format.height; + } } else { switch (fmt-pad) { case OIF_ISP_PAD: -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] qv4l2: add cropping and qt opimization
On Fri 9 August 2013 09:43:49 Bård Eirik Winther wrote: Adds cropping to CaptureWin. It also optimizes Qt renderer to make it perform as expected with cropping and scaling. Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/capture-win-gl.cpp | 27 +++-- utils/qv4l2/capture-win-gl.h | 1 + utils/qv4l2/capture-win-qt.cpp | 89 -- utils/qv4l2/capture-win-qt.h | 17 +++- utils/qv4l2/capture-win.cpp| 57 ++- utils/qv4l2/capture-win.h | 20 +++--- utils/qv4l2/general-tab.cpp| 57 --- utils/qv4l2/general-tab.h | 5 +++ utils/qv4l2/qv4l2.cpp | 7 utils/qv4l2/qv4l2.h| 1 + 10 files changed, 216 insertions(+), 65 deletions(-) diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp index 27ff3d3..d1828cf 100644 --- a/utils/qv4l2/capture-win-gl.cpp +++ b/utils/qv4l2/capture-win-gl.cpp @@ -261,6 +261,18 @@ void CaptureWinGLEngine::changeShader() glClear(GL_COLOR_BUFFER_BIT); } +void CaptureWinGLEngine::paintFrame() +{ + float crop = (float)CaptureWin::cropHeight(m_frameWidth, m_frameHeight) / m_frameHeight; + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, crop); glVertex2f(0.0, 0); + glTexCoord2f(1.0f, crop); glVertex2f(m_frameWidth, 0); + glTexCoord2f(1.0f, 1.0f - crop); glVertex2f(m_frameWidth, m_frameHeight); + glTexCoord2f(0.0f, 1.0f - crop); glVertex2f(0, m_frameHeight); + glEnd(); +} + void CaptureWinGLEngine::paintGL() { if (m_frameWidth 1 || m_frameHeight 1) { @@ -271,12 +283,7 @@ void CaptureWinGLEngine::paintGL() changeShader(); if (m_frameData == NULL) { - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight); - glEnd(); + paintFrame(); return; } @@ -329,13 +336,7 @@ void CaptureWinGLEngine::paintGL() checkError(Default paint); break; } - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight); - glEnd(); + paintFrame(); } void CaptureWinGLEngine::configureTexture(size_t idx) diff --git a/utils/qv4l2/capture-win-gl.h b/utils/qv4l2/capture-win-gl.h index 0c3ff8b..5a7fb3d 100644 --- a/utils/qv4l2/capture-win-gl.h +++ b/utils/qv4l2/capture-win-gl.h @@ -65,6 +65,7 @@ private: void clearShader(); void changeShader(); + void paintFrame(); void configureTexture(size_t idx); void checkError(const char *msg); diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp index 82c618c..cc21364 100644 --- a/utils/qv4l2/capture-win-qt.cpp +++ b/utils/qv4l2/capture-win-qt.cpp @@ -20,12 +20,19 @@ #include capture-win-qt.h CaptureWinQt::CaptureWinQt() : - m_frame(new QImage(0, 0, QImage::Format_Invalid)) + m_frame(new QImage(0, 0, QImage::Format_Invalid)), + m_data(NULL), + m_supportedFormat(false), + m_filled(false) { CaptureWin::buildWindow(m_videoSurface); m_scaledSize.setWidth(0); m_scaledSize.setHeight(0); + m_crop.crop = 0; + m_crop.height = 0; + m_crop.offset = 0; + m_crop.bytes = 0; } CaptureWinQt::~CaptureWinQt() @@ -33,46 +40,88 @@ CaptureWinQt::~CaptureWinQt() delete m_frame; } -void CaptureWinQt::resizeEvent(QResizeEvent *event) +void CaptureWinQt::resizeScaleCrop() { - if (m_frame-bits() == NULL) - return; - - QPixmap img = QPixmap::fromImage(*m_frame); m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), -QSize(m_frame-width(), m_frame-height())); - img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); - m_videoSurface.setPixmap(img); - QWidget::resizeEvent(event); + QSize(m_frame-width(), m_frame-height())); + + if (!m_crop.bytes || m_crop.crop != cropHeight(m_frame-width(), m_frame-height())) { + m_crop.crop = cropHeight(m_frame-width(), m_frame-height()); + m_crop.height = m_frame-height() - (m_crop.crop * 2); + m_crop.offset = m_crop.crop * (m_frame-depth() / 8) * m_frame-width(); + + // Even though the values above can be valid, it might be that there is no + // data at all. This makes sure
[PATCH v2] mt9v032: Use the common clock framework
Configure the device external clock using the common clock framework instead of a board code callback function. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/media/i2c/mt9v032.c | 17 +++-- include/media/mt9v032.h | 4 2 files changed, 11 insertions(+), 10 deletions(-) Changes since v1: - Set the pixel clock rate with clk_set_rate() diff --git a/drivers/media/i2c/mt9v032.c b/drivers/media/i2c/mt9v032.c index 60c6f67..2c50eff 100644 --- a/drivers/media/i2c/mt9v032.c +++ b/drivers/media/i2c/mt9v032.c @@ -12,6 +12,7 @@ * published by the Free Software Foundation. */ +#include linux/clk.h #include linux/delay.h #include linux/i2c.h #include linux/log2.h @@ -135,6 +136,8 @@ struct mt9v032 { struct mutex power_lock; int power_count; + struct clk *clk; + struct mt9v032_platform_data *pdata; u32 sysclk; @@ -219,10 +222,9 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032) struct i2c_client *client = v4l2_get_subdevdata(mt9v032-subdev); int ret; - if (mt9v032-pdata-set_clock) { - mt9v032-pdata-set_clock(mt9v032-subdev, mt9v032-sysclk); - udelay(1); - } + clk_set_rate(mt9v032-clk, mt9v032-sysclk); + clk_prepare_enable(mt9v032-clk); + udelay(1); /* Reset the chip and stop data read out */ ret = mt9v032_write(client, MT9V032_RESET, 1); @@ -238,8 +240,7 @@ static int mt9v032_power_on(struct mt9v032 *mt9v032) static void mt9v032_power_off(struct mt9v032 *mt9v032) { - if (mt9v032-pdata-set_clock) - mt9v032-pdata-set_clock(mt9v032-subdev, 0); + clk_disable_unprepare(mt9v032-clk); } static int __mt9v032_set_power(struct mt9v032 *mt9v032, bool on) @@ -748,6 +749,10 @@ static int mt9v032_probe(struct i2c_client *client, if (!mt9v032) return -ENOMEM; + mt9v032-clk = devm_clk_get(client-dev, NULL); + if (IS_ERR(mt9v032-clk)) + return PTR_ERR(mt9v032-clk); + mutex_init(mt9v032-power_lock); mt9v032-pdata = pdata; diff --git a/include/media/mt9v032.h b/include/media/mt9v032.h index 78fd39e..12175a6 100644 --- a/include/media/mt9v032.h +++ b/include/media/mt9v032.h @@ -1,13 +1,9 @@ #ifndef _MEDIA_MT9V032_H #define _MEDIA_MT9V032_H -struct v4l2_subdev; - struct mt9v032_platform_data { unsigned int clk_pol:1; - void (*set_clock)(struct v4l2_subdev *subdev, unsigned int rate); - const s64 *link_freqs; s64 link_def_freq; }; -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
holiday absence
Hi all As many of you already know, I'm on holidays for the next two weeks - until 25th August - with very limited to no access to the internet and email. I'll be sending a couple more emails today to try to make sure nothing gets lost on the way to 3.12. Wishing all a good fortnight. Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] Fix AB-BA deadlock in vb2_prepare_buffer()
Hello, This patch set fixes a deadlock in the vb2_prepare_buffer() function. See the commit message of patch 1/2 for more information. Patch 2/2 then proceeds to refactor vb2_prepare_buffer() and vb2_qbuf() to avoid code duplication. Laurent Pinchart (2): media: vb2: Fix potential deadlock in vb2_prepare_buffer media: vb2: Share code between vb2_prepare_buf and vb2_qbuf drivers/media/v4l2-core/videobuf2-core.c | 212 +++ 1 file changed, 101 insertions(+), 111 deletions(-) -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] media: vb2: Share code between vb2_prepare_buf and vb2_qbuf
The two operations are very similar, refactor most of the code in a helper function. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/media/v4l2-core/videobuf2-core.c | 202 --- 1 file changed, 79 insertions(+), 123 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7c2a8ce..c9f8c3f 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1231,42 +1231,31 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) return ret; } -/** - * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel - * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_prepare_buf - * handler in driver - * - * Should be called from vidioc_prepare_buf ioctl handler of a driver. - * This function: - * 1) verifies the passed buffer, - * 2) calls buf_prepare callback in the driver (if provided), in which - *driver-specific buffer initialization can be performed, - * - * The return values from this function are intended to be directly returned - * from vidioc_prepare_buf handler in driver. - */ -int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) +static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b, + const char *opname, + int (*handler)(struct vb2_queue *, + struct v4l2_buffer *, + struct vb2_buffer *)) { struct rw_semaphore *mmap_sem = NULL; struct vb2_buffer *vb; int ret; /* -* In case of user pointer buffers vb2 allocator needs to get direct -* access to userspace pages. This requires getting read access on -* mmap semaphore in the current process structure. The same -* semaphore is taken before calling mmap operation, while both mmap -* and prepare_buf are called by the driver or v4l2 core with driver's -* lock held. To avoid a AB-BA deadlock (mmap_sem then driver's lock in -* mmap and driver's lock then mmap_sem in prepare_buf) the videobuf2 -* core release driver's lock, takes mmap_sem and then takes again -* driver's lock. +* In case of user pointer buffers vb2 allocators need to get direct +* access to userspace pages. This requires getting the mmap semaphore +* for read access in the current process structure. The same semaphore +* is taken before calling mmap operation, while both qbuf/prepare_buf +* and mmap are called by the driver or v4l2 core with the driver's lock +* held. To avoid an AB-BA deadlock (mmap_sem then driver's lock in mmap +* and driver's lock then mmap_sem in qbuf/prepare_buf) the videobuf2 +* core releases the driver's lock, takes mmap_sem and then takes the +* driver's lock again. * -* To avoid race with other vb2 calls, which might be called after -* releasing driver's lock, this operation is performed at the -* beggining of prepare_buf processing. This way the queue status is -* consistent after getting driver's lock back. +* To avoid racing with other vb2 calls, which might be called after +* releasing the driver's lock, this operation is performed at the +* beginning of qbuf/prepare_buf processing. This way the queue status +* is consistent after getting the driver's lock back. */ if (q-memory == V4L2_MEMORY_USERPTR) { mmap_sem = current-mm-mmap_sem; @@ -1276,19 +1265,19 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) } if (q-fileio) { - dprintk(1, %s(): file io in progress\n, __func__); + dprintk(1, %s(): file io in progress\n, opname); ret = -EBUSY; goto unlock; } if (b-type != q-type) { - dprintk(1, %s(): invalid buffer type\n, __func__); + dprintk(1, %s(): invalid buffer type\n, opname); ret = -EINVAL; goto unlock; } if (b-index = q-num_buffers) { - dprintk(1, %s(): buffer index out of range\n, __func__); + dprintk(1, %s(): buffer index out of range\n, opname); ret = -EINVAL; goto unlock; } @@ -1296,131 +1285,83 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) vb = q-bufs[b-index]; if (NULL == vb) { /* Should never happen */ - dprintk(1, %s(): buffer is NULL\n, __func__); + dprintk(1, %s(): buffer is NULL\n, opname); ret = -EINVAL; goto unlock; } if
[PATCH 1/2] media: vb2: Fix potential deadlock in vb2_prepare_buffer
Commit b037c0fde22b1d3cd0b3c3717d28e54619fc1592 (media: vb2: fix potential deadlock in mmap vs. get_userptr handling) fixes an AB-BA deadlock related to the mmap_sem and driver locks. The same deadlock can occur in vb2_prepare_buffer(), fix it the same way. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/media/v4l2-core/videobuf2-core.c | 52 ++-- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7f32860..7c2a8ce 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1248,50 +1248,84 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) */ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) { + struct rw_semaphore *mmap_sem = NULL; struct vb2_buffer *vb; int ret; + /* +* In case of user pointer buffers vb2 allocator needs to get direct +* access to userspace pages. This requires getting read access on +* mmap semaphore in the current process structure. The same +* semaphore is taken before calling mmap operation, while both mmap +* and prepare_buf are called by the driver or v4l2 core with driver's +* lock held. To avoid a AB-BA deadlock (mmap_sem then driver's lock in +* mmap and driver's lock then mmap_sem in prepare_buf) the videobuf2 +* core release driver's lock, takes mmap_sem and then takes again +* driver's lock. +* +* To avoid race with other vb2 calls, which might be called after +* releasing driver's lock, this operation is performed at the +* beggining of prepare_buf processing. This way the queue status is +* consistent after getting driver's lock back. +*/ + if (q-memory == V4L2_MEMORY_USERPTR) { + mmap_sem = current-mm-mmap_sem; + call_qop(q, wait_prepare, q); + down_read(mmap_sem); + call_qop(q, wait_finish, q); + } + if (q-fileio) { dprintk(1, %s(): file io in progress\n, __func__); - return -EBUSY; + ret = -EBUSY; + goto unlock; } if (b-type != q-type) { dprintk(1, %s(): invalid buffer type\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (b-index = q-num_buffers) { dprintk(1, %s(): buffer index out of range\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } vb = q-bufs[b-index]; if (NULL == vb) { /* Should never happen */ dprintk(1, %s(): buffer is NULL\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (b-memory != q-memory) { dprintk(1, %s(): invalid memory type\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (vb-state != VB2_BUF_STATE_DEQUEUED) { dprintk(1, %s(): invalid buffer state %d\n, __func__, vb-state); - return -EINVAL; + ret = -EINVAL; + goto unlock; } ret = __verify_planes_array(vb, b); if (ret 0) - return ret; + goto unlock; + ret = __buf_prepare(vb, b); if (ret 0) - return ret; + goto unlock; __fill_v4l2_buffer(vb, b); - return 0; +unlock: + if (mmap_sem) + up_read(mmap_sem); + return ret; } EXPORT_SYMBOL_GPL(vb2_prepare_buf); -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH FINAL 0/6] qv4l2: cropping, optimization and documentatio
qv4l2: Add cropping to the CaptureWin. In order to make the Qt renderer work with this as well, it had to be optimized to not lose framerate. A basic manpage is added along width fixing the input parameters. New Features/Improvements: - Add cropping to CaptureWin - Qt renderer has been optimized (no longer uses memcpy!) - Add a basic manpage - About window shows version number and ALSA/OpenGL support - Fix program parameters - Fix status hints for some missing GeneralTab elements - Code cleanup and fixes -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH FINAL 1/6] qv4l2: change m_scaledFrame to m_scaledSize
Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/capture-win-qt.cpp | 12 ++-- utils/qv4l2/capture-win-qt.h | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp index f746379..82c618c 100644 --- a/utils/qv4l2/capture-win-qt.cpp +++ b/utils/qv4l2/capture-win-qt.cpp @@ -24,8 +24,8 @@ CaptureWinQt::CaptureWinQt() : { CaptureWin::buildWindow(m_videoSurface); - m_scaledFrame.setWidth(0); - m_scaledFrame.setHeight(0); + m_scaledSize.setWidth(0); + m_scaledSize.setHeight(0); } CaptureWinQt::~CaptureWinQt() @@ -39,9 +39,9 @@ void CaptureWinQt::resizeEvent(QResizeEvent *event) return; QPixmap img = QPixmap::fromImage(*m_frame); - m_scaledFrame = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), + m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), QSize(m_frame-width(), m_frame-height())); - img = img.scaled(m_scaledFrame.width(), m_scaledFrame.height(), Qt::IgnoreAspectRatio); + img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); m_videoSurface.setPixmap(img); QWidget::resizeEvent(event); } @@ -56,7 +56,7 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char * if (m_frame-width() != width || m_frame-height() != height || m_frame-format() != dstFmt) { delete m_frame; m_frame = new QImage(width, height, dstFmt); - m_scaledFrame = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), + m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), QSize(m_frame-width(), m_frame-height())); } @@ -68,7 +68,7 @@ void CaptureWinQt::setFrame(int width, int height, __u32 format, unsigned char * m_information.setText(info); QPixmap img = QPixmap::fromImage(*m_frame); - img = img.scaled(m_scaledFrame.width(), m_scaledFrame.height(), Qt::IgnoreAspectRatio); + img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); m_videoSurface.setPixmap(img); } diff --git a/utils/qv4l2/capture-win-qt.h b/utils/qv4l2/capture-win-qt.h index 6029109..9faa12f 100644 --- a/utils/qv4l2/capture-win-qt.h +++ b/utils/qv4l2/capture-win-qt.h @@ -48,6 +48,6 @@ private: QImage *m_frame; QLabel m_videoSurface; - QSize m_scaledFrame; + QSize m_scaledSize; }; #endif -- 1.8.4.rc1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH FINAL 3/6] qv4l2: fix missing status tips
Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/general-tab.cpp | 11 +-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp index 3855296..cfc6bcf 100644 --- a/utils/qv4l2/general-tab.cpp +++ b/utils/qv4l2/general-tab.cpp @@ -249,7 +249,9 @@ GeneralTab::GeneralTab(const QString device, v4l2 fd, int n, QWidget *parent) m_freq = new QLineEdit(parent); m_freq-setValidator(val); m_freq-setWhatsThis(QString(Frequency\nLow: %1\nHigh: %2) - .arg(m_tuner.rangelow / factor).arg(m_tuner.rangehigh / factor)); +.arg(m_tuner.rangelow / factor) +.arg((double)m_tuner.rangehigh / factor, 0, 'f', 2)); + m_freq-setStatusTip(m_freq-whatsThis()); connect(m_freq, SIGNAL(lostFocus()), SLOT(freqChanged())); connect(m_freq, SIGNAL(returnPressed()), SLOT(freqChanged())); updateFreq(); @@ -319,7 +321,9 @@ GeneralTab::GeneralTab(const QString device, v4l2 fd, int n, QWidget *parent) m_freq = new QLineEdit(parent); m_freq-setValidator(val); m_freq-setWhatsThis(QString(Frequency\nLow: %1\nHigh: %2) - .arg(m_modulator.rangelow / factor).arg(m_modulator.rangehigh / factor)); +.arg(m_tuner.rangelow / factor) +.arg((double)m_tuner.rangehigh / factor, 0, 'f', 2)); + m_freq-setStatusTip(m_freq-whatsThis()); connect(m_freq, SIGNAL(lostFocus()), SLOT(freqChanged())); connect(m_freq, SIGNAL(returnPressed()), SLOT(freqChanged())); updateFreq(); @@ -912,6 +916,7 @@ void GeneralTab::updateAudioInput() what += , has AVL; if (audio.mode V4L2_AUDMODE_AVL) what += , AVL is on; + m_audioInput-setStatusTip(what); m_audioInput-setWhatsThis(what); } @@ -964,6 +969,7 @@ void GeneralTab::updateStandard() (double)vs.frameperiod.numerator / vs.frameperiod.denominator, vs.frameperiod.numerator, vs.frameperiod.denominator, vs.framelines); + m_tvStandard-setStatusTip(what); m_tvStandard-setWhatsThis(what); updateVidCapFormat(); } @@ -1027,6 +1033,7 @@ void GeneralTab::updateTimings() what.sprintf(Video Timings (%u)\n Frame %ux%u\n, p.index, p.timings.bt.width, p.timings.bt.height); + m_videoTimings-setStatusTip(what); m_videoTimings-setWhatsThis(what); updateVidCapFormat(); } -- 1.8.4.rc1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH FINAL 4/6] qv4l2: fix program input parameters
Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/qv4l2.cpp | 137 -- 1 file changed, 121 insertions(+), 16 deletions(-) diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp index 7e2dba0..a0f21cd 100644 --- a/utils/qv4l2/qv4l2.cpp +++ b/utils/qv4l2/qv4l2.cpp @@ -1158,33 +1158,138 @@ void ApplicationWindow::closeEvent(QCloseEvent *event) ApplicationWindow *g_mw; +static void usage() +{ + printf( Usage:\n +qv4l2 [-R] [-h] [-d dev] [-r dev] [-V dev]\n + \n -d, --device=dev use device dev as the video device\n + if dev is a number, then /dev/videodev is used\n +-r, --radio-device=dev use device dev as the radio device\n + if dev is a number, then /dev/radiodev is used\n +-V, --vbi-device=dev use device dev as the vbi device\n + if dev is a number, then /dev/vbidev is used\n +-h, --help display this help message\n +-R, --raw open device in raw mode.\n); +} + +static void usageError(const char *msg) +{ + printf(Missing parameter for %s\n, msg); + usage(); +} + +static QString getDeviceName(QString dev, QString name) +{ + bool ok; + name.toInt(ok); + return ok ? QString(%1%2).arg(dev).arg(name) : name; +} + int main(int argc, char **argv) { QApplication a(argc, argv); - QString device = /dev/video0; bool raw = false; - bool help = false; - int i; + QString device; + QString video_device; + QString radio_device; + QString vbi_device; a.setWindowIcon(QIcon(:/qv4l2.png)); g_mw = new ApplicationWindow(); g_mw-setWindowTitle(V4L2 Test Bench); - for (i = 1; i argc; i++) { - const char *arg = a.argv()[i]; - if (!strcmp(arg, -r)) + QStringList args = a.arguments(); + for (int i = 1; i args.size(); i++) { + if (args[i] == -d || args[i] == --device) { + ++i; + if (i = args.size()) { + usageError(-d); + return 0; + } + + video_device = args[i]; + if (video_device.startsWith(-)) { + usageError(-d); + return 0; + } + + } else if (args[i] == -r || args[i] == --radio-device) { + ++i; + if (i = args.size()) { + usageError(-r); + return 0; + } + + radio_device = args[i]; + if (radio_device.startsWith(-)) { + usageError(-r); + return 0; + } + + } else if (args[i] == -V || args[i] == --vbi-device) { + ++i; + if (i = args.size()) { + usageError(-V); + return 0; + } + + vbi_device = args[i]; + if (vbi_device.startsWith(-)) { + usageError(-V); + return 0; + } + + } else if (args[i].startsWith(--device)) { + QStringList param = args[i].split(=); + if (param.size() == 2) { + video_device = param[1]; + } else { + usageError(--device); + return 0; + } + + } else if (args[i].startsWith(--radio-device)) { + QStringList param = args[i].split(=); + if (param.size() == 2) { + radio_device = param[1]; + } else { + usageError(--radio-device); + return 0; + } + + + } else if (args[i].startsWith(--vbi-device)) { + QStringList param = args[i].split(=); + if (param.size() == 2) { + vbi_device = param[1]; + } else { + usageError(--vbi-device); + return 0; + } + + } else if (args[i] == -h || args[i] == --help) { + usage(); + return 0; + + } else if (args[i] == -R || args[i] == --raw) { raw = true; - else if (!strcmp(arg, -h)) -
[PATCH FINAL 2/6] qv4l2: add cropping to CaptureWin and Qt render
Allows for removal of letterboxes from common video formats. The Qt renderer has been rewritten to increase performance required when applying cropping. No longer uses memcpy. Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/capture-win-gl.cpp | 27 +++-- utils/qv4l2/capture-win-gl.h | 1 + utils/qv4l2/capture-win-qt.cpp | 89 -- utils/qv4l2/capture-win-qt.h | 15 ++- utils/qv4l2/capture-win.cpp| 57 ++- utils/qv4l2/capture-win.h | 73 +- utils/qv4l2/general-tab.cpp| 63 +++--- utils/qv4l2/general-tab.h | 5 +++ utils/qv4l2/qv4l2.cpp | 7 utils/qv4l2/qv4l2.h| 1 + 10 files changed, 270 insertions(+), 68 deletions(-) diff --git a/utils/qv4l2/capture-win-gl.cpp b/utils/qv4l2/capture-win-gl.cpp index 27ff3d3..d1828cf 100644 --- a/utils/qv4l2/capture-win-gl.cpp +++ b/utils/qv4l2/capture-win-gl.cpp @@ -261,6 +261,18 @@ void CaptureWinGLEngine::changeShader() glClear(GL_COLOR_BUFFER_BIT); } +void CaptureWinGLEngine::paintFrame() +{ + float crop = (float)CaptureWin::cropHeight(m_frameWidth, m_frameHeight) / m_frameHeight; + + glBegin(GL_QUADS); + glTexCoord2f(0.0f, crop); glVertex2f(0.0, 0); + glTexCoord2f(1.0f, crop); glVertex2f(m_frameWidth, 0); + glTexCoord2f(1.0f, 1.0f - crop); glVertex2f(m_frameWidth, m_frameHeight); + glTexCoord2f(0.0f, 1.0f - crop); glVertex2f(0, m_frameHeight); + glEnd(); +} + void CaptureWinGLEngine::paintGL() { if (m_frameWidth 1 || m_frameHeight 1) { @@ -271,12 +283,7 @@ void CaptureWinGLEngine::paintGL() changeShader(); if (m_frameData == NULL) { - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight); - glEnd(); + paintFrame(); return; } @@ -329,13 +336,7 @@ void CaptureWinGLEngine::paintGL() checkError(Default paint); break; } - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0, 0); - glTexCoord2f(1.0f, 0.0f); glVertex2f(m_frameWidth, 0); - glTexCoord2f(1.0f, 1.0f); glVertex2f(m_frameWidth, m_frameHeight); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0, m_frameHeight); - glEnd(); + paintFrame(); } void CaptureWinGLEngine::configureTexture(size_t idx) diff --git a/utils/qv4l2/capture-win-gl.h b/utils/qv4l2/capture-win-gl.h index 0c3ff8b..5a7fb3d 100644 --- a/utils/qv4l2/capture-win-gl.h +++ b/utils/qv4l2/capture-win-gl.h @@ -65,6 +65,7 @@ private: void clearShader(); void changeShader(); + void paintFrame(); void configureTexture(size_t idx); void checkError(const char *msg); diff --git a/utils/qv4l2/capture-win-qt.cpp b/utils/qv4l2/capture-win-qt.cpp index 82c618c..d70f317 100644 --- a/utils/qv4l2/capture-win-qt.cpp +++ b/utils/qv4l2/capture-win-qt.cpp @@ -20,12 +20,19 @@ #include capture-win-qt.h CaptureWinQt::CaptureWinQt() : - m_frame(new QImage(0, 0, QImage::Format_Invalid)) + m_frame(new QImage(0, 0, QImage::Format_Invalid)), + m_data(NULL), + m_supportedFormat(false), + m_filled(false) { CaptureWin::buildWindow(m_videoSurface); m_scaledSize.setWidth(0); m_scaledSize.setHeight(0); + m_crop.crop = 0; + m_crop.height = 0; + m_crop.offset = 0; + m_crop.bytes = 0; } CaptureWinQt::~CaptureWinQt() @@ -33,46 +40,88 @@ CaptureWinQt::~CaptureWinQt() delete m_frame; } -void CaptureWinQt::resizeEvent(QResizeEvent *event) +void CaptureWinQt::resizeScaleCrop() { - if (m_frame-bits() == NULL) - return; - - QPixmap img = QPixmap::fromImage(*m_frame); m_scaledSize = scaleFrameSize(QSize(m_videoSurface.width(), m_videoSurface.height()), - QSize(m_frame-width(), m_frame-height())); - img = img.scaled(m_scaledSize.width(), m_scaledSize.height(), Qt::IgnoreAspectRatio); - m_videoSurface.setPixmap(img); - QWidget::resizeEvent(event); + QSize(m_frame-width(), m_frame-height())); + + if (!m_crop.bytes || m_crop.crop != cropHeight(m_frame-width(), m_frame-height())) { + m_crop.crop = cropHeight(m_frame-width(), m_frame-height()); + m_crop.height = m_frame-height() - (m_crop.crop * 2); + m_crop.offset = m_crop.crop * (m_frame-depth() / 8) * m_frame-width(); + + // Even though the values above can be valid, it might be that there is no + // data at all.
[PATCH FINAL 5/6] qv4l2: add manpage
Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/Makefile.am | 1 + utils/qv4l2/qv4l2.1 | 58 + 2 files changed, 59 insertions(+) create mode 100644 utils/qv4l2/qv4l2.1 diff --git a/utils/qv4l2/Makefile.am b/utils/qv4l2/Makefile.am index 58ac097..bdc64fd 100644 --- a/utils/qv4l2/Makefile.am +++ b/utils/qv4l2/Makefile.am @@ -1,4 +1,5 @@ bin_PROGRAMS = qv4l2 +man_MANS = qv4l2.1 qv4l2_SOURCES = qv4l2.cpp general-tab.cpp ctrl-tab.cpp vbi-tab.cpp v4l2-api.cpp capture-win.cpp \ capture-win-qt.cpp capture-win-qt.h capture-win-gl.cpp capture-win-gl.h alsa_stream.c alsa_stream.h \ diff --git a/utils/qv4l2/qv4l2.1 b/utils/qv4l2/qv4l2.1 new file mode 100644 index 000..c6abe7c --- /dev/null +++ b/utils/qv4l2/qv4l2.1 @@ -0,0 +1,58 @@ +.TH QV4L2 1 August 2013 v4l-utils User Commands +.SH NAME +qv4l2 - A test bench application for video4linux devices +.SH SYNOPSIS +.B qv4l2 +[\fI-R\fR] [\fI-h\fR] [\fI-d dev\fR] [\fI-r dev\fR] [\fI-V dev\fR] +.SH DESCRIPTION +The qv4l2 tool is used to test video4linux capture devices, either video, vbi or radio. +This application can also serve as a generic video/TV viewer application. +.PP +However, it does not (yet) support compressed video streams other than MJPEG +.SH OPTIONS +.TP +\fB\-d\fR, \fB\-\-device\fR=\fIdev\fR +Use device dev as the video device. If dev is a number, then /dev/videodev is used. +.TP +\fB\-r\fR, \fB\-\-radio-device\fR=\fIdev\fR +Use device dev as the radio device. If dev is a number, then /dev/radiodev is used. +.TP +\fB\-V\fR, \fB\-\-vbi-device\fR=\fIdev\fR +Use device dev as the vbi device. If dev is a number, then /dev/vbidev is used. +.TP +\fB\-R\fR, \fB\-\-raw\fR +Open device in raw mode, i.e. without using the libv4l2 wrapper functions. +.TP +\fB\-h\fR, \fB\-\-help\fR +Prints the help message. +.SH HOTKEYS +.SS Main Window +.TP +\fICtrl + O\fR +Open device +.TP +\fICtrl + R\fR +Open device in raw mode +.TP +\fICtrl + W\fR +Close the device +.TP +\fICtrl + V\fR +Start capture +.TP +\fICtrl + F\fR +Resize Capture Window to frame size +.TP +\fICtrl + Q\fR +Exit the application +.SS Capture Window +.TP +\fICtrl + W\fR +Closes the window and stops capture +.TP +\fICtrl + F\fR +Resize Capture Window to frame size +.SH EXIT STATUS +On success, it returns 0. Otherwise, it will return the error code. +.SH BUGS +Report bugs to Hans Verkuil hverk...@xs4all.nl -- 1.8.4.rc1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH FINAL 6/6] qv4l2: updated about window
Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/qv4l2.cpp | 18 +- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/utils/qv4l2/qv4l2.cpp b/utils/qv4l2/qv4l2.cpp index a0f21cd..056e15d 100644 --- a/utils/qv4l2/qv4l2.cpp +++ b/utils/qv4l2/qv4l2.cpp @@ -1110,8 +1110,24 @@ void ApplicationWindow::saveRaw(bool checked) void ApplicationWindow::about() { +#ifdef HAVE_ALSA + bool alsa = true; +#else + bool alsa = false; +#endif +#ifdef HAVE_QTGL + bool gl = true; +#else + bool gl = false; +#endif + QMessageBox::about(this, V4L2 Test Bench, - This program allows easy experimenting with video4linux devices.); + QString(This program allows easy experimenting with video4linux devices.\n + v. %1\n\nALSA support : %2\nOpenGL support : %3) + .arg(V4L_UTILS_VERSION) + .arg(alsa ? Present : Not Available) + .arg(gl ? Present : Not Available) + ); } void ApplicationWindow::error(const QString error) -- 1.8.4.rc1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] V4L: async: Make sure subdevs are stored in a list before being moved
Hi Sylwester, On Thursday 08 August 2013 17:51:46 Sylwester Nawrocki wrote: On 08/07/2013 12:41 PM, Laurent Pinchart wrote: Subdevices have an async_list field used to store them in the global list of subdevices or in the notifier done lists. List entries are moved from the former to the latter in v4l2_async_test_notify() using list_move(). However, v4l2_async_test_notify() can be called right away when the subdev is registered with v4l2_async_register_subdev(), in which case the entry is not stored in any list. Although this behaviour is not correct, the code doesn't crash at the moment as the async_list field is initialized as a list head, despite being a list entry. Add the subdev to the global subdevs list a registration time before matching them with the notifiers to make sure the list_move() call will get a subdev that is stored in a list, and remove the list head initialization for the subdev async_list field. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Shouldn't we initialize the async_list field in v4l2_subdev_init() ? diff --git a/drivers/media/v4l2-core/v4l2-subdev.c b/drivers/media/v4l2-core/v4l2-subdev.c index 996c248..31b2375 100644 --- a/drivers/media/v4l2-core/v4l2-subdev.c +++ b/drivers/media/v4l2-core/v4l2-subdev.c @@ -460,6 +460,7 @@ EXPORT_SYMBOL_GPL(v4l2_subdev_link_validate); void v4l2_subdev_init(struct v4l2_subdev *sd, const struct v4l2_subdev_ops *ops) { INIT_LIST_HEAD(sd-list); + INIT_LIST_HEAD(sd-async_list); BUG_ON(!ops); sd-ops = ops; sd-v4l2_dev = NULL; --- drivers/media/v4l2-core/v4l2-async.c | 11 ++- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/media/v4l2-core/v4l2-async.c b/drivers/media/v4l2-core/v4l2-async.c index b350ab9..4485dfe 100644 --- a/drivers/media/v4l2-core/v4l2-async.c +++ b/drivers/media/v4l2-core/v4l2-async.c @@ -122,7 +122,7 @@ static void v4l2_async_cleanup(struct v4l2_subdev *sd) { v4l2_device_unregister_subdev(sd); /* Subdevice driver will reprobe and put the subdev back onto the list */ - list_del_init(sd-async_list); + list_del(sd-async_list); It is not safe to do so, since v4l2_async_cleanup() can be called multiple times and list_del() leaves async_list in an undefined state. I'm actually observing a crash with this change. I agree, this is something I've overlooked. What bothers me is that the async_list is treated as a list head while it's really a list entry. I'm not sure whether this is valid or just happens to work because we're lucky the current list implementation. Wouldn't it make more sense to make sure v4l2_async_cleanup is not called multiple times ? sd-asd = NULL; sd-dev = NULL; } @@ -238,7 +238,11 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) mutex_lock(list_lock); - INIT_LIST_HEAD(sd-async_list); + /* +* Add the subdev to the global subdevs list. It will be moved to the +* notifier done list by v4l2_async_test_notify(). +*/ + list_add(sd-async_list, subdev_list); list_for_each_entry(notifier, notifier_list, list) { struct v4l2_async_subdev *asd = v4l2_async_belongs(notifier, sd); @@ -249,9 +253,6 @@ int v4l2_async_register_subdev(struct v4l2_subdev *sd) } } - /* None matched, wait for hot-plugging */ - list_add(sd-async_list, subdev_list); - mutex_unlock(list_lock); return 0; -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] v4l: Fix colorspace conversion error in sample code
On Thu 8 August 2013 17:01:10 Laurent Pinchart wrote: The sample code erroneously scales the y1, pb and pr variables from the [0.0 .. 1.0] and [-0.5 .. 0.5] ranges to [0 .. 255] and [-128 .. 127]. Fix it. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Acked-by: Hans Verkuil hans.verk...@cisco.com Regards, Hans --- Documentation/DocBook/media/v4l/pixfmt.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/DocBook/media/v4l/pixfmt.xml b/Documentation/DocBook/media/v4l/pixfmt.xml index 99b8d2a..4babd4d 100644 --- a/Documentation/DocBook/media/v4l/pixfmt.xml +++ b/Documentation/DocBook/media/v4l/pixfmt.xml @@ -391,9 +391,9 @@ clamp (double x) else return r; } -y1 = (255 / 219.0) * (Y1 - 16); -pb = (255 / 224.0) * (Cb - 128); -pr = (255 / 224.0) * (Cr - 128); +y1 = (Y1 - 16) / 219.0; +pb = (Cb - 128) / 224.0; +pr = (Cr - 128) / 224.0; r = 1.0 * y1 + 0 * pb + 1.402 * pr; g = 1.0 * y1 - 0.344 * pb - 0.714 * pr; -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] MAINTAINERS: Add entry for the Aptina PLL library
Add a maintainers entry for the Aptina PLL library, and rename the Aptina sensors entries to make it clear they refer to Aptina camera sensors. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- MAINTAINERS | 14 ++ 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index bf61e04..9b12947 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -638,6 +638,12 @@ S: Maintained F: drivers/net/appletalk/ F: net/appletalk/ +APTINA CAMERA SENSOR PLL +M: Laurent Pinchart laurent.pinch...@ideasonboard.com +L: linux-media@vger.kernel.org +S: Maintained +F: drivers/media/i2c/aptina-pll.* + ARASAN COMPACT FLASH PATA CONTROLLER M: Viresh Kumar viresh.li...@gmail.com L: linux-...@vger.kernel.org @@ -5496,7 +5502,7 @@ L:platform-driver-...@vger.kernel.org S: Supported F: drivers/platform/x86/msi-wmi.c -MT9M032 SENSOR DRIVER +MT9M032 APTINA SENSOR DRIVER M: Laurent Pinchart laurent.pinch...@ideasonboard.com L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git @@ -5504,7 +5510,7 @@ S:Maintained F: drivers/media/i2c/mt9m032.c F: include/media/mt9m032.h -MT9P031 SENSOR DRIVER +MT9P031 APTINA CAMERA SENSOR M: Laurent Pinchart laurent.pinch...@ideasonboard.com L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git @@ -5512,7 +5518,7 @@ S:Maintained F: drivers/media/i2c/mt9p031.c F: include/media/mt9p031.h -MT9T001 SENSOR DRIVER +MT9T001 APTINA CAMERA SENSOR M: Laurent Pinchart laurent.pinch...@ideasonboard.com L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git @@ -5520,7 +5526,7 @@ S:Maintained F: drivers/media/i2c/mt9t001.c F: include/media/mt9t001.h -MT9V032 SENSOR DRIVER +MT9V032 APTINA CAMERA SENSOR M: Laurent Pinchart laurent.pinch...@ideasonboard.com L: linux-media@vger.kernel.org T: git git://linuxtv.org/media_tree.git -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL FOR v3.12] Mixed V4L2 core and vb2 patches
Hi Mauro, The following changes since commit dfb9f94e8e5e7f73c8e2bcb7d4fb1de57e7c333d: [media] stk1160: Build as a module if SND is m and audio support is selected (2013-08-01 14:55:25 -0300) are available in the git repository at: git://linuxtv.org/pinchartl/media.git v4l2/core for you to fetch changes up to c751c5876e39470dedc627349743a662108dd99d: v4l: async: Make it safe to unregister unregistered notifier (2013-08-09 14:48:30 +0200) Laurent Pinchart (5): videobuf2-core: Verify planes lengths for output buffers v4l: of: Use of_get_child_by_name() v4l: of: Drop acquired reference to node when getting next endpoint v4l: Fix colorspace conversion error in sample code v4l: async: Make it safe to unregister unregistered notifier Documentation/DocBook/media/v4l/pixfmt.xml | 6 +++--- drivers/media/v4l2-core/v4l2-async.c | 6 ++ drivers/media/v4l2-core/v4l2-of.c | 9 +++-- drivers/media/v4l2-core/videobuf2-core.c | 39 + 4 files changed, 51 insertions(+), 9 deletions(-) -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 1/3] cx23885-dvb: use a better approach to hook set_frontend
When the frontend drivers got converted to DVBv5 API, the original hook that tracked when a frontend is set got removed, being replaced by an approach that would use the gate control. That doesn't work fine with some boards. Also, the code were called more times than desired. Replace it by a logic that will hook the dvb set_frontend ops, with works with both DVBv3 and DVBv5 calls. Tested on a Mygica X8502 OEM board. Tested-by: Alfredo Delaiti alfredodela...@netscape.net Signed-off-by: Mauro Carvalho Chehab m.che...@samsung.com --- drivers/media/pci/cx23885/cx23885-dvb.c | 24 drivers/media/pci/cx23885/cx23885.h | 2 ++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index bb291c6..a25a037 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -119,8 +119,6 @@ static void dvb_buf_release(struct videobuf_queue *q, cx23885_free_buffer(q, (struct cx23885_buffer *)vb); } -static int cx23885_dvb_set_frontend(struct dvb_frontend *fe); - static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) { struct videobuf_dvb_frontends *f; @@ -135,12 +133,6 @@ static void cx23885_dvb_gate_ctrl(struct cx23885_tsport *port, int open) if (fe fe-dvb.frontend fe-dvb.frontend-ops.i2c_gate_ctrl) fe-dvb.frontend-ops.i2c_gate_ctrl(fe-dvb.frontend, open); - - /* -* FIXME: Improve this path to avoid calling the -* cx23885_dvb_set_frontend() every time it passes here. -*/ - cx23885_dvb_set_frontend(fe-dvb.frontend); } static struct videobuf_queue_ops dvb_qops = { @@ -561,9 +553,21 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) cx23885_gpio_set(dev, GPIO_0); break; } + + /* Call the real set_frontend */ + if (port-set_frontend) + return port-set_frontend(fe); + return 0; } +static void cx23885_set_frontend_hook(struct cx23885_tsport *port, +struct dvb_frontend *fe) +{ + port-set_frontend = fe-ops.set_frontend; + fe-ops.set_frontend = cx23885_dvb_set_frontend; +} + static struct lgs8gxx_config magicpro_prohdtve2_lgs8g75_config = { .prod = LGS8GXX_PROD_LGS8G75, .demod_address = 0x19, @@ -771,6 +775,8 @@ static int dvb_register(struct cx23885_tsport *port) 0x60, dev-i2c_bus[1].i2c_adap, hauppauge_hvr127x_config); } + if (dev-board == CX23885_BOARD_HAUPPAUGE_HVR1275) + cx23885_set_frontend_hook(port, fe0-dvb.frontend); break; case CX23885_BOARD_HAUPPAUGE_HVR1255: case CX23885_BOARD_HAUPPAUGE_HVR1255_22111: @@ -1106,6 +1112,7 @@ static int dvb_register(struct cx23885_tsport *port) i2c_bus2-i2c_adap, mygica_x8506_xc5000_config); } + cx23885_set_frontend_hook(port, fe0-dvb.frontend); break; case CX23885_BOARD_MAGICPRO_PROHDTVE2: i2c_bus = dev-i2c_bus[0]; @@ -1119,6 +1126,7 @@ static int dvb_register(struct cx23885_tsport *port) i2c_bus2-i2c_adap, magicpro_prohdtve2_xc5000_config); } + cx23885_set_frontend_hook(port, fe0-dvb.frontend); break; case CX23885_BOARD_HAUPPAUGE_HVR1850: i2c_bus = dev-i2c_bus[0]; diff --git a/drivers/media/pci/cx23885/cx23885.h b/drivers/media/pci/cx23885/cx23885.h index 5687d3f..038caf5 100644 --- a/drivers/media/pci/cx23885/cx23885.h +++ b/drivers/media/pci/cx23885/cx23885.h @@ -320,6 +320,8 @@ struct cx23885_tsport { /* Workaround for a temp dvb_frontend that the tuner can attached to */ struct dvb_frontend analog_fe; + + int (*set_frontend)(struct dvb_frontend *fe); }; struct cx23885_kernel_ir { -- 1.8.3.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 3/3] cx23885: Add DTV support for Mygica X8502/X8507 boards
Those boards were missing the ISDB-T support. Most of the work on this patch were done by Alfredo. My work here were to port this patch from Kernel 3.2 to upstream, fix the issue caused by the set_frontend bad hook, and add the Kconfig bits. Tested on a X8502 board rebranded as: Leadership - Placa PCI-e de Captura de Vídeo Híbrida - product code 3800. Thanks-to: Alfredo Delaiti alfredodela...@netscape.net Tested-by: Alfredo Delaiti alfredodela...@netscape.net Signed-off-by: Mauro Carvalho Chehab m.che...@samsung.com --- drivers/media/pci/cx23885/Kconfig | 1 + drivers/media/pci/cx23885/cx23885-cards.c | 6 -- drivers/media/pci/cx23885/cx23885-dvb.c | 25 + 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/drivers/media/pci/cx23885/Kconfig b/drivers/media/pci/cx23885/Kconfig index b3688aa..5104c80 100644 --- a/drivers/media/pci/cx23885/Kconfig +++ b/drivers/media/pci/cx23885/Kconfig @@ -29,6 +29,7 @@ config VIDEO_CX23885 select DVB_STV0367 if MEDIA_SUBDRV_AUTOSELECT select DVB_TDA10071 if MEDIA_SUBDRV_AUTOSELECT select DVB_A8293 if MEDIA_SUBDRV_AUTOSELECT + select DVB_MB86A20S if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MT2063 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_MT2131 if MEDIA_SUBDRV_AUTOSELECT select MEDIA_TUNER_XC2028 if MEDIA_SUBDRV_AUTOSELECT diff --git a/drivers/media/pci/cx23885/cx23885-cards.c b/drivers/media/pci/cx23885/cx23885-cards.c index 7e923f8..6a71a96 100644 --- a/drivers/media/pci/cx23885/cx23885-cards.c +++ b/drivers/media/pci/cx23885/cx23885-cards.c @@ -528,11 +528,12 @@ struct cx23885_board cx23885_boards[] = { } }, }, [CX23885_BOARD_MYGICA_X8507] = { - .name = Mygica X8507, + .name = Mygica X8502/X8507 ISDB-T, .tuner_type = TUNER_XC5000, .tuner_addr = 0x61, .tuner_bus = 1, .porta = CX23885_ANALOG_VIDEO, + .portb = CX23885_MPEG_DVB, .input = { { .type = CX23885_VMUX_TELEVISION, @@ -1281,7 +1282,7 @@ void cx23885_gpio_setup(struct cx23885_dev *dev) case CX23885_BOARD_MYGICA_X8507: /* GPIO-0 (0)Analog / (1)Digital TV */ /* GPIO-1 reset XC5000 */ - /* GPIO-2 reset LGS8GL5 / LGS8G75 */ + /* GPIO-2 demod reset */ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1); cx23885_gpio_clear(dev, GPIO_1 | GPIO_2); mdelay(100); @@ -1677,6 +1678,7 @@ void cx23885_card_setup(struct cx23885_dev *dev) break; case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: + case CX23885_BOARD_MYGICA_X8507: ts1-gen_ctrl_val = 0x5; /* Parallel */ ts1-ts_clk_en_val = 0x1; /* Enable TS_CLK */ ts1-src_sel_val = CX23885_SRC_SEL_PARALLEL_MPEG_VIDEO; diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c index a25a037..971e4ff 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -69,6 +69,7 @@ #include stb6100_cfg.h #include tda10071.h #include a8293.h +#include mb86a20s.h static unsigned int debug; @@ -492,6 +493,15 @@ static struct xc5000_config mygica_x8506_xc5000_config = { .if_khz = 5380, }; +static struct mb86a20s_config mygica_x8507_mb86a20s_config = { + .demod_address = 0x10, +}; + +static struct xc5000_config mygica_x8507_xc5000_config = { + .i2c_address = 0x61, + .if_khz = 4000, +}; + static struct stv090x_config prof_8000_stv090x_config = { .device = STV0903, .demod_mode = STV090x_SINGLE, @@ -548,6 +558,7 @@ static int cx23885_dvb_set_frontend(struct dvb_frontend *fe) } break; case CX23885_BOARD_MYGICA_X8506: + case CX23885_BOARD_MYGICA_X8507: case CX23885_BOARD_MAGICPRO_PROHDTVE2: /* Select Digital TV */ cx23885_gpio_set(dev, GPIO_0); @@ -1114,6 +1125,20 @@ static int dvb_register(struct cx23885_tsport *port) } cx23885_set_frontend_hook(port, fe0-dvb.frontend); break; + case CX23885_BOARD_MYGICA_X8507: + i2c_bus = dev-i2c_bus[0]; + i2c_bus2 = dev-i2c_bus[1]; + fe0-dvb.frontend = dvb_attach(mb86a20s_attach, + mygica_x8507_mb86a20s_config, + i2c_bus-i2c_adap); + if (fe0-dvb.frontend != NULL) { + dvb_attach(xc5000_attach, + fe0-dvb.frontend, + i2c_bus2-i2c_adap, + mygica_x8507_xc5000_config); + } +
[PATCHv2 2/3] mb86a20s: Fix TS parallel mode
changeset 768e6dadd74 caused a regression on using mb86a20s in parallel mode, as the parallel mode selection got overriden by mb86a20s_init2. Cc: sta...@vger.kernel.org Signed-off-by: Mauro Carvalho Chehab m.che...@samsung.com --- drivers/media/dvb-frontends/mb86a20s.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/drivers/media/dvb-frontends/mb86a20s.c b/drivers/media/dvb-frontends/mb86a20s.c index 856374b..2c7217f 100644 --- a/drivers/media/dvb-frontends/mb86a20s.c +++ b/drivers/media/dvb-frontends/mb86a20s.c @@ -157,7 +157,6 @@ static struct regdata mb86a20s_init2[] = { { 0x45, 0x04 }, /* CN symbol 4 */ { 0x48, 0x04 }, /* CN manual mode */ - { 0x50, 0xd5 }, { 0x51, 0x01 }, /* Serial */ { 0x50, 0xd6 }, { 0x51, 0x1f }, { 0x50, 0xd2 }, { 0x51, 0x03 }, { 0x50, 0xd7 }, { 0x51, 0xbf }, @@ -1860,16 +1859,15 @@ static int mb86a20s_initfe(struct dvb_frontend *fe) dev_dbg(state-i2c-dev, %s: IF=%d, IF reg=0x%06llx\n, __func__, state-if_freq, (long long)pll); - if (!state-config-is_serial) { + if (!state-config-is_serial) regD5 = ~1; - rc = mb86a20s_writereg(state, 0x50, 0xd5); - if (rc 0) - goto err; - rc = mb86a20s_writereg(state, 0x51, regD5); - if (rc 0) - goto err; - } + rc = mb86a20s_writereg(state, 0x50, 0xd5); + if (rc 0) + goto err; + rc = mb86a20s_writereg(state, 0x51, regD5); + if (rc 0) + goto err; rc = mb86a20s_writeregdata(state, mb86a20s_init2); if (rc 0) -- 1.8.3.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCHv2 0/3] Add ISDB-T support on Mygica X8502/X8507
This is likely the final version of the patches that adds support for Mygica X8502/X8507. After bisecting the mb86a20s configs, I discovered that the failure was due to a regression on setting the frontend to parallel mode. So, I removed the dirty mb86a20s from this series, and added a proper regression fix for mb86a20s. That probably means that the cx88 and saa7134 ISDB-T devices based on mb86a20s were also broken. I also addressed the issues pointed by Alfredo. So, if nobody complains, I'll merge those patches soon. The mb86a20s should be merged at the fixes tree. The two other patches will follow their normal way upstream, for their addition on kernel 3.12. Mauro Carvalho Chehab (3): cx23885-dvb: use a better approach to hook set_frontend mb86a20s: Fix TS parallel mode cx23885: Add DTV support for Mygica X8502/X8507 boards drivers/media/dvb-frontends/mb86a20s.c| 16 +- drivers/media/pci/cx23885/Kconfig | 1 + drivers/media/pci/cx23885/cx23885-cards.c | 6 ++-- drivers/media/pci/cx23885/cx23885-dvb.c | 49 ++- drivers/media/pci/cx23885/cx23885.h | 2 ++ 5 files changed, 55 insertions(+), 19 deletions(-) -- 1.8.3.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] media: vb2: Share code between vb2_prepare_buf and vb2_qbuf
On Fri 9 August 2013 14:11:26 Laurent Pinchart wrote: The two operations are very similar, refactor most of the code in a helper function. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Hans Verkuil hans.verk...@cisco.com Regards, Hans --- drivers/media/v4l2-core/videobuf2-core.c | 202 --- 1 file changed, 79 insertions(+), 123 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7c2a8ce..c9f8c3f 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1231,42 +1231,31 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) return ret; } -/** - * vb2_prepare_buf() - Pass ownership of a buffer from userspace to the kernel - * @q: videobuf2 queue - * @b: buffer structure passed from userspace to vidioc_prepare_buf - * handler in driver - * - * Should be called from vidioc_prepare_buf ioctl handler of a driver. - * This function: - * 1) verifies the passed buffer, - * 2) calls buf_prepare callback in the driver (if provided), in which - *driver-specific buffer initialization can be performed, - * - * The return values from this function are intended to be directly returned - * from vidioc_prepare_buf handler in driver. - */ -int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) +static int vb2_queue_or_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b, + const char *opname, + int (*handler)(struct vb2_queue *, +struct v4l2_buffer *, +struct vb2_buffer *)) { struct rw_semaphore *mmap_sem = NULL; struct vb2_buffer *vb; int ret; /* - * In case of user pointer buffers vb2 allocator needs to get direct - * access to userspace pages. This requires getting read access on - * mmap semaphore in the current process structure. The same - * semaphore is taken before calling mmap operation, while both mmap - * and prepare_buf are called by the driver or v4l2 core with driver's - * lock held. To avoid a AB-BA deadlock (mmap_sem then driver's lock in - * mmap and driver's lock then mmap_sem in prepare_buf) the videobuf2 - * core release driver's lock, takes mmap_sem and then takes again - * driver's lock. + * In case of user pointer buffers vb2 allocators need to get direct + * access to userspace pages. This requires getting the mmap semaphore + * for read access in the current process structure. The same semaphore + * is taken before calling mmap operation, while both qbuf/prepare_buf + * and mmap are called by the driver or v4l2 core with the driver's lock + * held. To avoid an AB-BA deadlock (mmap_sem then driver's lock in mmap + * and driver's lock then mmap_sem in qbuf/prepare_buf) the videobuf2 + * core releases the driver's lock, takes mmap_sem and then takes the + * driver's lock again. * - * To avoid race with other vb2 calls, which might be called after - * releasing driver's lock, this operation is performed at the - * beggining of prepare_buf processing. This way the queue status is - * consistent after getting driver's lock back. + * To avoid racing with other vb2 calls, which might be called after + * releasing the driver's lock, this operation is performed at the + * beginning of qbuf/prepare_buf processing. This way the queue status + * is consistent after getting the driver's lock back. */ if (q-memory == V4L2_MEMORY_USERPTR) { mmap_sem = current-mm-mmap_sem; @@ -1276,19 +1265,19 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) } if (q-fileio) { - dprintk(1, %s(): file io in progress\n, __func__); + dprintk(1, %s(): file io in progress\n, opname); ret = -EBUSY; goto unlock; } if (b-type != q-type) { - dprintk(1, %s(): invalid buffer type\n, __func__); + dprintk(1, %s(): invalid buffer type\n, opname); ret = -EINVAL; goto unlock; } if (b-index = q-num_buffers) { - dprintk(1, %s(): buffer index out of range\n, __func__); + dprintk(1, %s(): buffer index out of range\n, opname); ret = -EINVAL; goto unlock; } @@ -1296,131 +1285,83 @@ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) vb = q-bufs[b-index]; if (NULL == vb) { /* Should never happen */ - dprintk(1, %s(): buffer is NULL\n, __func__); +
Re: [PATCH 1/2] media: vb2: Fix potential deadlock in vb2_prepare_buffer
On Fri 9 August 2013 14:11:25 Laurent Pinchart wrote: Commit b037c0fde22b1d3cd0b3c3717d28e54619fc1592 (media: vb2: fix potential deadlock in mmap vs. get_userptr handling) fixes an AB-BA deadlock related to the mmap_sem and driver locks. The same deadlock can occur in vb2_prepare_buffer(), fix it the same way. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com Reviewed-by: Hans Verkuil hans.verk...@cisco.com Regards, Hans --- drivers/media/v4l2-core/videobuf2-core.c | 52 ++-- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/drivers/media/v4l2-core/videobuf2-core.c b/drivers/media/v4l2-core/videobuf2-core.c index 7f32860..7c2a8ce 100644 --- a/drivers/media/v4l2-core/videobuf2-core.c +++ b/drivers/media/v4l2-core/videobuf2-core.c @@ -1248,50 +1248,84 @@ static int __buf_prepare(struct vb2_buffer *vb, const struct v4l2_buffer *b) */ int vb2_prepare_buf(struct vb2_queue *q, struct v4l2_buffer *b) { + struct rw_semaphore *mmap_sem = NULL; struct vb2_buffer *vb; int ret; + /* + * In case of user pointer buffers vb2 allocator needs to get direct + * access to userspace pages. This requires getting read access on + * mmap semaphore in the current process structure. The same + * semaphore is taken before calling mmap operation, while both mmap + * and prepare_buf are called by the driver or v4l2 core with driver's + * lock held. To avoid a AB-BA deadlock (mmap_sem then driver's lock in + * mmap and driver's lock then mmap_sem in prepare_buf) the videobuf2 + * core release driver's lock, takes mmap_sem and then takes again + * driver's lock. + * + * To avoid race with other vb2 calls, which might be called after + * releasing driver's lock, this operation is performed at the + * beggining of prepare_buf processing. This way the queue status is + * consistent after getting driver's lock back. + */ + if (q-memory == V4L2_MEMORY_USERPTR) { + mmap_sem = current-mm-mmap_sem; + call_qop(q, wait_prepare, q); + down_read(mmap_sem); + call_qop(q, wait_finish, q); + } + if (q-fileio) { dprintk(1, %s(): file io in progress\n, __func__); - return -EBUSY; + ret = -EBUSY; + goto unlock; } if (b-type != q-type) { dprintk(1, %s(): invalid buffer type\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (b-index = q-num_buffers) { dprintk(1, %s(): buffer index out of range\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } vb = q-bufs[b-index]; if (NULL == vb) { /* Should never happen */ dprintk(1, %s(): buffer is NULL\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (b-memory != q-memory) { dprintk(1, %s(): invalid memory type\n, __func__); - return -EINVAL; + ret = -EINVAL; + goto unlock; } if (vb-state != VB2_BUF_STATE_DEQUEUED) { dprintk(1, %s(): invalid buffer state %d\n, __func__, vb-state); - return -EINVAL; + ret = -EINVAL; + goto unlock; } ret = __verify_planes_array(vb, b); if (ret 0) - return ret; + goto unlock; + ret = __buf_prepare(vb, b); if (ret 0) - return ret; + goto unlock; __fill_v4l2_buffer(vb, b); - return 0; +unlock: + if (mmap_sem) + up_read(mmap_sem); + return ret; } EXPORT_SYMBOL_GPL(vb2_prepare_buf); -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] qv4l2: fix GeneralTab layout
This moves the layout items for cropping, scaling and ALSA to not interfere with driver specific controls. Signed-off-by: Bård Eirik Winther bwint...@cisco.com --- utils/qv4l2/general-tab.cpp | 129 ++-- 1 file changed, 64 insertions(+), 65 deletions(-) diff --git a/utils/qv4l2/general-tab.cpp b/utils/qv4l2/general-tab.cpp index cfc6bcf..cd00ecd 100644 --- a/utils/qv4l2/general-tab.cpp +++ b/utils/qv4l2/general-tab.cpp @@ -98,6 +98,70 @@ GeneralTab::GeneralTab(const QString device, v4l2 fd, int n, QWidget *parent) if (m_querycap.capabilities V4L2_CAP_DEVICE_CAPS) m_isVbi = caps() (V4L2_CAP_VBI_CAPTURE | V4L2_CAP_SLICED_VBI_CAPTURE); + if (hasAlsaAudio()) { + m_audioInDevice = new QComboBox(parent); + m_audioOutDevice = new QComboBox(parent); + m_audioInDevice-setSizeAdjustPolicy(QComboBox::AdjustToContents); + m_audioOutDevice-setSizeAdjustPolicy(QComboBox::AdjustToContents); + + if (createAudioDeviceList()) { + addLabel(Audio Input Device); + connect(m_audioInDevice, SIGNAL(activated(int)), SLOT(changeAudioDevice())); + addWidget(m_audioInDevice); + + addLabel(Audio Output Device); + connect(m_audioOutDevice, SIGNAL(activated(int)), SLOT(changeAudioDevice())); + addWidget(m_audioOutDevice); + + if (isRadio()) { + setAudioDeviceBufferSize(75); + } else { + v4l2_fract fract; + if (!v4l2::get_interval(fract)) { + // Default values are for 30 FPS + fract.numerator = 33; + fract.denominator = 1000; + } + // Standard capacity is two frames + setAudioDeviceBufferSize((fract.numerator * 2000) / fract.denominator); + } + } else { + delete m_audioInDevice; + delete m_audioOutDevice; + m_audioInDevice = NULL; + m_audioOutDevice = NULL; + } + } + + if (!isRadio() !isVbi()) { + m_pixelAspectRatio = new QComboBox(parent); + m_pixelAspectRatio-addItem(Autodetect); + m_pixelAspectRatio-addItem(Square); + m_pixelAspectRatio-addItem(NTSC/PAL-M/PAL-60); + m_pixelAspectRatio-addItem(NTSC/PAL-M/PAL-60, Anamorphic); + m_pixelAspectRatio-addItem(PAL/SECAM); + m_pixelAspectRatio-addItem(PAL/SECAM, Anamorphic); + + // Update hints by calling a get + getPixelAspectRatio(); + + addLabel(Pixel Aspect Ratio); + addWidget(m_pixelAspectRatio); + connect(m_pixelAspectRatio, SIGNAL(activated(int)), SLOT(changePixelAspectRatio())); + + m_crop = new QComboBox(parent); + m_crop-addItem(None); + m_crop-addItem(Top and Bottom Line); + m_crop-addItem(Widescreen 14:9); + m_crop-addItem(Widescreen 16:9); + m_crop-addItem(Cinema 1.85:1); + m_crop-addItem(Cinema 2.39:1); + + addLabel(Cropping); + addWidget(m_crop); + connect(m_crop, SIGNAL(activated(int)), SIGNAL(cropChanged())); + } + if (!isRadio() enum_input(vin, true)) { addLabel(Input); m_videoInput = new QComboBox(parent); @@ -148,42 +212,6 @@ GeneralTab::GeneralTab(const QString device, v4l2 fd, int n, QWidget *parent) updateAudioOutput(); } - if (hasAlsaAudio()) { - m_audioInDevice = new QComboBox(parent); - m_audioOutDevice = new QComboBox(parent); - m_audioInDevice-setSizeAdjustPolicy(QComboBox::AdjustToContents); - m_audioOutDevice-setSizeAdjustPolicy(QComboBox::AdjustToContents); - - if (createAudioDeviceList()) { - addLabel(Audio Input Device); - connect(m_audioInDevice, SIGNAL(activated(int)), SLOT(changeAudioDevice())); - addWidget(m_audioInDevice); - - addLabel(Audio Output Device); - connect(m_audioOutDevice, SIGNAL(activated(int)), SLOT(changeAudioDevice())); - addWidget(m_audioOutDevice); - - if (isRadio()) { - setAudioDeviceBufferSize(75); - } else { - v4l2_fract fract; - if
[PATCH] qv4l2: fix GeneralTab layout
Cleans up the layout of GeneralTab. Also removes a single debug printout from original ALSA source. The debug was in a corner case and will most likely not be noticed there anyway, but is now removed. -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] uvc: more buffers
From: Oliver Neukum oneu...@suse.de This is necessary to let the new generation of cameras from LiteOn used in Haswell ULT notebook operate. Otherwise the images will be truncated. Signed-off-by: Oliver Neukum oneu...@suse.de --- drivers/media/usb/uvc/uvcvideo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 9e35982..9f1930b 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -114,9 +114,9 @@ /* Number of isochronous URBs. */ #define UVC_URBS 5 /* Maximum number of packets per URB. */ -#define UVC_MAX_PACKETS32 +#define UVC_MAX_PACKETS128 /* Maximum number of video buffers. */ -#define UVC_MAX_VIDEO_BUFFERS 32 +#define UVC_MAX_VIDEO_BUFFERS 128 /* Maximum status buffer size in bytes of interrupt URB. */ #define UVC_MAX_STATUS_SIZE16 -- 1.8.3.1 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH RFC 0/3] Experimental patches for ISDB-T on Mygica X8502/X8507
Em Thu, 08 Aug 2013 21:00:30 -0300 Alfredo Jesús Delaiti alfredodela...@netscape.net escreveu: Hi El 08/08/13 13:51, Mauro Carvalho Chehab escribió: This is a first set of experimental patches for Mygica X8502/X8507. The last patch is just a very dirty hack, for testing purposes. I intend to get rid of it, but it is there to replace exactly the same changes that Alfredo reported to work on Kernel 3.2. I intend to remove it on a final series, eventually replacing by some other changes at mb86a20s. Alfredo, Please test, and send your tested-by, if this works for you. tested-by: Alfredo Delaiti alfredodela...@netscape.net two comments: two breaks: @@ -1106,6 +1112,8 @@ static int dvb_register(struct cx23885_tsport *port) i2c_bus2-i2c_adap, mygica_x8506_xc5000_config); } + cx23885_set_frontend_hook(port, fe0-dvb.frontend); + break; break; and I would add this on cx23885-cards.c (is not a patch): case CX23885_BOARD_MYGICA_X8506: case CX23885_BOARD_MAGICPRO_PROHDTVE2: case CX23885_BOARD_MYGICA_X8507: /* GPIO-0 (0)Analog / (1)Digital TV */ /* GPIO-1 reset XC5000 */ -/* GPIO-2 reset LGS8GL5 / LGS8G75 */ +/* GPIO-2 reset LGS8GL5 / LGS8G75 / MB86A20S */ cx23885_gpio_enable(dev, GPIO_0 | GPIO_1 | GPIO_2, 1); cx23885_gpio_clear(dev, GPIO_1 | GPIO_2); mdelay(100); cx23885_gpio_set(dev, GPIO_0 | GPIO_1 | GPIO_2); mdelay(100); break; Thanks again Mauro, Thank you for your tests. I just pushed a new patch series addressing the above, and getting rid of the horrible mb86a20s hack. Please test it again, to see if the mb86a20s fixes also worked for you. Thanks! Mauro -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] uvc: more buffers
Hi Oliver, Thank you for the patch. On Friday 09 August 2013 15:11:36 oli...@neukum.org wrote: From: Oliver Neukum oneu...@suse.de This is necessary to let the new generation of cameras from LiteOn used in Haswell ULT notebook operate. Otherwise the images will be truncated. Could you please post the lsusb -v output for the device ? Why does it need more buffers, is it a superspeed webcam ? Signed-off-by: Oliver Neukum oneu...@suse.de --- drivers/media/usb/uvc/uvcvideo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h index 9e35982..9f1930b 100644 --- a/drivers/media/usb/uvc/uvcvideo.h +++ b/drivers/media/usb/uvc/uvcvideo.h @@ -114,9 +114,9 @@ /* Number of isochronous URBs. */ #define UVC_URBS 5 /* Maximum number of packets per URB. */ -#define UVC_MAX_PACKETS 32 +#define UVC_MAX_PACKETS 128 That would mean up to 384KiB per URB. While not unreasonable, I'd like to know how much data your camera produces to require this. /* Maximum number of video buffers. */ -#define UVC_MAX_VIDEO_BUFFERS32 +#define UVC_MAX_VIDEO_BUFFERS128 I don't think your camera really needs more than 32 V4L2 (full frame) buffers :-) /* Maximum status buffer size in bytes of interrupt URB. */ #define UVC_MAX_STATUS_SIZE 16 -- Regards, Laurent Pinchart -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[GIT PULL] soc-camera for 3.12 #1
Hi Mauro Please, push to 3.12: The following changes since commit 20bf249c2d909c8530615c46d0f9aaa90c73498f: Add linux-next specific files for 20130808 (2013-08-08 16:49:48 +1000) are available in the git repository at: git://linuxtv.org/gliakhovetski/v4l-dvb.git for-3.12-1 Guennadi Liakhovetski (6): V4L2: soc-camera: fix requesting regulators in synchronous case V4L2: mx3_camera: convert to managed resource allocation V4L2: mx3_camera: print V4L2_MBUS_FMT_* codes in hexadecimal format V4L2: mx3_camera: add support for asynchronous subdevice registration V4L2: mt9t031: don't Oops if asynchronous probing is attempted V4L2: mt9m111: switch to asynchronous subdevice probing Hans Verkuil (1): soc_camera: fix compiler warning Vladimir Barinov (1): V4L2: soc_camera: Renesas R-Car VIN driver drivers/media/i2c/soc_camera/mt9m111.c | 38 +- drivers/media/i2c/soc_camera/mt9t031.c |7 +- drivers/media/platform/soc_camera/Kconfig |8 + drivers/media/platform/soc_camera/Makefile |1 + drivers/media/platform/soc_camera/mx3_camera.c | 67 +- drivers/media/platform/soc_camera/rcar_vin.c | 1486 drivers/media/platform/soc_camera/soc_camera.c | 38 +- include/linux/platform_data/camera-mx3.h |4 + include/linux/platform_data/camera-rcar.h | 25 + 9 files changed, 1610 insertions(+), 64 deletions(-) create mode 100644 drivers/media/platform/soc_camera/rcar_vin.c create mode 100644 include/linux/platform_data/camera-rcar.h Thanks Guennadi --- Guennadi Liakhovetski, Ph.D. Freelance Open-Source Software Developer http://www.open-technology.de/ -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] libv4lconvert: Support for RGB32 and BGR32 format
ping? On Sun, Aug 4, 2013 at 10:05 AM, Ricardo Ribalda Delgado ricardo.riba...@gmail.com wrote: Hello Gregor Thanks for your comments. I have replied inline. On Sat, Aug 3, 2013 at 6:42 PM, Gregor Jasny gja...@googlemail.com wrote: On 8/3/13 12:42 AM, Ricardo Ribalda Delgado wrote: + case V4L2_PIX_FMT_RGB32: + switch (dest_pix_fmt) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_rgb32_to_rgb24(src, dest, width, height, 0); + break; + case V4L2_PIX_FMT_BGR24: + v4lconvert_rgb32_to_rgb24(src, dest, width, height, 1); + break; + case V4L2_PIX_FMT_YUV420: + v4lconvert_rgb24_to_yuv420(src, dest, fmt, 0, 0, 4); + break; + case V4L2_PIX_FMT_YVU420: + v4lconvert_rgb24_to_yuv420(src, dest, fmt, 0, 1, 4); + break; + } + if (src_size (width * height * 4)) { + V4LCONVERT_ERR(short rgb32 data frame\n); + errno = EPIPE; + result = -1; + } + break; I have not looked at the whole function but shouldn't this sanity check happen before the actual work? Yes, but it is how it is done in the whole library with all the formats. Please grep for short on libv4lconvert.c Also aren't you applying the condition here also for rgb24_to_xxx which should have only three bpp? I have modified the function rgb24_to_yuv420 to support other bytes per pixel. + case V4L2_PIX_FMT_BGR32: + switch (dest_pix_fmt) { + case V4L2_PIX_FMT_RGB24: + v4lconvert_rgb32_to_rgb24(src, dest, width, height, 1); + break; + case V4L2_PIX_FMT_BGR24: + v4lconvert_rgb32_to_rgb24(src, dest, width, height, 0); + break; + case V4L2_PIX_FMT_YUV420: + v4lconvert_rgb24_to_yuv420(src, dest, fmt, 1, 0, 4); + break; + case V4L2_PIX_FMT_YVU420: + v4lconvert_rgb24_to_yuv420(src, dest, fmt, 1, 1, 4); + break; + } + if (src_size (width * height * 4)) { + V4LCONVERT_ERR(short bgr32 data frame\n); + errno = EPIPE; + result = -1; + } + break; Same here. And also in the other patch. Thanks again -- Ricardo Ribalda -- Ricardo Ribalda -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/2] libv4lconvert: Support for Y16 pixel format
ping? On Sat, Aug 3, 2013 at 12:42 AM, Ricardo Ribalda Delgado ricardo.riba...@gmail.com wrote: This patch adds support for V4L2_PIX_FMT_Y16 format. Signed-off-by: Ricardo Ribalda Delgado ricardo.riba...@gmail.com --- lib/libv4lconvert/libv4lconvert-priv.h |6 ++ lib/libv4lconvert/libv4lconvert.c | 19 +++ lib/libv4lconvert/rgbyuv.c | 30 ++ 3 files changed, 55 insertions(+) diff --git a/lib/libv4lconvert/libv4lconvert-priv.h b/lib/libv4lconvert/libv4lconvert-priv.h index c37e220..6422fdd 100644 --- a/lib/libv4lconvert/libv4lconvert-priv.h +++ b/lib/libv4lconvert/libv4lconvert-priv.h @@ -152,6 +152,12 @@ void v4lconvert_grey_to_rgb24(const unsigned char *src, unsigned char *dest, void v4lconvert_grey_to_yuv420(const unsigned char *src, unsigned char *dest, const struct v4l2_format *src_fmt); +void v4lconvert_y16_to_rgb24(const unsigned char *src, unsigned char *dest, + int width, int height); + +void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest, + const struct v4l2_format *src_fmt); + int v4lconvert_y10b_to_rgb24(struct v4lconvert_data *data, const unsigned char *src, unsigned char *dest, int width, int height); diff --git a/lib/libv4lconvert/libv4lconvert.c b/lib/libv4lconvert/libv4lconvert.c index 60010f1..bc5e34f 100644 --- a/lib/libv4lconvert/libv4lconvert.c +++ b/lib/libv4lconvert/libv4lconvert.c @@ -128,6 +128,7 @@ static const struct v4lconvert_pixfmt supported_src_pixfmts[] = { { V4L2_PIX_FMT_Y4, 8, 20, 20, 0 }, { V4L2_PIX_FMT_Y6, 8, 20, 20, 0 }, { V4L2_PIX_FMT_Y10BPACK,10, 20, 20, 0 }, + { V4L2_PIX_FMT_Y16, 16, 20, 20, 0 }, }; static const struct v4lconvert_pixfmt supported_dst_pixfmts[] = { @@ -989,6 +990,24 @@ static int v4lconvert_convert_pixfmt(struct v4lconvert_data *data, break; } + case V4L2_PIX_FMT_Y16: + switch (dest_pix_fmt) { + case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR24: + v4lconvert_y16_to_rgb24(src, dest, width, height); + break; + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + v4lconvert_y16_to_yuv420(src, dest, fmt); + break; + } + if (src_size (width * height * 2)) { + V4LCONVERT_ERR(short y16 data frame\n); + errno = EPIPE; + result = -1; + } + break; + case V4L2_PIX_FMT_GREY: case V4L2_PIX_FMT_Y4: case V4L2_PIX_FMT_Y6: diff --git a/lib/libv4lconvert/rgbyuv.c b/lib/libv4lconvert/rgbyuv.c index d05abe9..bef034f 100644 --- a/lib/libv4lconvert/rgbyuv.c +++ b/lib/libv4lconvert/rgbyuv.c @@ -586,6 +586,36 @@ void v4lconvert_rgb565_to_yuv420(const unsigned char *src, unsigned char *dest, } } +void v4lconvert_y16_to_rgb24(const unsigned char *src, unsigned char *dest, + int width, int height) +{ + int j; + while (--height = 0) { + for (j = 0; j width; j++) { + *dest++ = *src; + *dest++ = *src; + *dest++ = *src; + src+=2; + } + } +} + +void v4lconvert_y16_to_yuv420(const unsigned char *src, unsigned char *dest, + const struct v4l2_format *src_fmt) +{ + int x, y; + + /* Y */ + for (y = 0; y src_fmt-fmt.pix.height; y++) + for (x = 0; x src_fmt-fmt.pix.width; x++){ + *dest++ = *src; + src+=2; + } + + /* Clear U/V */ + memset(dest, 0x80, src_fmt-fmt.pix.width * src_fmt-fmt.pix.height / 2); +} + void v4lconvert_grey_to_rgb24(const unsigned char *src, unsigned char *dest, int width, int height) { -- 1.7.10.4 -- Ricardo Ribalda -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: How to express planar formats with mediabus format code?
Hi Laurent / Guennadi, On Fri, Aug 9, 2013 at 5:12 AM, Laurent Pinchart laurent.pinch...@ideasonboard.com wrote: Hi, On Tuesday 06 August 2013 17:18:14 Su Jiaquan wrote: Hi Guennadi, Thanks for the reply! Please see my description inline. On Mon, Aug 5, 2013 at 5:02 AM, Guennadi Liakhovetski wrote: On Sun, 4 Aug 2013, Su Jiaquan wrote: Hi, I know the title looks crazy, but here is our problem: In our SoC based ISP, the hardware can be divide to several blocks. Some blocks can do color space conversion(raw to YUV interleave/planar), others can do the pixel re-order(interleave/planar/semi-planar conversion, UV planar switch). We use one subdev to describe each of them, then came the problem: How can we express the planar formats with mediabus format code? Could you please explain more exactly what you mean? How are those your blocks connected? How do they exchange data? If they exchange data over a serial bus, then I don't think planar formats make sense, right? Or do your blocks really output planes one after another, reordering data internally? That would be odd... If OTOH your blocks output data to RAM, and the next block takes data from there, then you use V4L2_PIX_FMT_* formats to describe them and any further processing block should be a mem2mem device. Wouldn't this work? These two hardware blocks are both located inside of ISP, and is connected by a hardware data bus. Actually, there are three blocks inside ISP: One is close to sensor, and can do color space conversion(RGB-YUV), we call it IPC; The other two are at back end, which are basically DMA Engine, and they are identical. When data flow out of IPC, it can go into each one of these DMA Engines and finally into RAM. Whether the DMA Engine is turned on/off and the output format can be controlled independently. Since they are DMA Engines, they have some basic pixel reordering ability(i.e. interleave-planar/semi-planar). In our H/W design, when we want to get YUV semi-planar format, the IPC output should be configured to interleave, and the DMA engine will do the interleave-semi-planar job. If we want planar / interleave format, the IPC will output planar format directly, DMA engine simply send the data to RAM, and don't do any re-order. So in the planar output case, media-bus formats can't express the format of the data between IPC and DMA Engine, that's the problem we meet. If the format between the two subdevs is really planar, I don't see any problem defining a media bus pixel code for it. You will have to properly document the format of course. I'm a bit surprised that the IPC could output planar data. It would need to buffer a whole image to do so, do you need to give it a temporary system RAM buffer ? We want to adopt a formal solution before we send our patch to the community, that's where our headache comes. -- Regards, Laurent Pinchart Thanks for the reply! Actually, we don't need to buffer the frame inside IPC, there are three channels in the data bus. When transfering interleave format, only one channel is used, for planar formats, three channels send one planar each, and to difference address(Let me confirm this with our H/W team and get back to you later). So the planars is not sent one after an other, but in parallel. This may be a bit different from the planar formats as people think it should be. Can we use planar format to describe it? Since this won't cause any misunderstanding given it's used in this special case. Please advice. Thanks a lot! Jiaquan -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC 0/1] drm/pl111: Initial drm/kms driver for pl111
On Fri, Aug 9, 2013 at 12:15 PM, Tom Cooksey tom.cook...@arm.com wrote: Turning to DRM/KMS, it seems the supported formats of a plane can be queried using drm_mode_get_plane. However, there doesn't seem to be a way to query the supported formats of a crtc? If display HW only supports scanning out from a single buffer (like pl111 does), I think it won't have any planes and a fb can only be set on the crtc. In which case, how should user-space query which pixel formats that crtc supports? it is exposed for drm plane's. What is missing is to expose the primary-plane associated with the crtc. Cool - so a patch which adds a way to query the what formats a crtc supports would be welcome? well, I kinda think we want something that exposes the primary plane of the crtc.. I'm thinking something roughly like: - diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 53db7ce..c7ffca8 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -157,6 +157,12 @@ struct drm_mode_get_plane { struct drm_mode_get_plane_res { __u64 plane_id_ptr; __u32 count_planes; + /* The primary planes are in matching order to crtc_id_ptr in +* drm_mode_card_res (and same length). For crtc_id[n], it's +* primary plane is given by primary_plane_id[n]. +*/ + __u32 count_primary_planes; + __u64 primary_plane_id_ptr; }; #define DRM_MODE_ENCODER_NONE 0 - then use the existing GETPLANE ioctl to query the capabilities What about a way to query the stride alignment constraints? Presumably using the drm_mode_get_property mechanism would be the right way to implement that? I suppose you could try that.. typically that is in userspace, however. It seems like get_property would get messy quickly (ie. is it a pitch alignment constraint, or stride alignment? What if this is different for different formats (in particular tiled)? etc) As with v4l2, DRM doesn't appear to have a way to query the stride constraints? Assuming there is a way to query the stride constraints, there also isn't a way to specify them when creating a buffer with DRM, though perhaps the existing pitch parameter of drm_mode_create_dumb could be used to allow user-space to pass in a minimum stride as well as receive the allocated stride? well, you really shouldn't be using create_dumb.. you should have a userspace piece that is specific to the drm driver, and knows how to use that driver's gem allocate ioctl. Sorry, why does this need a driver-specific allocation function? It's just a display controller driver and I just want to allocate a scan- out buffer - all I'm asking is for the display controller driver to use a minimum stride alignment so I can export the buffer and use another device to fill it with data. Sure.. but userspace has more information readily available to make a better choice. For example, for omapdrm I'd do things differently depending on whether I wanted to scan out that buffer (or a portion of it) rotated. This is something I know in the DDX driver, but not in the kernel. And it is quite likely something that is driver specific. Sure, we could add that to a generic allocate me a buffer ioctl. But that doesn't really seem better, and it becomes a problem as soon as we come across some hw that needs to know something different. In userspace, you have a lot more flexibility, since you don't really need to commit to an API for life. And to bring back the GStreamer argument (since that seems a fitting example when you start talking about sharing buffers between many devices, for example camera+codec+display), it would already be negotiating format between v4l2src + fooencoder + displaysink.. the pitch/stride is part of that format information. If the display isn't the one with the strictest requirements, we don't want the display driver deciding what pitch to use. The whole point is to be able to allocate the buffer in such a way that another device can access it. So the driver _can't_ use a special, device specific format, nor can it allocate it from a private memory pool because doing so would preclude it from being shared with another device. That other device doesn't need to be a GPU wither, it could just as easily be a camera/ISP or video decoder. So presumably you're talking about a GPU driver being the exporter here? If so, how could the GPU driver do these kind of tricks on memory shared with another device? Yes, that is gpu-as-exporter. If someone else is allocating buffers, it is up to them to do these tricks or not. Probably there is a pretty good chance that if you aren't a GPU you don't need those sort of tricks for fast allocation of transient upload buffers, staging textures, temporary pixmaps, etc. Ie. I don't really think a v4l camera or video decoder would benefit from that sort of optimization. Right - but none of
[GIT PULL FOR 3.12] v4l2-async and Samsung driver fixes
Hi Mauro, This includes v4l2-async regression fix introduced in my previous patch series - sorry about that omission, and couple Samsung SoC driver fixes. The following changes since commit dfb9f94e8e5e7f73c8e2bcb7d4fb1de57e7c333d: [media] stk1160: Build as a module if SND is m and audio support is selected (2013-08-01 14:55:25 -0300) are available in the git repository at: git://linuxtv.org/snawrocki/samsung.git for-v3.12-2 for you to fetch changes up to 886976a6db6c7bf1aaeb181e2b5fafb7e0d0e5d4: exynos-gsc: fix s2r functionality (2013-08-09 18:54:41 +0200) Andrzej Hajda (1): V4L: s5c73m3: Add format propagation for TRY formats Prathyush K (1): exynos-gsc: fix s2r functionality Sachin Kamat (2): exynos4-is: Fix potential NULL pointer dereference exynos4-is: Staticize local symbol Sylwester Nawrocki (1): v4l2-async: Use proper list head for iteration over registered subdevs drivers/media/i2c/s5c73m3/s5c73m3-core.c |5 + drivers/media/platform/exynos-gsc/gsc-core.c | 13 - drivers/media/platform/exynos4-is/fimc-is-param.c |2 +- drivers/media/platform/exynos4-is/fimc-lite.c | 13 +++-- drivers/media/v4l2-core/v4l2-async.c |2 +- 5 files changed, 22 insertions(+), 13 deletions(-) -- Regards, Sylwester -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
cron job: media_tree daily build: WARNINGS
This message is generated daily by a cron job that builds media_tree for the kernels and architectures in the list below. Results of the daily build of media_tree: date: Fri Aug 9 19:00:37 CEST 2013 git branch: test git hash: dfb9f94e8e5e7f73c8e2bcb7d4fb1de57e7c333d gcc version:i686-linux-gcc (GCC) 4.8.1 sparse version: v0.4.5-rc1 host hardware: x86_64 host os:3.9-7.slh.1-amd64 linux-git-arm-at91: OK linux-git-arm-davinci: OK linux-git-arm-exynos: OK linux-git-arm-mx: OK linux-git-arm-omap: OK linux-git-arm-omap1: OK linux-git-arm-pxa: OK linux-git-blackfin: OK linux-git-i686: OK linux-git-m32r: OK linux-git-mips: OK linux-git-powerpc64: OK linux-git-sh: OK linux-git-x86_64: OK linux-2.6.31.14-i686: WARNINGS linux-2.6.32.27-i686: WARNINGS linux-2.6.33.7-i686: WARNINGS linux-2.6.34.7-i686: WARNINGS linux-2.6.35.9-i686: WARNINGS linux-2.6.36.4-i686: WARNINGS linux-2.6.37.6-i686: WARNINGS linux-2.6.38.8-i686: WARNINGS linux-2.6.39.4-i686: WARNINGS linux-3.0.60-i686: OK linux-3.10-i686: OK linux-3.1.10-i686: OK linux-3.2.37-i686: OK linux-3.3.8-i686: OK linux-3.4.27-i686: WARNINGS linux-3.5.7-i686: WARNINGS linux-3.6.11-i686: WARNINGS linux-3.7.4-i686: WARNINGS linux-3.8-i686: WARNINGS linux-3.9.2-i686: WARNINGS linux-2.6.31.14-x86_64: WARNINGS linux-2.6.32.27-x86_64: WARNINGS linux-2.6.33.7-x86_64: WARNINGS linux-2.6.34.7-x86_64: WARNINGS linux-2.6.35.9-x86_64: WARNINGS linux-2.6.36.4-x86_64: WARNINGS linux-2.6.37.6-x86_64: WARNINGS linux-2.6.38.8-x86_64: WARNINGS linux-2.6.39.4-x86_64: WARNINGS linux-3.0.60-x86_64: OK linux-3.10-x86_64: OK linux-3.1.10-x86_64: OK linux-3.2.37-x86_64: OK linux-3.3.8-x86_64: OK linux-3.4.27-x86_64: WARNINGS linux-3.5.7-x86_64: WARNINGS linux-3.6.11-x86_64: WARNINGS linux-3.7.4-x86_64: WARNINGS linux-3.8-x86_64: WARNINGS linux-3.9.2-x86_64: WARNINGS apps: WARNINGS spec-git: OK sparse version: v0.4.5-rc1 sparse: ERRORS Detailed results are available here: http://www.xs4all.nl/~hverkuil/logs/Friday.log Full logs are available here: http://www.xs4all.nl/~hverkuil/logs/Friday.tar.bz2 The Media Infrastructure API from this daily build is here: http://www.xs4all.nl/~hverkuil/spec/media.html -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/10] exynos4-is: Asynchronous subdev registration support
This patch series is a refactoring of the exynos4-is driver to get rid of the common fimc-is-sensor driver and to adapt it to use standard sensor subdev drivers, one per each image sensor type. Then a clock provider is added and the s5k6a3 subdev is modified to use one of the clocks exposed by the exynos4-is driver. Finally a v4l2-async notifier support is added for image sensor subdevs. I have also included a couple bug fixes not really related to v4l2-async. This series depends on patches adding clock deregistration support at the common clock framework [1] and the other series those depend on [2]. The series can be found in git repository: http://git.linuxtv.org/snawrocki/samsung.git/v3.11-rc2-dts-exynos4-is-clk [1] http://www.spinics.net/lists/arm-kernel/msg265989.html [2] http://www.mail-archive.com/linux-kernel@vger.kernel.org/msg481861.html Sylwester Nawrocki (9): V4L: Add driver for s5k6a3 image sensor V4L: s5k6a3: Add support for asynchronous subdev registration exynos4-is: Initialize the ISP subdev sd-owner field exynos4-is: Add missing MODULE_LICENSE for exynos-fimc-is.ko exynos4-is: Add missing v4l2_device_unregister() call in fimc_md_remove() exynos4-is: Simplify sclk_cam clocks handling exynos4-is: Add clock provider for the external clocks exynos4-is: Use external s5k6a3 sensor driver exynos4-is: Add support for asynchronous sensor subddevs registration Tomasz Figa (1): exynos4-is: Handle suspend/resume of fimc-is-i2c correctly .../devicetree/bindings/media/samsung-fimc.txt | 21 +- drivers/media/i2c/Kconfig |8 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/s5k6a3.c | 357 drivers/media/platform/exynos4-is/fimc-is-i2c.c| 33 +- drivers/media/platform/exynos4-is/fimc-is-regs.c |2 +- drivers/media/platform/exynos4-is/fimc-is-sensor.c | 285 +--- drivers/media/platform/exynos4-is/fimc-is-sensor.h | 49 +-- drivers/media/platform/exynos4-is/fimc-is.c| 98 +++--- drivers/media/platform/exynos4-is/fimc-is.h|4 +- drivers/media/platform/exynos4-is/fimc-isp.c |2 + drivers/media/platform/exynos4-is/media-dev.c | 350 +-- drivers/media/platform/exynos4-is/media-dev.h | 31 +- 13 files changed, 746 insertions(+), 495 deletions(-) create mode 100644 drivers/media/i2c/s5k6a3.c -- 1.7.9.5 -- Thanks, Sylwester -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 01/10] V4L: Add driver for s5k6a3 image sensor
This patch adds subdev driver for Samsung S5K6A3 raw image sensor. As it is intended at the moment to be used only with the Exynos FIMC-IS (camera ISP) subsystem it is pretty minimal subdev driver. It doesn't do any I2C communication since the sensor is controlled by the ISP and its own firmware. This driver can be updated in future, should anyone need it to be a regular subdev driver where the main CPU communicates with the sensor directly. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- Changes since v1: - added missing pm_runtime_disable(), - removed subdev name overriding, - s/S5K6A3_DEF_PIX/S5K6A3_DEFAULT_ --- drivers/media/i2c/Kconfig |8 ++ drivers/media/i2c/Makefile |1 + drivers/media/i2c/s5k6a3.c | 316 3 files changed, 325 insertions(+) create mode 100644 drivers/media/i2c/s5k6a3.c diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index b2cd8ca..f7e9147 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -564,6 +564,14 @@ config VIDEO_S5K6AA This is a V4L2 sensor-level driver for Samsung S5K6AA(FX) 1.3M camera sensor with an embedded SoC image signal processor. +config VIDEO_S5K6A3 + tristate Samsung S5K6A3 sensor support + depends on MEDIA_CAMERA_SUPPORT + depends on I2C VIDEO_V4L2 VIDEO_V4L2_SUBDEV_API OF + ---help--- + This is a V4L2 sensor-level driver for Samsung S5K6A3 raw + camera sensor. + config VIDEO_S5K4ECGX tristate Samsung S5K4ECGX sensor support depends on I2C VIDEO_V4L2 VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index dc20653..cf3cf03 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -64,6 +64,7 @@ obj-$(CONFIG_VIDEO_MT9V032) += mt9v032.o obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o obj-$(CONFIG_VIDEO_NOON010PC30)+= noon010pc30.o obj-$(CONFIG_VIDEO_S5K6AA) += s5k6aa.o +obj-$(CONFIG_VIDEO_S5K6A3) += s5k6a3.o obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o obj-$(CONFIG_VIDEO_S5C73M3)+= s5c73m3/ obj-$(CONFIG_VIDEO_ADP1653)+= adp1653.o diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c new file mode 100644 index 000..0817664 --- /dev/null +++ b/drivers/media/i2c/s5k6a3.c @@ -0,0 +1,316 @@ +/* + * Samsung S5K6A3 image sensor driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Sylwester Nawrocki s.nawro...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/clk.h +#include linux/delay.h +#include linux/device.h +#include linux/errno.h +#include linux/gpio.h +#include linux/i2c.h +#include linux/kernel.h +#include linux/module.h +#include linux/of_gpio.h +#include linux/pm_runtime.h +#include linux/regulator/consumer.h +#include linux/slab.h +#include linux/videodev2.h +#include media/v4l2-async.h +#include media/v4l2-subdev.h + +#define S5K6A3_SENSOR_MAX_WIDTH1392 +#define S5K6A3_SENSOR_MAX_HEIGHT 1392 +#define S5K6A3_SENSOR_MIN_WIDTH32 +#define S5K6A3_SENSOR_MIN_HEIGHT 32 + +#define S5K6A3_DEFAULT_WIDTH 1296 +#define S5K6A3_DEFAULT_HEIGHT 732 + +#define S5K6A3_DRV_NAMES5K6A3 + +#define S5K6A3_NUM_SUPPLIES2 + +/** + * struct s5k6a3 - fimc-is sensor data structure + * @dev: pointer to this I2C client device structure + * @subdev: the image sensor's v4l2 subdev + * @pad: subdev media source pad + * @supplies: image sensor's voltage regulator supplies + * @gpio_reset: GPIO connected to the sensor's reset pin + * @lock: mutex protecting the structure's members below + * @format: media bus format at the sensor's source pad + */ +struct s5k6a3 { + struct device *dev; + struct v4l2_subdev subdev; + struct media_pad pad; + struct regulator_bulk_data supplies[S5K6A3_NUM_SUPPLIES]; + int gpio_reset; + struct mutex lock; + struct v4l2_mbus_framefmt format; + u32 clock_frequency; +}; + +static const char * const s5k6a3_supply_names[] = { + svdda, + svddio +}; + +static inline struct s5k6a3 *sd_to_s5k6a3(struct v4l2_subdev *sd) +{ + return container_of(sd, struct s5k6a3, subdev); +} + +static const struct v4l2_mbus_framefmt s5k6a3_formats[] = { + { + .code = V4L2_MBUS_FMT_SGRBG10_1X10, + .colorspace = V4L2_COLORSPACE_SRGB, + .field = V4L2_FIELD_NONE, + } +}; + +static const struct v4l2_mbus_framefmt *find_sensor_format( + struct v4l2_mbus_framefmt *mf) +{ + int i; + + for (i = 0; i ARRAY_SIZE(s5k6a3_formats); i++) + if (mf-code == s5k6a3_formats[i].code) +
[PATCH 08/10] exynos4-is: Add clock provider for the external clocks
This patch adds clock provider to expose the sclk_cam0/1 clocks for image sensor subdevs. Cc: devicet...@vger.kernel.org Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- .../devicetree/bindings/media/samsung-fimc.txt | 17 ++- drivers/media/platform/exynos4-is/media-dev.c | 115 drivers/media/platform/exynos4-is/media-dev.h | 18 ++- 3 files changed, 147 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt index 96312f6..9f4d295 100644 --- a/Documentation/devicetree/bindings/media/samsung-fimc.txt +++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt @@ -91,6 +91,15 @@ Optional properties - samsung,camclk-out : specifies clock output for remote sensor, 0 - CAM_A_CLKOUT, 1 - CAM_B_CLKOUT; +'clock-controller' node (optional) +-- + +The purpose of this node is to define a clock provider for external image +sensors and link any of the CAM_?_CLKOUT clock outputs with related external +clock consumer device. Properties specific to this node are described in +../clock/clock-bindings.txt. + + Image sensor nodes -- @@ -114,7 +123,7 @@ Example: vddio-supply = ...; clock-frequency = 2400; - clocks = ...; + clocks = camclk 1; clock-names = mclk; port { @@ -135,7 +144,7 @@ Example: vddio-supply = ...; clock-frequency = 2400; - clocks = ...; + clocks = camclk 0; clock-names = mclk; port { @@ -156,6 +165,10 @@ Example: pinctrl-names = default; pinctrl-0 = cam_port_a_clk_active; + camclk: clock-controller { + #clock-cells = 1; + }; + /* parallel camera ports */ parallel-ports { /* camera A input */ diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index e327f45..6fba5f6 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -11,6 +11,8 @@ */ #include linux/bug.h +#include linux/clk.h +#include linux/clk-provider.h #include linux/device.h #include linux/errno.h #include linux/i2c.h @@ -1438,6 +1440,108 @@ static int fimc_md_get_pinctrl(struct fimc_md *fmd) return 0; } +#ifdef CONFIG_OF +static int cam_clk_prepare(struct clk_hw *hw) +{ + struct cam_clk *camclk = to_cam_clk(hw); + int ret; + + if (camclk-fmd-pmf == NULL) + return -ENODEV; + + ret = pm_runtime_get_sync(camclk-fmd-pmf); + return ret 0 ? ret : 0; +} + +static void cam_clk_unprepare(struct clk_hw *hw) +{ + struct cam_clk *camclk = to_cam_clk(hw); + + if (camclk-fmd-pmf == NULL) + return; + + pm_runtime_put_sync(camclk-fmd-pmf); +} + +static const struct clk_ops cam_clk_ops = { + .prepare = cam_clk_prepare, + .unprepare = cam_clk_unprepare, +}; + +static const char *cam_clk_p_names[] = { sclk_cam0, sclk_cam1 }; + +static void fimc_md_unregister_clk_provider(struct fimc_md *fmd) +{ + struct cam_clk_provider *cp = fmd-clk_provider; + unsigned int i; + + if (cp-of_node) + of_clk_del_provider(cp-of_node); + + for (i = 0; i ARRAY_SIZE(cp-clks); i++) + if (!IS_ERR(cp-clks[i])) + clk_unregister(cp-clks[i]); +} + +static int fimc_md_register_clk_provider(struct fimc_md *fmd) +{ + struct cam_clk_provider *cp = fmd-clk_provider; + struct device *dev = fmd-pdev-dev; + struct device_node *node; + int i, ret; + + for (i = 0; i ARRAY_SIZE(cp-clks); i++) + cp-clks[i] = ERR_PTR(-EINVAL); + + node = of_get_child_by_name(dev-of_node, clock-controller); + if (!node) { + dev_warn(dev, clock-controller node at %s not found\n, + dev-of_node-full_name); + return 0; + } + for (i = 0; i FIMC_MAX_CAMCLKS; i++) { + struct cam_clk *camclk = cp-camclk[i]; + struct clk_init_data init; + char clk_name[16]; + struct clk *clk; + + snprintf(clk_name, sizeof(clk_name), cam_clkout%d, i); + + init.name = clk_name; + init.ops = cam_clk_ops; + init.flags = CLK_SET_RATE_PARENT; + init.parent_names = cam_clk_p_names[i]; + init.num_parents = 1; + camclk-hw.init = init; + camclk-fmd =
[PATCH 05/10] exynos4-is: Add missing MODULE_LICENSE for exynos-fimc-is.ko
This fixes compilation warning: WARNING: modpost: missing MODULE_LICENSE() in drivers/media/platform/exynos4-is/exynos-fimc-is.o Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/platform/exynos4-is/fimc-is.c |1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/platform/exynos4-is/fimc-is.c b/drivers/media/platform/exynos4-is/fimc-is.c index 967f6a9..9b7fd1c 100644 --- a/drivers/media/platform/exynos4-is/fimc-is.c +++ b/drivers/media/platform/exynos4-is/fimc-is.c @@ -993,3 +993,4 @@ module_exit(fimc_is_module_exit); MODULE_ALIAS(platform: FIMC_IS_DRV_NAME); MODULE_AUTHOR(Younghwan Joo yhwan@samsung.com); MODULE_AUTHOR(Sylwester Nawrocki s.nawro...@samsung.com); +MODULE_LICENSE(GPL v2); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 07/10] exynos4-is: Simplify sclk_cam clocks handling
Use clk_prepare_enable()/clk_disable_unprepare() instead of separately prearing/unparing the clk_cam clocks. This simplifies the code that is now mostly not going to be used, function __fimc_md_set_camclk() is only left for S5PV210 platform which is not yet converted to Device Tree. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/platform/exynos4-is/media-dev.c | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 0446ab3..e327f45 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1150,7 +1150,6 @@ static void fimc_md_put_clocks(struct fimc_md *fmd) while (--i = 0) { if (IS_ERR(fmd-camclk[i].clock)) continue; - clk_unprepare(fmd-camclk[i].clock); clk_put(fmd-camclk[i].clock); fmd-camclk[i].clock = ERR_PTR(-EINVAL); } @@ -1169,7 +1168,7 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) struct device *dev = NULL; char clk_name[32]; struct clk *clock; - int ret, i; + int i, ret = 0; for (i = 0; i FIMC_MAX_CAMCLKS; i++) fmd-camclk[i].clock = ERR_PTR(-EINVAL); @@ -1187,12 +1186,6 @@ static int fimc_md_get_clocks(struct fimc_md *fmd) ret = PTR_ERR(clock); break; } - ret = clk_prepare(clock); - if (ret 0) { - clk_put(clock); - fmd-camclk[i].clock = ERR_PTR(-EINVAL); - break; - } fmd-camclk[i].clock = clock; } if (ret) @@ -1249,7 +1242,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, ret = pm_runtime_get_sync(fmd-pmf); if (ret 0) return ret; - ret = clk_enable(camclk-clock); + ret = clk_prepare_enable(camclk-clock); dbg(Enabled camclk %d: f: %lu, si-clk_id, clk_get_rate(camclk-clock)); } @@ -1260,7 +1253,7 @@ static int __fimc_md_set_camclk(struct fimc_md *fmd, return 0; if (--camclk-use_count == 0) { - clk_disable(camclk-clock); + clk_disable_unprepare(camclk-clock); pm_runtime_put(fmd-pmf); dbg(Disabled camclk %d, si-clk_id); } -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/10] exynos4-is: Handle suspend/resume of fimc-is-i2c correctly
From: Tomasz Figa t.f...@samsung.com If the same callbacks are used for runtime and system suspend/resume, clocks can get disabled twice, which can lead to negative reference counts and kernel warnings. This patch splits suspend/resume callbacks into separate runtime and system-wide functions, so clock gating is done correctly. Signed-off-by: Tomasz Figa t.f...@samsung.com Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/platform/exynos4-is/fimc-is-i2c.c | 33 --- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is-i2c.c b/drivers/media/platform/exynos4-is/fimc-is-i2c.c index 617a798..6bc481a 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-i2c.c +++ b/drivers/media/platform/exynos4-is/fimc-is-i2c.c @@ -83,21 +83,46 @@ static int fimc_is_i2c_remove(struct platform_device *pdev) return 0; } -static int fimc_is_i2c_suspend(struct device *dev) +#if defined(CONFIG_PM_RUNTIME) || defined(CONFIG_PM_SLEEP) +static int fimc_is_i2c_runtime_suspend(struct device *dev) { struct fimc_is_i2c *isp_i2c = dev_get_drvdata(dev); + clk_disable_unprepare(isp_i2c-clock); return 0; } -static int fimc_is_i2c_resume(struct device *dev) +static int fimc_is_i2c_runtime_resume(struct device *dev) { struct fimc_is_i2c *isp_i2c = dev_get_drvdata(dev); + return clk_prepare_enable(isp_i2c-clock); } +#endif -static UNIVERSAL_DEV_PM_OPS(fimc_is_i2c_pm_ops, fimc_is_i2c_suspend, -fimc_is_i2c_resume, NULL); +#ifdef CONFIG_PM_SLEEP +static int fimc_is_i2c_suspend(struct device *dev) +{ + if (pm_runtime_suspended(dev)) + return 0; + + return fimc_is_i2c_runtime_suspend(dev); +} + +static int fimc_is_i2c_resume(struct device *dev) +{ + if (pm_runtime_suspended(dev)) + return 0; + + return fimc_is_i2c_runtime_resume(dev); +} +#endif + +static struct dev_pm_ops fimc_is_i2c_pm_ops = { + SET_RUNTIME_PM_OPS(fimc_is_i2c_runtime_suspend, + fimc_is_i2c_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(fimc_is_i2c_suspend, fimc_is_i2c_resume) +}; static const struct of_device_id fimc_is_i2c_of_match[] = { { .compatible = FIMC_IS_I2C_COMPATIBLE }, -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/10] exynos4-is: Initialize the ISP subdev sd-owner field
Set the subdevs owner module so the exynos4_fimc_is module cannot be unloaded when the FIMC-IS driver is in use. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/platform/exynos4-is/fimc-isp.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/exynos4-is/fimc-isp.c b/drivers/media/platform/exynos4-is/fimc-isp.c index cf520a7..d2e6cba 100644 --- a/drivers/media/platform/exynos4-is/fimc-isp.c +++ b/drivers/media/platform/exynos4-is/fimc-isp.c @@ -672,6 +672,8 @@ int fimc_isp_subdev_create(struct fimc_isp *isp) mutex_init(isp-subdev_lock); v4l2_subdev_init(sd, fimc_is_subdev_ops); + + sd-owner = THIS_MODULE; sd-grp_id = GRP_ID_FIMC_IS; sd-flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; snprintf(sd-name, sizeof(sd-name), FIMC-IS-ISP); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/10] exynos4-is: Add support for asynchronous sensor subddevs registration
Add support for registering external sensor subdevs using the v4l2-async API. The async API is used only for sensor subdevs and only for platforms instantiated from Device Tree. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- Changes since v1: - register clock provider after registering FIMC devices so the clock can be actually used right after it is registered. --- .../devicetree/bindings/media/samsung-fimc.txt |4 +- drivers/media/platform/exynos4-is/media-dev.c | 234 +++- drivers/media/platform/exynos4-is/media-dev.h | 13 +- 3 files changed, 146 insertions(+), 105 deletions(-) diff --git a/Documentation/devicetree/bindings/media/samsung-fimc.txt b/Documentation/devicetree/bindings/media/samsung-fimc.txt index 9f4d295..daf145d 100644 --- a/Documentation/devicetree/bindings/media/samsung-fimc.txt +++ b/Documentation/devicetree/bindings/media/samsung-fimc.txt @@ -106,8 +106,8 @@ Image sensor nodes The sensor device nodes should be added to their control bus controller (e.g. I2C0) nodes and linked to a port node in the csis or the parallel-ports node, using the common video interfaces bindings, defined in video-interfaces.txt. -The implementation of this bindings requires clock-frequency property to be -present in the sensor device nodes. +An optional clock-frequency property needs to be present in the sensor device +nodes. Default value when this property is not present is 24 MHz. Example: diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 6fba5f6..c10dee2 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -27,6 +27,7 @@ #include linux/pm_runtime.h #include linux/types.h #include linux/slab.h +#include media/v4l2-async.h #include media/v4l2-ctrls.h #include media/v4l2-of.h #include media/media-device.h @@ -221,6 +222,7 @@ static int __fimc_pipeline_open(struct exynos_media_pipeline *ep, if (ret 0) return ret; } + ret = fimc_md_set_camclk(sd, true); if (ret 0) goto err_wbclk; @@ -381,77 +383,18 @@ static void fimc_md_unregister_sensor(struct v4l2_subdev *sd) struct i2c_client *client = v4l2_get_subdevdata(sd); struct i2c_adapter *adapter; - if (!client) + if (!client || client-dev.of_node) return; v4l2_device_unregister_subdev(sd); - if (!client-dev.of_node) { - adapter = client-adapter; - i2c_unregister_device(client); - if (adapter) - i2c_put_adapter(adapter); - } + adapter = client-adapter; + i2c_unregister_device(client); + if (adapter) + i2c_put_adapter(adapter); } #ifdef CONFIG_OF -/* Register I2C client subdev associated with @node. */ -static int fimc_md_of_add_sensor(struct fimc_md *fmd, -struct device_node *node, int index) -{ - struct fimc_sensor_info *si; - struct i2c_client *client; - struct v4l2_subdev *sd; - int ret; - - if (WARN_ON(index = ARRAY_SIZE(fmd-sensor))) - return -EINVAL; - si = fmd-sensor[index]; - - client = of_find_i2c_device_by_node(node); - if (!client) - return -EPROBE_DEFER; - - device_lock(client-dev); - - if (!client-driver || - !try_module_get(client-driver-driver.owner)) { - ret = -EPROBE_DEFER; - v4l2_info(fmd-v4l2_dev, No driver found for %s\n, - node-full_name); - goto dev_put; - } - - /* Enable sensor's master clock */ - ret = __fimc_md_set_camclk(fmd, si-pdata, true); - if (ret 0) - goto mod_put; - sd = i2c_get_clientdata(client); - - ret = v4l2_device_register_subdev(fmd-v4l2_dev, sd); - __fimc_md_set_camclk(fmd, si-pdata, false); - if (ret 0) - goto mod_put; - - v4l2_set_subdev_hostdata(sd, si-pdata); - if (si-pdata.fimc_bus_type == FIMC_BUS_TYPE_ISP_WRITEBACK) - sd-grp_id = GRP_ID_FIMC_IS_SENSOR; - else - sd-grp_id = GRP_ID_SENSOR; - - si-subdev = sd; - v4l2_info(fmd-v4l2_dev, Registered sensor subdevice: %s (%d)\n, - sd-name, fmd-num_sensors); - fmd-num_sensors++; - -mod_put: - module_put(client-driver-driver.owner); -dev_put: - device_unlock(client-dev); - put_device(client-dev); - return ret; -} - /* Parse port node and register as a sub-device any sensor specified there. */ static int fimc_md_parse_port_node(struct fimc_md *fmd, struct device_node *port, @@ -460,7 +403,6 @@ static int fimc_md_parse_port_node(struct fimc_md *fmd,
[PATCH 02/10] V4L: s5k6a3: Add support for asynchronous subdev registration
This patch converts the driver to use v4l2 asynchronous subdev registration API an the common clock API. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com Changes since v1: - clock-frequency property is now optional and a default frequency value will be used when it is missing, rather than bailing out. --- drivers/media/i2c/s5k6a3.c | 63 1 file changed, 52 insertions(+), 11 deletions(-) diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index 0817664..d396cfe 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -34,6 +34,8 @@ #define S5K6A3_DEFAULT_HEIGHT 732 #define S5K6A3_DRV_NAMES5K6A3 +#define S5K6A3_CLK_NAMEmclk +#define S5K6A3_DEFAULT_CLK_FREQ2400U #define S5K6A3_NUM_SUPPLIES2 @@ -55,6 +57,7 @@ struct s5k6a3 { int gpio_reset; struct mutex lock; struct v4l2_mbus_framefmt format; + struct clk *clock; u32 clock_frequency; }; @@ -180,19 +183,29 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on) { struct s5k6a3 *sensor = sd_to_s5k6a3(sd); int gpio = sensor-gpio_reset; - int ret; + int ret = 0; if (on) { + sensor-clock = clk_get(sensor-dev, S5K6A3_CLK_NAME); + if (IS_ERR(sensor-clock)) + return PTR_ERR(sensor-clock); + + ret = clk_set_rate(sensor-clock, sensor-clock_frequency); + if (ret 0) + goto clk_put; + ret = pm_runtime_get(sensor-dev); if (ret 0) - return ret; + goto clk_put; ret = regulator_bulk_enable(S5K6A3_NUM_SUPPLIES, sensor-supplies); - if (ret 0) { - pm_runtime_put(sensor-dev); - return ret; - } + if (ret 0) + goto rpm_put; + + ret = clk_prepare_enable(sensor-clock); + if (ret 0) + goto reg_dis; if (gpio_is_valid(gpio)) { gpio_set_value(gpio, 1); @@ -208,10 +221,14 @@ static int s5k6a3_s_power(struct v4l2_subdev *sd, int on) if (gpio_is_valid(gpio)) gpio_set_value(gpio, 0); - ret = regulator_bulk_disable(S5K6A3_NUM_SUPPLIES, -sensor-supplies); - if (!ret) - pm_runtime_put(sensor-dev); + clk_disable_unprepare(sensor-clock); +reg_dis: + regulator_bulk_disable(S5K6A3_NUM_SUPPLIES, + sensor-supplies); +rpm_put: + pm_runtime_put(sensor-dev); +clk_put: + clk_put(sensor-clock); } return ret; } @@ -239,6 +256,7 @@ static int s5k6a3_probe(struct i2c_client *client, mutex_init(sensor-lock); sensor-gpio_reset = -EINVAL; + sensor-clock = ERR_PTR(-EINVAL); sensor-dev = dev; gpio = of_get_gpio_flags(dev-of_node, 0, NULL); @@ -250,6 +268,13 @@ static int s5k6a3_probe(struct i2c_client *client, } sensor-gpio_reset = gpio; + if (of_property_read_u32(dev-of_node, clock-frequency, +sensor-clock_frequency)) { + sensor-clock_frequency = S5K6A3_DEFAULT_CLK_FREQ; + dev_info(dev, using default %u Hz clock frequency\n, + sensor-clock_frequency); + } + for (i = 0; i S5K6A3_NUM_SUPPLIES; i++) sensor-supplies[i].supply = s5k6a3_supply_names[i]; @@ -258,6 +283,11 @@ static int s5k6a3_probe(struct i2c_client *client, if (ret 0) return ret; + /* Defer probing if the clock is not available yet */ + sensor-clock = clk_get(dev, S5K6A3_CLK_NAME); + if (IS_ERR(sensor-clock)) + return -EPROBE_DEFER; + sd = sensor-subdev; v4l2_i2c_subdev_init(sd, client, s5k6a3_subdev_ops); sensor-subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE; @@ -274,7 +304,17 @@ static int s5k6a3_probe(struct i2c_client *client, pm_runtime_no_callbacks(dev); pm_runtime_enable(dev); - return 0; + ret = v4l2_async_register_subdev(sd); + + /* +* Don't hold reference to the clock to avoid circular dependency +* between the subdev and the host driver, in case the host is +* a supplier of the clock. +* clk_get()/clk_put() will be called in s_power callback. +*/ + clk_put(sensor-clock); + + return ret; } static int s5k6a3_remove(struct i2c_client *client) @@ -282,6 +322,7 @@
[PATCH 06/10] exynos4-is: Add missing v4l2_device_unregister() call in fimc_md_remove()
Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/platform/exynos4-is/media-dev.c |2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/platform/exynos4-is/media-dev.c b/drivers/media/platform/exynos4-is/media-dev.c index 91f21e2..0446ab3 100644 --- a/drivers/media/platform/exynos4-is/media-dev.c +++ b/drivers/media/platform/exynos4-is/media-dev.c @@ -1544,6 +1544,8 @@ static int fimc_md_remove(struct platform_device *pdev) if (!fmd) return 0; + + v4l2_device_unregister(fmd-v4l2_dev); device_remove_file(pdev-dev, dev_attr_subdev_conf_mode); fimc_md_unregister_entities(fmd); fimc_md_pipelines_free(fmd); -- 1.7.9.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/10] exynos4-is: Use external s5k6a3 sensor driver
This patch removes the common fimc-is-sensor driver for image sensors that are normally controlled by the FIMC-IS firmware. The FIMC-IS driver now contains only a table of properties specific to each sensor. The sensor properties required for the ISP's firmware are parsed from device tree and retrieved from the internal table, which is selected based on the compatible property of an image sensor. To use the Exynos4x12 internal ISP the S5K6A3 sensor driver (drivers/ media/i2c/s5k6a3.c) is now required. Signed-off-by: Sylwester Nawrocki s.nawro...@samsung.com Signed-off-by: Kyungmin Park kyungmin.p...@samsung.com --- drivers/media/platform/exynos4-is/fimc-is-regs.c |2 +- drivers/media/platform/exynos4-is/fimc-is-sensor.c | 285 +--- drivers/media/platform/exynos4-is/fimc-is-sensor.h | 49 +--- drivers/media/platform/exynos4-is/fimc-is.c| 97 +++ drivers/media/platform/exynos4-is/fimc-is.h|4 +- 5 files changed, 57 insertions(+), 380 deletions(-) diff --git a/drivers/media/platform/exynos4-is/fimc-is-regs.c b/drivers/media/platform/exynos4-is/fimc-is-regs.c index 63c68ec..3e51aa6 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-regs.c +++ b/drivers/media/platform/exynos4-is/fimc-is-regs.c @@ -136,7 +136,7 @@ void fimc_is_hw_set_sensor_num(struct fimc_is *is) mcuctl_write(IH_REPLY_DONE, is, MCUCTL_REG_ISSR(0)); mcuctl_write(is-sensor_index, is, MCUCTL_REG_ISSR(1)); mcuctl_write(IHC_GET_SENSOR_NUM, is, MCUCTL_REG_ISSR(2)); - mcuctl_write(FIMC_IS_SENSOR_NUM, is, MCUCTL_REG_ISSR(3)); + mcuctl_write(FIMC_IS_SENSORS_NUM, is, MCUCTL_REG_ISSR(3)); } void fimc_is_hw_close_sensor(struct fimc_is *is, unsigned int index) diff --git a/drivers/media/platform/exynos4-is/fimc-is-sensor.c b/drivers/media/platform/exynos4-is/fimc-is-sensor.c index 6647421..10e82e2 100644 --- a/drivers/media/platform/exynos4-is/fimc-is-sensor.c +++ b/drivers/media/platform/exynos4-is/fimc-is-sensor.c @@ -2,276 +2,21 @@ * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver * * Copyright (C) 2013 Samsung Electronics Co., Ltd. - * * Author: Sylwester Nawrocki s.nawro...@samsung.com * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */ -#include linux/delay.h -#include linux/device.h -#include linux/errno.h -#include linux/gpio.h -#include linux/i2c.h -#include linux/kernel.h -#include linux/module.h -#include linux/of_gpio.h -#include linux/pm_runtime.h -#include linux/regulator/consumer.h -#include linux/slab.h -#include media/v4l2-subdev.h -#include fimc-is.h #include fimc-is-sensor.h -#define DRIVER_NAME FIMC-IS-SENSOR - -static const char * const sensor_supply_names[] = { - svdda, - svddio, -}; - -static const struct v4l2_mbus_framefmt fimc_is_sensor_formats[] = { - { - .code = V4L2_MBUS_FMT_SGRBG10_1X10, - .colorspace = V4L2_COLORSPACE_SRGB, - .field = V4L2_FIELD_NONE, - } -}; - -static const struct v4l2_mbus_framefmt *find_sensor_format( - struct v4l2_mbus_framefmt *mf) -{ - int i; - - for (i = 0; i ARRAY_SIZE(fimc_is_sensor_formats); i++) - if (mf-code == fimc_is_sensor_formats[i].code) - return fimc_is_sensor_formats[i]; - - return fimc_is_sensor_formats[0]; -} - -static int fimc_is_sensor_enum_mbus_code(struct v4l2_subdev *sd, - struct v4l2_subdev_fh *fh, - struct v4l2_subdev_mbus_code_enum *code) -{ - if (code-index = ARRAY_SIZE(fimc_is_sensor_formats)) - return -EINVAL; - - code-code = fimc_is_sensor_formats[code-index].code; - return 0; -} - -static void fimc_is_sensor_try_format(struct fimc_is_sensor *sensor, - struct v4l2_mbus_framefmt *mf) -{ - const struct sensor_drv_data *dd = sensor-drvdata; - const struct v4l2_mbus_framefmt *fmt; - - fmt = find_sensor_format(mf); - mf-code = fmt-code; - v4l_bound_align_image(mf-width, 16 + 8, dd-width, 0, - mf-height, 12 + 8, dd-height, 0, 0); -} - -static struct v4l2_mbus_framefmt *__fimc_is_sensor_get_format( - struct fimc_is_sensor *sensor, struct v4l2_subdev_fh *fh, - u32 pad, enum v4l2_subdev_format_whence which) -{ - if (which == V4L2_SUBDEV_FORMAT_TRY) - return fh ? v4l2_subdev_get_try_format(fh, pad) : NULL; - - return sensor-format; -} - -static int fimc_is_sensor_set_fmt(struct v4l2_subdev *sd, - struct v4l2_subdev_fh *fh, - struct v4l2_subdev_format *fmt) -{ - struct fimc_is_sensor *sensor = sd_to_fimc_is_sensor(sd); - struct v4l2_mbus_framefmt *mf; - -
Re: [PATCH v4 03/13] [media] exynos5-fimc-is: Add driver core files
Hi, On 08/07/2013 11:03 AM, Arun Kumar K wrote: This driver is for the FIMC-IS IP available in Samsung Exynos5 SoC onwards. This patch adds the core files for the new driver. Signed-off-by: Arun Kumar Karun...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-core.c | 413 ++ drivers/media/platform/exynos5-is/fimc-is-core.h | 134 +++ 2 files changed, 547 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-core.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-core.c b/drivers/media/platform/exynos5-is/fimc-is-core.c new file mode 100644 index 000..067dea6 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-core.c @@ -0,0 +1,413 @@ +/* + * Samsung EXYNOS5 FIMC-IS (Imaging Subsystem) driver +* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#includelinux/bug.h +#includelinux/ctype.h +#includelinux/device.h +#includelinux/debugfs.h +#includelinux/delay.h +#includelinux/errno.h +#includelinux/err.h +#includelinux/firmware.h +#includelinux/fs.h +#includelinux/gpio.h +#includelinux/interrupt.h +#includelinux/kernel.h +#includelinux/list.h +#includelinux/module.h +#includelinux/types.h +#includelinux/platform_device.h +#includelinux/pm_runtime.h +#includelinux/slab.h +#includelinux/videodev2.h +#includelinux/of.h +#includelinux/of_gpio.h +#includelinux/of_address.h +#includelinux/of_platform.h +#includelinux/of_irq.h +#includelinux/pinctrl/consumer.h nit: some entries are not in alphabetical order +#includemedia/v4l2-device.h +#includemedia/v4l2-ioctl.h +#includemedia/v4l2-mem2mem.h +#includemedia/v4l2-of.h +#includemedia/videobuf2-core.h +#includemedia/videobuf2-dma-contig.h + +#include fimc-is.h +#include fimc-is-i2c.h + +#define CLK_MCU_ISP_DIV0_FREQ (200 * 100) +#define CLK_MCU_ISP_DIV1_FREQ (100 * 100) +#define CLK_ISP_DIV0_FREQ (134 * 100) +#define CLK_ISP_DIV1_FREQ (68 * 100) +#define CLK_ISP_DIVMPWM_FREQ (34 * 100) + +static char *fimc_is_clock_name[] = { static const * char const fimc_is_clock_name[] ? + [IS_CLK_ISP]= isp, + [IS_CLK_MCU_ISP]= mcu_isp, + [IS_CLK_ISP_DIV0] = isp_div0, + [IS_CLK_ISP_DIV1] = isp_div1, + [IS_CLK_ISP_DIVMPWM]= isp_divmpwm, + [IS_CLK_MCU_ISP_DIV0] = mcu_isp_div0, + [IS_CLK_MCU_ISP_DIV1] = mcu_isp_div1, +}; + +static void fimc_is_put_clocks(struct fimc_is *is) +{ + int i; + + for (i = 0; i IS_CLK_MAX_NUM; i++) { + if (IS_ERR(is-clock[i])) + continue; + clk_unprepare(is-clock[i]); + clk_put(is-clock[i]); + is-clock[i] = NULL; is-clock[i] = ERR_PTR(-EINVAL); + } +} + +static int fimc_is_get_clocks(struct fimc_is *is) +{ + struct device *dev =is-pdev-dev; + int i, ret; + + for (i = 0; i IS_CLK_MAX_NUM; i++) { + is-clock[i] = clk_get(dev, fimc_is_clock_name[i]); + if (IS_ERR(is-clock[i])) + goto err; + ret = clk_prepare(is-clock[i]); + if (ret 0) { + clk_put(is-clock[i]); + is-clock[i] = ERR_PTR(-EINVAL); + goto err; + } + } + return 0; +err: + fimc_is_put_clocks(is); + pr_err(Failed to get clock: %s\n, fimc_is_clock_name[i]); dev_err(dev, ... + return -ENXIO; +} + +static int fimc_is_configure_clocks(struct fimc_is *is) +{ + int i, ret; + + for (i = 0; i IS_CLK_MAX_NUM; i++) + is-clock[i] = ERR_PTR(-EINVAL); + + ret = fimc_is_get_clocks(is); + if (ret) + return ret; + + /* Set rates */ + ret = clk_set_rate(is-clock[IS_CLK_MCU_ISP_DIV0], + CLK_MCU_ISP_DIV0_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_MCU_ISP_DIV1], + CLK_MCU_ISP_DIV1_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIV0], CLK_ISP_DIV0_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIV1], CLK_ISP_DIV1_FREQ); + if (ret) + return ret; + ret = clk_set_rate(is-clock[IS_CLK_ISP_DIVMPWM], + CLK_ISP_DIVMPWM_FREQ); + return ret; +} + +static void fimc_is_pipelines_destroy(struct fimc_is *is) +{ + int i; + + for (i = 0; i is-drvdata-num_instance; i++) + fimc_is_pipeline_destroy(is-pipeline[i]); +} + +static
Re: [PATCH v4 05/13] [media] exynos5-fimc-is: Add register definition and context header
On 08/07/2013 11:03 AM, Arun Kumar K wrote: This patch adds the register definition file for the fimc-is driver and also the header file containing the main context for the driver. Signed-off-by: Arun Kumar Karun...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-regs.h | 105 ++ drivers/media/platform/exynos5-is/fimc-is.h | 160 ++ 2 files changed, 265 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-regs.h create mode 100644 drivers/media/platform/exynos5-is/fimc-is.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-regs.h b/drivers/media/platform/exynos5-is/fimc-is-regs.h new file mode 100644 index 000..06aa466 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-regs.h @@ -0,0 +1,105 @@ +/* + * Samsung Exynos5 SoC series FIMC-IS driver + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd + * Arun Kumar Karun...@samsung.com + * Kil-yeon Limkilyeon...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#ifndef FIMC_IS_REGS_H +#define FIMC_IS_REGS_H + +/* WDT_ISP register */ +#define WDT0x0017 +/* MCUCTL register */ +#define MCUCTL 0x0018 +/* MCU Controller Register */ +#define MCUCTLR(MCUCTL+0x00) +#define MCUCTLR_AXI_ISPX_AWCACHE(x)((x) 16) +#define MCUCTLR_AXI_ISPX_ARCACHE(x)((x) 12) +#define MCUCTLR_MSWRST (1 0) +/* Boot Base OFfset Address Register */ +#define BBOAR (MCUCTL+0x04) +#define BBOAR_BBOA(x) ((x) 0) + +/* Interrupt Generation Register 0 from Host CPU to VIC */ +#define INTGR0 (MCUCTL+0x08) +#define INTGR0_INTGC(n)(1 ((n) + 16)) +#define INTGR0_INTGD(n)(1 (n)) + +/* Interrupt Clear Register 0 from Host CPU to VIC */ +#define INTCR0 (MCUCTL+0x0c) +#define INTCR0_INTCC(n)(1 ((n) + 16)) +#define INTCR0_INTCD(n)(1 (n)) + +/* Interrupt Mask Register 0 from Host CPU to VIC */ +#define INTMR0 (MCUCTL+0x10) +#define INTMR0_INTMC(n)(1 ((n) + 16)) +#define INTMR0_INTMD(n)(1 (n)) + +/* Interrupt Status Register 0 from Host CPU to VIC */ +#define INTSR0 (MCUCTL+0x14) +#define INTSR0_GET_INTSD(n, x) (((x) (n)) 0x1) +#define INTSR0_GET_INTSC(n, x) (((x) ((n) + 16)) 0x1) + +/* Interrupt Mask Status Register 0 from Host CPU to VIC */ +#define INTMSR0(MCUCTL+0x18) +#define INTMSR0_GET_INTMSD(n, x) (((x) (n)) 0x1) +#define INTMSR0_GET_INTMSC(n, x) (((x) ((n) + 16)) 0x1) + +/* Interrupt Generation Register 1 from ISP CPU to Host IC */ +#define INTGR1 (MCUCTL+0x1c) +#define INTGR1_INTGC(n)(1 (n)) + +/* Interrupt Clear Register 1 from ISP CPU to Host IC */ +#define INTCR1 (MCUCTL+0x20) +#define INTCR1_INTCC(n)(1 (n)) + +/* Interrupt Mask Register 1 from ISP CPU to Host IC */ +#define INTMR1 (MCUCTL+0x24) +#define INTMR1_INTMC(n)(1 (n)) + +/* Interrupt Status Register 1 from ISP CPU to Host IC */ +#define INTSR1 (MCUCTL+0x28) +/* Interrupt Mask Status Register 1 from ISP CPU to Host IC */ +#define INTMSR1(MCUCTL+0x2c) +/* Interrupt Clear Register 2 from ISP BLK's interrupts to Host IC */ +#define INTCR2 (MCUCTL+0x30) +#define INTCR2_INTCC(n)(1 (n)) + +/* Interrupt Mask Register 2 from ISP BLK's interrupts to Host IC */ +#define INTMR2 (MCUCTL+0x34) +#define INTMR2_INTMCIS(n) (1 (n)) + +/* Interrupt Status Register 2 from ISP BLK's interrupts to Host IC */ +#define INTSR2 (MCUCTL+0x38) +/* Interrupt Mask Status Register 2 from ISP BLK's interrupts to Host IC */ +#define INTMSR2(MCUCTL+0x3c) +/* General Purpose Output Control Register (0~17) */ +#define GPOCTLR(MCUCTL+0x40) +#define GPOCTLR_GPOG(n, x) ((x) (n)) + +/* General Purpose Pad Output Enable Register (0~17) */ +#define GPOENCTLR (MCUCTL+0x44) +#define GPOENCTLR_GPOEN0(n, x) ((x) (n)) + +/* General Purpose Input Control Register (0~17) */ +#define GPICTLR(MCUCTL+0x48) + +/* IS Shared Registers between ISP CPU and HOST CPU */ +#define ISSR(n)(MCUCTL + 0x80 + (n)) + +/* PMU for FIMC-IS*/ +#define
Re: [PATCH v4 07/13] [media] exynos5-fimc-is: Add scaler subdev
On 08/07/2013 11:03 AM, Arun Kumar K wrote: FIMC-IS has two hardware scalers named as scaler-codec and scaler-preview. This patch adds the common code handling the video nodes and subdevs of both the scalers. Signed-off-by: Arun Kumar Karun...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-scaler.c | 449 drivers/media/platform/exynos5-is/fimc-is-scaler.h | 106 + 2 files changed, 555 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-scaler.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-scaler.c b/drivers/media/platform/exynos5-is/fimc-is-scaler.c new file mode 100644 index 000..c9bd07b --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-scaler.c @@ -0,0 +1,449 @@ +/* + * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#includemedia/v4l2-ioctl.h +#includemedia/videobuf2-dma-contig.h + +#include fimc-is.h + +#define IS_SCALER_DRV_NAME fimc-is-scaler + +static const struct fimc_is_fmt formats[] = { + { + .name = YUV 4:2:0 3p MultiPlanar, + .fourcc = V4L2_PIX_FMT_YUV420M, + .depth = {8, 2, 2}, + .num_planes = 3, + }, + { + .name = YUV 4:2:0 2p MultiPlanar, + .fourcc = V4L2_PIX_FMT_NV12M, + .depth = {8, 4}, + .num_planes = 2, + }, + { + .name = YUV 4:2:2 1p MultiPlanar, + .fourcc = V4L2_PIX_FMT_NV16, + .depth = {16}, + .num_planes = 1, + }, +}; +#define NUM_FORMATS ARRAY_SIZE(formats) + +static const struct fimc_is_fmt *find_format(struct v4l2_format *f) +{ + unsigned int i; + + for (i = 0; i NUM_FORMATS; i++) { + if (formats[i].fourcc == f-fmt.pix_mp.pixelformat) + returnformats[i]; + } + return NULL; +} + +static int scaler_video_capture_start_streaming(struct vb2_queue *vq, + unsigned int count) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + int ret; + + ret = fimc_is_pipeline_scaler_start(ctx-pipeline, + ctx-scaler_id, + vq-num_buffers, + ctx-fmt-num_planes); + if (ret) { + v4l2_err(ctx-subdev, Scaler start failed.\n); + return -EINVAL; + } + + set_bit(STATE_RUNNING,ctx-capture_state); + return 0; +} + +static int scaler_video_capture_stop_streaming(struct vb2_queue *vq) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + struct fimc_is_buf *buf; + int ret; + + ret = fimc_is_pipeline_scaler_stop(ctx-pipeline, ctx-scaler_id); + if (ret) + v4l2_info(ctx-subdev, Scaler already stopped.\n); + + /* Release un-used buffers */ + while (!list_empty(ctx-wait_queue)) { + buf = fimc_is_scaler_wait_queue_get(ctx); + vb2_buffer_done(buf-vb, VB2_BUF_STATE_ERROR); + } + while (!list_empty(ctx-run_queue)) { + buf = fimc_is_scaler_run_queue_get(ctx); + vb2_buffer_done(buf-vb, VB2_BUF_STATE_ERROR); + } + + clear_bit(STATE_RUNNING,ctx-capture_state); + return 0; +} + +static int scaler_video_capture_queue_setup(struct vb2_queue *vq, + const struct v4l2_format *pfmt, + unsigned int *num_buffers, unsigned int *num_planes, + unsigned int sizes[], void *allocators[]) +{ + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + const struct fimc_is_fmt *fmt = ctx-fmt; + unsigned int wh; + int i; + + if (!fmt) + return -EINVAL; + + *num_planes = fmt-num_planes; + wh = ctx-width * ctx-height; + + for (i = 0; i *num_planes; i++) { + allocators[i] = ctx-alloc_ctx; + sizes[i] = (wh * fmt-depth[i]) / 8; + } + return 0; +} + +static int scaler_video_capture_buffer_init(struct vb2_buffer *vb) +{ + struct vb2_queue *vq = vb-vb2_queue; + struct fimc_is_scaler *ctx = vb2_get_drv_priv(vq); + struct fimc_is_buf *buf = container_of(vb, struct fimc_is_buf, vb); + const struct fimc_is_fmt *fmt; + int i; + + fmt = ctx-fmt; + for (i = 0; i fmt-num_planes; i++) + buf-paddr[i] = vb2_dma_contig_plane_dma_addr(vb, i); + + return 0; +} +
Re: [PATCH v4 08/13] [media] exynos5-fimc-is: Add sensor interface
On 08/07/2013 11:03 AM, Arun Kumar K wrote: Some sensors to be used with fimc-is are exclusively controlled by the fimc-is firmware. This minimal sensor driver provides the required info for the firmware to configure the sensors sitting on I2C bus. Signed-off-by: Arun Kumar Karun...@samsung.com --- drivers/media/platform/exynos5-is/fimc-is-sensor.c | 45 + drivers/media/platform/exynos5-is/fimc-is-sensor.h | 66 2 files changed, 111 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-sensor.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-sensor.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-sensor.c b/drivers/media/platform/exynos5-is/fimc-is-sensor.c new file mode 100644 index 000..7df2b11 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-sensor.c @@ -0,0 +1,45 @@ +/* + * Samsung EXYNOS5250 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include fimc-is-sensor.h + +static const struct sensor_drv_data s5k6a3_drvdata = { + .id = FIMC_IS_SENSOR_ID_S5K6A3, + .open_timeout = S5K6A3_OPEN_TIMEOUT, + .setfile_name = setfile_6a3.bin, +}; + +static const struct sensor_drv_data s5k4e5_drvdata = { + .id = FIMC_IS_SENSOR_ID_S5K4E5, + .open_timeout = S5K4E5_OPEN_TIMEOUT, + .setfile_name = setfile_4e5.bin, These file names should be prefixed with exynos5_, since they are FIMC-IS firmware specific, right ? Also I would spell out full sensor name, e.g. exynos5_s5k6a3_setfile.bin exynos5_s5k4e5_setfile.bin Similar patter is used in the exynos4-is driver. +}; + +static const struct of_device_id fimc_is_sensor_of_ids[] = { + { + .compatible = samsung,s5k6a3, + .data =s5k6a3_drvdata, + }, + { + .compatible = samsung,s5k4e5, + .data =s5k4e5_drvdata, + }, + { } +}; + +const struct sensor_drv_data *exynos5_is_sensor_get_drvdata( + struct device_node *node) +{ + const struct of_device_id *of_id; + + of_id = of_match_node(fimc_is_sensor_of_ids, node); + return of_id ? of_id-data : NULL; +} diff --git a/drivers/media/platform/exynos5-is/fimc-is-sensor.h b/drivers/media/platform/exynos5-is/fimc-is-sensor.h new file mode 100644 index 000..736ef16 --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-sensor.h @@ -0,0 +1,66 @@ +/* + * Samsung EXYNOS4x12 FIMC-IS (Imaging Subsystem) driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * nit: in the other places there is no such empty line + * Author: Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#ifndef FIMC_IS_SENSOR_H_ +#define FIMC_IS_SENSOR_H_ + +#includelinux/of.h +#includelinux/types.h + +#define S5K6A3_OPEN_TIMEOUT2000 /* ms */ +#define S5K6A3_SENSOR_WIDTH1392 +#define S5K6A3_SENSOR_HEIGHT 1392 + +#define S5K4E5_OPEN_TIMEOUT2000 /* ms */ +#define S5K4E5_SENSOR_WIDTH2560 +#define S5K4E5_SENSOR_HEIGHT 1920 + +#define SENSOR_WIDTH_PADDING 16 +#define SENSOR_HEIGHT_PADDING 10 + +enum fimc_is_sensor_id { + FIMC_IS_SENSOR_ID_S5K3H2 = 1, + FIMC_IS_SENSOR_ID_S5K6A3, + FIMC_IS_SENSOR_ID_S5K4E5, + FIMC_IS_SENSOR_ID_S5K3H7, + FIMC_IS_SENSOR_ID_CUSTOM, + FIMC_IS_SENSOR_ID_END +}; + +struct sensor_drv_data { + enum fimc_is_sensor_id id; + /* sensor open timeout in ms */ + unsigned short open_timeout; + char *setfile_name; +}; + +/** + * struct fimc_is_sensor - fimc-is sensor data structure + * @drvdata: a pointer to the sensor's parameters data structure + * @i2c_bus: ISP I2C bus index (0...1) + * @width: sensor active width + * @height: sensor active height + * @pixel_width: sensor effective pixel width (width + padding) + * @pixel_height: sensor effective pixel height (height + padding) + */ +struct fimc_is_sensor { + const struct sensor_drv_data *drvdata; + unsigned int i2c_bus; + unsigned int width; + unsigned int height; + unsigned int pixel_width; + unsigned int pixel_height; +}; + +const struct sensor_drv_data *exynos5_is_sensor_get_drvdata( + struct device_node *node); + +#endif /* FIMC_IS_SENSOR_H_ */ Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com -- Thanks, Sylwester -- To unsubscribe from this list: send the line unsubscribe
[PATCH/RFC v3 14/19] ARM: shmobile: r8a7790: Add DU clocks for DT
Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- arch/arm/mach-shmobile/clock-r8a7790.c | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c index d99b87b..7229f96 100644 --- a/arch/arm/mach-shmobile/clock-r8a7790.c +++ b/arch/arm/mach-shmobile/clock-r8a7790.c @@ -257,10 +257,15 @@ static struct clk_lookup lookups[] = { /* MSTP */ CLKDEV_ICK_ID(lvds.0, rcar-du-r8a7790, mstp_clks[MSTP726]), + CLKDEV_ICK_ID(lvds.0, feb0.display, mstp_clks[MSTP726]), CLKDEV_ICK_ID(lvds.1, rcar-du-r8a7790, mstp_clks[MSTP725]), + CLKDEV_ICK_ID(lvds.1, feb0.display, mstp_clks[MSTP725]), CLKDEV_ICK_ID(du.0, rcar-du-r8a7790, mstp_clks[MSTP724]), + CLKDEV_ICK_ID(du.0, feb0.display, mstp_clks[MSTP724]), CLKDEV_ICK_ID(du.1, rcar-du-r8a7790, mstp_clks[MSTP723]), + CLKDEV_ICK_ID(du.1, feb0.display, mstp_clks[MSTP723]), CLKDEV_ICK_ID(du.2, rcar-du-r8a7790, mstp_clks[MSTP722]), + CLKDEV_ICK_ID(du.2, feb0.display, mstp_clks[MSTP722]), CLKDEV_DEV_ID(sh-sci.0, mstp_clks[MSTP204]), CLKDEV_DEV_ID(sh-sci.1, mstp_clks[MSTP203]), CLKDEV_DEV_ID(sh-sci.2, mstp_clks[MSTP206]), -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC v3 11/19] video: panel: Add R61517 panel support
The R61517 is a MIPI DBI panel controller from Renesas. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/video/display/Kconfig| 10 + drivers/video/display/Makefile | 1 + drivers/video/display/panel-r61517.c | 460 +++ include/video/panel-r61517.h | 28 +++ 4 files changed, 499 insertions(+) create mode 100644 drivers/video/display/panel-r61517.c create mode 100644 include/video/panel-r61517.h diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig index 76729ef..9b44b5f 100644 --- a/drivers/video/display/Kconfig +++ b/drivers/video/display/Kconfig @@ -29,4 +29,14 @@ config DISPLAY_PANEL_R61505 If you are in doubt, say N. To compile this driver as a module, choose M here; the module will be called panel-r61505. +config DISPLAY_PANEL_R61517 + tristate Renesas R61517-based Display Panel + select DISPLAY_MIPI_DBI + ---help--- + Support panels based on the Renesas R61517 panel controller. + Those panels are controlled through a MIPI DBI interface. + + If you are in doubt, say N. To compile this driver as a module, choose + M here; the module will be called panel-r61517. + endif # DISPLAY_CORE diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile index db8a4c3..1cdc8d4 100644 --- a/drivers/video/display/Makefile +++ b/drivers/video/display/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DISPLAY_CORE) += display.o obj-$(CONFIG_DISPLAY_MIPI_DBI) += mipi-dbi-bus.o obj-$(CONFIG_DISPLAY_PANEL_DPI)+= panel-dpi.o obj-$(CONFIG_DISPLAY_PANEL_R61505) += panel-r61505.o +obj-$(CONFIG_DISPLAY_PANEL_R61517) += panel-r61517.o diff --git a/drivers/video/display/panel-r61517.c b/drivers/video/display/panel-r61517.c new file mode 100644 index 000..ccfec33 --- /dev/null +++ b/drivers/video/display/panel-r61517.c @@ -0,0 +1,460 @@ +/* + * Renesas R61517-based Display Panels + * + * Copyright (C) 2012 Renesas Solutions Corp. + * Based on KFR2R09 LCD panel support + * Copyright (C) 2009 Magnus Damm + * Register settings based on the out-of-tree t33fb.c driver + * Copyright (C) 2008 Lineo Solutions, Inc. + * + * Contacts: Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/delay.h +#include linux/err.h +#include linux/fb.h +#include linux/init.h +#include linux/kernel.h +#include linux/module.h +#include linux/gpio.h + +#include video/display.h +#include video/mipi-dbi-bus.h +#include video/mipi_display.h +#include video/panel-r61517.h +#include video/videomode.h + +struct r61517 { + struct display_entity entity; + struct mipi_dbi_device *dbi; + const struct panel_r61517_platform_data *pdata; +}; + +static inline struct r61517 *to_panel(struct display_entity *e) +{ + return container_of(e, struct r61517, entity); +} + +/* - + * Read, write and reset + */ + +static void r61517_write_command(struct r61517 *panel, u16 cmd) +{ + mipi_dbi_write_command(panel-dbi, cmd); +} + +static void r61517_write_data(struct r61517 *panel, u8 data) +{ + mipi_dbi_write_data(panel-dbi, data, 1); +} + +static int r61517_read_data(struct r61517 *panel) +{ + u8 data; + int ret; + + ret = mipi_dbi_read_data(panel-dbi, data, 1); + if (ret 0) + return ret; + + return data; +} + +static void r61517_write(struct r61517 *panel, u8 reg, const u8 *data, +size_t len) +{ + mipi_dbi_write_command(panel-dbi, reg); + mipi_dbi_write_data(panel-dbi, data, len); +} + +static void r61517_write8(struct r61517 *panel, u8 reg, u8 data) +{ + r61517_write(panel, reg, data, 1); +} + +static void r61517_write16(struct r61517 *panel, u8 reg, u16 data) +{ + u8 buffer[2] = { (data 8) 0xff, (data 0) 0xff }; + + r61517_write(panel, reg, buffer, 2); +} + +static void r61517_write32(struct r61517 *panel, u8 reg, u32 data) +{ + u8 buffer[4] = { (data 24) 0xff, (data 16) 0xff, +(data 8) 0xff, (data 0) 0xff }; + + r61517_write(panel, reg, buffer, 4); +} + +#define r61517_write_array(p, c, a) \ + r61517_write((p), (c), (a), ARRAY_SIZE(a)) + +static void r61517_reset(struct r61517 *panel) +{ + gpio_set_value(panel-pdata-protect, 0); /* PROTECT/ - L */ + gpio_set_value(panel-pdata-reset, 0); /* LCD_RST/ - L */ + gpio_set_value(panel-pdata-protect, 1); /* PROTECT/ - H */ + usleep_range(1100, 1200); + gpio_set_value(panel-pdata-reset, 1); /* LCD_RST/ - H */ +
[PATCH/RFC v3 02/19] video: Add Common Display Framework core
The Common Display Framework (CDF) splits display devices in entities that interact through an abstract API. Each entity is managed by its own driver independently of the other entities, with the framework orchestrating interactions. This commit introduces the CDF core with entity (un)registration and core control operations support. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/video/Kconfig| 1 + drivers/video/Makefile | 1 + drivers/video/display/Kconfig| 4 + drivers/video/display/Makefile | 2 + drivers/video/display/display-core.c | 236 +++ include/video/display.h | 94 ++ 6 files changed, 338 insertions(+) create mode 100644 drivers/video/display/Kconfig create mode 100644 drivers/video/display/Makefile create mode 100644 drivers/video/display/display-core.c create mode 100644 include/video/display.h diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4cf1e1d..c9ca1d5 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -2477,6 +2477,7 @@ source drivers/video/omap2/Kconfig source drivers/video/exynos/Kconfig source drivers/video/mmp/Kconfig source drivers/video/backlight/Kconfig +source drivers/video/display/Kconfig if VT source drivers/video/console/Kconfig diff --git a/drivers/video/Makefile b/drivers/video/Makefile index e8bae8d..d7fd4a2 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -15,6 +15,7 @@ fb-objs := $(fb-y) obj-$(CONFIG_VT) += console/ obj-$(CONFIG_LOGO) += logo/ obj-y+= backlight/ +obj-y+= display/ obj-$(CONFIG_EXYNOS_VIDEO) += exynos/ diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig new file mode 100644 index 000..1d533e7 --- /dev/null +++ b/drivers/video/display/Kconfig @@ -0,0 +1,4 @@ +menuconfig DISPLAY_CORE + tristate Display Core + ---help--- + Support common display framework for graphics devices. diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile new file mode 100644 index 000..3054adc --- /dev/null +++ b/drivers/video/display/Makefile @@ -0,0 +1,2 @@ +display-y := display-core.o +obj-$(CONFIG_DISPLAY_CORE) += display.o diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c new file mode 100644 index 000..82fc58b --- /dev/null +++ b/drivers/video/display/display-core.c @@ -0,0 +1,236 @@ +/* + * Display Core + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * Contacts: Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/export.h +#include linux/kernel.h +#include linux/module.h +#include linux/slab.h + +#include media/media-device.h + +#include video/display.h +#include video/videomode.h + +/* - + * Control operations + */ + +/** + * display_entity_get_modes - Get video modes supported by the display entity + * @entity: The display entity + * @port: The display entity port + * @modes: Pointer to an array of modes + * + * Fill the modes argument with a pointer to an array of video modes. The array + * is owned by the display entity. + * + * Return the number of supported modes on success (including 0 if no mode is + * supported) or a negative error code otherwise. + */ +int display_entity_get_modes(struct display_entity *entity, unsigned int port, +const struct videomode **modes) +{ + if (port = entity-entity.num_pads) + return -EINVAL; + + if (!entity-ops-ctrl || !entity-ops-ctrl-get_modes) + return 0; + + return entity-ops-ctrl-get_modes(entity, port, modes); +} +EXPORT_SYMBOL_GPL(display_entity_get_modes); + +/** + * display_entity_get_size - Get display entity physical size + * @entity: The display entity + * @width: Physical width in millimeters + * @height: Physical height in millimeters + * + * When applicable, for instance for display panels, retrieve the display + * physical size in millimeters. + * + * Return 0 on success or a negative error code otherwise. + */ +int display_entity_get_size(struct display_entity *entity, + unsigned int *width, unsigned int *height) +{ + if (!entity-ops-ctrl || !entity-ops-ctrl-get_size) + return -EOPNOTSUPP; + + return entity-ops-ctrl-get_size(entity, width, height); +} +EXPORT_SYMBOL_GPL(display_entity_get_size); + +/** + * display_entity_get_params - Get display entity interface parameters + * @entity: The display
[PATCH/RFC v3 17/19] ARM: shmobile: lager: Port DU platform data to CDF
Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- arch/arm/mach-shmobile/board-lager.c | 76 +--- 1 file changed, 53 insertions(+), 23 deletions(-) diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c index 75a01bc..d61b892 100644 --- a/arch/arm/mach-shmobile/board-lager.c +++ b/arch/arm/mach-shmobile/board-lager.c @@ -33,6 +33,8 @@ #include linux/regulator/fixed.h #include linux/regulator/machine.h #include linux/sh_eth.h +#include video/panel-dpi.h +#include video/videomode.h #include mach/common.h #include mach/irqs.h #include mach/r8a7790.h @@ -40,35 +42,56 @@ #include asm/mach/arch.h /* DU */ -static struct rcar_du_encoder_data lager_du_encoders[] = { +static const struct videomode lager_panel_mode = { + .pixelclock = 6500, + .hactive = 1024, + .hfront_porch = 24, + .hback_porch = 160, + .hsync_len = 136, + .vactive = 768, + .vfront_porch = 3, + .vback_porch = 29, + .vsync_len = 6, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW, +}; + +static const struct panel_dpi_platform_data lager_panel_data = { + .width = 210, + .height = 158, + .mode = lager_panel_mode, +}; + +static const struct display_entity_graph_data lager_du_entities[] = { { - .type = RCAR_DU_ENCODER_VGA, - .output = RCAR_DU_OUTPUT_DPAD0, + .name = adv7123, + .sources = (const struct display_entity_source_data[]) { + { + .name = rcar-du, + .port = 0, + }, + }, }, { - .type = RCAR_DU_ENCODER_NONE, - .output = RCAR_DU_OUTPUT_LVDS1, - .connector.lvds.panel = { - .width_mm = 210, - .height_mm = 158, - .mode = { - .clock = 65000, - .hdisplay = 1024, - .hsync_start = 1048, - .hsync_end = 1184, - .htotal = 1344, - .vdisplay = 768, - .vsync_start = 771, - .vsync_end = 777, - .vtotal = 806, - .flags = 0, + .name = con-vga, + .sources = (const struct display_entity_source_data[]) { + { + .name = adv7123, + .port = 1, }, }, + }, { + .name = panel-dpi, + .sources = (const struct display_entity_source_data[]) { + { + .name = rcar-du, + .port = 2, + }, + }, + }, { }, }; static const struct rcar_du_platform_data lager_du_pdata __initconst = { - .encoders = lager_du_encoders, - .num_encoders = ARRAY_SIZE(lager_du_encoders), + .graph = lager_du_entities, }; static const struct resource du_resources[] __initconst = { @@ -87,8 +110,8 @@ static void __init lager_add_du_device(void) .id = -1, .res = du_resources, .num_res = ARRAY_SIZE(du_resources), - .data = du_resources, - .size_data = sizeof(du_resources), + .data = lager_du_pdata, + .size_data = sizeof(lager_du_pdata), .dma_mask = DMA_BIT_MASK(32), }; @@ -202,6 +225,7 @@ static void __init lager_add_standard_devices(void) r8a7790_pinmux_init(); r8a7790_add_standard_devices(); + platform_device_register_data(platform_bus, leds-gpio, -1, lager_leds_pdata, sizeof(lager_leds_pdata)); @@ -220,6 +244,12 @@ static void __init lager_add_standard_devices(void) ether_pdata, sizeof(ether_pdata)); lager_add_du_device(); + + platform_device_register_simple(adv7123, -1, NULL, 0); + platform_device_register_simple(con-vga, -1, NULL, 0); + platform_device_register_data(platform_bus, panel-dpi, -1, + lager_panel_data, + sizeof(lager_panel_data)); } static const char * const lager_boards_compat_dt[] __initconst = { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC v3 01/19] OMAPDSS: panels: Rename Kconfig options to OMAP2_DISPLAY_*
The DISPLAY_ prefix will clash with the Common Display Framework, rename it. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/omap2/displays-new/Kconfig | 24 drivers/video/omap2/displays-new/Makefile | 24 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/omap2/displays-new/Kconfig index 6c90885..2a44b41 100644 --- a/drivers/video/omap2/displays-new/Kconfig +++ b/drivers/video/omap2/displays-new/Kconfig @@ -1,68 +1,68 @@ menu OMAP Display Device Drivers (new device model) depends on OMAP2_DSS -config DISPLAY_ENCODER_TFP410 +config OMAP2_DISPLAY_ENCODER_TFP410 tristate TFP410 DPI to DVI Encoder help Driver for TFP410 DPI to DVI encoder. -config DISPLAY_ENCODER_TPD12S015 +config OMAP2_DISPLAY_ENCODER_TPD12S015 tristate TPD12S015 HDMI ESD protection and level shifter help Driver for TPD12S015, which offers HDMI ESD protection and level shifting. -config DISPLAY_CONNECTOR_DVI +config OMAP2_DISPLAY_CONNECTOR_DVI tristate DVI Connector depends on I2C help Driver for a generic DVI connector. -config DISPLAY_CONNECTOR_HDMI +config OMAP2_DISPLAY_CONNECTOR_HDMI tristate HDMI Connector help Driver for a generic HDMI connector. -config DISPLAY_CONNECTOR_ANALOG_TV +config OMAP2_DISPLAY_CONNECTOR_ANALOG_TV tristate Analog TV Connector help Driver for a generic analog TV connector. -config DISPLAY_PANEL_DPI +config OMAP2_DISPLAY_PANEL_DPI tristate Generic DPI panel help Driver for generic DPI panels. -config DISPLAY_PANEL_DSI_CM +config OMAP2_DISPLAY_PANEL_DSI_CM tristate Generic DSI Command Mode Panel help Driver for generic DSI command mode panels. -config DISPLAY_PANEL_SONY_ACX565AKM +config OMAP2_DISPLAY_PANEL_SONY_ACX565AKM tristate ACX565AKM Panel depends on SPI BACKLIGHT_CLASS_DEVICE help This is the LCD panel used on Nokia N900 -config DISPLAY_PANEL_LGPHILIPS_LB035Q02 +config OMAP2_DISPLAY_PANEL_LGPHILIPS_LB035Q02 tristate LG.Philips LB035Q02 LCD Panel depends on SPI help LCD Panel used on the Gumstix Overo Palo35 -config DISPLAY_PANEL_SHARP_LS037V7DW01 +config OMAP2_DISPLAY_PANEL_SHARP_LS037V7DW01 tristate Sharp LS037V7DW01 LCD Panel depends on BACKLIGHT_CLASS_DEVICE help LCD Panel used in TI's SDP3430 and EVM boards -config DISPLAY_PANEL_TPO_TD043MTEA1 +config OMAP2_DISPLAY_PANEL_TPO_TD043MTEA1 tristate TPO TD043MTEA1 LCD Panel depends on SPI help LCD Panel used in OMAP3 Pandora -config DISPLAY_PANEL_NEC_NL8048HL11 +config OMAP2_DISPLAY_PANEL_NEC_NL8048HL11 tristate NEC NL8048HL11 Panel depends on SPI depends on BACKLIGHT_CLASS_DEVICE diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/omap2/displays-new/Makefile index 5aeb11b..768ad94 100644 --- a/drivers/video/omap2/displays-new/Makefile +++ b/drivers/video/omap2/displays-new/Makefile @@ -1,12 +1,12 @@ -obj-$(CONFIG_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o -obj-$(CONFIG_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o -obj-$(CONFIG_DISPLAY_CONNECTOR_DVI) += connector-dvi.o -obj-$(CONFIG_DISPLAY_CONNECTOR_HDMI) += connector-hdmi.o -obj-$(CONFIG_DISPLAY_CONNECTOR_ANALOG_TV) += connector-analog-tv.o -obj-$(CONFIG_DISPLAY_PANEL_DPI) += panel-dpi.o -obj-$(CONFIG_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o -obj-$(CONFIG_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o -obj-$(CONFIG_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o -obj-$(CONFIG_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o -obj-$(CONFIG_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o -obj-$(CONFIG_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o +obj-$(CONFIG_OMAP2_DISPLAY_ENCODER_TFP410) += encoder-tfp410.o +obj-$(CONFIG_OMAP2_DISPLAY_ENCODER_TPD12S015) += encoder-tpd12s015.o +obj-$(CONFIG_OMAP2_DISPLAY_CONNECTOR_DVI) += connector-dvi.o +obj-$(CONFIG_OMAP2_DISPLAY_CONNECTOR_HDMI) += connector-hdmi.o +obj-$(CONFIG_OMAP2_DISPLAY_CONNECTOR_ANALOG_TV) += connector-analog-tv.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_DPI) += panel-dpi.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_DSI_CM) += panel-dsi-cm.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_SONY_ACX565AKM) += panel-sony-acx565akm.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_LGPHILIPS_LB035Q02) += panel-lgphilips-lb035q02.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_TPO_TD043MTEA1) += panel-tpo-td043mtea1.o +obj-$(CONFIG_OMAP2_DISPLAY_PANEL_NEC_NL8048HL11) += panel-nec-nl8048hl11.o -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in
[PATCH/RFC v3 18/19] ARM: shmobile: lager-reference: Add display device nodes to device tree
Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- arch/arm/boot/dts/r8a7790-lager-reference.dts | 92 +++ 1 file changed, 92 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790-lager-reference.dts b/arch/arm/boot/dts/r8a7790-lager-reference.dts index d9a25d5..ba2469b 100644 --- a/arch/arm/boot/dts/r8a7790-lager-reference.dts +++ b/arch/arm/boot/dts/r8a7790-lager-reference.dts @@ -42,6 +42,98 @@ gpios = gpio5 17 GPIO_ACTIVE_HIGH; }; }; + + adv7123 { + compatible = adi,adv7123; + + ports { + #address-cells = 1; + #size-cells = 0; + + port@0 { + reg = 0; + adv7123_in: endpoint { + remote-endpoint = du_out_rgb; + }; + }; + port@1 { + reg = 1; + adv7123_out: endpoint { + remote-endpoint = con_vga_in; + }; + }; + }; + }; + + con-vga { + compatible = con-vga; + + ports { + #address-cells = 1; + #size-cells = 0; + + port@0 { + reg = 0; + con_vga_in: endpoint { + remote-endpoint = adv7123_out; + }; + }; + }; + }; + + panel-dpi { + compatible = panel-dpi; + + width-mm = 210; + height-mm = 158; + + display-timings { + timing { + /* 1024x768 @65Hz */ + clock-frequency = 6500; + hactive = 1024; + vactive = 768; + hsync-len = 136; + hfront-porch = 20; + hback-porch = 160; + vfront-porch = 3; + vback-porch = 29; + vsync-len = 6; + }; + }; + + ports { + #address-cells = 1; + #size-cells = 0; + + port@0 { + reg = 0; + panel_in: endpoint { + remote-endpoint = du_out_lvds1; + }; + }; + }; + }; +}; + +du { + pinctrl-0 = du_pins; + pinctrl-names = default; +}; + +du_out_rgb { + remote-endpoint = adv7123_in; +}; + +du_out_lvds1 { + remote-endpoint = panel_in; +}; + +pfc { + du_pins: du { + renesas,groups = du_rgb666, du_sync_1, du_clk_out_0; + renesas,function = du; + }; }; pfc { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC v3 16/19] ARM: shmobile: marzen: Port DU platform data to CDF
Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- arch/arm/mach-shmobile/board-marzen.c | 77 --- 1 file changed, 53 insertions(+), 24 deletions(-) diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c index 6499f1a..be1b7cb 100644 --- a/arch/arm/mach-shmobile/board-marzen.c +++ b/arch/arm/mach-shmobile/board-marzen.c @@ -39,6 +39,8 @@ #include linux/mmc/host.h #include linux/mmc/sh_mobile_sdhi.h #include linux/mfd/tmio.h +#include video/panel-dpi.h +#include video/videomode.h #include mach/r8a7779.h #include mach/common.h #include mach/irqs.h @@ -174,35 +176,56 @@ static struct platform_device hspi_device = { * The panel only specifies the [hv]display and [hv]total values. The position * and width of the sync pulses don't matter, they're copied from VESA timings. */ -static struct rcar_du_encoder_data du_encoders[] = { +static const struct videomode marzen_panel_mode = { + .pixelclock = 6500, + .hactive = 1024, + .hfront_porch = 24, + .hback_porch = 160, + .hsync_len = 136, + .vactive = 768, + .vfront_porch = 3, + .vback_porch = 29, + .vsync_len = 6, + .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW, +}; + +static const struct panel_dpi_platform_data marzen_panel_data = { + .width = 210, + .height = 158, + .mode = marzen_panel_mode, +}; + +static const struct display_entity_graph_data marzen_du_entities[] = { { - .type = RCAR_DU_ENCODER_VGA, - .output = RCAR_DU_OUTPUT_DPAD0, + .name = adv7123, + .sources = (const struct display_entity_source_data[]) { + { + .name = rcar-du, + .port = 0, + }, + }, }, { - .type = RCAR_DU_ENCODER_LVDS, - .output = RCAR_DU_OUTPUT_DPAD1, - .connector.lvds.panel = { - .width_mm = 210, - .height_mm = 158, - .mode = { - .clock = 65000, - .hdisplay = 1024, - .hsync_start = 1048, - .hsync_end = 1184, - .htotal = 1344, - .vdisplay = 768, - .vsync_start = 771, - .vsync_end = 777, - .vtotal = 806, - .flags = 0, + .name = con-vga, + .sources = (const struct display_entity_source_data[]) { + { + .name = adv7123, + .port = 1, }, }, + }, { + .name = panel-dpi, + .sources = (const struct display_entity_source_data[]) { + { + .name = rcar-du, + .port = 1, + }, + }, + }, { }, }; -static const struct rcar_du_platform_data du_pdata __initconst = { - .encoders = du_encoders, - .num_encoders = ARRAY_SIZE(du_encoders), +static const struct rcar_du_platform_data marzen_du_pdata __initconst = { + .graph = marzen_du_entities, }; static const struct resource du_resources[] __initconst = { @@ -217,8 +240,8 @@ static void __init marzen_add_du_device(void) .id = -1, .res = du_resources, .num_res = ARRAY_SIZE(du_resources), - .data = du_pdata, - .size_data = sizeof(du_pdata), + .data = marzen_du_pdata, + .size_data = sizeof(marzen_du_pdata), .dma_mask = DMA_BIT_MASK(32), }; @@ -327,6 +350,12 @@ static void __init marzen_init(void) r8a7779_add_standard_devices(); platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices)); marzen_add_du_device(); + + platform_device_register_simple(adv7123, -1, NULL, 0); + platform_device_register_simple(con-vga, -1, NULL, 0); + platform_device_register_data(platform_bus, panel-dpi, -1, + marzen_panel_data, + sizeof(marzen_panel_data)); } static const char *marzen_boards_compat_dt[] __initdata = { -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC v3 12/19] video: display: Add VGA Digital to Analog Converter support
This driver implements support for VGA Digital to Analog Converters (DACs) that receive pixel data through a DPI interface and have no control interface (GPIOs- and/or regulators-based control can be implemented later when needed). It exposes the devices a display entities. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/display/Kconfig | 9 +++ drivers/video/display/Makefile | 1 + drivers/video/display/vga-dac.c | 152 3 files changed, 162 insertions(+) create mode 100644 drivers/video/display/vga-dac.c diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig index 9b44b5f..32ce08d 100644 --- a/drivers/video/display/Kconfig +++ b/drivers/video/display/Kconfig @@ -39,4 +39,13 @@ config DISPLAY_PANEL_R61517 If you are in doubt, say N. To compile this driver as a module, choose M here; the module will be called panel-r61517. +config DISPLAY_VGA_DAC + tristate VGA Digital to Analog Converters + ---help--- + Support for simple VGA digital to analog converters. Those converters + receive pixel data through a parallel bus and have no control bus. + + If you are in doubt, say N. To compile this driver as a module, choose + M here: the module will be called vga-dac. + endif # DISPLAY_CORE diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile index 1cdc8d4..43cd78d 100644 --- a/drivers/video/display/Makefile +++ b/drivers/video/display/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_DISPLAY_MIPI_DBI) += mipi-dbi-bus.o obj-$(CONFIG_DISPLAY_PANEL_DPI)+= panel-dpi.o obj-$(CONFIG_DISPLAY_PANEL_R61505) += panel-r61505.o obj-$(CONFIG_DISPLAY_PANEL_R61517) += panel-r61517.o +obj-$(CONFIG_DISPLAY_VGA_DAC) += vga-dac.o diff --git a/drivers/video/display/vga-dac.c b/drivers/video/display/vga-dac.c new file mode 100644 index 000..d0256e6 --- /dev/null +++ b/drivers/video/display/vga-dac.c @@ -0,0 +1,152 @@ +/* + * VGA Digital to Analog Converter + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * Contacts: Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/of.h +#include linux/platform_device.h +#include linux/slab.h + +#include video/display.h + +#define VGA_DAC_PORT_SINK 0 +#define VGA_DAC_PORT_SOURCE1 + +struct vga_dac { + struct display_entity entity; +}; + +static inline struct vga_dac *to_vga_dac(struct display_entity *e) +{ + return container_of(e, struct vga_dac, entity); +} + +static int vga_dac_set_state(struct display_entity *entity, +enum display_entity_state state) +{ + struct media_pad *source; + + source = media_entity_remote_pad(entity-entity.pads[0]); + if (source == NULL) + return -EPIPE; + + switch (state) { + case DISPLAY_ENTITY_STATE_OFF: + case DISPLAY_ENTITY_STATE_STANDBY: + display_entity_set_stream(to_display_entity(source-entity), + source-index, + DISPLAY_ENTITY_STREAM_STOPPED); + break; + + case DISPLAY_ENTITY_STATE_ON: + display_entity_set_stream(to_display_entity(source-entity), + source-index, + DISPLAY_ENTITY_STREAM_CONTINUOUS); + break; + } + + return 0; +} + +static int vga_dac_get_params(struct display_entity *entity, unsigned int port, + struct display_entity_interface_params *params) +{ + memset(params, 0, sizeof(*params)); + + if (port == VGA_DAC_PORT_SINK) + params-type = DISPLAY_ENTITY_INTERFACE_DPI; + else + params-type = DISPLAY_ENTITY_INTERFACE_VGA; + + return 0; +} + +static const struct display_entity_control_ops vga_dac_control_ops = { + .set_state = vga_dac_set_state, + .get_params = vga_dac_get_params, +}; + +static const struct display_entity_ops vga_dac_ops = { + .ctrl = vga_dac_control_ops, +}; + +static int vga_dac_remove(struct platform_device *pdev) +{ + struct vga_dac *dac = platform_get_drvdata(pdev); + + display_entity_remove(dac-entity); + display_entity_cleanup(dac-entity); + + return 0; +} + +static int vga_dac_probe(struct platform_device *pdev) +{ + struct vga_dac *dac; + int ret; + + dac = devm_kzalloc(pdev-dev, sizeof(*dac), GFP_KERNEL); + if (dac == NULL) + return -ENOMEM; + + dac-entity.dev = pdev-dev; +
[PATCH/RFC v3 06/19] video: display: OF support
Extend the notifier with DT node matching support, and add helper functions to build the notifier and link entities based on a graph representation in DT. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/display/display-core.c | 334 +++ drivers/video/display/display-notifier.c | 187 + include/video/display.h | 45 + 3 files changed, 566 insertions(+) diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c index c3b47d3..328ead7 100644 --- a/drivers/video/display/display-core.c +++ b/drivers/video/display/display-core.c @@ -14,6 +14,7 @@ #include linux/export.h #include linux/kernel.h #include linux/module.h +#include linux/of.h #include linux/slab.h #include media/media-device.h @@ -315,6 +316,184 @@ void display_entity_unregister(struct display_entity *entity) EXPORT_SYMBOL_GPL(display_entity_unregister); /* - + * OF Helpers + */ + +#ifdef CONFIG_OF + +/** + * display_of_get_next_endpoint() - get next endpoint node + * @parent: pointer to the parent device node + * @prev: previous endpoint node, or NULL to get first + * + * Return: An 'endpoint' node pointer with refcount incremented. Refcount + * of the passed @prev node is not decremented, the caller have to use + * of_node_put() on it when done. + */ +struct device_node * +display_of_get_next_endpoint(const struct device_node *parent, +struct device_node *prev) +{ + struct device_node *endpoint; + struct device_node *port = NULL; + + if (!parent) + return NULL; + + if (!prev) { + struct device_node *node; + /* +* It's the first call, we have to find a port subnode +* within this node or within an optional 'ports' node. +*/ + node = of_get_child_by_name(parent, ports); + if (node) + parent = node; + + port = of_get_child_by_name(parent, port); + + if (port) { + /* Found a port, get an endpoint. */ + endpoint = of_get_next_child(port, NULL); + of_node_put(port); + } else { + endpoint = NULL; + } + + if (!endpoint) + pr_err(%s(): no endpoint nodes specified for %s\n, + __func__, parent-full_name); + of_node_put(node); + } else { + port = of_get_parent(prev); + if (!port) + /* Hm, has someone given us the root node ?... */ + return NULL; + + /* Avoid dropping prev node refcount to 0. */ + of_node_get(prev); + endpoint = of_get_next_child(port, prev); + if (endpoint) { + of_node_put(port); + return endpoint; + } + + /* No more endpoints under this port, try the next one. */ + do { + port = of_get_next_child(parent, port); + if (!port) + return NULL; + } while (of_node_cmp(port-name, port)); + + /* Pick up the first endpoint in this port. */ + endpoint = of_get_next_child(port, NULL); + of_node_put(port); + } + + return endpoint; +} + +/** + * display_of_get_remote_port_parent() - get remote port's parent node + * @node: pointer to a local endpoint device_node + * + * Return: Remote device node associated with remote endpoint node linked + *to @node. Use of_node_put() on it when done. + */ +struct device_node * +display_of_get_remote_port_parent(const struct device_node *node) +{ + struct device_node *np; + unsigned int depth; + + /* Get remote endpoint node. */ + np = of_parse_phandle(node, remote-endpoint, 0); + + /* Walk 3 levels up only if there is 'ports' node. */ + for (depth = 3; depth np; depth--) { + np = of_get_next_parent(np); + if (depth == 2 of_node_cmp(np-name, ports)) + break; + } + return np; +} + +/** + * struct display_of_link - a link between two endpoints + * @local_node: pointer to device_node of this endpoint + * @local_port: identifier of the port this endpoint belongs to + * @remote_node: pointer to device_node of the remote endpoint + * @remote_port: identifier of the port the remote endpoint belongs to + */ +struct display_of_link { + struct device_node *local_node; + unsigned int local_port; + struct device_node *remote_node; + unsigned int remote_port; +}; + +/** + * display_of_parse_link() - parse a
[PATCH/RFC v3 15/19] ARM: shmobile: r8a7790: Add DU device node to device tree
Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- arch/arm/boot/dts/r8a7790.dtsi | 33 + 1 file changed, 33 insertions(+) diff --git a/arch/arm/boot/dts/r8a7790.dtsi b/arch/arm/boot/dts/r8a7790.dtsi index ab0582c..b63f1a6 100644 --- a/arch/arm/boot/dts/r8a7790.dtsi +++ b/arch/arm/boot/dts/r8a7790.dtsi @@ -186,4 +186,37 @@ reg = 0 0xe606 0 0x250; #gpio-range-cells = 3; }; + + du: display@feb0 { + compatible = renesas,du-r8a7790; + reg = 0 0xfeb0 0 0x7, + 0 0xfeb9 0 0x1c, + 0 0xfeb94000 0 0x1c; + reg-names = core, lvds.0, lvds.1; + interrupt-parent = gic; + interrupts = 0 256 4 + 0 268 4 + 0 269 4; + + ports { + #address-cells = 1; + #size-cells = 0; + + port@0 { + reg = 0; + du_out_rgb: endpoint { + }; + }; + port@1 { + reg = 1; + du_out_lvds0: endpoint { + }; + }; + port@2 { + reg = 2; + du_out_lvds1: endpoint { + }; + }; + }; + }; }; -- 1.8.1.5 -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH/RFC v3 19/19] drm/rcar-du: Port to the Common Display Framework
Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/gpu/drm/rcar-du/Kconfig | 3 +- drivers/gpu/drm/rcar-du/Makefile| 7 +- drivers/gpu/drm/rcar-du/rcar_du_connector.c | 164 drivers/gpu/drm/rcar-du/rcar_du_connector.h | 36 drivers/gpu/drm/rcar-du/rcar_du_crtc.h | 2 +- drivers/gpu/drm/rcar-du/rcar_du_drv.c | 279 drivers/gpu/drm/rcar-du/rcar_du_drv.h | 28 ++- drivers/gpu/drm/rcar-du/rcar_du_encoder.c | 87 - drivers/gpu/drm/rcar-du/rcar_du_encoder.h | 22 +-- drivers/gpu/drm/rcar-du/rcar_du_kms.c | 116 ++-- drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c | 131 - drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h | 25 --- drivers/gpu/drm/rcar-du/rcar_du_vgacon.c| 96 -- drivers/gpu/drm/rcar-du/rcar_du_vgacon.h| 23 --- include/linux/platform_data/rcar-du.h | 55 +- 15 files changed, 611 insertions(+), 463 deletions(-) create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_connector.c create mode 100644 drivers/gpu/drm/rcar-du/rcar_du_connector.h delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vgacon.c delete mode 100644 drivers/gpu/drm/rcar-du/rcar_du_vgacon.h diff --git a/drivers/gpu/drm/rcar-du/Kconfig b/drivers/gpu/drm/rcar-du/Kconfig index c590cd9..a54eeba 100644 --- a/drivers/gpu/drm/rcar-du/Kconfig +++ b/drivers/gpu/drm/rcar-du/Kconfig @@ -1,9 +1,10 @@ config DRM_RCAR_DU tristate DRM Support for R-Car Display Unit - depends on DRM ARM + depends on DRM ARM OF select DRM_KMS_HELPER select DRM_KMS_CMA_HELPER select DRM_GEM_CMA_HELPER + select VIDEOMODE_HELPERS help Choose this option if you have an R-Car chipset. If M is selected the module will be called rcar-du-drm. diff --git a/drivers/gpu/drm/rcar-du/Makefile b/drivers/gpu/drm/rcar-du/Makefile index 12b8d44..3ac8566 100644 --- a/drivers/gpu/drm/rcar-du/Makefile +++ b/drivers/gpu/drm/rcar-du/Makefile @@ -1,11 +1,10 @@ -rcar-du-drm-y := rcar_du_crtc.o \ +rcar-du-drm-y := rcar_du_connector.o \ +rcar_du_crtc.o \ rcar_du_drv.o \ rcar_du_encoder.o \ rcar_du_group.o \ rcar_du_kms.o \ -rcar_du_lvdscon.o \ -rcar_du_plane.o \ -rcar_du_vgacon.o +rcar_du_plane.o rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS)+= rcar_du_lvdsenc.o diff --git a/drivers/gpu/drm/rcar-du/rcar_du_connector.c b/drivers/gpu/drm/rcar-du/rcar_du_connector.c new file mode 100644 index 000..a09aada --- /dev/null +++ b/drivers/gpu/drm/rcar-du/rcar_du_connector.c @@ -0,0 +1,164 @@ +/* + * rcar_du_connector.c -- R-Car Display Unit Connector + * + * Copyright (C) 2013 Renesas Corporation + * + * Contact: Laurent Pinchart (laurent.pinch...@ideasonboard.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include linux/export.h +#include video/videomode.h + +#include drm/drmP.h +#include drm/drm_crtc.h +#include drm/drm_crtc_helper.h + +#include rcar_du_drv.h +#include rcar_du_connector.h +#include rcar_du_encoder.h +#include rcar_du_kms.h + +static int rcar_du_connector_get_modes(struct drm_connector *connector) +{ + struct rcar_du_connector *rcon = to_rcar_connector(connector); + struct display_entity *entity = to_display_entity(rcon-pad-entity); + const struct videomode *modes; + int ret; + int i; + + ret = display_entity_get_modes(entity, rcon-pad-index, modes); + if (ret = 0) + return drm_add_modes_noedid(connector, 1280, 768); + + for (i = 0; i ret; ++i) { + struct drm_display_mode *mode; + + mode = drm_mode_create(connector-dev); + if (mode == NULL) + break; + + mode-type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; + drm_display_mode_from_videomode(modes[i], mode); + drm_mode_probed_add(connector, mode); + } + + return i; +} + +static int rcar_du_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + return MODE_OK; +} + +static struct drm_encoder * +rcar_du_connector_best_encoder(struct drm_connector *connector) +{ + struct rcar_du_connector *rcon = to_rcar_connector(connector); + + return rcon-encoder-encoder; +} + +static const struct drm_connector_helper_funcs connector_helper_funcs = { + .get_modes = rcar_du_connector_get_modes, +
[PATCH/RFC v3 07/19] video: display: Add pixel coding definitions
Pixel codings describe how pixels are transmitted on a physical bus. The information can be communicated between drivers to configure devices. Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- include/video/display.h | 120 1 file changed, 120 insertions(+) diff --git a/include/video/display.h b/include/video/display.h index 36ff637..ba319d6 100644 --- a/include/video/display.h +++ b/include/video/display.h @@ -18,6 +18,126 @@ #include linux/module.h #include media/media-entity.h +#define DISPLAY_PIXEL_CODING(option, type, from, to, variant) \ + (((option) 17) | ((type) 13) | ((variant) 10) | \ +((to) 5) | (from)) + +#define DISPLAY_PIXEL_CODING_FROM(coding) ((coding) 0x1f) +#define DISPLAY_PIXEL_CODING_TO(coding)(((coding) 5) 0x1f) +#define DISPLAY_PIXEL_CODING_VARIANT(coding) (((coding) 10) 7) +#define DISPLAY_PIXEL_CODING_TYPE(coding) (((coding) 13) 0xf) + +#define DISPLAY_PIXEL_CODING_TYPE_DBI 0 +#define DISPLAY_PIXEL_CODING_TYPE_DPI 1 + +/* DBI pixel codings. */ +#define DISPLAY_PIXEL_CODING_DBI(from, to, variant) \ + DISPLAY_PIXEL_CODING_TYPE(DISPLAY_PIXEL_CODING_TYPE_DBI, \ + from, to, variant, 0) + +/* Standard DBI codings, defined in the DBI specification. */ +/* 17 16 15 14 13 12 11 109876543 210 */ +/*---------- R0,2 R0,1 R0,0 G0,2 G0,1 G0,0 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_8TO8 DISPLAY_PIXEL_CODING_DBI(8, 8, 0) +/*---------- R0,3 R0,2 R0,1 R0,0 G0,3 G0,2 G0,1 G0,0 */ +/*---------- B0,3 B0,2 B0,1 B0,0 R1,3 R1,2 R1,1 R1,0 */ +/*---------- G1,3 G1,2 G1,1 G1,0 B1,3 B1,2 B1,1 b1,0 */ +#define DISPLAY_PIXEL_CODING_DBI_12TO8 DISPLAY_PIXEL_CODING_DBI(12, 8, 0) +/*---------- R0,4 R0,3 R0,2 R0,1 R0,0 G0,5 G0,4 G0,3 */ +/*---------- G0,2 G0,1 G0,0 B0,4 B0,3 B0,2 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_16TO8 DISPLAY_PIXEL_CODING_DBI(16, 8, 0) +/*---------- R0,5 R0,4 R0,3 R0,2 R0,1 R0,0-- */ +/*---------- G0,5 G0,4 G0,3 G0,2 G0,1 G0,0-- */ +/*---------- B0,5 B0,4 B0,3 B0,2 B0,1 B0,0-- */ +#define DISPLAY_PIXEL_CODING_DBI_18TO8 DISPLAY_PIXEL_CODING_DBI(18, 8, 0) +/*---------- R0,7 R0,6 R0,5 R0,4 R0,3 R0,2 R0,1 R0,0 */ +/*---------- G0,7 G0,6 G0,5 G0,4 G0,3 G0,2 G0,1 G0,0 */ +/*---------- B0,7 B0,6 B0,5 B0,4 B0,3 B0,2 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_24TO8 DISPLAY_PIXEL_CODING_DBI(24, 8, 0) +/*--------- R0,5 R0,4 R0,3 R0,2 R0,1 R0,0 G0,5 G0,4 G0,4 */ +/*--------- G0,2 G0,1 G0,0 B0,5 B0,4 B0,3 B0,2 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_18TO9 DISPLAY_PIXEL_CODING_DBI(18, 9, 0) +/*-- R1,2 R1,1 R1,0 G1,2 G1,1 G1,0 B1,1 B1,0 R0,2 R0,1 R0,0 G0,2 G0,1 G0,0 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_8TO16 DISPLAY_PIXEL_CODING_DBI(8, 16, 0) +/*------ R0,3 R0,2 R0,1 R0,0 G0,3 G0,2 G0,1 G0,0 B0,3 B0,2 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_12TO16 DISPLAY_PIXEL_CODING_DBI(12, 16, 0) +/*-- R0,4 R0,3 R0,2 R0,1 R0,0 G0,5 G0,4 G0,3 G0,2 G0,1 G0,0 B0,4 B0,3 B0,2 B0,1 B0,0 */ +#define DISPLAY_PIXEL_CODING_DBI_16TO16 DISPLAY_PIXEL_CODING_DBI(16, 16, 0) +/*-- R0,5 R0,4 R0,3 R0,2 R0,1 R0,0-- G0,5 G0,4 G0,3 G0,2 G0,1 G0,0-- */ +/*-- B0,5 B0,4 B0,3 B0,2 B0,1 B0,0-- R1,5 R1,4 R1,3 R1,2 R1,1 R1,0-- */ +/*-- G1,5 G1,4 G1,3 G1,2 G1,1 G1,0-- B1,5 B1,4 B1,3 B1,2 B1,1 B1,0-- */ +#define DISPLAY_PIXEL_CODING_DBI_18TO16_A DISPLAY_PIXEL_CODING_DBI(18, 16, 0) +/*---------- R0,5 R0,4 R0,3 R0,2 R0,1 R0,0-- */ +/*-- G0,5 G0,4 G0,3 G0,2 G0,1 G0,0-- B0,5 B0,4 B0,3 B0,2 B0,1 B0,0-- */ +#define DISPLAY_PIXEL_CODING_DBI_18TO16_B DISPLAY_PIXEL_CODING_DBI(18, 16, 1) +/*-- R0,7 R0,6 R0,5 R0,4 R0,3 R0,2 R0,1 R0,0 G0,7 G0,6 G0,5 G0,4 G0,3 G0,2 G0,1 G0,0 */ +/*-- B0,7 B0,6 B0,5 B0,4 B0,3 B0,2 B0,1 B0,0 R1,7 R1,6 R1,5 R1,4 R1,3 R1,2 R1,1 R1,0 */ +/*-- G1,7 G1,6 G1,5 G1,4 G1,3 G1,2 G1,1 G1,0 B1,7 B1,6 B1,5 B1,4 B1,3 B1,2 B1,1 B1,0 */ +#define DISPLAY_PIXEL_CODING_DBI_24TO16_A DISPLAY_PIXEL_CODING_DBI(24, 16, 0) +/*---------- R0,7 R0,6
[PATCH/RFC v3 08/19] video: display: Add MIPI DBI bus support
MIPI DBI is a configurable-width parallel display bus that transmits commands and data. Add a new DBI Linux bus type that implements the usual bus infrastructure (including devices and drivers (un)registration and matching, and bus configuration and access functions). Signed-off-by: Laurent Pinchart laurent.pinch...@ideasonboard.com --- drivers/video/display/Kconfig| 8 ++ drivers/video/display/Makefile | 1 + drivers/video/display/mipi-dbi-bus.c | 234 +++ include/video/display.h | 4 + include/video/mipi-dbi-bus.h | 125 +++ 5 files changed, 372 insertions(+) create mode 100644 drivers/video/display/mipi-dbi-bus.c create mode 100644 include/video/mipi-dbi-bus.h diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig index 1d533e7..f7532c1 100644 --- a/drivers/video/display/Kconfig +++ b/drivers/video/display/Kconfig @@ -2,3 +2,11 @@ menuconfig DISPLAY_CORE tristate Display Core ---help--- Support common display framework for graphics devices. + +if DISPLAY_CORE + +config DISPLAY_MIPI_DBI + tristate + default n + +endif # DISPLAY_CORE diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile index b907aad..59022d2 100644 --- a/drivers/video/display/Makefile +++ b/drivers/video/display/Makefile @@ -1,3 +1,4 @@ display-y := display-core.o \ display-notifier.o obj-$(CONFIG_DISPLAY_CORE) += display.o +obj-$(CONFIG_DISPLAY_MIPI_DBI) += mipi-dbi-bus.o diff --git a/drivers/video/display/mipi-dbi-bus.c b/drivers/video/display/mipi-dbi-bus.c new file mode 100644 index 000..791fb4d --- /dev/null +++ b/drivers/video/display/mipi-dbi-bus.c @@ -0,0 +1,234 @@ +/* + * MIPI DBI Bus + * + * Copyright (C) 2012 Renesas Solutions Corp. + * + * Contacts: Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/device.h +#include linux/export.h +#include linux/kernel.h +#include linux/list.h +#include linux/module.h +#include linux/mutex.h +#include linux/pm.h +#include linux/pm_runtime.h + +#include video/mipi-dbi-bus.h + +/* - + * Bus operations + */ + +int mipi_dbi_set_data_width(struct mipi_dbi_device *dev, unsigned int width) +{ + if (width != 8 width != 16) + return -EINVAL; + + dev-data_width = width; + return 0; +} +EXPORT_SYMBOL_GPL(mipi_dbi_set_data_width); + +int mipi_dbi_write_command(struct mipi_dbi_device *dev, u16 cmd) +{ + return dev-bus-ops-write_command(dev-bus, dev, cmd); +} +EXPORT_SYMBOL_GPL(mipi_dbi_write_command); + +int mipi_dbi_write_data(struct mipi_dbi_device *dev, const u8 *data, + size_t len) +{ + return dev-bus-ops-write_data(dev-bus, dev, data, len); +} +EXPORT_SYMBOL_GPL(mipi_dbi_write_data); + +int mipi_dbi_read_data(struct mipi_dbi_device *dev, u8 *data, size_t len) +{ + return dev-bus-ops-read_data(dev-bus, dev, data, len); +} +EXPORT_SYMBOL_GPL(mipi_dbi_read_data); + +/* - + * Bus type + */ + +static const struct mipi_dbi_device_id * +mipi_dbi_match_id(const struct mipi_dbi_device_id *id, + struct mipi_dbi_device *dev) +{ + while (id-name[0]) { + if (strcmp(dev-name, id-name) == 0) { + dev-id_entry = id; + return id; + } + id++; + } + return NULL; +} + +static int mipi_dbi_match(struct device *_dev, struct device_driver *_drv) +{ + struct mipi_dbi_device *dev = to_mipi_dbi_device(_dev); + struct mipi_dbi_driver *drv = to_mipi_dbi_driver(_drv); + + if (drv-id_table) + return mipi_dbi_match_id(drv-id_table, dev) != NULL; + + return (strcmp(dev-name, _drv-name) == 0); +} + +static ssize_t modalias_show(struct device *_dev, struct device_attribute *a, +char *buf) +{ + struct mipi_dbi_device *dev = to_mipi_dbi_device(_dev); + int len = snprintf(buf, PAGE_SIZE, MIPI_DBI_MODULE_PREFIX %s\n, + dev-name); + + return (len = PAGE_SIZE) ? (PAGE_SIZE - 1) : len; +} + +static struct device_attribute mipi_dbi_dev_attrs[] = { + __ATTR_RO(modalias), + __ATTR_NULL, +}; + +static int mipi_dbi_uevent(struct device *_dev, struct kobj_uevent_env *env) +{ + struct mipi_dbi_device *dev = to_mipi_dbi_device(_dev); + + add_uevent_var(env, MODALIAS=%s%s, MIPI_DBI_MODULE_PREFIX, + dev-name); + return 0; +} + +static
[PATCH/RFC v3 05/19] video: display: Graph helpers
Add two graph helper functions. display_entity_build_notifier() builds an entity notifier from an entities graph represented as a flat array, typically passed from platform data. display_entity_link_graph() can then be used to create media controller links between all entities in the graph. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/display/display-core.c | 107 +++ drivers/video/display/display-notifier.c | 51 +++ include/video/display.h | 20 ++ 3 files changed, 178 insertions(+) diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c index bb18723..c3b47d3 100644 --- a/drivers/video/display/display-core.c +++ b/drivers/video/display/display-core.c @@ -10,6 +10,7 @@ * published by the Free Software Foundation. */ +#include linux/device.h #include linux/export.h #include linux/kernel.h #include linux/module.h @@ -313,6 +314,112 @@ void display_entity_unregister(struct display_entity *entity) } EXPORT_SYMBOL_GPL(display_entity_unregister); +/* - + * Graph Helpers + */ + +static int display_entity_link_entity(struct device *dev, + struct display_entity *entity, + struct list_head *entities) +{ + const struct display_entity_graph_data *graph = entity-match-data; + u32 link_flags = MEDIA_LNK_FL_IMMUTABLE | MEDIA_LNK_FL_ENABLED; + struct media_entity *local = entity-entity; + unsigned int i; + int ret = 0; + + dev_dbg(dev, creating links for entity %s\n, local-name); + + for (i = 0; i entity-entity.num_pads; ++i) { + const struct display_entity_source_data *source; + struct media_pad *local_pad = local-pads[i]; + struct media_entity *remote = NULL; + struct media_pad *remote_pad; + struct display_entity *ent; + + dev_dbg(dev, processing pad %u\n, i); + + /* Skip source pads, they will be processed from the other end +* of the link. +*/ + if (local_pad-flags MEDIA_PAD_FL_SOURCE) { + dev_dbg(dev, skipping source pad %s:%u\n, + local-name, i); + continue; + } + + /* Find the remote entity. If not found, just skip the link as +* it goes out of scope of the entities handled by the notifier. +*/ + source = graph-sources[i]; + list_for_each_entry(ent, entities, list) { + if (strcmp(source-name, dev_name(ent-dev)) == 0) { + remote = ent-entity; + break; + } + } + + if (remote == NULL) { + dev_dbg(dev, no entity found for %s\n, source-name); + continue; + } + + if (source-port = remote-num_pads) { + dev_err(dev, invalid port number %u on %s\n, + source-port, source-name); + ret = -EINVAL; + break; + } + + remote_pad = remote-pads[source-port]; + + /* Create the media link. */ + dev_dbg(dev, creating %s:%u - %s:%u link\n, + remote-name, remote_pad-index, + local-name, local_pad-index); + + ret = media_entity_create_link(remote, remote_pad-index, + local, local_pad-index, + link_flags); + if (ret 0) { + dev_err(dev, failed to create %s:%u - %s:%u link\n, + remote-name, remote_pad-index, + local-name, local_pad-index); + break; + } + } + + return ret; +} + +/** + * display_entity_link_graph - Link all entities in a graph + * @dev: device used to print debugging and error messages + * @entities: list of display entities in the graph + * + * This function creates media controller links for all entities in a graph + * based on graph link data. It relies on the entities match data pointers + * having been initialized by the display_entity_build_notifier() function when + * building the notifier and thus can't be used when the notifier is built in a + * different way. + * + * Return 0 on success or a negative error code otherwise. + */ +int display_entity_link_graph(struct device *dev, struct list_head *entities) +{ + struct display_entity *entity; + int ret; + + list_for_each_entry(entity, entities, list) { +
[PATCH/RFC v3 13/19] video: display: Add VGA connector support
This driver exposes VGA connectors as display entity devices. The connectors are passive devices that pass analog VGA signals though. They optionally cary DDC signals for bidirectional control communications with the devices connected to the connectors. EDID retrieval isn't supported yet. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/display/Kconfig | 11 +++ drivers/video/display/Makefile | 1 + drivers/video/display/con-vga.c | 148 3 files changed, 160 insertions(+) create mode 100644 drivers/video/display/con-vga.c diff --git a/drivers/video/display/Kconfig b/drivers/video/display/Kconfig index 32ce08d..9b482a8 100644 --- a/drivers/video/display/Kconfig +++ b/drivers/video/display/Kconfig @@ -5,6 +5,17 @@ menuconfig DISPLAY_CORE if DISPLAY_CORE + +config DISPLAY_CONNECTOR_VGA + tristate VGA Connector + ---help--- + Support for simple digital (parallel) pixel interface panels. Those + panels receive pixel data through a parallel bus and have no control + bus. + + If you are in doubt, say N. To compile this driver as a module, choose + M here; the module will be called con-vga. + config DISPLAY_MIPI_DBI tristate default n diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile index 43cd78d..d03c64a 100644 --- a/drivers/video/display/Makefile +++ b/drivers/video/display/Makefile @@ -1,6 +1,7 @@ display-y := display-core.o \ display-notifier.o obj-$(CONFIG_DISPLAY_CORE) += display.o +obj-$(CONFIG_DISPLAY_CONNECTOR_VGA)+= con-vga.o obj-$(CONFIG_DISPLAY_MIPI_DBI) += mipi-dbi-bus.o obj-$(CONFIG_DISPLAY_PANEL_DPI)+= panel-dpi.o obj-$(CONFIG_DISPLAY_PANEL_R61505) += panel-r61505.o diff --git a/drivers/video/display/con-vga.c b/drivers/video/display/con-vga.c new file mode 100644 index 000..798ac9e --- /dev/null +++ b/drivers/video/display/con-vga.c @@ -0,0 +1,148 @@ +/* + * VGA Connector + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * Contacts: Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/kernel.h +#include linux/module.h +#include linux/of.h +#include linux/platform_device.h +#include linux/slab.h + +#include video/display.h + +struct con_vga { + struct display_entity entity; +}; + +static int con_vga_set_state(struct display_entity *entity, +enum display_entity_state state) +{ + struct media_pad *source; + + source = media_entity_remote_pad(entity-entity.pads[0]); + if (source == NULL) + return -EPIPE; + + switch (state) { + case DISPLAY_ENTITY_STATE_OFF: + case DISPLAY_ENTITY_STATE_STANDBY: + display_entity_set_stream(to_display_entity(source-entity), + source-index, + DISPLAY_ENTITY_STREAM_STOPPED); + break; + + case DISPLAY_ENTITY_STATE_ON: + display_entity_set_stream(to_display_entity(source-entity), + source-index, + DISPLAY_ENTITY_STREAM_CONTINUOUS); + break; + } + + return 0; +} + +static int con_vga_get_modes(struct display_entity *entity, unsigned int port, +const struct videomode **modes) +{ + /* TODO: Add EDID retrieval support. */ + return 0; +} + +static int con_vga_get_params(struct display_entity *entity, unsigned int port, + struct display_entity_interface_params *params) +{ + memset(params, 0, sizeof(*params)); + + params-type = DISPLAY_ENTITY_INTERFACE_VGA; + + return 0; +} + +static const struct display_entity_control_ops con_vga_control_ops = { + .set_state = con_vga_set_state, + .get_modes = con_vga_get_modes, + .get_params = con_vga_get_params, +}; + +static const struct display_entity_ops con_vga_ops = { + .ctrl = con_vga_control_ops, +}; + +static int con_vga_remove(struct platform_device *pdev) +{ + struct con_vga *con = platform_get_drvdata(pdev); + + display_entity_remove(con-entity); + display_entity_cleanup(con-entity); + + return 0; +} + +static int con_vga_probe(struct platform_device *pdev) +{ + struct con_vga *con; + int ret; + + con = devm_kzalloc(pdev-dev, sizeof(*con), GFP_KERNEL); + if (con == NULL) + return -ENOMEM; + + con-entity.dev = pdev-dev; + con-entity.ops = con_vga_ops; +
[PATCH/RFC v3 00/19] Common Display Framework
Hi everybody, Here's the third RFC of the Common Display Framework. This is a resent, the series I've sent earlier seems not to have made it to the vger mailing lists, possibly due to a too long list of CCs (the other explanation being that CDF has been delayed for so long that vger considers it as spam, which I really hope isn't the case :-)). I've thus dropped the CCs, sorry about that. I won't repeat all the background information from the versions one and two here, you can read it at http://lwn.net/Articles/512363/ and http://lwn.net/Articles/526965/. This RFC isn't final. Given the high interest in CDF and the urgent tasks that kept delaying the next version of the patch set, I've decided to release v3 before completing all parts of the implementation. Known missing items are - documentation: kerneldoc and this cover letter should provide basic information, more extensive documentation will likely make it to v4. - pipeline configuration and control: generic code to configure and control display pipelines (in a nutshell, translating high-level mode setting and DPMS calls to low-level entity operations) is missing. Video and stream control operations have been carried over from v2, but will need to be revised for v4. - DSI support: I still have no DSI hardware I can easily test the code on. Special thanks go to - Renesas for inviting me to LinuxCon Japan 2013 where I had the opportunity to validate the CDF v3 concepts with Alexandre Courbot (NVidia) and Tomasz Figa (Samsung). - Tomi Valkeinen (TI) for taking the time to deeply brainstorm v3 with me. - Linaro for inviting me to Linaro Connect Europe 2013, the discussions we had there greatly helped moving CDF forward. - And of course all the developers who showed interest in CDF and spent time sharing ideas, reviewing patches and testing code. I have to confess I was a bit lost and discouraged after all the CDF-related meetings during which we have discussed how to move from v2 to v3. With every meeting I was hoping to run the implementation through use cases of various interesting parties and narrow down the scope of the huge fuzzy beast that CDF was. With every meeting the scope actually broadened, with no clear path at sight anywhere. Earlier this year I was about to drop one of the requirements on which I had based CDF v2: sharing drivers between DRM/KMS and V4L2. With only two HDMI transmitters as use cases for that feature (with only out-of-tree drivers so far), I just thought the involved completely wasn't worth it and that I should implement CDF v3 as a DRM/KMS-only helper framework. However, a seemingly unrelated discussion with Xilinx developers showed me that hybrid SoC-FPGA platforms such as the Xilinx Zynq 7000 have a larger library of IP cores that can be used in camera capture pipelines and in display pipelines. The two use cases suddenly became tens or even hundreds of use cases that I couldn't ignore anymore. CDF v3 is thus userspace API agnostic. It isn't tied to DRM/KMS or V4L2 and can be used by any kernel subsystem, potentially including FBDEV (although I won't personally wrote FBDEV support code, as I've already advocated for FBDEV to be deprecated). The code you are about to read is based on the concept of display entities introduced in v2. Diagrams related to the explanations below are available at http://ideasonboard.org/media/cdf/20130709-lce-cdf.pdf. Display Entities A display entity abstracts any hardware block that sources, processes or sinks display-related video streams. It offers an abstract API, implemented by display entity drivers, that is used by master drivers (such as the main display driver) to query, configure and control display pipelines. Display entities are connected to at least one video data bus, and optionally to a control bus. The video data busses carry display-related video data out of sources (such as a CRTC in a display controller) to sinks (such as a panel or a monitor), optionally going through transmitters, encoders, decoders, bridges or other similar devices. A CRTC or a panel will usually be connected to a single data bus, while an encoder or a transmitter will be connected to two data busses. The simple linear display pipelines we find in most embedded platforms at the moment are expected to grow more complex with time. CDF needs to accomodate those needs from the start to be, if not future-proof, at least present-proof at the time it will get merged in to mainline. For this reason display entities have data ports through which video streams flow in or out, with link objects representing the connections between those ports. A typical entity in a linear display pipeline will have one (for video source and video sink entities such as CRTCs or panels) or two ports (for video processing entities such as encoders), but more ports are allowed, and entities can be linked in complex non-linear pipelines. Readers might think that this model if
[PATCH/RFC v3 03/19] video: display: Add video and stream control operations
The video and stream control operations handle video stream management, both from the control point of view (called in response to userspace requests) and the video stream point of view (called by entities to control the video stream they receive on their input(s)). Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/display/display-core.c | 82 include/video/display.h | 49 + 2 files changed, 131 insertions(+) diff --git a/drivers/video/display/display-core.c b/drivers/video/display/display-core.c index 82fc58b..bb18723 100644 --- a/drivers/video/display/display-core.c +++ b/drivers/video/display/display-core.c @@ -25,6 +25,57 @@ */ /** + * display_entity_set_state - Set the display entity operation state + * @entity: The display entity + * @state: Display entity operation state + * + * See enum display_entity_state for information regarding the entity states. + * + * Return 0 on success or a negative error code otherwise. + */ +int display_entity_set_state(struct display_entity *entity, +enum display_entity_state state) +{ + int ret; + + if (entity-state == state) + return 0; + + if (!entity-ops-ctrl || !entity-ops-ctrl-set_state) + return 0; + + ret = entity-ops-ctrl-set_state(entity, state); + if (ret 0) + return ret; + + entity-state = state; + return 0; +} +EXPORT_SYMBOL_GPL(display_entity_set_state); + +/** + * display_entity_update - Update the display + * @entity: The display entity + * + * Make the display entity ready to receive pixel data and start frame transfer. + * This operation can only be called if the display entity is in STANDBY or ON + * state. + * + * The display entity will call the upstream entity in the video chain to start + * the video stream. + * + * Return 0 on success or a negative error code otherwise. + */ +int display_entity_update(struct display_entity *entity) +{ + if (!entity-ops-ctrl || !entity-ops-ctrl-update) + return 0; + + return entity-ops-ctrl-update(entity); +} +EXPORT_SYMBOL_GPL(display_entity_update); + +/** * display_entity_get_modes - Get video modes supported by the display entity * @entity: The display entity * @port: The display entity port @@ -95,6 +146,36 @@ int display_entity_get_params(struct display_entity *entity, unsigned int port, EXPORT_SYMBOL_GPL(display_entity_get_params); /* - + * Video operations + */ + +/** + * display_entity_set_stream - Control the video stream state + * @entity: The display entity + * @port: The display entity port + * @state: Display video stream state + * + * Control the video stream state at the entity video output. + * + * See enum display_entity_stream_state for information regarding the stream + * states. + * + * Return 0 on success or a negative error code otherwise. + */ +int display_entity_set_stream(struct display_entity *entity, unsigned int port, + enum display_entity_stream_state state) +{ + if (port = entity-entity.num_pads) + return -EINVAL; + + if (!entity-ops-video || !entity-ops-video-set_stream) + return 0; + + return entity-ops-video-set_stream(entity, port, state); +} +EXPORT_SYMBOL_GPL(display_entity_set_stream); + +/* - * Connections */ @@ -177,6 +258,7 @@ int display_entity_init(struct display_entity *entity, unsigned int num_sinks, int ret; kref_init(entity-ref); + entity-state = DISPLAY_ENTITY_STATE_OFF; num_pads = num_sinks + num_sources; pads = kzalloc(sizeof(*pads) * num_pads, GFP_KERNEL); diff --git a/include/video/display.h b/include/video/display.h index 74b227d..fef05a68 100644 --- a/include/video/display.h +++ b/include/video/display.h @@ -25,6 +25,38 @@ struct display_entity; struct videomode; +/** + * enum display_entity_state - State of a display entity + * @DISPLAY_ENTITY_STATE_OFF: The entity is turned off completely, possibly + * including its power supplies. Communication with a display entity in + * that state is not possible. + * @DISPLAY_ENTITY_STATE_STANDBY: The entity is in a low-power state. Full + * communication with the display entity is supported, including pixel data + * transfer, but the output is kept blanked. + * @DISPLAY_ENTITY_STATE_ON: The entity is fully operational. + */ +enum display_entity_state { + DISPLAY_ENTITY_STATE_OFF, + DISPLAY_ENTITY_STATE_STANDBY, + DISPLAY_ENTITY_STATE_ON, +}; + +/** + * enum display_entity_stream_state - State of a video stream + * @DISPLAY_ENTITY_STREAM_STOPPED: The video stream is stopped, no frames are + * transferred. + *
[PATCH/RFC v3 04/19] video: display: Add display entity notifier
Display entities are initialized by they respective drivers asynchronously with the master display driver. The notifier infrastructure allows display drivers to create a list of entities they need (based on platform data) and be notified when those entities are added to or removed from the system. Signed-off-by: Laurent Pinchart laurent.pinchart+rene...@ideasonboard.com --- drivers/video/display/Makefile | 3 +- drivers/video/display/display-notifier.c | 304 +++ include/video/display.h | 66 +++ 3 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 drivers/video/display/display-notifier.c diff --git a/drivers/video/display/Makefile b/drivers/video/display/Makefile index 3054adc..b907aad 100644 --- a/drivers/video/display/Makefile +++ b/drivers/video/display/Makefile @@ -1,2 +1,3 @@ -display-y := display-core.o +display-y := display-core.o \ + display-notifier.o obj-$(CONFIG_DISPLAY_CORE) += display.o diff --git a/drivers/video/display/display-notifier.c b/drivers/video/display/display-notifier.c new file mode 100644 index 000..c9210ec --- /dev/null +++ b/drivers/video/display/display-notifier.c @@ -0,0 +1,304 @@ +/* + * Display Notifier + * + * Copyright (C) 2013 Renesas Solutions Corp. + * + * Contacts: Laurent Pinchart laurent.pinch...@ideasonboard.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include linux/device.h +#include linux/export.h +#include linux/kernel.h +#include linux/list.h +#include linux/mutex.h +#include linux/of.h + +#include video/display.h + +static LIST_HEAD(display_entity_list); +static LIST_HEAD(display_entity_notifiers); +static DEFINE_MUTEX(display_entity_mutex); + +/* - + * Notifiers + */ + +static bool match_platform(struct device *dev, + struct display_entity_match *match) +{ + pr_debug(%s: matching device '%s' with name '%s'\n, __func__, +dev_name(dev), match-match.platform.name); + + return !strcmp(match-match.platform.name, dev_name(dev)); +} + +static struct display_entity_match * +display_entity_notifier_match(struct display_entity_notifier *notifier, + struct display_entity *entity) +{ + bool (*match_func)(struct device *, struct display_entity_match *); + struct display_entity_match *match; + + pr_debug(%s: matching entity '%s' (ptr 0x%p dev '%s')\n, __func__, +entity-name, entity, dev_name(entity-dev)); + + list_for_each_entry(match, notifier-waiting, list) { + switch (match-type) { + default: + case DISPLAY_ENTITY_BUS_PLATFORM: + match_func = match_platform; + break; + } + + if (match_func(entity-dev, match)) + return match; + } + + return NULL; +} + +static void display_entity_notifier_cleanup(struct display_entity *entity) +{ + entity-match = NULL; + entity-notifier = NULL; +} + +static int +display_entity_notifier_notify(struct display_entity_notifier *notifier, + struct display_entity *entity, + struct display_entity_match *match) +{ + int ret; + + pr_debug(%s: notifying device '%s' for entity '%s' (ptr 0x%p dev '%s')\n, +__func__, dev_name(notifier-dev), entity-name, entity, +dev_name(entity-dev)); + + /* Remove the match from waiting list. */ + list_del(match-list); + entity-match = match; + entity-notifier = notifier; + + if (notifier-bound) { + ret = notifier-bound(notifier, entity, match); + if (ret 0) + goto error_bound; + } + + /* Move the entity from the global list to the notifier's done list. */ + list_move(entity-list, notifier-done); + + if (list_empty(notifier-waiting) notifier-complete) { + pr_debug(%s: notifying device '%s' of completion\n, __func__, +dev_name(notifier-dev)); + ret = notifier-complete(notifier); + if (ret 0) + goto error_complete; + } + + return 0; + +error_complete: + /* Move the entity back to the global list. */ + list_move(entity-list, display_entity_list); + if (notifier-unbind) + notifier-unbind(notifier, entity, match); +error_bound: + /* Put the match back to the waiting list. */ + list_add_tail(match-list, notifier-waiting); +
Re: [PATCH v4 10/13] [media] exynos5-fimc-is: Add the hardware interface module
On 08/07/2013 11:03 AM, Arun Kumar K wrote: The hardware interface module finally sends the commands to the FIMC-IS firmware and runs the interrupt handler for getting the responses. Signed-off-by: Arun Kumar Karun...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com --- .../media/platform/exynos5-is/fimc-is-interface.c | 810 .../media/platform/exynos5-is/fimc-is-interface.h | 125 +++ 2 files changed, 935 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/fimc-is-interface.c create mode 100644 drivers/media/platform/exynos5-is/fimc-is-interface.h diff --git a/drivers/media/platform/exynos5-is/fimc-is-interface.c b/drivers/media/platform/exynos5-is/fimc-is-interface.c new file mode 100644 index 000..9fcf89d --- /dev/null +++ b/drivers/media/platform/exynos5-is/fimc-is-interface.c @@ -0,0 +1,810 @@ +/* + * Samsung EXYNOS5 FIMC-IS (Imaging Subsystem) driver +* + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Kil-yeon Limkilyeon...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#includelinux/debugfs.h +#includelinux/seq_file.h +#include fimc-is.h +#include fimc-is-cmd.h +#include fimc-is-regs.h + +#define init_request_barrier(itf) mutex_init(itf-request_barrier) +#define enter_request_barrier(itf) mutex_lock(itf-request_barrier) +#define exit_request_barrier(itf) mutex_unlock(itf-request_barrier) + +static inline void itf_get_cmd(struct fimc_is_interface *itf, + struct fimc_is_msg *msg, unsigned int index) +{ + struct is_common_reg __iomem *com_regs = itf-com_regs; + + memset(msg, 0, sizeof(*msg)); + + switch (index) { + case INTR_GENERAL: + msg-command = com_regs-ihcmd; + msg-instance = com_regs-ihc_sensorid; + memcpy(msg-param, com_regs-ihc_param, + 4 * sizeof(msg-param[0])); + break; + case INTR_SCC_FDONE: + msg-command = IHC_FRAME_DONE; + msg-instance = com_regs-scc_sensor_id; + memcpy(msg-param, com_regs-scc_param, + 3 * sizeof(msg-param[0])); + break; + case INTR_SCP_FDONE: + msg-command = IHC_FRAME_DONE; + msg-instance = com_regs-scp_sensor_id; + memcpy(msg-param, com_regs-scp_param, + 3 * sizeof(msg-param[0])); + break; + case INTR_META_DONE: + msg-command = IHC_FRAME_DONE; + msg-instance = com_regs-meta_sensor_id; + msg-param[0] = com_regs-meta_param1; + break; + case INTR_SHOT_DONE: + msg-command = IHC_FRAME_DONE; + msg-instance = com_regs-shot_sensor_id; + memcpy(msg-param, com_regs-shot_param, + 2 * sizeof(msg-param[0])); + break; + default: + dev_err(itf-dev, %s Unknown command\n, __func__); + break; + } +} + +static inline unsigned int itf_get_intr(struct fimc_is_interface *itf) +{ + unsigned int status; + struct is_common_reg __iomem *com_regs = itf-com_regs; + + status = readl(itf-regs + INTMSR1) | com_regs-ihcmd_iflag | + com_regs-scc_iflag | + com_regs-scp_iflag | + com_regs-meta_iflag | + com_regs-shot_iflag; + + return status; +} + +static void itf_set_state(struct fimc_is_interface *itf, + unsigned long state) +{ + unsigned long flags; + spin_lock_irqsave(itf-slock_state, flags); + __set_bit(state,itf-state); + spin_unlock_irqrestore(itf-slock_state, flags); +} + +static void itf_clr_state(struct fimc_is_interface *itf, + unsigned long state) +{ + unsigned long flags; + spin_lock_irqsave(itf-slock_state, flags); + __clear_bit(state,itf-state); + spin_unlock_irqrestore(itf-slock_state, flags); +} + +static int itf_get_state(struct fimc_is_interface *itf, + unsigned long state) +{ + int ret = 0; + unsigned long flags; + + spin_lock_irqsave(itf-slock_state, flags); + ret = test_bit(state,itf-state); + spin_unlock_irqrestore(itf-slock_state, flags); + return ret; +} + +static void itf_init_wakeup(struct fimc_is_interface *itf) +{ + itf_set_state(itf, IS_IF_STATE_INIT); + wake_up(itf-irq_queue); +} + +void itf_busy_wakeup(struct fimc_is_interface *itf) +{ + itf_clr_state(itf, IS_IF_STATE_BUSY); + wake_up(itf-irq_queue); +} + +static int itf_wait_hw_ready(struct fimc_is_interface *itf) +{ + int t; + for (t = TRY_RECV_AWARE_COUNT; t= 0; t--) { + unsigned int cfg = readl(itf-regs + INTMSR0); + if
Re: [PATCH v4 11/13] [media] exynos5-is: Add Kconfig and Makefile
On 08/07/2013 11:03 AM, Arun Kumar K wrote: Adds Kconfig and Makefile for exynos5-is driver files. Signed-off-by: Shaik Ameer Bashashaik.am...@samsung.com Signed-off-by: Kilyeon Imkilyeon...@samsung.com Signed-off-by: Arun Kumar Karun...@samsung.com --- drivers/media/platform/Kconfig |1 + drivers/media/platform/Makefile|1 + drivers/media/platform/exynos5-is/Kconfig | 20 drivers/media/platform/exynos5-is/Makefile |7 +++ 4 files changed, 29 insertions(+) create mode 100644 drivers/media/platform/exynos5-is/Kconfig create mode 100644 drivers/media/platform/exynos5-is/Makefile diff --git a/drivers/media/platform/Kconfig b/drivers/media/platform/Kconfig index 08de865..4b0475e 100644 --- a/drivers/media/platform/Kconfig +++ b/drivers/media/platform/Kconfig @@ -123,6 +123,7 @@ config VIDEO_S3C_CAMIF source drivers/media/platform/soc_camera/Kconfig source drivers/media/platform/exynos4-is/Kconfig +source drivers/media/platform/exynos5-is/Kconfig source drivers/media/platform/s5p-tv/Kconfig endif # V4L_PLATFORM_DRIVERS diff --git a/drivers/media/platform/Makefile b/drivers/media/platform/Makefile index eee28dd..40bf09f 100644 --- a/drivers/media/platform/Makefile +++ b/drivers/media/platform/Makefile @@ -37,6 +37,7 @@ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_TV)+= s5p-tv/ obj-$(CONFIG_VIDEO_SAMSUNG_S5P_G2D) += s5p-g2d/ obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC)+= exynos-gsc/ +obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS5_CAMERA) += exynos5-is/ obj-$(CONFIG_BLACKFIN) += blackfin/ diff --git a/drivers/media/platform/exynos5-is/Kconfig b/drivers/media/platform/exynos5-is/Kconfig new file mode 100644 index 000..c872757 --- /dev/null +++ b/drivers/media/platform/exynos5-is/Kconfig @@ -0,0 +1,20 @@ +config VIDEO_SAMSUNG_EXYNOS5_CAMERA + bool Samsung Exynos5 Media Device driver Samsung Exynos5 SoC Camera Media Device driver ? + depends on VIDEO_V4L2 VIDEO_V4L2_SUBDEV_API PM_RUNTIME + depends on VIDEO_SAMSUNG_EXYNOS4_IS + help + This is a v4l2 based media controller driver for + Exynos5 SoC. Or perhaps: This is a V4L2 media device driver for Exynos5 SoC series camera subsystem. ? + +if VIDEO_SAMSUNG_EXYNOS5_CAMERA + +config VIDEO_SAMSUNG_EXYNOS5_FIMC_IS + tristate Samsung Exynos5 SoC FIMC-IS driver + depends on I2C OF + depends on VIDEO_EXYNOS4_FIMC_IS + select VIDEOBUF2_DMA_CONTIG + help + This is a V4L2 driver for Samsung Exynos5 SoC series Imaging + Subsystem known as FIMC-IS. + +endif #VIDEO_SAMSUNG_EXYNOS5_MDEV diff --git a/drivers/media/platform/exynos5-is/Makefile b/drivers/media/platform/exynos5-is/Makefile new file mode 100644 index 000..6cdb037 --- /dev/null +++ b/drivers/media/platform/exynos5-is/Makefile @@ -0,0 +1,7 @@ +ccflags-y += -Idrivers/media/platform/exynos4-is +exynos5-fimc-is-objs := fimc-is-core.o fimc-is-isp.o fimc-is-scaler.o +exynos5-fimc-is-objs += fimc-is-pipeline.o fimc-is-interface.o fimc-is-sensor.o +exynos-mdevice-objs := exynos5-mdev.o + +obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS5_FIMC_IS) += exynos5-fimc-is.o +obj-$(CONFIG_VIDEO_SAMSUNG_EXYNOS5_CAMERA) += exynos-mdevice.o Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 12/13] V4L: s5k6a3: Change sensor min/max resolutions
On 08/07/2013 11:04 AM, Arun Kumar K wrote: s5k6a3 sensor has actual pixel resolution of 1408x1402 against the active resolution 1392x1392. The real resolution is needed when raw sensor SRGB data is dumped to memory by fimc-lite. Signed-off-by: Arun Kumar Karun...@samsung.com --- drivers/media/i2c/s5k6a3.c | 21 + 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/media/i2c/s5k6a3.c b/drivers/media/i2c/s5k6a3.c index ccbb4fc..6dec2ec 100644 --- a/drivers/media/i2c/s5k6a3.c +++ b/drivers/media/i2c/s5k6a3.c @@ -25,10 +25,14 @@ #includemedia/v4l2-async.h #includemedia/v4l2-subdev.h -#define S5K6A3_SENSOR_MAX_WIDTH1392 -#define S5K6A3_SENSOR_MAX_HEIGHT 1392 -#define S5K6A3_SENSOR_MIN_WIDTH32 -#define S5K6A3_SENSOR_MIN_HEIGHT 32 +#define S5K6A3_SENSOR_MAX_WIDTH1408 +#define S5K6A3_SENSOR_MAX_HEIGHT 1408 Don't you want this to be 1402 ? + Empty line could be removed. +#define S5K6A3_SENSOR_ACTIVE_WIDTH 1392 +#define S5K6A3_SENSOR_ACTIVE_HEIGHT1392 + Ditto. +#define S5K6A3_SENSOR_MIN_WIDTH(32 + 16) +#define S5K6A3_SENSOR_MIN_HEIGHT (32 + 10) #define S5K6A3_DEF_PIX_WIDTH 1296 #define S5K6A3_DEF_PIX_HEIGHT 732 @@ -107,10 +111,11 @@ static void s5k6a3_try_format(struct v4l2_mbus_framefmt *mf) fmt = find_sensor_format(mf); mf-code = fmt-code; - v4l_bound_align_image(mf-width, S5K6A3_SENSOR_MIN_WIDTH, - S5K6A3_SENSOR_MAX_WIDTH, 0, - mf-height, S5K6A3_SENSOR_MIN_HEIGHT, - S5K6A3_SENSOR_MAX_HEIGHT, 0, 0); + v4l_bound_align_image(mf-width, + S5K6A3_SENSOR_MIN_WIDTH, S5K6A3_SENSOR_MAX_WIDTH, 0, + mf-height, + S5K6A3_SENSOR_MIN_HEIGHT, S5K6A3_SENSOR_MAX_HEIGHT, 0, + 0); } static struct v4l2_mbus_framefmt *__s5k6a3_get_format( Reviewed-by: Sylwester Nawrocki s.nawro...@samsung.com -- Thanks, Sylwester -- To unsubscribe from this list: send the line unsubscribe linux-media in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 13/13] V4L: Add driver for s5k4e5 image sensor
On 08/07/2013 11:04 AM, Arun Kumar K wrote: This patch adds subdev driver for Samsung S5K4E5 raw image sensor. Like s5k6a3, it is also another fimc-is firmware controlled sensor. This minimal sensor driver doesn't do any I2C communications as its done by ISP firmware. It can be updated if needed to a regular sensor driver by adding the I2C communication. Signed-off-by: Arun Kumar Karun...@samsung.com --- .../devicetree/bindings/media/i2c/s5k4e5.txt | 44 +++ drivers/media/i2c/Kconfig |8 + drivers/media/i2c/Makefile |1 + drivers/media/i2c/s5k4e5.c | 361 4 files changed, 414 insertions(+) create mode 100644 Documentation/devicetree/bindings/media/i2c/s5k4e5.txt create mode 100644 drivers/media/i2c/s5k4e5.c diff --git a/Documentation/devicetree/bindings/media/i2c/s5k4e5.txt b/Documentation/devicetree/bindings/media/i2c/s5k4e5.txt new file mode 100644 index 000..88dd726 --- /dev/null +++ b/Documentation/devicetree/bindings/media/i2c/s5k4e5.txt @@ -0,0 +1,44 @@ +* Samsung S5K4E5 Raw Image Sensor + +S5K4E5 is a raw image sensor with maximum resolution of 2560x1920 +pixels. Data transfer is carried out via MIPI-CSI2 port and controls s/MIPI-CSI2/MIPI CSI-2 ? +via I2C bus. + +Required Properties: +- compatible : must be samsung,s5k4e5 +- reg : I2C device address +- gpios: reset gpio pin +- clocks : clock specifier for the clock-names property. +- clock-names : must contain mclk entry and matching clock property + entry. Perhaps just: - clock-names : must contain mclk entry ? +- svdda-supply : core voltage supply +- svddio-supply: I/O voltage supply + +Optional Properties: +- clock-frequency : operating frequency for the sensor +default value will be taken if not provided. + +The device node should be added to their control bus controller (e.g. s/their/respective ? +I2C0) nodes and linked to the csis port node, using the common video +interfaces bindings, defined in video-interfaces.txt. + +Example: + + i2c-isp@1313 { + s5k4e5@20 { + compatible = samsung,s5k4e5; + reg =0x20; + gpios =gpx1 2 1; + clock-frequency =2400; + clocks =clock 129; + clock-names = mclk; + svdda-supply =...; + svddio-supply =...; + port { + is_s5k4e5_ep: endpoint { + data-lanes =1 2 3 4; + remote-endpoint =csis0_ep; + }; + }; + }; + }; diff --git a/drivers/media/i2c/Kconfig b/drivers/media/i2c/Kconfig index f7e9147..271028b 100644 --- a/drivers/media/i2c/Kconfig +++ b/drivers/media/i2c/Kconfig @@ -572,6 +572,14 @@ config VIDEO_S5K6A3 This is a V4L2 sensor-level driver for Samsung S5K6A3 raw camera sensor. +config VIDEO_S5K4E5 + tristate Samsung S5K4E5 sensor support + depends on MEDIA_CAMERA_SUPPORT + depends on I2C VIDEO_V4L2 VIDEO_V4L2_SUBDEV_API OF + ---help--- + This is a V4L2 sensor-level driver for Samsung S5K4E5 raw + camera sensor. + config VIDEO_S5K4ECGX tristate Samsung S5K4ECGX sensor support depends on I2C VIDEO_V4L2 VIDEO_V4L2_SUBDEV_API diff --git a/drivers/media/i2c/Makefile b/drivers/media/i2c/Makefile index cf3cf03..0aeed8e 100644 --- a/drivers/media/i2c/Makefile +++ b/drivers/media/i2c/Makefile @@ -65,6 +65,7 @@ obj-$(CONFIG_VIDEO_SR030PC30) += sr030pc30.o obj-$(CONFIG_VIDEO_NOON010PC30) += noon010pc30.o obj-$(CONFIG_VIDEO_S5K6AA)+= s5k6aa.o obj-$(CONFIG_VIDEO_S5K6A3)+= s5k6a3.o +obj-$(CONFIG_VIDEO_S5K4E5) += s5k4e5.o obj-$(CONFIG_VIDEO_S5K4ECGX) += s5k4ecgx.o obj-$(CONFIG_VIDEO_S5C73M3) += s5c73m3/ obj-$(CONFIG_VIDEO_ADP1653) += adp1653.o diff --git a/drivers/media/i2c/s5k4e5.c b/drivers/media/i2c/s5k4e5.c new file mode 100644 index 000..0a6ece6 --- /dev/null +++ b/drivers/media/i2c/s5k4e5.c @@ -0,0 +1,361 @@ +/* + * Samsung S5K4E5 image sensor driver + * + * Copyright (C) 2013 Samsung Electronics Co., Ltd. + * Author: Arun Kumar Karun...@samsung.com + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#includelinux/clk.h +#includelinux/delay.h +#includelinux/device.h +#includelinux/errno.h +#includelinux/gpio.h +#includelinux/i2c.h +#includelinux/kernel.h +#includelinux/module.h +#includelinux/of_gpio.h +#includelinux/pm_runtime.h +#includelinux/regulator/consumer.h +#includelinux/slab.h +#includelinux/videodev2.h